flag(enable_intra_edge_filter);
if (current->reduced_still_picture_header) {
- infer(enable_intraintra_compound, 0);
+ infer(enable_interintra_compound, 0);
infer(enable_masked_compound, 0);
infer(enable_warped_motion, 0);
infer(enable_dual_filter, 0);
infer(seq_force_integer_mv,
AV1_SELECT_INTEGER_MV);
} else {
- flag(enable_intraintra_compound);
+ flag(enable_interintra_compound);
flag(enable_masked_compound);
flag(enable_warped_motion);
flag(enable_dual_filter);
return 0;
}
+static int FUNC(set_frame_refs)(CodedBitstreamContext *ctx, RWContext *rw,
+ AV1RawFrameHeader *current)
+{
+ CodedBitstreamAV1Context *priv = ctx->priv_data;
+ const AV1RawSequenceHeader *seq = priv->sequence_header;
+ static const uint8_t ref_frame_list[AV1_NUM_REF_FRAMES - 2] = {
+ AV1_REF_FRAME_LAST2, AV1_REF_FRAME_LAST3, AV1_REF_FRAME_BWDREF,
+ AV1_REF_FRAME_ALTREF2, AV1_REF_FRAME_ALTREF
+ };
+ int8_t ref_frame_idx[AV1_REFS_PER_FRAME], used_frame[AV1_NUM_REF_FRAMES];
+ int8_t shifted_order_hints[AV1_NUM_REF_FRAMES];
+ int cur_frame_hint, latest_order_hint, earliest_order_hint, ref;
+ int i, j;
+
+ for (i = 0; i < AV1_REFS_PER_FRAME; i++)
+ ref_frame_idx[i] = -1;
+ ref_frame_idx[AV1_REF_FRAME_LAST - AV1_REF_FRAME_LAST] = current->last_frame_idx;
+ ref_frame_idx[AV1_REF_FRAME_GOLDEN - AV1_REF_FRAME_LAST] = current->golden_frame_idx;
+
+ for (i = 0; i < AV1_NUM_REF_FRAMES; i++)
+ used_frame[i] = 0;
+ used_frame[current->last_frame_idx] = 1;
+ used_frame[current->golden_frame_idx] = 1;
+
+ cur_frame_hint = 1 << (seq->order_hint_bits_minus_1);
+ for (i = 0; i < AV1_NUM_REF_FRAMES; i++)
+ shifted_order_hints[i] = cur_frame_hint +
+ cbs_av1_get_relative_dist(seq, priv->ref[i].order_hint,
+ current->order_hint);
+
+ latest_order_hint = shifted_order_hints[current->last_frame_idx];
+ earliest_order_hint = shifted_order_hints[current->golden_frame_idx];
+
+ ref = -1;
+ for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+ int hint = shifted_order_hints[i];
+ if (!used_frame[i] && hint >= cur_frame_hint &&
+ (ref < 0 || hint >= latest_order_hint)) {
+ ref = i;
+ latest_order_hint = hint;
+ }
+ }
+ if (ref >= 0) {
+ ref_frame_idx[AV1_REF_FRAME_ALTREF - AV1_REF_FRAME_LAST] = ref;
+ used_frame[ref] = 1;
+ }
+
+ ref = -1;
+ for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+ int hint = shifted_order_hints[i];
+ if (!used_frame[i] && hint >= cur_frame_hint &&
+ (ref < 0 || hint < earliest_order_hint)) {
+ ref = i;
+ earliest_order_hint = hint;
+ }
+ }
+ if (ref >= 0) {
+ ref_frame_idx[AV1_REF_FRAME_BWDREF - AV1_REF_FRAME_LAST] = ref;
+ used_frame[ref] = 1;
+ }
+
+ ref = -1;
+ for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+ int hint = shifted_order_hints[i];
+ if (!used_frame[i] && hint >= cur_frame_hint &&
+ (ref < 0 || hint < earliest_order_hint)) {
+ ref = i;
+ earliest_order_hint = hint;
+ }
+ }
+ if (ref >= 0) {
+ ref_frame_idx[AV1_REF_FRAME_ALTREF2 - AV1_REF_FRAME_LAST] = ref;
+ used_frame[ref] = 1;
+ }
+
+ for (i = 0; i < AV1_REFS_PER_FRAME - 2; i++) {
+ int ref_frame = ref_frame_list[i];
+ if (ref_frame_idx[ref_frame - AV1_REF_FRAME_LAST] < 0 ) {
+ ref = -1;
+ for (j = 0; j < AV1_NUM_REF_FRAMES; j++) {
+ int hint = shifted_order_hints[j];
+ if (!used_frame[j] && hint < cur_frame_hint &&
+ (ref < 0 || hint >= latest_order_hint)) {
+ ref = j;
+ latest_order_hint = hint;
+ }
+ }
+ if (ref >= 0) {
+ ref_frame_idx[ref_frame - AV1_REF_FRAME_LAST] = ref;
+ used_frame[ref] = 1;
+ }
+ }
+ }
+
+ ref = -1;
+ for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+ int hint = shifted_order_hints[i];
+ if (ref < 0 || hint < earliest_order_hint) {
+ ref = i;
+ earliest_order_hint = hint;
+ }
+ }
+ for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
+ if (ref_frame_idx[i] < 0)
+ ref_frame_idx[i] = ref;
+ infer(ref_frame_idx[i], ref_frame_idx[i]);
+ }
+
+ return 0;
+}
+
static int FUNC(superres_params)(CodedBitstreamContext *ctx, RWContext *rw,
AV1RawFrameHeader *current)
{
forward_idx = -1;
backward_idx = -1;
for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
- ref_hint = priv->ref[i].order_hint;
+ ref_hint = priv->ref[current->ref_frame_idx[i]].order_hint;
dist = cbs_av1_get_relative_dist(seq, ref_hint,
current->order_hint);
if (dist < 0) {
second_forward_idx = -1;
for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
- ref_hint = priv->ref[i].order_hint;
+ ref_hint = priv->ref[current->ref_frame_idx[i]].order_hint;
if (cbs_av1_get_relative_dist(seq, ref_hint,
forward_hint) < 0) {
if (second_forward_idx < 0 ||
return 0;
}
- fb(4, num_y_points);
+ fc(4, num_y_points, 0, 14);
for (i = 0; i < current->num_y_points; i++) {
fbs(8, point_y_value[i], 1, i);
fbs(8, point_y_scaling[i], 1, i);
if (current->frame_refs_short_signaling) {
fb(3, last_frame_idx);
fb(3, golden_frame_idx);
-
- for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
- if (i == 0)
- infer(ref_frame_idx[i], current->last_frame_idx);
- else if (i == AV1_REF_FRAME_GOLDEN -
- AV1_REF_FRAME_LAST)
- infer(ref_frame_idx[i], current->golden_frame_idx);
- else
- infer(ref_frame_idx[i], -1);
- }
+ CHECK(FUNC(set_frame_refs)(ctx, rw, current));
}
}
int err, i;
for (i = 0; i < 3; i++) {
- fcs(16, primary_chromaticity_x[i], 0, 50000, 1, i);
- fcs(16, primary_chromaticity_y[i], 0, 50000, 1, i);
+ fbs(16, primary_chromaticity_x[i], 1, i);
+ fbs(16, primary_chromaticity_y[i], 1, i);
}
- fc(16, white_point_chromaticity_x, 0, 50000);
- fc(16, white_point_chromaticity_y, 0, 50000);
+ fb(16, white_point_chromaticity_x);
+ fb(16, white_point_chromaticity_y);
fc(32, luminance_max, 1, MAX_UINT_BITS(32));
- fc(32, luminance_min, 0, current->luminance_max >> 6);
+ // luminance_min must be lower than luminance_max. Convert luminance_max from
+ // 24.8 fixed point to 18.14 fixed point in order to compare them.
+ fc(32, luminance_min, 0, FFMIN(((uint64_t)current->luminance_max << 6) - 1,
+ MAX_UINT_BITS(32)));
+
+ return 0;
+}
+
+static int FUNC(scalability_structure)(CodedBitstreamContext *ctx, RWContext *rw,
+ AV1RawMetadataScalability *current)
+{
+ CodedBitstreamAV1Context *priv = ctx->priv_data;
+ const AV1RawSequenceHeader *seq;
+ int err, i, j;
+
+ if (!priv->sequence_header) {
+ av_log(ctx->log_ctx, AV_LOG_ERROR, "No sequence header available: "
+ "unable to parse scalability metadata.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ seq = priv->sequence_header;
+
+ fb(2, spatial_layers_cnt_minus_1);
+ flag(spatial_layer_dimensions_present_flag);
+ flag(spatial_layer_description_present_flag);
+ flag(temporal_group_description_present_flag);
+ fc(3, scalability_structure_reserved_3bits, 0, 0);
+ if (current->spatial_layer_dimensions_present_flag) {
+ for (i = 0; i <= current->spatial_layers_cnt_minus_1; i++) {
+ fcs(16, spatial_layer_max_width[i],
+ 0, seq->max_frame_width_minus_1 + 1, 1, i);
+ fcs(16, spatial_layer_max_height[i],
+ 0, seq->max_frame_height_minus_1 + 1, 1, i);
+ }
+ }
+ if (current->spatial_layer_description_present_flag) {
+ for (i = 0; i <= current->spatial_layers_cnt_minus_1; i++)
+ fbs(8, spatial_layer_ref_id[i], 1, i);
+ }
+ if (current->temporal_group_description_present_flag) {
+ fb(8, temporal_group_size);
+ for (i = 0; i < current->temporal_group_size; i++) {
+ fbs(3, temporal_group_temporal_id[i], 1, i);
+ flags(temporal_group_temporal_switching_up_point_flag[i], 1, i);
+ flags(temporal_group_spatial_switching_up_point_flag[i], 1, i);
+ fbs(3, temporal_group_ref_cnt[i], 1, i);
+ for (j = 0; j < current->temporal_group_ref_cnt[i]; j++) {
+ fbs(8, temporal_group_ref_pic_diff[i][j], 2, i, j);
+ }
+ }
+ }
return 0;
}
static int FUNC(metadata_scalability)(CodedBitstreamContext *ctx, RWContext *rw,
AV1RawMetadataScalability *current)
{
- // TODO: scalability metadata.
+ int err;
- return AVERROR_PATCHWELCOME;
+ fb(8, scalability_mode_idc);
+
+ if (current->scalability_mode_idc == AV1_SCALABILITY_SS)
+ CHECK(FUNC(scalability_structure)(ctx, rw, current));
+
+ return 0;
}
static int FUNC(metadata_itut_t35)(CodedBitstreamContext *ctx, RWContext *rw,
#ifdef READ
// The payload runs up to the start of the trailing bits, but there might
// be arbitrarily many trailing zeroes so we need to read through twice.
- {
- GetBitContext tmp = *rw;
- current->payload_size = 0;
- for (i = 0; get_bits_left(rw) >= 8; i++) {
- if (get_bits(rw, 8))
- current->payload_size = i;
- }
- *rw = tmp;
- }
+ current->payload_size = cbs_av1_get_payload_bytes_left(rw);
current->payload_ref = av_buffer_alloc(current->payload_size);
if (!current->payload_ref)
fb(9, n_frames);
if (current->full_timestamp_flag) {
- fb(6, seconds_value);
- fb(6, minutes_value);
- fb(5, hours_value);
+ fc(6, seconds_value, 0, 59);
+ fc(6, minutes_value, 0, 59);
+ fc(5, hours_value, 0, 23);
} else {
flag(seconds_flag);
if (current->seconds_flag) {
- fb(6, seconds_value);
+ fc(6, seconds_value, 0, 59);
flag(minutes_flag);
if (current->minutes_flag) {
- fb(6, minutes_value);
+ fc(6, minutes_value, 0, 59);
flag(hours_flag);
if (current->hours_flag)
- fb(5, hours_value);
+ fc(5, hours_value, 0, 23);
}
}
}
fb(5, time_offset_length);
if (current->time_offset_length > 0)
fb(current->time_offset_length, time_offset_value);
+ else
+ infer(time_offset_length, 0);
return 0;
}
return 0;
}
+
+static int FUNC(padding_obu)(CodedBitstreamContext *ctx, RWContext *rw,
+ AV1RawPadding *current)
+{
+ int i, err;
+
+ HEADER("Padding");
+
+#ifdef READ
+ // The payload runs up to the start of the trailing bits, but there might
+ // be arbitrarily many trailing zeroes so we need to read through twice.
+ current->payload_size = cbs_av1_get_payload_bytes_left(rw);
+
+ current->payload_ref = av_buffer_alloc(current->payload_size);
+ if (!current->payload_ref)
+ return AVERROR(ENOMEM);
+ current->payload = current->payload_ref->data;
+#endif
+
+ for (i = 0; i < current->payload_size; i++)
+ xf(8, obu_padding_byte[i], current->payload[i], 0x00, 0xff, 1, i);
+
+ return 0;
+}