diff options
author | Peter Ross <pross@xvid.org> | 2019-01-13 07:45:07 +0300 |
---|---|---|
committer | Peter Ross <pross@xvid.org> | 2019-01-26 15:49:09 +0300 |
commit | d8ebfd1bdf7e2c47af3eb057b97de5b7fe854e35 (patch) | |
tree | 381ef5658380b185ae2b25af9f3e864cf33f4f81 /libavcodec/vp56.c | |
parent | 160ebe0a8d780f6db7c18e824d8ec6f437da33a2 (diff) |
avcodec/vp6: select idct based (loosely) on number of coefficients decoded
The VP3/4/5/6 reference decoders all use three IDCT versions: one for the
DC-only case, another for blocks with more than 10 coefficients, and an
optimised one for blocks with up to 10 AC coefficents. VP6 relies on the
sparse 10 coefficient version, and without it, IDCT drift occurs.
Fixes: https://trac.ffmpeg.org/ticket/1282
Signed-off-by: Peter Ross <pross@xvid.org>
Diffstat (limited to 'libavcodec/vp56.c')
-rw-r--r-- | libavcodec/vp56.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index e9e8d5d9fd..72fea3780e 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -406,6 +406,24 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src, } } +static void vp56_idct_put(VP56Context *s, uint8_t * dest, ptrdiff_t stride, int16_t *block, int selector) +{ + if (selector > 10 || selector == 1) + s->vp3dsp.idct_put(dest, stride, block); + else + ff_vp3dsp_idct10_put(dest, stride, block); +} + +static void vp56_idct_add(VP56Context *s, uint8_t * dest, ptrdiff_t stride, int16_t *block, int selector) +{ + if (selector > 10) + s->vp3dsp.idct_add(dest, stride, block); + else if (selector > 1) + ff_vp3dsp_idct10_add(dest, stride, block); + else + s->vp3dsp.idct_dc_add(dest, stride, block); +} + static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, int is_alpha, VP56mb mb_type) { int b, ab, b_max, plane, off; @@ -426,8 +444,8 @@ static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, in 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]); + vp56_idct_put(s, frame_current->data[plane] + s->block_offset[b], + s->stride[plane], s->block_coeff[b], s->idct_selector[b]); } break; @@ -439,8 +457,8 @@ static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, in 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]); + vp56_idct_add(s, frame_current->data[plane] + off, + s->stride[plane], s->block_coeff[b], s->idct_selector[b]); } break; @@ -457,8 +475,8 @@ static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, in plane = ff_vp56_b2p[b+ab]; vp56_mc(s, b, plane, frame_ref->data[plane], s->stride[plane], 16*col+x_off, 16*row+y_off); - s->vp3dsp.idct_add(frame_current->data[plane] + s->block_offset[b], - s->stride[plane], s->block_coeff[b]); + vp56_idct_add(s, frame_current->data[plane] + s->block_offset[b], + s->stride[plane], s->block_coeff[b], s->idct_selector[b]); } break; } |