Commit d34bf886 authored by Michael Niedermayer's avatar 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: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 3aef2fce
...@@ -261,6 +261,25 @@ static VP56mb vp56_decode_mv(VP56Context *s, int row, int col) ...@@ -261,6 +261,25 @@ static VP56mb vp56_decode_mv(VP56Context *s, int row, int col)
return s->mb_type; 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) static void vp56_add_predictors_dc(VP56Context *s, VP56Frame ref_frame)
{ {
int idx = s->idct_scantable[0]; int idx = s->idct_scantable[0];
...@@ -457,6 +476,57 @@ static int vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) ...@@ -457,6 +476,57 @@ static int vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
return 0; 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) static int vp56_size_changed(VP56Context *s)
{ {
AVCodecContext *avctx = s->avctx; AVCodecContext *avctx = s->avctx;
...@@ -593,6 +663,7 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, ...@@ -593,6 +663,7 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
int block, y, uv; int block, y, uv;
ptrdiff_t stride_y, stride_uv; ptrdiff_t stride_y, stride_uv;
int res; int res;
int damaged = 0;
if (p->key_frame) { if (p->key_frame) {
p->pict_type = AV_PICTURE_TYPE_I; p->pict_type = AV_PICTURE_TYPE_I;
...@@ -657,9 +728,13 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, ...@@ -657,9 +728,13 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
s->block_offset[5] = s->block_offset[4]; s->block_offset[5] = s->block_offset[4];
for (mb_col=0; mb_col<s->mb_width; mb_col++) { for (mb_col=0; mb_col<s->mb_width; mb_col++) {
int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha); if (!damaged) {
if (ret < 0) int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha);
return ret; if (ret < 0)
damaged = 1;
}
if (damaged)
vp56_conceal_mb(s, mb_row, mb_col, is_alpha);
for (y=0; y<4; y++) { for (y=0; y<4; y++) {
s->above_block_idx[y] += 2; s->above_block_idx[y] += 2;
......
...@@ -249,4 +249,4 @@ ...@@ -249,4 +249,4 @@
0, 243, 243, 1, 233472, 0x6f530ac6 0, 243, 243, 1, 233472, 0x6f530ac6
0, 244, 244, 1, 233472, 0x94f7466c 0, 244, 244, 1, 233472, 0x94f7466c
0, 245, 245, 1, 233472, 0xa8c1d365 0, 245, 245, 1, 233472, 0xa8c1d365
0, 246, 246, 1, 233472, 0x8843293b 0, 246, 246, 1, 233472, 0xbf73f1b7
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment