static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,

                                        int jobnr, int threadnr, int is_vp7)

{

    VP8Context *s = avctx->priv_data;

    VP8ThreadData *prev_td, *next_td, *td = &s->thread_data[threadnr];

    int mb_y = td->thread_mb_pos >> 16;

    int mb_x, mb_xy = mb_y * s->mb_width;

    int num_jobs = s->num_jobs;

    VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame;

    VP56RangeCoder *c  = &s->coeff_partition[mb_y & (s->num_coeff_partitions - 1)];

    VP8Macroblock *mb;

    uint8_t *dst[3] = {

        curframe->tf.f->data[0] + 16 * mb_y * s->linesize,

        curframe->tf.f->data[1] +  8 * mb_y * s->uvlinesize,

        curframe->tf.f->data[2] +  8 * mb_y * s->uvlinesize

    };







    if (mb_y == 0)

        prev_td = td;

    else

        prev_td = &s->thread_data[(jobnr + num_jobs - 1) % num_jobs];

    if (mb_y == s->mb_height - 1)

        next_td = td;

    else

        next_td = &s->thread_data[(jobnr + 1) % num_jobs];

    if (s->mb_layout == 1)

        mb = s->macroblocks_base + ((s->mb_width + 1) * (mb_y + 1) + 1);

    else {

        // Make sure the previous frame has read its segmentation map,

        // if we re-use the same map.

        if (prev_frame && s->segmentation.enabled &&

            !s->segmentation.update_map)

            ff_thread_await_progress(&prev_frame->tf, mb_y, 0);

        mb = s->macroblocks + (s->mb_height - mb_y - 1) * 2;

        memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock

        AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);

    }



    if (!is_vp7 || mb_y == 0)

        memset(td->left_nnz, 0, sizeof(td->left_nnz));



    s->mv_min.x = -MARGIN;

    s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;



    for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {



        // Wait for previous thread to read mb_x+2, and reach mb_y-1.

        if (prev_td != td) {

            if (threadnr != 0) {

                check_thread_pos(td, prev_td,

                                 mb_x + (is_vp7 ? 2 : 1),

                                 mb_y - (is_vp7 ? 2 : 1));

            } else {

                check_thread_pos(td, prev_td,

                                 mb_x + (is_vp7 ? 2 : 1) + s->mb_width + 3,

                                 mb_y - (is_vp7 ? 2 : 1));

            }

        }



        s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 * s->linesize + 64,

                         s->linesize, 4);

        s->vdsp.prefetch(dst[1] + (mb_x & 7) * s->uvlinesize + 64,

                         dst[2] - dst[1], 2);



        if (!s->mb_layout)

            decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,

                           prev_frame && prev_frame->seg_map ?

                           prev_frame->seg_map->data + mb_xy : NULL, 0, is_vp7);



        prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);



        if (!mb->skip)

            decode_mb_coeffs(s, td, c, mb, s->top_nnz[mb_x], td->left_nnz, is_vp7);



        if (mb->mode <= MODE_I4x4)

            intra_predict(s, td, dst, mb, mb_x, mb_y, is_vp7);

        else

            inter_predict(s, td, dst, mb, mb_x, mb_y);



        prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN);



        if (!mb->skip) {

            idct_mb(s, td, dst, mb);

        } else {

            AV_ZERO64(td->left_nnz);

            AV_WN64(s->top_nnz[mb_x], 0);   // array of 9, so unaligned



            /* Reset DC block predictors if they would exist

             * if the mb had coefficients */

            if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {

                td->left_nnz[8]     = 0;

                s->top_nnz[mb_x][8] = 0;

            }

        }



        if (s->deblock_filter)

            filter_level_for_mb(s, mb, &td->filter_strength[mb_x], is_vp7);



        if (s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {

            if (s->filter.simple)

                backup_mb_border(s->top_border[mb_x + 1], dst[0],

                                 NULL, NULL, s->linesize, 0, 1);

            else

                backup_mb_border(s->top_border[mb_x + 1], dst[0],

                                 dst[1], dst[2], s->linesize, s->uvlinesize, 0);

        }



        prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN2);



        dst[0]      += 16;

        dst[1]      += 8;

        dst[2]      += 8;

        s->mv_min.x -= 64;

        s->mv_max.x -= 64;



        if (mb_x == s->mb_width + 1) {

            update_pos(td, mb_y, s->mb_width + 3);

        } else {

            update_pos(td, mb_y, mb_x);

        }

    }

    return 0;

}