static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc,

                                            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 *in_mv,

                                            int px, int py, int pw, int ph,

                                            int bw, int bh, int w, int h, int bytesperpixel,

                                            const uint16_t *scale, const uint8_t *step)

{

    if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width &&

        s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) {

        mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame,

                         y, x, in_mv, bw, bh, w, h, bytesperpixel);

    } else {

#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14)

    int mx, my;

    int refbw_m1, refbh_m1;

    int th;

    VP56mv mv;



    mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8);

    mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8);

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

    mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0);

    my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1);



    y = my >> 4;

    x = mx >> 4;

    ref += y * ref_stride + x * bytesperpixel;

    mx &= 15;

    my &= 15;

    refbw_m1 = ((bw - 1) * step[0] + mx) >> 4;

    refbh_m1 = ((bh - 1) * step[1] + my) >> 4;

    // FIXME bilinear filter only needs 0/1 pixels, not 3/4

    // we use +7 because the last 7 pixels of each sbrow can be changed in

    // the longest loopfilter of the next sbrow

    th = (y + refbh_m1 + 4 + 7) >> 6;

    ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);

    if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {

        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,

                                 ref - 3 * ref_stride - 3 * bytesperpixel,

                                 288, ref_stride,

                                 refbw_m1 + 8, refbh_m1 + 8,

                                 x - 3, y - 3, w, h);

        ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;

        ref_stride = 288;

    }

    smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]);

    }

}

static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc,

                                            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 *in_mv,

                                            int px, int py, int pw, int ph,

                                            int bw, int bh, int w, int h, int bytesperpixel,

                                            const uint16_t *scale, const uint8_t *step)

{

    if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width &&

        s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) {

        mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame,

                         y, x, in_mv, bw, bh, w, h, bytesperpixel);

    } else {

#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14)

    int mx, my;

    int refbw_m1, refbh_m1;

    int th;

    VP56mv mv;



    mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8);

    mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8);

    

    

    

    mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0);

    my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1);



    y = my >> 4;

    x = mx >> 4;

    ref += y * ref_stride + x * bytesperpixel;

    mx &= 15;

    my &= 15;

    refbw_m1 = ((bw - 1) * step[0] + mx) >> 4;

    refbh_m1 = ((bh - 1) * step[1] + my) >> 4;

    

    

    

    th = (y + refbh_m1 + 4 + 7) >> 6;

    ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);

    if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {

        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,

                                 ref - 3 * ref_stride - 3 * bytesperpixel,

                                 288, ref_stride,

                                 refbw_m1 + 8, refbh_m1 + 8,

                                 x - 3, y - 3, w, h);

        ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;

        ref_stride = 288;

    }

    smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]);

    }

}

    if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {     if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {
static av_always_inline void FUNC_0(VP9Context *s, vp9_scaled_mc_func smc,

                                            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 *in_mv,

                                            int px, int py, int pw, int ph,

                                            int bw, int bh, int w, int h, int bytesperpixel,

                                            const uint16_t *scale, const uint8_t *step)

{

    if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width &&

        s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) {

        mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame,

                         y, x, in_mv, bw, bh, w, h, bytesperpixel);

    } else {

#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14)

    int VAR_0, VAR_1;

    int VAR_2, VAR_3;

    int VAR_4;

    VP56mv mv;



    mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8);

    mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8);

    

    

    

    VAR_0 = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0);

    VAR_1 = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1);



    y = VAR_1 >> 4;

    x = VAR_0 >> 4;

    ref += y * ref_stride + x * bytesperpixel;

    VAR_0 &= 15;

    VAR_1 &= 15;

    VAR_2 = ((bw - 1) * step[0] + VAR_0) >> 4;

    VAR_3 = ((bh - 1) * step[1] + VAR_1) >> 4;

    

    

    

    VAR_4 = (y + VAR_3 + 4 + 7) >> 6;

    ff_thread_await_progress(ref_frame, FFMAX(VAR_4, 0), 0);

    if (x < 3 || y < 3 || x + 4 >= w - VAR_2 || y + 4 >= h - VAR_3) {

        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,

                                 ref - 3 * ref_stride - 3 * bytesperpixel,

                                 288, ref_stride,

                                 VAR_2 + 8, VAR_3 + 8,

                                 x - 3, y - 3, w, h);

        ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;

        ref_stride = 288;

    }

    smc(dst, dst_stride, ref, ref_stride, bh, VAR_0, VAR_1, step[0], step[1]);

    }

}

static av_always_inline void FUNC_0(VP9Context *s, vp9_scaled_mc_func smc,
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 *in_mv,
int px, int py, int pw, int ph,
int bw, int bh, int w, int h, int bytesperpixel,
const uint16_t *scale, const uint8_t *step)
{ if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width &&
s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame,
y, x, in_mv, bw, bh, w, h, bytesperpixel); } else { #define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14)
int VAR_0, VAR_1; int VAR_2, VAR_3; int VAR_4; VP56mv mv; mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); VAR_0 = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); VAR_1 = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); y = VAR_1 >> 4; x = VAR_0 >> 4; ref += y * ref_stride + x * bytesperpixel; VAR_0 &= 15; VAR_1 &= 15; VAR_2 = ((bw - 1) * step[0] + VAR_0) >> 4; VAR_3 = ((bh - 1) * step[1] + VAR_1) >> 4; VAR_4 = (y + VAR_3 + 4 + 7) >> 6; ff_thread_await_progress(ref_frame, FFMAX(VAR_4, 0), 0); if (x < 3 || y < 3 || x + 4 >= w - VAR_2 || y + 4 >= h - VAR_3) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
ref - 3 * ref_stride - 3 * bytesperpixel,
288, ref_stride,
VAR_2 + 8, VAR_3 + 8,
x - 3, y - 3, w, h); ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; ref_stride = 288; } smc(dst, dst_stride, ref, ref_stride, bh, VAR_0, VAR_1, step[0], step[1]); } }