avcodec/vp56: Implement very basic error concealment
authorMichael Niedermayer <michael@niedermayer.cc>
Sat, 25 Feb 2017 11:37:32 +0000 (12:37 +0100)
committerMichael Niedermayer <michael@niedermayer.cc>
Wed, 17 May 2017 18:35:19 +0000 (20:35 +0200)
This should fix the fate failure due to a truncated last frame.
Alternatively the frame could be dropped.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit d34bf886e963445350c4987f7a9ed77bd9c9a5c7)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
libavcodec/vp56.c
tests/ref/fate/vp5

index d8fe994..b36c99f 100644 (file)
@@ -261,6 +261,25 @@ static VP56mb vp56_decode_mv(VP56Context *s, int row, int col)
     return s->mb_type;
 }
 
+static VP56mb vp56_conceal_mv(VP56Context *s, int row, int col)
+{
+    VP56mv *mv, vect = {0,0};
+    int b;
+
+    s->mb_type = VP56_MB_INTER_NOVEC_PF;
+    s->macroblocks[row * s->mb_width + col].type = s->mb_type;
+
+    mv = &vect;
+
+    s->macroblocks[row*s->mb_width + col].mv = *mv;
+
+    /* same vector for all blocks */
+    for (b=0; b<6; b++)
+        s->mv[b] = *mv;
+
+    return s->mb_type;
+}
+
 static void vp56_add_predictors_dc(VP56Context *s, VP56Frame ref_frame)
 {
     int idx = s->idct_scantable[0];
@@ -457,6 +476,57 @@ static int vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
     return 0;
 }
 
+static int vp56_conceal_mb(VP56Context *s, int row, int col, int is_alpha)
+{
+    AVFrame *frame_current, *frame_ref;
+    VP56mb mb_type;
+    VP56Frame ref_frame;
+    int b, ab, b_max, plane, off;
+
+    if (s->frames[VP56_FRAME_CURRENT]->key_frame)
+        mb_type = VP56_MB_INTRA;
+    else
+        mb_type = vp56_conceal_mv(s, row, col);
+    ref_frame = ff_vp56_reference_frame[mb_type];
+
+    frame_current = s->frames[VP56_FRAME_CURRENT];
+    frame_ref = s->frames[ref_frame];
+    if (mb_type != VP56_MB_INTRA && !frame_ref->data[0])
+        return 0;
+
+    ab = 6*is_alpha;
+    b_max = 6 - 2*is_alpha;
+
+    switch (mb_type) {
+        case VP56_MB_INTRA:
+            for (b=0; b<b_max; b++) {
+                plane = ff_vp56_b2p[b+ab];
+                s->vp3dsp.idct_put(frame_current->data[plane] + s->block_offset[b],
+                                s->stride[plane], s->block_coeff[b]);
+            }
+            break;
+
+        case VP56_MB_INTER_NOVEC_PF:
+        case VP56_MB_INTER_NOVEC_GF:
+            for (b=0; b<b_max; b++) {
+                plane = ff_vp56_b2p[b+ab];
+                off = s->block_offset[b];
+                s->hdsp.put_pixels_tab[1][0](frame_current->data[plane] + off,
+                                             frame_ref->data[plane] + off,
+                                             s->stride[plane], 8);
+                s->vp3dsp.idct_add(frame_current->data[plane] + off,
+                                s->stride[plane], s->block_coeff[b]);
+            }
+            break;
+    }
+
+    if (is_alpha) {
+        s->block_coeff[4][0] = 0;
+        s->block_coeff[5][0] = 0;
+    }
+    return 0;
+}
+
 static int vp56_size_changed(VP56Context *s)
 {
     AVCodecContext *avctx = s->avctx;
@@ -593,6 +663,7 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
     int block, y, uv;
     ptrdiff_t stride_y, stride_uv;
     int res;
+    int damaged = 0;
 
     if (p->key_frame) {
         p->pict_type = AV_PICTURE_TYPE_I;
@@ -657,9 +728,13 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
         s->block_offset[5] = s->block_offset[4];
 
         for (mb_col=0; mb_col<s->mb_width; mb_col++) {
-            int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha);
-            if (ret < 0)
-                return ret;
+            if (!damaged) {
+                int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha);
+                if (ret < 0)
+                    damaged = 1;
+            }
+            if (damaged)
+                vp56_conceal_mb(s, mb_row, mb_col, is_alpha);
 
             for (y=0; y<4; y++) {
                 s->above_block_idx[y] += 2;
index 25bc7aa..f044567 100644 (file)
 0,        243,        243,        1,   233472, 0x6f530ac6
 0,        244,        244,        1,   233472, 0x94f7466c
 0,        245,        245,        1,   233472, 0xa8c1d365
-0,        246,        246,        1,   233472, 0x8843293b
+0,        246,        246,        1,   233472, 0xbf73f1b7