Prevent undefined behaviour for AMVR experiment
Sequences starting with intra-only frames previously resulted in undefined
behaviour with CONFIG_AMVR == 1, as seq_force_integer_mv was only read for
keyframes.
This patch makes changes as follows:
- The syntax element force_screen_content_tools has been added to the
SequenceHeader struct, and is read and written correspondingly
- seq_force_integer_mv has been renamed to force_integer_mv and moved to the
SequenceHeader struct, and is read and written correspondingly (provided that
force_screen_content_tools != 0)
- The conditional reading/writing of allow_screen_content_tools now happens for
every frame after reading/writing error_resilient_mode (CONFIG_OBU == 1) or
the sequence header (CONFIG_OBU == 0)
- The conditional reading/writing of cur_frame_force_integer_mv now happens for
every frame after reading/writing allow_screen_content_tools
BUG=aomedia:1048
Change-Id: I689476fc2fa781dc8ec6fc8da91926cc8cfd3dc2
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index ec01e8f..cf7ff27 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3485,6 +3485,26 @@
}
write_sb_size(seq_params, wb);
+
+ if (seq_params->force_screen_content_tools == 2) {
+ aom_wb_write_bit(wb, 1);
+ } else {
+ aom_wb_write_bit(wb, 0);
+ aom_wb_write_bit(wb, seq_params->force_screen_content_tools);
+ }
+
+#if CONFIG_AMVR
+ if (seq_params->force_screen_content_tools > 0) {
+ if (seq_params->force_integer_mv == 2) {
+ aom_wb_write_bit(wb, 1);
+ } else {
+ aom_wb_write_bit(wb, 0);
+ aom_wb_write_bit(wb, seq_params->force_integer_mv);
+ }
+ } else {
+ assert(seq_params->force_integer_mv == 2);
+ }
+#endif
}
#endif // CONFIG_REFERENCE_BUFFER || CONFIG_OBU
@@ -3663,6 +3683,26 @@
write_sequence_header(cpi, wb);
#endif // CONFIG_REFERENCE_BUFFER
}
+
+ if (cm->seq_params.force_screen_content_tools == 2) {
+ aom_wb_write_bit(wb, cm->allow_screen_content_tools);
+ } else {
+ assert(cm->allow_screen_content_tools ==
+ cm->seq_params.force_screen_content_tools);
+ }
+
+#if CONFIG_AMVR
+ if (cm->allow_screen_content_tools) {
+ if (cm->seq_params.force_integer_mv == 2) {
+ aom_wb_write_bit(wb, cm->cur_frame_force_integer_mv);
+ } else {
+ assert(cm->cur_frame_force_integer_mv == cm->seq_params.force_integer_mv);
+ }
+ } else {
+ assert(cm->cur_frame_force_integer_mv == 0);
+ }
+#endif // CONFIG_AMVR
+
#if CONFIG_REFERENCE_BUFFER
cm->invalid_delta_frame_id_minus1 = 0;
if (cm->seq_params.frame_id_numbers_present_flag) {
@@ -3704,20 +3744,9 @@
#else
write_frame_size(cm, wb);
#endif
- aom_wb_write_bit(wb, cm->allow_screen_content_tools);
#if CONFIG_INTRABC
if (cm->allow_screen_content_tools) aom_wb_write_bit(wb, cm->allow_intrabc);
#endif // CONFIG_INTRABC
-#if CONFIG_AMVR
- if (cm->allow_screen_content_tools) {
- if (cm->seq_force_integer_mv == 2) {
- aom_wb_write_bit(wb, 1);
- } else {
- aom_wb_write_bit(wb, 0);
- aom_wb_write_bit(wb, cm->seq_force_integer_mv);
- }
- }
-#endif
} else {
#if !CONFIG_NO_FRAME_CONTEXT_SIGNALING
if (!cm->error_resilient_mode) {
@@ -3750,7 +3779,6 @@
#else
write_frame_size(cm, wb);
#endif
- aom_wb_write_bit(wb, cm->allow_screen_content_tools);
#if CONFIG_INTRABC
if (cm->allow_screen_content_tools)
aom_wb_write_bit(wb, cm->allow_intrabc);
@@ -3798,16 +3826,6 @@
#endif
#if CONFIG_AMVR
- if (cm->allow_screen_content_tools) {
- if (cm->seq_force_integer_mv == 2) {
- aom_wb_write_bit(wb, cm->cur_frame_force_integer_mv);
- } else {
- assert(cm->cur_frame_force_integer_mv == cm->seq_force_integer_mv);
- }
- } else {
- assert(cm->cur_frame_force_integer_mv == 0);
- }
-
if (cm->cur_frame_force_integer_mv) {
cm->allow_high_precision_mv = 0;
} else {
@@ -4017,6 +4035,25 @@
aom_wb_write_bit(wb, cm->show_frame);
aom_wb_write_bit(wb, cm->error_resilient_mode);
+ if (cm->seq_params.force_screen_content_tools == 2) {
+ aom_wb_write_bit(wb, cm->allow_screen_content_tools);
+ } else {
+ assert(cm->allow_screen_content_tools ==
+ cm->seq_params.force_screen_content_tools);
+ }
+
+#if CONFIG_AMVR
+ if (cm->allow_screen_content_tools) {
+ if (cm->seq_params.force_integer_mv == 2) {
+ aom_wb_write_bit(wb, cm->cur_frame_force_integer_mv);
+ } else {
+ assert(cm->cur_frame_force_integer_mv == cm->seq_params.force_integer_mv);
+ }
+ } else {
+ assert(cm->cur_frame_force_integer_mv == 0);
+ }
+#endif // CONFIG_AMVR
+
#if CONFIG_REFERENCE_BUFFER
cm->invalid_delta_frame_id_minus1 = 0;
if (cm->seq_params.frame_id_numbers_present_flag) {
@@ -4043,20 +4080,9 @@
#else
write_frame_size(cm, wb);
#endif
- aom_wb_write_bit(wb, cm->allow_screen_content_tools);
#if CONFIG_INTRABC
if (cm->allow_screen_content_tools) aom_wb_write_bit(wb, cm->allow_intrabc);
#endif // CONFIG_INTRABC
-#if CONFIG_AMVR
- if (cm->allow_screen_content_tools) {
- if (cm->seq_force_integer_mv == 2) {
- aom_wb_write_bit(wb, 1);
- } else {
- aom_wb_write_bit(wb, 0);
- aom_wb_write_bit(wb, cm->seq_force_integer_mv == 0);
- }
- }
-#endif
} else if (cm->frame_type == INTRA_ONLY_FRAME) {
#if !CONFIG_NO_FRAME_CONTEXT_SIGNALING
if (!cm->error_resilient_mode) {
@@ -4075,7 +4101,6 @@
#else
write_frame_size(cm, wb);
#endif
- aom_wb_write_bit(wb, cm->allow_screen_content_tools);
#if CONFIG_INTRABC
if (cm->allow_screen_content_tools)
aom_wb_write_bit(wb, cm->allow_intrabc);
@@ -4134,16 +4159,6 @@
#endif
#if CONFIG_AMVR
- if (cm->allow_screen_content_tools) {
- if (cm->seq_force_integer_mv == 2) {
- aom_wb_write_bit(wb, cm->cur_frame_force_integer_mv);
- } else {
- assert(cm->cur_frame_force_integer_mv == cm->seq_force_integer_mv);
- }
- } else {
- assert(cm->cur_frame_force_integer_mv == 0);
- }
-
if (cm->cur_frame_force_integer_mv) {
cm->allow_high_precision_mv = 0;
} else {