Fix for Encode/Decode mistmatch EXT_REFS
In av1/av1_cx_iface.c the encoder_encode function loops over calls made
to av1_get_compressed_data(). If the show_existing_frame flag is set,
the frame has already been flushed and the av1_twopass_postencode_update
function already incremented gf group index. The loop must exit, or else
the superframe might contain multiple shown frames. This causes a
mismatch in the test_decode function in that
av1_cx_iface.c:ctrl_get_new_frame_image will return the frame at
last_show_frame_buf_idx whereas, av1_dx_iface.c:ctrl_get_new_frame_image
will return cm->frame_to_show
BUG=aomedia:669
Change-Id: I0765048be9bd04936e080db119b54c4050019bff
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 6077963..f670762 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -23,6 +23,9 @@
#include "av1/encoder/firstpass.h"
#include "av1/av1_iface_common.h"
+#define MAG_SIZE (4)
+#define MAX_INDEX_SIZE (256)
+
struct av1_extracfg {
int cpu_used; // available cpu percentage in 1/16
unsigned int enable_auto_alt_ref;
@@ -1044,7 +1047,7 @@
// Choose the magnitude
int mag;
unsigned int mask;
- for (mag = 0, mask = 0xff; mag < 4; mag++) {
+ for (mag = 0, mask = 0xff; mag < MAG_SIZE; mag++) {
if (max_frame_sz <= mask) break;
mask <<= 8;
mask |= 0xff;
@@ -1052,7 +1055,7 @@
marker |= mag << 3;
// Write the index
- uint8_t buffer[256];
+ uint8_t buffer[MAX_INDEX_SIZE];
uint8_t *x = buffer;
if (TEST_SUPPLEMENTAL_SUPERFRAME_DATA) {
@@ -1080,6 +1083,7 @@
*x++ = marker;
const size_t index_sz = x - buffer;
+ assert(index_sz < MAX_INDEX_SIZE);
assert(ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz);
// move the frame to make room for the index
@@ -1229,9 +1233,13 @@
}
}
- size_t frame_size;
+ size_t frame_size = 0;
unsigned int lib_flags = 0;
- while (cx_data_sz >= ctx->cx_data_sz / 2 &&
+ int is_frame_visible = 0;
+ int index_size = 0;
+ // invisible frames get packed with the next visible frame
+ while (cx_data_sz - index_size >= ctx->cx_data_sz / 2 &&
+ !is_frame_visible &&
-1 != av1_get_compressed_data(cpi, &lib_flags, &frame_size, cx_data,
&dst_time_stamp, &dst_end_time_stamp,
!img)) {
@@ -1241,24 +1249,28 @@
return AOM_CODEC_ERROR;
}
#endif
- if (!frame_size) continue;
+ if (frame_size) {
+ if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
- if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
+ ctx->pending_frame_sizes[ctx->pending_frame_count++] = frame_size;
+ ctx->pending_cx_data_sz += frame_size;
- ctx->pending_frame_sizes[ctx->pending_frame_count++] = frame_size;
- ctx->pending_cx_data_sz += frame_size;
+ cx_data += frame_size;
+ cx_data_sz -= frame_size;
- cx_data += frame_size;
- cx_data_sz -= frame_size;
+ index_size = MAG_SIZE * (ctx->pending_frame_count - 1) + 2;
- // invisible frames get packed with the next visible frame
- if (!cpi->common.show_frame) continue;
-
+ is_frame_visible = cpi->common.show_frame;
+ }
+ }
+ if (is_frame_visible) {
// insert superframe index if needed
if (ctx->pending_frame_count > 1) {
- const size_t index_size = write_superframe_index(ctx);
- cx_data += index_size;
- cx_data_sz -= index_size;
+#if CONFIG_DEBUG
+ assert(index_size >= write_superframe_index(ctx));
+#else
+ write_superframe_index(ctx);
+#endif
}
// Add the frame packet to the list of returned packets.