[FFmpeg-devel] [PATCH 1/2] vp9: add support for resolution changes in inter frames.

Ronald S. Bultje rsbultje at gmail.com
Wed Apr 22 12:32:25 CEST 2015


Hi,

On Tue, Apr 21, 2015 at 11:25 PM, James Almer <jamrial at gmail.com> wrote:

> 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.


Yes, sadly, not much can be done here on our end...

Ronald


More information about the ffmpeg-devel mailing list