summaryrefslogtreecommitdiff
path: root/vp8
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2011-11-22 17:12:06 -0800
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2011-11-22 17:12:06 -0800
commitb79879c2e3ba79c0b4693b340756283e58dba3da (patch)
treeb35c3526064e2e92801f5268ecdd7f9c1edabffd /vp8
parent640ddcabccf194900985bcaeab694165ff240446 (diff)
parentb5ee7b12d232badfd54b4d2f76f8c3fa40d67e6a (diff)
downloadlibvpx-b79879c2e3ba79c0b4693b340756283e58dba3da.tar
libvpx-b79879c2e3ba79c0b4693b340756283e58dba3da.tar.gz
libvpx-b79879c2e3ba79c0b4693b340756283e58dba3da.tar.bz2
libvpx-b79879c2e3ba79c0b4693b340756283e58dba3da.zip
Merge "Decoder fixes to better support reference picture selection."
Diffstat (limited to 'vp8')
-rw-r--r--vp8/decoder/decodframe.c22
-rw-r--r--vp8/decoder/error_concealment.c38
-rw-r--r--vp8/decoder/onyxd_if.c40
3 files changed, 51 insertions, 49 deletions
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index e501b9ec7..6f2cdfabb 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -934,16 +934,38 @@ int vp8_decode_frame(VP8D_COMP *pbi)
if (!pc->refresh_golden_frame)
pc->copy_buffer_to_gf = vp8_read_literal(bc, 2);
+#if CONFIG_ERROR_CONCEALMENT
+ /* Assume we shouldn't copy to the golden if the bit is missing */
+ xd->corrupted |= vp8dx_bool_error(bc);
+ if (pbi->ec_active && xd->corrupted)
+ pc->copy_buffer_to_gf = 0;
+#endif
+
pc->copy_buffer_to_arf = 0;
if (!pc->refresh_alt_ref_frame)
pc->copy_buffer_to_arf = vp8_read_literal(bc, 2);
+#if CONFIG_ERROR_CONCEALMENT
+ /* Assume we shouldn't copy to the alt-ref if the bit is missing */
+ xd->corrupted |= vp8dx_bool_error(bc);
+ if (pbi->ec_active && xd->corrupted)
+ pc->copy_buffer_to_arf = 0;
+#endif
+
+
pc->ref_frame_sign_bias[GOLDEN_FRAME] = vp8_read_bit(bc);
pc->ref_frame_sign_bias[ALTREF_FRAME] = vp8_read_bit(bc);
}
pc->refresh_entropy_probs = vp8_read_bit(bc);
+#if CONFIG_ERROR_CONCEALMENT
+ /* Assume we shouldn't refresh the probabilities if the bit is
+ * missing */
+ xd->corrupted |= vp8dx_bool_error(bc);
+ if (pbi->ec_active && xd->corrupted)
+ pc->refresh_entropy_probs = 0;
+#endif
if (pc->refresh_entropy_probs == 0)
{
vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
diff --git a/vp8/decoder/error_concealment.c b/vp8/decoder/error_concealment.c
index 86fa191d3..b77d743f7 100644
--- a/vp8/decoder/error_concealment.c
+++ b/vp8/decoder/error_concealment.c
@@ -491,33 +491,6 @@ static void find_neighboring_blocks(MODE_INFO *mi,
assert(i == 20);
}
-/* Calculates which reference frame type is dominating among the neighbors */
-static MV_REFERENCE_FRAME dominant_ref_frame(EC_BLOCK *neighbors)
-{
- /* Default to referring to "skip" */
- MV_REFERENCE_FRAME dom_ref_frame = LAST_FRAME;
- int max_ref_frame_cnt = 0;
- int ref_frame_cnt[MAX_REF_FRAMES] = {0};
- int i;
- /* Count neighboring reference frames */
- for (i = 0; i < NUM_NEIGHBORS; ++i)
- {
- if (neighbors[i].ref_frame < MAX_REF_FRAMES &&
- neighbors[i].ref_frame != INTRA_FRAME)
- ++ref_frame_cnt[neighbors[i].ref_frame];
- }
- /* Find maximum */
- for (i = 0; i < MAX_REF_FRAMES; ++i)
- {
- if (ref_frame_cnt[i] > max_ref_frame_cnt)
- {
- dom_ref_frame = i;
- max_ref_frame_cnt = ref_frame_cnt[i];
- }
- }
- return dom_ref_frame;
-}
-
/* Interpolates all motion vectors for a macroblock from the neighboring blocks'
* motion vectors.
*/
@@ -591,7 +564,6 @@ void vp8_interpolate_motion(MACROBLOCKD *mb,
{
/* Find relevant neighboring blocks */
EC_BLOCK neighbors[NUM_NEIGHBORS];
- MV_REFERENCE_FRAME dom_ref_frame;
int i;
/* Initialize the array. MAX_REF_FRAMES is interpreted as "doesn't exist" */
for (i = 0; i < NUM_NEIGHBORS; ++i)
@@ -604,13 +576,11 @@ void vp8_interpolate_motion(MACROBLOCKD *mb,
mb_row, mb_col,
mb_rows, mb_cols,
mb->mode_info_stride);
- /* Determine the dominant block type */
- dom_ref_frame = dominant_ref_frame(neighbors);
- /* Interpolate MVs for the missing blocks
- * from the dominating MVs */
- interpolate_mvs(mb, neighbors, dom_ref_frame);
+ /* Interpolate MVs for the missing blocks from the surrounding
+ * blocks which refer to the last frame. */
+ interpolate_mvs(mb, neighbors, LAST_FRAME);
- mb->mode_info_context->mbmi.ref_frame = dom_ref_frame;
+ mb->mode_info_context->mbmi.ref_frame = LAST_FRAME;
mb->mode_info_context->mbmi.mode = SPLITMV;
mb->mode_info_context->mbmi.uv_mode = DC_PRED;
mb->mode_info_context->mbmi.partitioning = 3;
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index 077954948..cf525f4a9 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -359,28 +359,38 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
pbi->fragment_sizes[0] = 0;
}
- if (pbi->num_fragments <= 1 && pbi->fragment_sizes[0] == 0)
+ if (!pbi->ec_active &&
+ pbi->num_fragments <= 1 && pbi->fragment_sizes[0] == 0)
{
- /* This is used to signal that we are missing frames.
- * We do not know if the missing frame(s) was supposed to update
- * any of the reference buffers, but we act conservative and
- * mark only the last buffer as corrupted.
- */
- cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
-
/* If error concealment is disabled we won't signal missing frames
* to the decoder.
*/
- if (!pbi->ec_active)
+ if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1)
{
- /* Signal that we have no frame to show. */
- cm->show_frame = 0;
+ /* The last reference shares buffer with another reference
+ * buffer. Move it to its own buffer before setting it as
+ * corrupt, otherwise we will make multiple buffers corrupt.
+ */
+ const int prev_idx = cm->lst_fb_idx;
+ cm->fb_idx_ref_cnt[prev_idx]--;
+ cm->lst_fb_idx = get_free_fb(cm);
+ vp8_yv12_copy_frame_ptr(&cm->yv12_fb[prev_idx],
+ &cm->yv12_fb[cm->lst_fb_idx]);
+ }
+ /* This is used to signal that we are missing frames.
+ * We do not know if the missing frame(s) was supposed to update
+ * any of the reference buffers, but we act conservative and
+ * mark only the last buffer as corrupted.
+ */
+ cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
- pbi->num_fragments = 0;
+ /* Signal that we have no frame to show. */
+ cm->show_frame = 0;
- /* Nothing more to do. */
- return 0;
- }
+ pbi->num_fragments = 0;
+
+ /* Nothing more to do. */
+ return 0;
}
#if HAVE_ARMV7