[FFmpeg-devel] [PATCH 1/2] vp9: add support for resolution changes in inter frames.
James Almer
jamrial at gmail.com
Wed Apr 22 05:25:15 CEST 2015
On 22/04/15 12:20 AM, James Almer wrote:
> On 21/04/15 9:54 PM, Ronald S. Bultje wrote:
>> ---
>> libavcodec/vp9.c | 316 ++++++++++++++++++++++---------------------
>> libavcodec/vp9_mc_template.c | 171 +++++++++++++++++++++++
>> libavcodec/vp9_parser.c | 5 +-
>> libavcodec/vp9dsp.c | 205 ++++++++++++++++++++++++++--
>> libavcodec/vp9dsp.h | 9 ++
>> 5 files changed, 535 insertions(+), 171 deletions(-)
>> create mode 100644 libavcodec/vp9_mc_template.c
>>
>> diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
>> index 89257fa..ee73325 100644
>> --- a/libavcodec/vp9.c
>> +++ b/libavcodec/vp9.c
>> @@ -242,7 +242,7 @@ typedef struct VP9Context {
>> // whole-frame cache
>> uint8_t *intra_pred_data[3];
>> struct VP9Filter *lflvl;
>> - DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80];
>> + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135*144];
>>
>> // block reconstruction intermediates
>> int block_alloc_using_2pass;
>> @@ -251,6 +251,8 @@ typedef struct VP9Context {
>> struct { int x, y; } min_mv, max_mv;
>> DECLARE_ALIGNED(32, uint8_t, tmp_y)[64*64];
>> DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32*32];
>> + uint16_t mvscale[3][2];
>> + uint8_t mvstep[3][2];
>> } VP9Context;
>>
>> static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
>> @@ -577,6 +579,26 @@ static int decode_frame_header(AVCodecContext *ctx,
>> s->varcompref[1] = 2;
>> }
>> }
>> +
>> + for (i = 0; i < 3; i++) {
>> + AVFrame *ref = s->refs[s->refidx[i]].f;
>> + int refw = ref->width, refh = ref->height;
>> +
>> + if (refw == w && refh == h) {
>> + s->mvscale[i][0] = s->mvscale[i][1] = 0;
>> + } else {
>> + if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h > 16 * refh) {
>> + av_log(ctx, AV_LOG_ERROR,
>> + "Invalid ref frame dimensions %dx%d for frame size %dx%d\n",
>> + refw, refh, w, h);
>> + return AVERROR_INVALIDDATA;
>> + }
>> + s->mvscale[i][0] = (refw << 14) / w;
>> + s->mvscale[i][1] = (refh << 14) / h;
>> + s->mvstep[i][0] = 16 * s->mvscale[i][0] >> 14;
>> + s->mvstep[i][1] = 16 * s->mvscale[i][1] >> 14;
>> + }
>> + }
>> }
>> }
>> s->refreshctx = s->errorres ? 0 : get_bits1(&s->gb);
>> @@ -2524,12 +2546,118 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
>> }
>> }
>>
>> -static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func (*mc)[2],
>> - uint8_t *dst, ptrdiff_t dst_stride,
>> - const uint8_t *ref, ptrdiff_t ref_stride,
>> - ThreadFrame *ref_frame,
>> - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
>> - int bw, int bh, int w, int h)
>> +static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc,
>> + uint8_t *dst, ptrdiff_t dst_stride,
>> + const uint8_t *ref, ptrdiff_t ref_stride,
>> + ThreadFrame *ref_frame,
>> + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
>> + int bw, int bh, int w, int h,
>> + const uint16_t *scale, const uint8_t *step)
>> +{
>> +#define scale_mv(n, dim) (((int64_t)n * scale[dim]) >> 14)
>> + // BUG libvpx seems to scale the two components separately. This introduces
>> + // rounding errors but we have to reproduce them to be exactly compatible
>> + // with the output from libvpx...
>
> Did you report it to libvpx? It's probably a better idea to fix the bug in the reference
> library than purposely reproduce the buggy behavior in our implementation to remain
> compatible.
Just checked the link further down the patch (As i should have done before replying).
Assuming it's the same bug as this one then forget what i said, they decided to leave
the bitstream unchanged.
More information about the ffmpeg-devel
mailing list