[FFmpeg-cvslog] avcodec/vp56: Implement very basic error concealment

Ivan Kalvachev ikalvachev at gmail.com
Sat Feb 25 17:05:22 EET 2017


On 2/25/17, Michael Niedermayer <git at videolan.org> wrote:
> ffmpeg | branch: master | Michael Niedermayer <michael at niedermayer.cc> | Sat
> Feb 25 12:37:32 2017 +0100| [d34bf886e963445350c4987f7a9ed77bd9c9a5c7] |
> committer: Michael Niedermayer
>
> avcodec/vp56: Implement very basic error concealment
>
> This should fix the fate failure due to a truncated last frame.
> Alternatively the frame could be dropped.
>
> Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
>
>> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d34bf886e963445350c4987f7a9ed77bd9c9a5c7
> ---
>
>  libavcodec/vp56.c  | 81
> ++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  tests/ref/fate/vp5 |  2 +-
>  2 files changed, 79 insertions(+), 4 deletions(-)
>
> diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
> index d8fe994..b36c99f 100644
> --- a/libavcodec/vp56.c
> +++ b/libavcodec/vp56.c
> @@ -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;
> diff --git a/tests/ref/fate/vp5 b/tests/ref/fate/vp5
> index da510fc..2469a3e 100644
> --- a/tests/ref/fate/vp5
> +++ b/tests/ref/fate/vp5
> @@ -249,4 +249,4 @@
>  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
>

Michael, please, send patches to the maillist,
even if the thing are trivial.

You are not maintainer of this codec.


More information about the ffmpeg-cvslog mailing list