Move some vars from AV1_COMMON to SequenceHeader
These are part of the sequence header OBU and so belong in the
SequenceHeader struct.
Related:
- Use SequenceHeader / other small structs in function params when we
can, instead of passing whole AV1_COMMON struct.
- Update to are_seq_headers_consistent() function.
- Remove aom_op_timing_info_t struct that had a single member to
reduce indirection
- Documentation for these vars.
BUG=aomedia:2610
Change-Id: I33f1c4492eabd67d9f4dde54e482cecce38db9d3
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h
index 942edf2..a078149 100644
--- a/av1/common/av1_common_int.h
+++ b/av1/common/av1_common_int.h
@@ -223,6 +223,8 @@
// Note: All syntax elements of sequence_header_obu that need to be
// bit-identical across multiple sequence headers must be part of this struct,
// so that consistency is checked by are_seq_headers_consistent() function.
+// One exception is the last member 'op_params' that is ignored by
+// are_seq_headers_consistent() function.
typedef struct SequenceHeader {
int num_bits_width;
int num_bits_height;
@@ -261,15 +263,6 @@
uint8_t enable_restoration; // To turn on/off loop restoration
BITSTREAM_PROFILE profile;
- // Operating point info.
- int operating_points_cnt_minus_1;
- int operating_point_idc[MAX_NUM_OPERATING_POINTS];
- uint8_t display_model_info_present_flag;
- uint8_t decoder_model_info_present_flag;
- AV1_LEVEL seq_level_idx[MAX_NUM_OPERATING_POINTS];
- uint8_t tier[MAX_NUM_OPERATING_POINTS]; // seq_tier in the spec. One bit: 0
- // or 1.
-
// Color config.
aom_bit_depth_t bit_depth; // AOM_BITS_8 in profile 0 or 1,
// AOM_BITS_10 or AOM_BITS_12 in profile 2 or 3.
@@ -284,6 +277,22 @@
aom_chroma_sample_position_t chroma_sample_position;
uint8_t separate_uv_delta_q;
uint8_t film_grain_params_present;
+
+ // Operating point info.
+ int operating_points_cnt_minus_1;
+ int operating_point_idc[MAX_NUM_OPERATING_POINTS];
+ int timing_info_present;
+ aom_timing_info_t timing_info;
+ uint8_t decoder_model_info_present_flag;
+ aom_dec_model_info_t decoder_model_info;
+ uint8_t display_model_info_present_flag;
+ AV1_LEVEL seq_level_idx[MAX_NUM_OPERATING_POINTS];
+ uint8_t tier[MAX_NUM_OPERATING_POINTS]; // seq_tier in spec. One bit: 0 or 1.
+
+ // IMPORTANT: the op_params member must be at the end of the struct so that
+ // are_seq_headers_consistent() can be implemented with a memcmp() call.
+ // TODO(urvang): We probably don't need the +1 here.
+ aom_dec_model_op_parameters_t op_params[MAX_NUM_OPERATING_POINTS + 1];
} SequenceHeader;
typedef struct {
@@ -520,12 +529,16 @@
// Note: The numerator is fixed to be SCALE_NUMERATOR.
uint8_t superres_scale_denominator;
- int timing_info_present;
- aom_timing_info_t timing_info;
- int buffer_removal_time_present;
- aom_dec_model_info_t buffer_model;
- aom_dec_model_op_parameters_t op_params[MAX_NUM_OPERATING_POINTS + 1];
- aom_op_timing_info_t op_frame_timing[MAX_NUM_OPERATING_POINTS + 1];
+ // If true, buffer removal times are present.
+ bool buffer_removal_time_present;
+ // buffer_removal_times[op_num] specifies the frame removal time in units of
+ // DecCT clock ticks counted from the removal time of the last random access
+ // point for operating point op_num.
+ // TODO(urvang): We probably don't need the +1 here.
+ uint32_t buffer_removal_times[MAX_NUM_OPERATING_POINTS + 1];
+ // Presentation time of the frame in clock ticks DispCT counted from the
+ // removal time of the last random access point for the operating point that
+ // is being decoded.
uint32_t frame_presentation_time;
// Buffer where previous frame is stored.
diff --git a/av1/common/timing.h b/av1/common/timing.h
index 9aca58f..9192124 100644
--- a/av1/common/timing.h
+++ b/av1/common/timing.h
@@ -42,10 +42,6 @@
int initial_display_delay;
} aom_dec_model_op_parameters_t;
-typedef struct aom_op_timing_info_t {
- uint32_t buffer_removal_time;
-} aom_op_timing_info_t;
-
void av1_set_aom_dec_model_info(aom_dec_model_info_t *decoder_model);
void av1_set_dec_model_op_parameters(aom_dec_model_op_parameters_t *op_params);
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 3634dec..84fda91 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4327,64 +4327,59 @@
seq_params->separate_uv_delta_q = aom_rb_read_bit(rb);
}
-void av1_read_timing_info_header(AV1_COMMON *cm,
+void av1_read_timing_info_header(aom_timing_info_t *timing_info,
+ struct aom_internal_error_info *error,
struct aom_read_bit_buffer *rb) {
- cm->timing_info.num_units_in_display_tick = aom_rb_read_unsigned_literal(
- rb, 32); // Number of units in a display tick
- cm->timing_info.time_scale =
- aom_rb_read_unsigned_literal(rb, 32); // Time scale
- if (cm->timing_info.num_units_in_display_tick == 0 ||
- cm->timing_info.time_scale == 0) {
+ timing_info->num_units_in_display_tick =
+ aom_rb_read_unsigned_literal(rb,
+ 32); // Number of units in a display tick
+ timing_info->time_scale = aom_rb_read_unsigned_literal(rb, 32); // Time scale
+ if (timing_info->num_units_in_display_tick == 0 ||
+ timing_info->time_scale == 0) {
aom_internal_error(
- &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
+ error, AOM_CODEC_UNSUP_BITSTREAM,
"num_units_in_display_tick and time_scale must be greater than 0.");
}
- cm->timing_info.equal_picture_interval =
+ timing_info->equal_picture_interval =
aom_rb_read_bit(rb); // Equal picture interval bit
- if (cm->timing_info.equal_picture_interval) {
+ if (timing_info->equal_picture_interval) {
const uint32_t num_ticks_per_picture_minus_1 = aom_rb_read_uvlc(rb);
if (num_ticks_per_picture_minus_1 == UINT32_MAX) {
aom_internal_error(
- &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
+ error, AOM_CODEC_UNSUP_BITSTREAM,
"num_ticks_per_picture_minus_1 cannot be (1 << 32) − 1.");
}
- cm->timing_info.num_ticks_per_picture = num_ticks_per_picture_minus_1 + 1;
+ timing_info->num_ticks_per_picture = num_ticks_per_picture_minus_1 + 1;
}
}
-void av1_read_decoder_model_info(AV1_COMMON *cm,
+void av1_read_decoder_model_info(aom_dec_model_info_t *decoder_model_info,
struct aom_read_bit_buffer *rb) {
- cm->buffer_model.encoder_decoder_buffer_delay_length =
+ decoder_model_info->encoder_decoder_buffer_delay_length =
aom_rb_read_literal(rb, 5) + 1;
- cm->buffer_model.num_units_in_decoding_tick = aom_rb_read_unsigned_literal(
- rb, 32); // Number of units in a decoding tick
- cm->buffer_model.buffer_removal_time_length = aom_rb_read_literal(rb, 5) + 1;
- cm->buffer_model.frame_presentation_time_length =
+ decoder_model_info->num_units_in_decoding_tick =
+ aom_rb_read_unsigned_literal(rb,
+ 32); // Number of units in a decoding tick
+ decoder_model_info->buffer_removal_time_length =
+ aom_rb_read_literal(rb, 5) + 1;
+ decoder_model_info->frame_presentation_time_length =
aom_rb_read_literal(rb, 5) + 1;
}
-void av1_read_op_parameters_info(AV1_COMMON *const cm,
- struct aom_read_bit_buffer *rb, int op_num) {
- // The cm->op_params array has MAX_NUM_OPERATING_POINTS + 1 elements.
- if (op_num > MAX_NUM_OPERATING_POINTS) {
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "AV1 does not support %d decoder model operating points",
- op_num + 1);
- }
-
- cm->op_params[op_num].decoder_buffer_delay = aom_rb_read_unsigned_literal(
- rb, cm->buffer_model.encoder_decoder_buffer_delay_length);
-
- cm->op_params[op_num].encoder_buffer_delay = aom_rb_read_unsigned_literal(
- rb, cm->buffer_model.encoder_decoder_buffer_delay_length);
-
- cm->op_params[op_num].low_delay_mode_flag = aom_rb_read_bit(rb);
+void av1_read_op_parameters_info(aom_dec_model_op_parameters_t *op_params,
+ int buffer_delay_length,
+ struct aom_read_bit_buffer *rb) {
+ op_params->decoder_buffer_delay =
+ aom_rb_read_unsigned_literal(rb, buffer_delay_length);
+ op_params->encoder_buffer_delay =
+ aom_rb_read_unsigned_literal(rb, buffer_delay_length);
+ op_params->low_delay_mode_flag = aom_rb_read_bit(rb);
}
static AOM_INLINE void read_temporal_point_info(
AV1_COMMON *const cm, struct aom_read_bit_buffer *rb) {
cm->frame_presentation_time = aom_rb_read_unsigned_literal(
- rb, cm->buffer_model.frame_presentation_time_length);
+ rb, cm->seq_params.decoder_model_info.frame_presentation_time_length);
}
void av1_read_sequence_header(AV1_COMMON *cm, struct aom_read_bit_buffer *rb,
@@ -4703,7 +4698,7 @@
"Buffer does not contain a decoded frame");
}
if (seq_params->decoder_model_info_present_flag &&
- cm->timing_info.equal_picture_interval == 0) {
+ seq_params->timing_info.equal_picture_interval == 0) {
read_temporal_point_info(cm, rb);
}
if (seq_params->frame_id_numbers_present_flag) {
@@ -4781,7 +4776,7 @@
cm->showable_frame = current_frame->frame_type != KEY_FRAME;
if (cm->show_frame) {
if (seq_params->decoder_model_info_present_flag &&
- cm->timing_info.equal_picture_interval == 0)
+ seq_params->timing_info.equal_picture_interval == 0)
read_temporal_point_info(cm, rb);
} else {
// See if this frame can be used as show_existing_frame in future
@@ -4882,7 +4877,7 @@
if (cm->buffer_removal_time_present) {
for (int op_num = 0;
op_num < seq_params->operating_points_cnt_minus_1 + 1; op_num++) {
- if (cm->op_params[op_num].decoder_model_param_present_flag) {
+ if (seq_params->op_params[op_num].decoder_model_param_present_flag) {
if ((((seq_params->operating_point_idc[op_num] >>
cm->temporal_layer_id) &
0x1) &&
@@ -4890,14 +4885,13 @@
(cm->spatial_layer_id + 8)) &
0x1)) ||
seq_params->operating_point_idc[op_num] == 0) {
- cm->op_frame_timing[op_num].buffer_removal_time =
- aom_rb_read_unsigned_literal(
- rb, cm->buffer_model.buffer_removal_time_length);
+ cm->buffer_removal_times[op_num] = aom_rb_read_unsigned_literal(
+ rb, seq_params->decoder_model_info.buffer_removal_time_length);
} else {
- cm->op_frame_timing[op_num].buffer_removal_time = 0;
+ cm->buffer_removal_times[op_num] = 0;
}
} else {
- cm->op_frame_timing[op_num].buffer_removal_time = 0;
+ cm->buffer_removal_times[op_num] = 0;
}
}
}
diff --git a/av1/decoder/decodeframe.h b/av1/decoder/decodeframe.h
index 13b9696..95b3c9f 100644
--- a/av1/decoder/decodeframe.h
+++ b/av1/decoder/decodeframe.h
@@ -56,19 +56,21 @@
struct aom_internal_error_info *error_info);
// Implements the timing_info() function in the spec. Reports errors by calling
-// rb->error_handler().
-void av1_read_timing_info_header(AV1_COMMON *cm,
+// rb->error_handler() or aom_internal_error().
+void av1_read_timing_info_header(aom_timing_info_t *timing_info,
+ struct aom_internal_error_info *error,
struct aom_read_bit_buffer *rb);
// Implements the decoder_model_info() function in the spec. Reports errors by
// calling rb->error_handler().
-void av1_read_decoder_model_info(AV1_COMMON *cm,
+void av1_read_decoder_model_info(aom_dec_model_info_t *decoder_model_info,
struct aom_read_bit_buffer *rb);
// Implements the operating_parameters_info() function in the spec. Reports
-// errors by calling rb->error_handler() or aom_internal_error().
-void av1_read_op_parameters_info(AV1_COMMON *const cm,
- struct aom_read_bit_buffer *rb, int op_num);
+// errors by calling rb->error_handler().
+void av1_read_op_parameters_info(aom_dec_model_op_parameters_t *op_params,
+ int buffer_delay_length,
+ struct aom_read_bit_buffer *rb);
struct aom_read_bit_buffer *av1_init_read_bit_buffer(
struct AV1Decoder *pbi, struct aom_read_bit_buffer *rb, const uint8_t *data,
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index f8f944d..791e596 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -87,10 +87,14 @@
}
// Returns whether two sequence headers are consistent with each other.
-// TODO(huisu,wtc@google.com): make sure the code matches the spec exactly.
+// Note that the 'op_params' field is not compared per Section 7.5 in the spec:
+// Within a particular coded video sequence, the contents of
+// sequence_header_obu must be bit-identical each time the sequence header
+// appears except for the contents of operating_parameters_info.
static int are_seq_headers_consistent(const SequenceHeader *seq_params_old,
const SequenceHeader *seq_params_new) {
- return !memcmp(seq_params_old, seq_params_new, sizeof(SequenceHeader));
+ return !memcmp(seq_params_old, seq_params_new,
+ offsetof(SequenceHeader, op_params));
}
// On success, sets pbi->sequence_header_ready to 1 and returns the number of
@@ -125,7 +129,7 @@
}
if (seq_params->reduced_still_picture_hdr) {
- cm->timing_info_present = 0;
+ seq_params->timing_info_present = 0;
seq_params->decoder_model_info_present_flag = 0;
seq_params->display_model_info_present_flag = 0;
seq_params->operating_points_cnt_minus_1 = 0;
@@ -135,16 +139,16 @@
return 0;
}
seq_params->tier[0] = 0;
- cm->op_params[0].decoder_model_param_present_flag = 0;
- cm->op_params[0].display_model_param_present_flag = 0;
+ seq_params->op_params[0].decoder_model_param_present_flag = 0;
+ seq_params->op_params[0].display_model_param_present_flag = 0;
} else {
- cm->timing_info_present = aom_rb_read_bit(rb); // timing_info_present_flag
- if (cm->timing_info_present) {
- av1_read_timing_info_header(cm, rb);
+ seq_params->timing_info_present = aom_rb_read_bit(rb);
+ if (seq_params->timing_info_present) {
+ av1_read_timing_info_header(&seq_params->timing_info, &cm->error, rb);
seq_params->decoder_model_info_present_flag = aom_rb_read_bit(rb);
if (seq_params->decoder_model_info_present_flag)
- av1_read_decoder_model_info(cm, rb);
+ av1_read_decoder_model_info(&seq_params->decoder_model_info, rb);
} else {
seq_params->decoder_model_info_present_flag = 0;
}
@@ -165,51 +169,57 @@
else
seq_params->tier[i] = 0;
if (seq_params->decoder_model_info_present_flag) {
- cm->op_params[i].decoder_model_param_present_flag = aom_rb_read_bit(rb);
- if (cm->op_params[i].decoder_model_param_present_flag)
- av1_read_op_parameters_info(cm, rb, i);
+ seq_params->op_params[i].decoder_model_param_present_flag =
+ aom_rb_read_bit(rb);
+ if (seq_params->op_params[i].decoder_model_param_present_flag)
+ av1_read_op_parameters_info(&seq_params->op_params[i],
+ seq_params->decoder_model_info
+ .encoder_decoder_buffer_delay_length,
+ rb);
} else {
- cm->op_params[i].decoder_model_param_present_flag = 0;
+ seq_params->op_params[i].decoder_model_param_present_flag = 0;
}
- if (cm->timing_info_present &&
- (cm->timing_info.equal_picture_interval ||
- cm->op_params[i].decoder_model_param_present_flag)) {
- cm->op_params[i].bitrate = av1_max_level_bitrate(
+ if (seq_params->timing_info_present &&
+ (seq_params->timing_info.equal_picture_interval ||
+ seq_params->op_params[i].decoder_model_param_present_flag)) {
+ seq_params->op_params[i].bitrate = av1_max_level_bitrate(
seq_params->profile, seq_params->seq_level_idx[i],
seq_params->tier[i]);
// Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass
// the check
- if (cm->op_params[i].bitrate == 0)
+ if (seq_params->op_params[i].bitrate == 0)
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"AV1 does not support this combination of "
"profile, level, and tier.");
// Buffer size in bits/s is bitrate in bits/s * 1 s
- cm->op_params[i].buffer_size = cm->op_params[i].bitrate;
+ seq_params->op_params[i].buffer_size = seq_params->op_params[i].bitrate;
}
- if (cm->timing_info_present && cm->timing_info.equal_picture_interval &&
- !cm->op_params[i].decoder_model_param_present_flag) {
+ if (seq_params->timing_info_present &&
+ seq_params->timing_info.equal_picture_interval &&
+ !seq_params->op_params[i].decoder_model_param_present_flag) {
// When the decoder_model_parameters are not sent for this op, set
// the default ones that can be used with the resource availability mode
- cm->op_params[i].decoder_buffer_delay = 70000;
- cm->op_params[i].encoder_buffer_delay = 20000;
- cm->op_params[i].low_delay_mode_flag = 0;
+ seq_params->op_params[i].decoder_buffer_delay = 70000;
+ seq_params->op_params[i].encoder_buffer_delay = 20000;
+ seq_params->op_params[i].low_delay_mode_flag = 0;
}
if (seq_params->display_model_info_present_flag) {
- cm->op_params[i].display_model_param_present_flag = aom_rb_read_bit(rb);
- if (cm->op_params[i].display_model_param_present_flag) {
- cm->op_params[i].initial_display_delay =
+ seq_params->op_params[i].display_model_param_present_flag =
+ aom_rb_read_bit(rb);
+ if (seq_params->op_params[i].display_model_param_present_flag) {
+ seq_params->op_params[i].initial_display_delay =
aom_rb_read_literal(rb, 4) + 1;
- if (cm->op_params[i].initial_display_delay > 10)
+ if (seq_params->op_params[i].initial_display_delay > 10)
aom_internal_error(
&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"AV1 does not support more than 10 decoded frames delay");
} else {
- cm->op_params[i].initial_display_delay = 10;
+ seq_params->op_params[i].initial_display_delay = 10;
}
} else {
- cm->op_params[i].display_model_param_present_flag = 0;
- cm->op_params[i].initial_display_delay = 10;
+ seq_params->op_params[i].display_model_param_present_flag = 0;
+ seq_params->op_params[i].initial_display_delay = 10;
}
}
}
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 324ce4c..24d42e7 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2425,61 +2425,44 @@
}
static AOM_INLINE void write_timing_info_header(
- AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) {
- aom_wb_write_unsigned_literal(wb, cm->timing_info.num_units_in_display_tick,
- 32); // Number of units in tick
- aom_wb_write_unsigned_literal(wb, cm->timing_info.time_scale,
- 32); // Time scale
- aom_wb_write_bit(
- wb,
- cm->timing_info.equal_picture_interval); // Equal picture interval bit
- if (cm->timing_info.equal_picture_interval) {
- aom_wb_write_uvlc(
- wb,
- cm->timing_info.num_ticks_per_picture - 1); // ticks per picture
+ const aom_timing_info_t *const timing_info,
+ struct aom_write_bit_buffer *wb) {
+ aom_wb_write_unsigned_literal(wb, timing_info->num_units_in_display_tick, 32);
+ aom_wb_write_unsigned_literal(wb, timing_info->time_scale, 32);
+ aom_wb_write_bit(wb, timing_info->equal_picture_interval);
+ if (timing_info->equal_picture_interval) {
+ aom_wb_write_uvlc(wb, timing_info->num_ticks_per_picture - 1);
}
}
static AOM_INLINE void write_decoder_model_info(
- AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) {
+ const aom_dec_model_info_t *const decoder_model_info,
+ struct aom_write_bit_buffer *wb) {
aom_wb_write_literal(
- wb, cm->buffer_model.encoder_decoder_buffer_delay_length - 1, 5);
- aom_wb_write_unsigned_literal(wb, cm->buffer_model.num_units_in_decoding_tick,
- 32); // Number of units in decoding tick
- aom_wb_write_literal(wb, cm->buffer_model.buffer_removal_time_length - 1, 5);
- aom_wb_write_literal(wb, cm->buffer_model.frame_presentation_time_length - 1,
+ wb, decoder_model_info->encoder_decoder_buffer_delay_length - 1, 5);
+ aom_wb_write_unsigned_literal(
+ wb, decoder_model_info->num_units_in_decoding_tick, 32);
+ aom_wb_write_literal(wb, decoder_model_info->buffer_removal_time_length - 1,
5);
+ aom_wb_write_literal(
+ wb, decoder_model_info->frame_presentation_time_length - 1, 5);
}
static AOM_INLINE void write_dec_model_op_parameters(
- AV1_COMMON *const cm, struct aom_write_bit_buffer *wb, int op_num) {
- if (op_num > MAX_NUM_OPERATING_POINTS)
- aom_internal_error(
- &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "Encoder does not support %d decoder model operating points", op_num);
-
- // aom_wb_write_bit(wb, cm->op_params[op_num].has_parameters);
- // if (!cm->op_params[op_num].has_parameters) return;
-
- aom_wb_write_unsigned_literal(
- wb, cm->op_params[op_num].decoder_buffer_delay,
- cm->buffer_model.encoder_decoder_buffer_delay_length);
-
- aom_wb_write_unsigned_literal(
- wb, cm->op_params[op_num].encoder_buffer_delay,
- cm->buffer_model.encoder_decoder_buffer_delay_length);
-
- aom_wb_write_bit(wb, cm->op_params[op_num].low_delay_mode_flag);
-
- cm->op_frame_timing[op_num].buffer_removal_time =
- 0; // reset the decoded frame counter
+ const aom_dec_model_op_parameters_t *op_params, int buffer_delay_length,
+ struct aom_write_bit_buffer *wb) {
+ aom_wb_write_unsigned_literal(wb, op_params->decoder_buffer_delay,
+ buffer_delay_length);
+ aom_wb_write_unsigned_literal(wb, op_params->encoder_buffer_delay,
+ buffer_delay_length);
+ aom_wb_write_bit(wb, op_params->low_delay_mode_flag);
}
static AOM_INLINE void write_tu_pts_info(AV1_COMMON *const cm,
struct aom_write_bit_buffer *wb) {
aom_wb_write_unsigned_literal(
wb, cm->frame_presentation_time,
- cm->buffer_model.frame_presentation_time_length);
+ cm->seq_params.decoder_model_info.frame_presentation_time_length);
}
static AOM_INLINE void write_film_grain_params(
@@ -2844,7 +2827,7 @@
aom_wb_write_literal(wb, cpi->existing_fb_idx_to_show, 3);
if (seq_params->decoder_model_info_present_flag &&
- cm->timing_info.equal_picture_interval == 0) {
+ seq_params->timing_info.equal_picture_interval == 0) {
write_tu_pts_info(cm, wb);
}
if (seq_params->frame_id_numbers_present_flag) {
@@ -2862,7 +2845,7 @@
aom_wb_write_bit(wb, cm->show_frame);
if (cm->show_frame) {
if (seq_params->decoder_model_info_present_flag &&
- cm->timing_info.equal_picture_interval == 0)
+ seq_params->timing_info.equal_picture_interval == 0)
write_tu_pts_info(cm, wb);
} else {
aom_wb_write_bit(wb, cm->showable_frame);
@@ -2932,7 +2915,7 @@
if (cm->buffer_removal_time_present) {
for (int op_num = 0;
op_num < seq_params->operating_points_cnt_minus_1 + 1; op_num++) {
- if (cm->op_params[op_num].decoder_model_param_present_flag) {
+ if (seq_params->op_params[op_num].decoder_model_param_present_flag) {
if (((seq_params->operating_point_idc[op_num] >>
cm->temporal_layer_id) &
0x1 &&
@@ -2941,10 +2924,10 @@
0x1) ||
seq_params->operating_point_idc[op_num] == 0) {
aom_wb_write_unsigned_literal(
- wb, cm->op_frame_timing[op_num].buffer_removal_time,
- cm->buffer_model.buffer_removal_time_length);
- cm->op_frame_timing[op_num].buffer_removal_time++;
- if (cm->op_frame_timing[op_num].buffer_removal_time == 0) {
+ wb, cm->buffer_removal_times[op_num],
+ seq_params->decoder_model_info.buffer_removal_time_length);
+ cm->buffer_removal_times[op_num]++;
+ if (cm->buffer_removal_times[op_num] == 0) {
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"buffer_removal_time overflowed");
}
@@ -3331,68 +3314,74 @@
aom_wb_write_literal(wb, seq_level_idx, LEVEL_BITS);
}
-uint32_t av1_write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst) {
- AV1_COMMON *const cm = &cpi->common;
+uint32_t av1_write_sequence_header_obu(const SequenceHeader *seq_params,
+ uint8_t *const dst) {
struct aom_write_bit_buffer wb = { dst, 0 };
uint32_t size = 0;
- write_profile(cm->seq_params.profile, &wb);
+ write_profile(seq_params->profile, &wb);
// Still picture or not
- aom_wb_write_bit(&wb, cm->seq_params.still_picture);
- assert(IMPLIES(!cm->seq_params.still_picture,
- !cm->seq_params.reduced_still_picture_hdr));
+ aom_wb_write_bit(&wb, seq_params->still_picture);
+ assert(IMPLIES(!seq_params->still_picture,
+ !seq_params->reduced_still_picture_hdr));
// whether to use reduced still picture header
- aom_wb_write_bit(&wb, cm->seq_params.reduced_still_picture_hdr);
+ aom_wb_write_bit(&wb, seq_params->reduced_still_picture_hdr);
- if (cm->seq_params.reduced_still_picture_hdr) {
- assert(cm->timing_info_present == 0);
- assert(cm->seq_params.decoder_model_info_present_flag == 0);
- assert(cm->seq_params.display_model_info_present_flag == 0);
- write_bitstream_level(cm->seq_params.seq_level_idx[0], &wb);
+ if (seq_params->reduced_still_picture_hdr) {
+ assert(seq_params->timing_info_present == 0);
+ assert(seq_params->decoder_model_info_present_flag == 0);
+ assert(seq_params->display_model_info_present_flag == 0);
+ write_bitstream_level(seq_params->seq_level_idx[0], &wb);
} else {
- aom_wb_write_bit(&wb, cm->timing_info_present); // timing info present flag
+ aom_wb_write_bit(
+ &wb, seq_params->timing_info_present); // timing info present flag
- if (cm->timing_info_present) {
+ if (seq_params->timing_info_present) {
// timing_info
- write_timing_info_header(cm, &wb);
- aom_wb_write_bit(&wb, cm->seq_params.decoder_model_info_present_flag);
- if (cm->seq_params.decoder_model_info_present_flag) {
- write_decoder_model_info(cm, &wb);
+ write_timing_info_header(&seq_params->timing_info, &wb);
+ aom_wb_write_bit(&wb, seq_params->decoder_model_info_present_flag);
+ if (seq_params->decoder_model_info_present_flag) {
+ write_decoder_model_info(&seq_params->decoder_model_info, &wb);
}
}
- aom_wb_write_bit(&wb, cm->seq_params.display_model_info_present_flag);
- aom_wb_write_literal(&wb, cm->seq_params.operating_points_cnt_minus_1,
+ aom_wb_write_bit(&wb, seq_params->display_model_info_present_flag);
+ aom_wb_write_literal(&wb, seq_params->operating_points_cnt_minus_1,
OP_POINTS_CNT_MINUS_1_BITS);
int i;
- for (i = 0; i < cm->seq_params.operating_points_cnt_minus_1 + 1; i++) {
- aom_wb_write_literal(&wb, cm->seq_params.operating_point_idc[i],
+ for (i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; i++) {
+ aom_wb_write_literal(&wb, seq_params->operating_point_idc[i],
OP_POINTS_IDC_BITS);
- write_bitstream_level(cm->seq_params.seq_level_idx[i], &wb);
- if (cm->seq_params.seq_level_idx[i] >= SEQ_LEVEL_4_0)
- aom_wb_write_bit(&wb, cm->seq_params.tier[i]);
- if (cm->seq_params.decoder_model_info_present_flag) {
- aom_wb_write_bit(&wb,
- cm->op_params[i].decoder_model_param_present_flag);
- if (cm->op_params[i].decoder_model_param_present_flag)
- write_dec_model_op_parameters(cm, &wb, i);
+ write_bitstream_level(seq_params->seq_level_idx[i], &wb);
+ if (seq_params->seq_level_idx[i] >= SEQ_LEVEL_4_0)
+ aom_wb_write_bit(&wb, seq_params->tier[i]);
+ if (seq_params->decoder_model_info_present_flag) {
+ aom_wb_write_bit(
+ &wb, seq_params->op_params[i].decoder_model_param_present_flag);
+ if (seq_params->op_params[i].decoder_model_param_present_flag) {
+ write_dec_model_op_parameters(
+ &seq_params->op_params[i],
+ seq_params->decoder_model_info
+ .encoder_decoder_buffer_delay_length,
+ &wb);
+ }
}
- if (cm->seq_params.display_model_info_present_flag) {
- aom_wb_write_bit(&wb,
- cm->op_params[i].display_model_param_present_flag);
- if (cm->op_params[i].display_model_param_present_flag) {
- assert(cm->op_params[i].initial_display_delay <= 10);
- aom_wb_write_literal(&wb, cm->op_params[i].initial_display_delay - 1,
- 4);
+ if (seq_params->display_model_info_present_flag) {
+ aom_wb_write_bit(
+ &wb, seq_params->op_params[i].display_model_param_present_flag);
+ if (seq_params->op_params[i].display_model_param_present_flag) {
+ assert(seq_params->op_params[i].initial_display_delay <= 10);
+ aom_wb_write_literal(
+ &wb, seq_params->op_params[i].initial_display_delay - 1, 4);
}
}
}
}
- write_sequence_header(&cm->seq_params, &wb);
+ write_sequence_header(seq_params, &wb);
- write_color_config(&cm->seq_params, &wb);
+ write_color_config(seq_params, &wb);
- aom_wb_write_bit(&wb, cm->seq_params.film_grain_params_present);
+ aom_wb_write_bit(&wb, seq_params->film_grain_params_present);
add_trailing_bits(&wb);
@@ -3858,7 +3847,7 @@
obu_header_size = av1_write_obu_header(cpi, OBU_SEQUENCE_HEADER, 0, data);
obu_payload_size =
- av1_write_sequence_header_obu(cpi, data + obu_header_size);
+ av1_write_sequence_header_obu(&cm->seq_params, data + obu_header_size);
const size_t length_field_size =
obu_memmove(obu_header_size, obu_payload_size, data);
if (av1_write_uleb_obu_size(obu_header_size, obu_payload_size, data) !=
diff --git a/av1/encoder/bitstream.h b/av1/encoder/bitstream.h
index 24530ce..51e0059 100644
--- a/av1/encoder/bitstream.h
+++ b/av1/encoder/bitstream.h
@@ -23,7 +23,8 @@
// Writes only the OBU Sequence Header payload, and returns the size of the
// payload written to 'dst'. This function does not write the OBU header, the
// optional extension, or the OBU size to 'dst'.
-uint32_t av1_write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst);
+uint32_t av1_write_sequence_header_obu(const SequenceHeader *seq_params,
+ uint8_t *const dst);
// Writes the OBU header byte, and the OBU header extension byte when
// 'obu_extension' is non-zero. Returns number of bytes written to 'dst'.
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 22b87ee..e67b8ca 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -1285,20 +1285,21 @@
level = SEQ_LEVEL_6_2;
}
+ SequenceHeader *const seq_params = &cm->seq_params;
for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
seq->seq_level_idx[i] = level;
// Set the maximum parameters for bitrate and buffer size for this profile,
// level, and tier
- cm->op_params[i].bitrate = av1_max_level_bitrate(
+ seq_params->op_params[i].bitrate = av1_max_level_bitrate(
cm->seq_params.profile, seq->seq_level_idx[i], seq->tier[i]);
// Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass the
// check
- if (cm->op_params[i].bitrate == 0)
+ if (seq_params->op_params[i].bitrate == 0)
aom_internal_error(
&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"AV1 does not support this combination of profile, level, and tier.");
// Buffer size in bits/s is bitrate in bits/s * 1 s
- cm->op_params[i].buffer_size = cm->op_params[i].bitrate;
+ seq_params->op_params[i].buffer_size = seq_params->op_params[i].bitrate;
}
}
@@ -1379,78 +1380,79 @@
static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
AV1_COMMON *const cm = &cpi->common;
+ SequenceHeader *const seq_params = &cm->seq_params;
cpi->oxcf = *oxcf;
cpi->framerate = oxcf->init_framerate;
- cm->seq_params.profile = oxcf->profile;
- cm->seq_params.bit_depth = oxcf->bit_depth;
- cm->seq_params.use_highbitdepth = oxcf->use_highbitdepth;
- cm->seq_params.color_primaries = oxcf->color_primaries;
- cm->seq_params.transfer_characteristics = oxcf->transfer_characteristics;
- cm->seq_params.matrix_coefficients = oxcf->matrix_coefficients;
- cm->seq_params.monochrome = oxcf->monochrome;
- cm->seq_params.chroma_sample_position = oxcf->chroma_sample_position;
- cm->seq_params.color_range = oxcf->color_range;
- cm->timing_info_present = oxcf->timing_info_present;
- cm->timing_info.num_units_in_display_tick =
+ seq_params->profile = oxcf->profile;
+ seq_params->bit_depth = oxcf->bit_depth;
+ seq_params->use_highbitdepth = oxcf->use_highbitdepth;
+ seq_params->color_primaries = oxcf->color_primaries;
+ seq_params->transfer_characteristics = oxcf->transfer_characteristics;
+ seq_params->matrix_coefficients = oxcf->matrix_coefficients;
+ seq_params->monochrome = oxcf->monochrome;
+ seq_params->chroma_sample_position = oxcf->chroma_sample_position;
+ seq_params->color_range = oxcf->color_range;
+ seq_params->timing_info_present = oxcf->timing_info_present;
+ seq_params->timing_info.num_units_in_display_tick =
oxcf->timing_info.num_units_in_display_tick;
- cm->timing_info.time_scale = oxcf->timing_info.time_scale;
- cm->timing_info.equal_picture_interval =
+ seq_params->timing_info.time_scale = oxcf->timing_info.time_scale;
+ seq_params->timing_info.equal_picture_interval =
oxcf->timing_info.equal_picture_interval;
- cm->timing_info.num_ticks_per_picture =
+ seq_params->timing_info.num_ticks_per_picture =
oxcf->timing_info.num_ticks_per_picture;
- cm->seq_params.display_model_info_present_flag =
+ seq_params->display_model_info_present_flag =
oxcf->display_model_info_present_flag;
- cm->seq_params.decoder_model_info_present_flag =
+ seq_params->decoder_model_info_present_flag =
oxcf->decoder_model_info_present_flag;
if (oxcf->decoder_model_info_present_flag) {
// set the decoder model parameters in schedule mode
- cm->buffer_model.num_units_in_decoding_tick =
+ seq_params->decoder_model_info.num_units_in_decoding_tick =
oxcf->buffer_model.num_units_in_decoding_tick;
cm->buffer_removal_time_present = 1;
- av1_set_aom_dec_model_info(&cm->buffer_model);
- av1_set_dec_model_op_parameters(&cm->op_params[0]);
- } else if (cm->timing_info_present &&
- cm->timing_info.equal_picture_interval &&
- !cm->seq_params.decoder_model_info_present_flag) {
+ av1_set_aom_dec_model_info(&seq_params->decoder_model_info);
+ av1_set_dec_model_op_parameters(&seq_params->op_params[0]);
+ } else if (seq_params->timing_info_present &&
+ seq_params->timing_info.equal_picture_interval &&
+ !seq_params->decoder_model_info_present_flag) {
// set the decoder model parameters in resource availability mode
- av1_set_resource_availability_parameters(&cm->op_params[0]);
+ av1_set_resource_availability_parameters(&seq_params->op_params[0]);
} else {
- cm->op_params[0].initial_display_delay =
+ seq_params->op_params[0].initial_display_delay =
10; // Default value (not signaled)
}
- if (cm->seq_params.monochrome) {
- cm->seq_params.subsampling_x = 1;
- cm->seq_params.subsampling_y = 1;
- } else if (cm->seq_params.color_primaries == AOM_CICP_CP_BT_709 &&
- cm->seq_params.transfer_characteristics == AOM_CICP_TC_SRGB &&
- cm->seq_params.matrix_coefficients == AOM_CICP_MC_IDENTITY) {
- cm->seq_params.subsampling_x = 0;
- cm->seq_params.subsampling_y = 0;
+ if (seq_params->monochrome) {
+ seq_params->subsampling_x = 1;
+ seq_params->subsampling_y = 1;
+ } else if (seq_params->color_primaries == AOM_CICP_CP_BT_709 &&
+ seq_params->transfer_characteristics == AOM_CICP_TC_SRGB &&
+ seq_params->matrix_coefficients == AOM_CICP_MC_IDENTITY) {
+ seq_params->subsampling_x = 0;
+ seq_params->subsampling_y = 0;
} else {
- if (cm->seq_params.profile == 0) {
- cm->seq_params.subsampling_x = 1;
- cm->seq_params.subsampling_y = 1;
- } else if (cm->seq_params.profile == 1) {
- cm->seq_params.subsampling_x = 0;
- cm->seq_params.subsampling_y = 0;
+ if (seq_params->profile == 0) {
+ seq_params->subsampling_x = 1;
+ seq_params->subsampling_y = 1;
+ } else if (seq_params->profile == 1) {
+ seq_params->subsampling_x = 0;
+ seq_params->subsampling_y = 0;
} else {
- if (cm->seq_params.bit_depth == AOM_BITS_12) {
- cm->seq_params.subsampling_x = oxcf->chroma_subsampling_x;
- cm->seq_params.subsampling_y = oxcf->chroma_subsampling_y;
+ if (seq_params->bit_depth == AOM_BITS_12) {
+ seq_params->subsampling_x = oxcf->chroma_subsampling_x;
+ seq_params->subsampling_y = oxcf->chroma_subsampling_y;
} else {
- cm->seq_params.subsampling_x = 1;
- cm->seq_params.subsampling_y = 0;
+ seq_params->subsampling_x = 1;
+ seq_params->subsampling_y = 0;
}
}
}
cm->width = oxcf->width;
cm->height = oxcf->height;
- set_sb_size(&cm->seq_params,
+ set_sb_size(seq_params,
select_sb_size(cpi)); // set sb size before allocations
alloc_compressor_data(cpi);
@@ -2775,13 +2777,13 @@
assert(IMPLIES(seq_params->profile <= PROFILE_1,
seq_params->bit_depth <= AOM_BITS_10));
- cm->timing_info_present = oxcf->timing_info_present;
- cm->timing_info.num_units_in_display_tick =
+ seq_params->timing_info_present = oxcf->timing_info_present;
+ seq_params->timing_info.num_units_in_display_tick =
oxcf->timing_info.num_units_in_display_tick;
- cm->timing_info.time_scale = oxcf->timing_info.time_scale;
- cm->timing_info.equal_picture_interval =
+ seq_params->timing_info.time_scale = oxcf->timing_info.time_scale;
+ seq_params->timing_info.equal_picture_interval =
oxcf->timing_info.equal_picture_interval;
- cm->timing_info.num_ticks_per_picture =
+ seq_params->timing_info.num_ticks_per_picture =
oxcf->timing_info.num_ticks_per_picture;
seq_params->display_model_info_present_flag =
@@ -2790,18 +2792,18 @@
oxcf->decoder_model_info_present_flag;
if (oxcf->decoder_model_info_present_flag) {
// set the decoder model parameters in schedule mode
- cm->buffer_model.num_units_in_decoding_tick =
+ seq_params->decoder_model_info.num_units_in_decoding_tick =
oxcf->buffer_model.num_units_in_decoding_tick;
cm->buffer_removal_time_present = 1;
- av1_set_aom_dec_model_info(&cm->buffer_model);
- av1_set_dec_model_op_parameters(&cm->op_params[0]);
- } else if (cm->timing_info_present &&
- cm->timing_info.equal_picture_interval &&
+ av1_set_aom_dec_model_info(&seq_params->decoder_model_info);
+ av1_set_dec_model_op_parameters(&seq_params->op_params[0]);
+ } else if (seq_params->timing_info_present &&
+ seq_params->timing_info.equal_picture_interval &&
!seq_params->decoder_model_info_present_flag) {
// set the decoder model parameters in resource availability mode
- av1_set_resource_availability_parameters(&cm->op_params[0]);
+ av1_set_resource_availability_parameters(&seq_params->op_params[0]);
} else {
- cm->op_params[0].initial_display_delay =
+ seq_params->op_params[0].initial_display_delay =
10; // Default value (not signaled)
}
@@ -6387,7 +6389,7 @@
(frame_is_intra_only(cm) || !cm->show_frame) ? 0 : 1;
break;
}
- cm->timing_info_present &= !seq_params->reduced_still_picture_hdr;
+ seq_params->timing_info_present &= !seq_params->reduced_still_picture_hdr;
int largest_tile_id = 0;
#if CONFIG_SUPERRES_IN_RECODE
@@ -7074,7 +7076,7 @@
uint8_t header_buf[512] = { 0 };
const uint32_t sequence_header_size =
- av1_write_sequence_header_obu(cpi, &header_buf[0]);
+ av1_write_sequence_header_obu(&cpi->common.seq_params, &header_buf[0]);
assert(sequence_header_size <= sizeof(header_buf));
if (sequence_header_size == 0) return NULL;
diff --git a/av1/encoder/level.c b/av1/encoder/level.c
index 94d4f55..47d647e 100644
--- a/av1/encoder/level.c
+++ b/av1/encoder/level.c
@@ -507,18 +507,19 @@
dfg_interval_queue->head = 0;
dfg_interval_queue->size = 0;
- if (cm->timing_info_present) {
+ if (seq_params->timing_info_present) {
decoder_model->num_ticks_per_picture =
- cm->timing_info.num_ticks_per_picture;
+ seq_params->timing_info.num_ticks_per_picture;
decoder_model->display_clock_tick =
- cm->timing_info.num_units_in_display_tick / cm->timing_info.time_scale;
+ seq_params->timing_info.num_units_in_display_tick /
+ seq_params->timing_info.time_scale;
} else {
decoder_model->num_ticks_per_picture = 1;
decoder_model->display_clock_tick = 1.0 / cpi->framerate;
}
decoder_model->initial_display_delay =
- cm->op_params[op_index].initial_display_delay;
+ seq_params->op_params[op_index].initial_display_delay;
decoder_model->initial_presentation_delay = INVALID_TIME;
decoder_model->decode_rate = av1_level_defs[level].max_decode_rate;
}