static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,

                                         int n, int square, int height,

                                         int delta, int list,

                                         uint8_t *dest_y, uint8_t *dest_cb,

                                         uint8_t *dest_cr,

                                         int src_x_offset, int src_y_offset,

                                         qpel_mc_func *qpix_op,

                                         h264_chroma_mc_func chroma_op,

                                         int pixel_shift, int chroma_idc)

{

    const int mx      = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8;

    int my            = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8;

    const int luma_xy = (mx & 3) + ((my & 3) << 2);

    int offset        = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize;

    uint8_t *src_y    = pic->f.data[0] + offset;

    uint8_t *src_cb, *src_cr;

    int extra_width  = 0;

    int extra_height = 0;

    int emu = 0;

    const int full_mx    = mx >> 2;

    const int full_my    = my >> 2;

    const int pic_width  = 16 * h->mb_width;

    const int pic_height = 16 * h->mb_height >> MB_FIELD(h);

    int ysh;



    if (mx & 7)

        extra_width -= 3;

    if (my & 7)

        extra_height -= 3;



    if (full_mx                <          0 - extra_width  ||

        full_my                <          0 - extra_height ||

        full_mx + 16 /*FIXME*/ > pic_width  + extra_width  ||

        full_my + 16 /*FIXME*/ > pic_height + extra_height) {

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

                                 src_y - (2 << pixel_shift) - 2 * h->mb_linesize,

                                 h->mb_linesize,

                                 16 + 5, 16 + 5 /*FIXME*/, full_mx - 2,

                                 full_my - 2, pic_width, pic_height);

        src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        emu   = 1;

    }



    qpix_op[luma_xy](dest_y, src_y, h->mb_linesize); // FIXME try variable height perhaps?

    if (!square)

        qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize);



    if (CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY)

        return;



    if (chroma_idc == 3 /* yuv444 */) {

        src_cb = pic->f.data[1] + offset;

        if (emu) {

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

                                     src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,

                                     h->mb_linesize,

                                     16 + 5, 16 + 5 /*FIXME*/,

                                     full_mx - 2, full_my - 2,

                                     pic_width, pic_height);

            src_cb = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        }

        qpix_op[luma_xy](dest_cb, src_cb, h->mb_linesize); // FIXME try variable height perhaps?

        if (!square)

            qpix_op[luma_xy](dest_cb + delta, src_cb + delta, h->mb_linesize);



        src_cr = pic->f.data[2] + offset;

        if (emu) {

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

                                     src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,

                                     h->mb_linesize,

                                     16 + 5, 16 + 5 /*FIXME*/,

                                     full_mx - 2, full_my - 2,

                                     pic_width, pic_height);

            src_cr = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        }

        qpix_op[luma_xy](dest_cr, src_cr, h->mb_linesize); // FIXME try variable height perhaps?

        if (!square)

            qpix_op[luma_xy](dest_cr + delta, src_cr + delta, h->mb_linesize);

        return;

    }



    ysh = 3 - (chroma_idc == 2 /* yuv422 */);

    if (chroma_idc == 1 /* yuv420 */ && MB_FIELD(h)) {

        // chroma offset when predicting from a field of opposite parity

        my  += 2 * ((h->mb_y & 1) - (pic->reference - 1));

        emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1);

    }



    src_cb = pic->f.data[1] + ((mx >> 3) << pixel_shift) +

             (my >> ysh) * h->mb_uvlinesize;

    src_cr = pic->f.data[2] + ((mx >> 3) << pixel_shift) +

             (my >> ysh) * h->mb_uvlinesize;



    if (emu) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->mb_uvlinesize,

                                 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),

                                 pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));

        src_cb = h->edge_emu_buffer;

    }

    chroma_op(dest_cb, src_cb, h->mb_uvlinesize,

              height >> (chroma_idc == 1 /* yuv420 */),

              mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);



    if (emu) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->mb_uvlinesize,

                                 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),

                                 pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));

        src_cr = h->edge_emu_buffer;

    }

    chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 /* yuv420 */),

              mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);

}

static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,

                                         int n, int square, int height,

                                         int delta, int list,

                                         uint8_t *dest_y, uint8_t *dest_cb,

                                         uint8_t *dest_cr,

                                         int src_x_offset, int src_y_offset,

                                         qpel_mc_func *qpix_op,

                                         h264_chroma_mc_func chroma_op,

                                         int pixel_shift, int chroma_idc)

{

    const int mx      = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8;

    int my            = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8;

    const int luma_xy = (mx & 3) + ((my & 3) << 2);

    int offset        = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize;

    uint8_t *src_y    = pic->f.data[0] + offset;

    uint8_t *src_cb, *src_cr;

    int extra_width  = 0;

    int extra_height = 0;

    int emu = 0;

    const int full_mx    = mx >> 2;

    const int full_my    = my >> 2;

    const int pic_width  = 16 * h->mb_width;

    const int pic_height = 16 * h->mb_height >> MB_FIELD(h);

    int ysh;



    if (mx & 7)

        extra_width -= 3;

    if (my & 7)

        extra_height -= 3;



    if (full_mx                <          0 - extra_width  ||

        full_my                <          0 - extra_height ||

        full_mx + 16  > pic_width  + extra_width  ||

        full_my + 16  > pic_height + extra_height) {

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

                                 src_y - (2 << pixel_shift) - 2 * h->mb_linesize,

                                 h->mb_linesize,

                                 16 + 5, 16 + 5 , full_mx - 2,

                                 full_my - 2, pic_width, pic_height);

        src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        emu   = 1;

    }



    qpix_op[luma_xy](dest_y, src_y, h->mb_linesize); 

    if (!square)

        qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize);



    if (CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY)

        return;



    if (chroma_idc == 3 ) {

        src_cb = pic->f.data[1] + offset;

        if (emu) {

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

                                     src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,

                                     h->mb_linesize,

                                     16 + 5, 16 + 5 ,

                                     full_mx - 2, full_my - 2,

                                     pic_width, pic_height);

            src_cb = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        }

        qpix_op[luma_xy](dest_cb, src_cb, h->mb_linesize); 

        if (!square)

            qpix_op[luma_xy](dest_cb + delta, src_cb + delta, h->mb_linesize);



        src_cr = pic->f.data[2] + offset;

        if (emu) {

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

                                     src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,

                                     h->mb_linesize,

                                     16 + 5, 16 + 5 ,

                                     full_mx - 2, full_my - 2,

                                     pic_width, pic_height);

            src_cr = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        }

        qpix_op[luma_xy](dest_cr, src_cr, h->mb_linesize); 

        if (!square)

            qpix_op[luma_xy](dest_cr + delta, src_cr + delta, h->mb_linesize);

        return;

    }



    ysh = 3 - (chroma_idc == 2 );

    if (chroma_idc == 1  && MB_FIELD(h)) {

        

        my  += 2 * ((h->mb_y & 1) - (pic->reference - 1));

        emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1);

    }



    src_cb = pic->f.data[1] + ((mx >> 3) << pixel_shift) +

             (my >> ysh) * h->mb_uvlinesize;

    src_cr = pic->f.data[2] + ((mx >> 3) << pixel_shift) +

             (my >> ysh) * h->mb_uvlinesize;



    if (emu) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->mb_uvlinesize,

                                 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),

                                 pic_width >> 1, pic_height >> (chroma_idc == 1 ));

        src_cb = h->edge_emu_buffer;

    }

    chroma_op(dest_cb, src_cb, h->mb_uvlinesize,

              height >> (chroma_idc == 1 ),

              mx & 7, (my << (chroma_idc == 2 )) & 7);



    if (emu) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->mb_uvlinesize,

                                 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),

                                 pic_width >> 1, pic_height >> (chroma_idc == 1 ));

        src_cr = h->edge_emu_buffer;

    }

    chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 ),

              mx & 7, (my << (chroma_idc == 2 )) & 7);

}

    int offset        = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize;
static av_always_inline void FUNC_0(H264Context *h, Picture *pic,

                                         int n, int square, int height,

                                         int delta, int list,

                                         uint8_t *dest_y, uint8_t *dest_cb,

                                         uint8_t *dest_cr,

                                         int src_x_offset, int src_y_offset,

                                         qpel_mc_func *qpix_op,

                                         h264_chroma_mc_func chroma_op,

                                         int pixel_shift, int chroma_idc)

{

    const int VAR_0      = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8;

    int VAR_1            = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8;

    const int VAR_2 = (VAR_0 & 3) + ((VAR_1 & 3) << 2);

    int VAR_3        = ((VAR_0 >> 2) << pixel_shift) + (VAR_1 >> 2) * h->mb_linesize;

    uint8_t *src_y    = pic->f.data[0] + VAR_3;

    uint8_t *src_cb, *src_cr;

    int VAR_4  = 0;

    int VAR_5 = 0;

    int VAR_6 = 0;

    const int VAR_7    = VAR_0 >> 2;

    const int VAR_8    = VAR_1 >> 2;

    const int VAR_9  = 16 * h->mb_width;

    const int VAR_10 = 16 * h->mb_height >> MB_FIELD(h);

    int VAR_11;



    if (VAR_0 & 7)

        VAR_4 -= 3;

    if (VAR_1 & 7)

        VAR_5 -= 3;



    if (VAR_7                <          0 - VAR_4  ||

        VAR_8                <          0 - VAR_5 ||

        VAR_7 + 16  > VAR_9  + VAR_4  ||

        VAR_8 + 16  > VAR_10 + VAR_5) {

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

                                 src_y - (2 << pixel_shift) - 2 * h->mb_linesize,

                                 h->mb_linesize,

                                 16 + 5, 16 + 5 , VAR_7 - 2,

                                 VAR_8 - 2, VAR_9, VAR_10);

        src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        VAR_6   = 1;

    }



    qpix_op[VAR_2](dest_y, src_y, h->mb_linesize); 

    if (!square)

        qpix_op[VAR_2](dest_y + delta, src_y + delta, h->mb_linesize);



    if (CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY)

        return;



    if (chroma_idc == 3 ) {

        src_cb = pic->f.data[1] + VAR_3;

        if (VAR_6) {

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

                                     src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,

                                     h->mb_linesize,

                                     16 + 5, 16 + 5 ,

                                     VAR_7 - 2, VAR_8 - 2,

                                     VAR_9, VAR_10);

            src_cb = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        }

        qpix_op[VAR_2](dest_cb, src_cb, h->mb_linesize); 

        if (!square)

            qpix_op[VAR_2](dest_cb + delta, src_cb + delta, h->mb_linesize);



        src_cr = pic->f.data[2] + VAR_3;

        if (VAR_6) {

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

                                     src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,

                                     h->mb_linesize,

                                     16 + 5, 16 + 5 ,

                                     VAR_7 - 2, VAR_8 - 2,

                                     VAR_9, VAR_10);

            src_cr = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        }

        qpix_op[VAR_2](dest_cr, src_cr, h->mb_linesize); 

        if (!square)

            qpix_op[VAR_2](dest_cr + delta, src_cr + delta, h->mb_linesize);

        return;

    }



    VAR_11 = 3 - (chroma_idc == 2 );

    if (chroma_idc == 1  && MB_FIELD(h)) {

        

        VAR_1  += 2 * ((h->mb_y & 1) - (pic->reference - 1));

        VAR_6 |= (VAR_1 >> 3) < 0 || (VAR_1 >> 3) + 8 >= (VAR_10 >> 1);

    }



    src_cb = pic->f.data[1] + ((VAR_0 >> 3) << pixel_shift) +

             (VAR_1 >> VAR_11) * h->mb_uvlinesize;

    src_cr = pic->f.data[2] + ((VAR_0 >> 3) << pixel_shift) +

             (VAR_1 >> VAR_11) * h->mb_uvlinesize;



    if (VAR_6) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->mb_uvlinesize,

                                 9, 8 * chroma_idc + 1, (VAR_0 >> 3), (VAR_1 >> VAR_11),

                                 VAR_9 >> 1, VAR_10 >> (chroma_idc == 1 ));

        src_cb = h->edge_emu_buffer;

    }

    chroma_op(dest_cb, src_cb, h->mb_uvlinesize,

              height >> (chroma_idc == 1 ),

              VAR_0 & 7, (VAR_1 << (chroma_idc == 2 )) & 7);



    if (VAR_6) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->mb_uvlinesize,

                                 9, 8 * chroma_idc + 1, (VAR_0 >> 3), (VAR_1 >> VAR_11),

                                 VAR_9 >> 1, VAR_10 >> (chroma_idc == 1 ));

        src_cr = h->edge_emu_buffer;

    }

    chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 ),

              VAR_0 & 7, (VAR_1 << (chroma_idc == 2 )) & 7);

}

static av_always_inline void FUNC_0(H264Context *h, Picture *pic,
int n, int square, int height,
int delta, int list,
uint8_t *dest_y, uint8_t *dest_cb,
uint8_t *dest_cr,
int src_x_offset, int src_y_offset,
qpel_mc_func *qpix_op,
h264_chroma_mc_func chroma_op,
int pixel_shift, int chroma_idc)
{ const int VAR_0      = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8; int VAR_1            = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8; const int VAR_2 = (VAR_0 & 3) + ((VAR_1 & 3) << 2); int VAR_3        = ((VAR_0 >> 2) << pixel_shift) + (VAR_1 >> 2) * h->mb_linesize; uint8_t *src_y    = pic->f.data[0] + VAR_3; uint8_t *src_cb, *src_cr; int VAR_4  = 0; int VAR_5 = 0; int VAR_6 = 0; const int VAR_7    = VAR_0 >> 2; const int VAR_8    = VAR_1 >> 2; const int VAR_9  = 16 * h->mb_width; const int VAR_10 = 16 * h->mb_height >> MB_FIELD(h); int VAR_11; if (VAR_0 & 7)
VAR_4 -= 3; if (VAR_1 & 7)
VAR_5 -= 3; if (VAR_7                <          0 - VAR_4  ||
VAR_8                <          0 - VAR_5 ||
VAR_7 + 16  > VAR_9  + VAR_4  ||
VAR_8 + 16  > VAR_10 + VAR_5) { h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
src_y - (2 << pixel_shift) - 2 * h->mb_linesize,
h->mb_linesize,
16 + 5, 16 + 5 , VAR_7 - 2,
VAR_8 - 2, VAR_9, VAR_10); src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize; VAR_6   = 1; } qpix_op[VAR_2](dest_y, src_y, h->mb_linesize); if (!square)
qpix_op[VAR_2](dest_y + delta, src_y + delta, h->mb_linesize); if (CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY)
return; if (chroma_idc == 3 ) { src_cb = pic->f.data[1] + VAR_3; if (VAR_6) { h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,
h->mb_linesize,
16 + 5, 16 + 5 ,
VAR_7 - 2, VAR_8 - 2,
VAR_9, VAR_10); src_cb = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize; } qpix_op[VAR_2](dest_cb, src_cb, h->mb_linesize); if (!square)
qpix_op[VAR_2](dest_cb + delta, src_cb + delta, h->mb_linesize); src_cr = pic->f.data[2] + VAR_3; if (VAR_6) { h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,
h->mb_linesize,
16 + 5, 16 + 5 ,
VAR_7 - 2, VAR_8 - 2,
VAR_9, VAR_10); src_cr = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize; } qpix_op[VAR_2](dest_cr, src_cr, h->mb_linesize); if (!square)
qpix_op[VAR_2](dest_cr + delta, src_cr + delta, h->mb_linesize); return; } VAR_11 = 3 - (chroma_idc == 2 ); if (chroma_idc == 1  && MB_FIELD(h)) { VAR_1  += 2 * ((h->mb_y & 1) - (pic->reference - 1)); VAR_6 |= (VAR_1 >> 3) < 0 || (VAR_1 >> 3) + 8 >= (VAR_10 >> 1); } src_cb = pic->f.data[1] + ((VAR_0 >> 3) << pixel_shift) +
(VAR_1 >> VAR_11) * h->mb_uvlinesize; src_cr = pic->f.data[2] + ((VAR_0 >> 3) << pixel_shift) +
(VAR_1 >> VAR_11) * h->mb_uvlinesize; if (VAR_6) { h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->mb_uvlinesize,
9, 8 * chroma_idc + 1, (VAR_0 >> 3), (VAR_1 >> VAR_11),
VAR_9 >> 1, VAR_10 >> (chroma_idc == 1 )); src_cb = h->edge_emu_buffer; } chroma_op(dest_cb, src_cb, h->mb_uvlinesize,
height >> (chroma_idc == 1 ),
VAR_0 & 7, (VAR_1 << (chroma_idc == 2 )) & 7); if (VAR_6) { h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->mb_uvlinesize,
9, 8 * chroma_idc + 1, (VAR_0 >> 3), (VAR_1 >> VAR_11),
VAR_9 >> 1, VAR_10 >> (chroma_idc == 1 )); src_cr = h->edge_emu_buffer; } chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 ),
VAR_0 & 7, (VAR_1 << (chroma_idc == 2 )) & 7); }