11b362b15af34006e6a11974088a46d42b903418eJohann/*
21b362b15af34006e6a11974088a46d42b903418eJohann *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
31b362b15af34006e6a11974088a46d42b903418eJohann *
41b362b15af34006e6a11974088a46d42b903418eJohann *  Use of this source code is governed by a BSD-style license
51b362b15af34006e6a11974088a46d42b903418eJohann *  that can be found in the LICENSE file in the root of the source
61b362b15af34006e6a11974088a46d42b903418eJohann *  tree. An additional intellectual property rights grant can be found
71b362b15af34006e6a11974088a46d42b903418eJohann *  in the file PATENTS.  All contributing project authors may
81b362b15af34006e6a11974088a46d42b903418eJohann *  be found in the AUTHORS file in the root of the source tree.
91b362b15af34006e6a11974088a46d42b903418eJohann */
101b362b15af34006e6a11974088a46d42b903418eJohann
111b362b15af34006e6a11974088a46d42b903418eJohann
121b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_config.h"
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp8_rtcd.h"
141b362b15af34006e6a11974088a46d42b903418eJohann#if !defined(WIN32) && CONFIG_OS_SUPPORT == 1
151b362b15af34006e6a11974088a46d42b903418eJohann# include <unistd.h>
161b362b15af34006e6a11974088a46d42b903418eJohann#endif
171b362b15af34006e6a11974088a46d42b903418eJohann#include "onyxd_int.h"
181b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_mem/vpx_mem.h"
191b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/threading.h"
201b362b15af34006e6a11974088a46d42b903418eJohann
211b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/loopfilter.h"
221b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/extend.h"
231b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_ports/vpx_timer.h"
241b362b15af34006e6a11974088a46d42b903418eJohann#include "detokenize.h"
251b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/reconintra4x4.h"
261b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/reconinter.h"
271b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/setupintrarecon.h"
281b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_ERROR_CONCEALMENT
291b362b15af34006e6a11974088a46d42b903418eJohann#include "error_concealment.h"
301b362b15af34006e6a11974088a46d42b903418eJohann#endif
311b362b15af34006e6a11974088a46d42b903418eJohann
321b362b15af34006e6a11974088a46d42b903418eJohann#define CALLOC_ARRAY(p, n) CHECK_MEM_ERROR((p), vpx_calloc(sizeof(*(p)), (n)))
331b362b15af34006e6a11974088a46d42b903418eJohann#define CALLOC_ARRAY_ALIGNED(p, n, algn) do {                      \
341b362b15af34006e6a11974088a46d42b903418eJohann  CHECK_MEM_ERROR((p), vpx_memalign((algn), sizeof(*(p)) * (n)));  \
351b362b15af34006e6a11974088a46d42b903418eJohann  memset((p), 0, (n) * sizeof(*(p)));                              \
361b362b15af34006e6a11974088a46d42b903418eJohann} while (0)
371b362b15af34006e6a11974088a46d42b903418eJohann
381b362b15af34006e6a11974088a46d42b903418eJohann
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp8_mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd);
401b362b15af34006e6a11974088a46d42b903418eJohann
411b362b15af34006e6a11974088a46d42b903418eJohannstatic void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
421b362b15af34006e6a11974088a46d42b903418eJohann{
431b362b15af34006e6a11974088a46d42b903418eJohann    VP8_COMMON *const pc = & pbi->common;
441b362b15af34006e6a11974088a46d42b903418eJohann    int i;
451b362b15af34006e6a11974088a46d42b903418eJohann
461b362b15af34006e6a11974088a46d42b903418eJohann    for (i = 0; i < count; i++)
471b362b15af34006e6a11974088a46d42b903418eJohann    {
481b362b15af34006e6a11974088a46d42b903418eJohann        MACROBLOCKD *mbd = &mbrd[i].mbd;
491b362b15af34006e6a11974088a46d42b903418eJohann        mbd->subpixel_predict        = xd->subpixel_predict;
501b362b15af34006e6a11974088a46d42b903418eJohann        mbd->subpixel_predict8x4     = xd->subpixel_predict8x4;
511b362b15af34006e6a11974088a46d42b903418eJohann        mbd->subpixel_predict8x8     = xd->subpixel_predict8x8;
521b362b15af34006e6a11974088a46d42b903418eJohann        mbd->subpixel_predict16x16   = xd->subpixel_predict16x16;
531b362b15af34006e6a11974088a46d42b903418eJohann
541b362b15af34006e6a11974088a46d42b903418eJohann        mbd->mode_info_context = pc->mi   + pc->mode_info_stride * (i + 1);
551b362b15af34006e6a11974088a46d42b903418eJohann        mbd->mode_info_stride  = pc->mode_info_stride;
561b362b15af34006e6a11974088a46d42b903418eJohann
571b362b15af34006e6a11974088a46d42b903418eJohann        mbd->frame_type = pc->frame_type;
581b362b15af34006e6a11974088a46d42b903418eJohann        mbd->pre = xd->pre;
591b362b15af34006e6a11974088a46d42b903418eJohann        mbd->dst = xd->dst;
601b362b15af34006e6a11974088a46d42b903418eJohann
611b362b15af34006e6a11974088a46d42b903418eJohann        mbd->segmentation_enabled    = xd->segmentation_enabled;
621b362b15af34006e6a11974088a46d42b903418eJohann        mbd->mb_segement_abs_delta     = xd->mb_segement_abs_delta;
631b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memcpy(mbd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
641b362b15af34006e6a11974088a46d42b903418eJohann
651b362b15af34006e6a11974088a46d42b903418eJohann        /*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/
661b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memcpy(mbd->ref_lf_deltas, xd->ref_lf_deltas, sizeof(xd->ref_lf_deltas));
671b362b15af34006e6a11974088a46d42b903418eJohann        /*signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];*/
681b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memcpy(mbd->mode_lf_deltas, xd->mode_lf_deltas, sizeof(xd->mode_lf_deltas));
691b362b15af34006e6a11974088a46d42b903418eJohann        /*unsigned char mode_ref_lf_delta_enabled;
701b362b15af34006e6a11974088a46d42b903418eJohann        unsigned char mode_ref_lf_delta_update;*/
711b362b15af34006e6a11974088a46d42b903418eJohann        mbd->mode_ref_lf_delta_enabled    = xd->mode_ref_lf_delta_enabled;
721b362b15af34006e6a11974088a46d42b903418eJohann        mbd->mode_ref_lf_delta_update    = xd->mode_ref_lf_delta_update;
731b362b15af34006e6a11974088a46d42b903418eJohann
741b362b15af34006e6a11974088a46d42b903418eJohann        mbd->current_bc = &pbi->mbc[0];
751b362b15af34006e6a11974088a46d42b903418eJohann
761b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memcpy(mbd->dequant_y1_dc, xd->dequant_y1_dc, sizeof(xd->dequant_y1_dc));
771b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memcpy(mbd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1));
781b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memcpy(mbd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2));
791b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memcpy(mbd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv));
801b362b15af34006e6a11974088a46d42b903418eJohann
811b362b15af34006e6a11974088a46d42b903418eJohann        mbd->fullpixel_mask = 0xffffffff;
821b362b15af34006e6a11974088a46d42b903418eJohann
831b362b15af34006e6a11974088a46d42b903418eJohann        if (pc->full_pixel)
841b362b15af34006e6a11974088a46d42b903418eJohann            mbd->fullpixel_mask = 0xfffffff8;
851b362b15af34006e6a11974088a46d42b903418eJohann
861b362b15af34006e6a11974088a46d42b903418eJohann    }
871b362b15af34006e6a11974088a46d42b903418eJohann
881b362b15af34006e6a11974088a46d42b903418eJohann    for (i = 0; i < pc->mb_rows; i++)
891b362b15af34006e6a11974088a46d42b903418eJohann        pbi->mt_current_mb_col[i] = -1;
901b362b15af34006e6a11974088a46d42b903418eJohann}
911b362b15af34006e6a11974088a46d42b903418eJohann
921b362b15af34006e6a11974088a46d42b903418eJohannstatic void mt_decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
931b362b15af34006e6a11974088a46d42b903418eJohann                                 unsigned int mb_idx)
941b362b15af34006e6a11974088a46d42b903418eJohann{
951b362b15af34006e6a11974088a46d42b903418eJohann    MB_PREDICTION_MODE mode;
961b362b15af34006e6a11974088a46d42b903418eJohann    int i;
971b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_ERROR_CONCEALMENT
981b362b15af34006e6a11974088a46d42b903418eJohann    int corruption_detected = 0;
991b362b15af34006e6a11974088a46d42b903418eJohann#endif
1001b362b15af34006e6a11974088a46d42b903418eJohann
1011b362b15af34006e6a11974088a46d42b903418eJohann    if (xd->mode_info_context->mbmi.mb_skip_coeff)
1021b362b15af34006e6a11974088a46d42b903418eJohann    {
1031b362b15af34006e6a11974088a46d42b903418eJohann        vp8_reset_mb_tokens_context(xd);
1041b362b15af34006e6a11974088a46d42b903418eJohann    }
1051b362b15af34006e6a11974088a46d42b903418eJohann    else if (!vp8dx_bool_error(xd->current_bc))
1061b362b15af34006e6a11974088a46d42b903418eJohann    {
1071b362b15af34006e6a11974088a46d42b903418eJohann        int eobtotal;
1081b362b15af34006e6a11974088a46d42b903418eJohann        eobtotal = vp8_decode_mb_tokens(pbi, xd);
1091b362b15af34006e6a11974088a46d42b903418eJohann
1101b362b15af34006e6a11974088a46d42b903418eJohann        /* Special case:  Force the loopfilter to skip when eobtotal is zero */
1111b362b15af34006e6a11974088a46d42b903418eJohann        xd->mode_info_context->mbmi.mb_skip_coeff = (eobtotal==0);
1121b362b15af34006e6a11974088a46d42b903418eJohann    }
1131b362b15af34006e6a11974088a46d42b903418eJohann
1141b362b15af34006e6a11974088a46d42b903418eJohann    mode = xd->mode_info_context->mbmi.mode;
1151b362b15af34006e6a11974088a46d42b903418eJohann
1161b362b15af34006e6a11974088a46d42b903418eJohann    if (xd->segmentation_enabled)
1171b362b15af34006e6a11974088a46d42b903418eJohann        vp8_mb_init_dequantizer(pbi, xd);
1181b362b15af34006e6a11974088a46d42b903418eJohann
1191b362b15af34006e6a11974088a46d42b903418eJohann
1201b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_ERROR_CONCEALMENT
1211b362b15af34006e6a11974088a46d42b903418eJohann
1221b362b15af34006e6a11974088a46d42b903418eJohann    if(pbi->ec_active)
1231b362b15af34006e6a11974088a46d42b903418eJohann    {
1241b362b15af34006e6a11974088a46d42b903418eJohann        int throw_residual;
1251b362b15af34006e6a11974088a46d42b903418eJohann        /* When we have independent partitions we can apply residual even
1261b362b15af34006e6a11974088a46d42b903418eJohann         * though other partitions within the frame are corrupt.
1271b362b15af34006e6a11974088a46d42b903418eJohann         */
1281b362b15af34006e6a11974088a46d42b903418eJohann        throw_residual = (!pbi->independent_partitions &&
1291b362b15af34006e6a11974088a46d42b903418eJohann                          pbi->frame_corrupt_residual);
1301b362b15af34006e6a11974088a46d42b903418eJohann        throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc));
1311b362b15af34006e6a11974088a46d42b903418eJohann
1321b362b15af34006e6a11974088a46d42b903418eJohann        if ((mb_idx >= pbi->mvs_corrupt_from_mb || throw_residual))
1331b362b15af34006e6a11974088a46d42b903418eJohann        {
1341b362b15af34006e6a11974088a46d42b903418eJohann            /* MB with corrupt residuals or corrupt mode/motion vectors.
1351b362b15af34006e6a11974088a46d42b903418eJohann             * Better to use the predictor as reconstruction.
1361b362b15af34006e6a11974088a46d42b903418eJohann             */
1371b362b15af34006e6a11974088a46d42b903418eJohann            pbi->frame_corrupt_residual = 1;
1381b362b15af34006e6a11974088a46d42b903418eJohann            vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
1391b362b15af34006e6a11974088a46d42b903418eJohann            vp8_conceal_corrupt_mb(xd);
1401b362b15af34006e6a11974088a46d42b903418eJohann
1411b362b15af34006e6a11974088a46d42b903418eJohann
1421b362b15af34006e6a11974088a46d42b903418eJohann            corruption_detected = 1;
1431b362b15af34006e6a11974088a46d42b903418eJohann
1441b362b15af34006e6a11974088a46d42b903418eJohann            /* force idct to be skipped for B_PRED and use the
1451b362b15af34006e6a11974088a46d42b903418eJohann             * prediction only for reconstruction
1461b362b15af34006e6a11974088a46d42b903418eJohann             * */
1471b362b15af34006e6a11974088a46d42b903418eJohann            vpx_memset(xd->eobs, 0, 25);
1481b362b15af34006e6a11974088a46d42b903418eJohann        }
1491b362b15af34006e6a11974088a46d42b903418eJohann    }
1501b362b15af34006e6a11974088a46d42b903418eJohann#endif
1511b362b15af34006e6a11974088a46d42b903418eJohann
1521b362b15af34006e6a11974088a46d42b903418eJohann    /* do prediction */
1531b362b15af34006e6a11974088a46d42b903418eJohann    if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
1541b362b15af34006e6a11974088a46d42b903418eJohann    {
1551b362b15af34006e6a11974088a46d42b903418eJohann        vp8_build_intra_predictors_mbuv_s(xd,
1561b362b15af34006e6a11974088a46d42b903418eJohann                                          xd->recon_above[1],
1571b362b15af34006e6a11974088a46d42b903418eJohann                                          xd->recon_above[2],
1581b362b15af34006e6a11974088a46d42b903418eJohann                                          xd->recon_left[1],
1591b362b15af34006e6a11974088a46d42b903418eJohann                                          xd->recon_left[2],
1601b362b15af34006e6a11974088a46d42b903418eJohann                                          xd->recon_left_stride[1],
1611b362b15af34006e6a11974088a46d42b903418eJohann                                          xd->dst.u_buffer, xd->dst.v_buffer,
1621b362b15af34006e6a11974088a46d42b903418eJohann                                          xd->dst.uv_stride);
1631b362b15af34006e6a11974088a46d42b903418eJohann
1641b362b15af34006e6a11974088a46d42b903418eJohann        if (mode != B_PRED)
1651b362b15af34006e6a11974088a46d42b903418eJohann        {
1661b362b15af34006e6a11974088a46d42b903418eJohann            vp8_build_intra_predictors_mby_s(xd,
1671b362b15af34006e6a11974088a46d42b903418eJohann                                                 xd->recon_above[0],
1681b362b15af34006e6a11974088a46d42b903418eJohann                                                 xd->recon_left[0],
1691b362b15af34006e6a11974088a46d42b903418eJohann                                                 xd->recon_left_stride[0],
1701b362b15af34006e6a11974088a46d42b903418eJohann                                                 xd->dst.y_buffer,
1711b362b15af34006e6a11974088a46d42b903418eJohann                                                 xd->dst.y_stride);
1721b362b15af34006e6a11974088a46d42b903418eJohann        }
1731b362b15af34006e6a11974088a46d42b903418eJohann        else
1741b362b15af34006e6a11974088a46d42b903418eJohann        {
1751b362b15af34006e6a11974088a46d42b903418eJohann            short *DQC = xd->dequant_y1;
1761b362b15af34006e6a11974088a46d42b903418eJohann            int dst_stride = xd->dst.y_stride;
1771b362b15af34006e6a11974088a46d42b903418eJohann
1781b362b15af34006e6a11974088a46d42b903418eJohann            /* clear out residual eob info */
1791b362b15af34006e6a11974088a46d42b903418eJohann            if(xd->mode_info_context->mbmi.mb_skip_coeff)
1801b362b15af34006e6a11974088a46d42b903418eJohann                vpx_memset(xd->eobs, 0, 25);
1811b362b15af34006e6a11974088a46d42b903418eJohann
1821b362b15af34006e6a11974088a46d42b903418eJohann            intra_prediction_down_copy(xd, xd->recon_above[0] + 16);
1831b362b15af34006e6a11974088a46d42b903418eJohann
1841b362b15af34006e6a11974088a46d42b903418eJohann            for (i = 0; i < 16; i++)
1851b362b15af34006e6a11974088a46d42b903418eJohann            {
1861b362b15af34006e6a11974088a46d42b903418eJohann                BLOCKD *b = &xd->block[i];
1871b362b15af34006e6a11974088a46d42b903418eJohann                unsigned char *dst = xd->dst.y_buffer + b->offset;
1881b362b15af34006e6a11974088a46d42b903418eJohann                B_PREDICTION_MODE b_mode =
1891b362b15af34006e6a11974088a46d42b903418eJohann                    xd->mode_info_context->bmi[i].as_mode;
1901b362b15af34006e6a11974088a46d42b903418eJohann                unsigned char *Above;
1911b362b15af34006e6a11974088a46d42b903418eJohann                unsigned char *yleft;
1921b362b15af34006e6a11974088a46d42b903418eJohann                int left_stride;
1931b362b15af34006e6a11974088a46d42b903418eJohann                unsigned char top_left;
1941b362b15af34006e6a11974088a46d42b903418eJohann
1951b362b15af34006e6a11974088a46d42b903418eJohann                /*Caution: For some b_mode, it needs 8 pixels (4 above + 4 above-right).*/
1961b362b15af34006e6a11974088a46d42b903418eJohann                if (i < 4 && pbi->common.filter_level)
1971b362b15af34006e6a11974088a46d42b903418eJohann                    Above = xd->recon_above[0] + b->offset;
1981b362b15af34006e6a11974088a46d42b903418eJohann                else
1991b362b15af34006e6a11974088a46d42b903418eJohann                    Above = dst - dst_stride;
2001b362b15af34006e6a11974088a46d42b903418eJohann
2011b362b15af34006e6a11974088a46d42b903418eJohann                if (i%4==0 && pbi->common.filter_level)
2021b362b15af34006e6a11974088a46d42b903418eJohann                {
2031b362b15af34006e6a11974088a46d42b903418eJohann                    yleft = xd->recon_left[0] + i;
2041b362b15af34006e6a11974088a46d42b903418eJohann                    left_stride = 1;
2051b362b15af34006e6a11974088a46d42b903418eJohann                }
2061b362b15af34006e6a11974088a46d42b903418eJohann                else
2071b362b15af34006e6a11974088a46d42b903418eJohann                {
2081b362b15af34006e6a11974088a46d42b903418eJohann                    yleft = dst - 1;
2091b362b15af34006e6a11974088a46d42b903418eJohann                    left_stride = dst_stride;
2101b362b15af34006e6a11974088a46d42b903418eJohann                }
2111b362b15af34006e6a11974088a46d42b903418eJohann
2121b362b15af34006e6a11974088a46d42b903418eJohann                if ((i==4 || i==8 || i==12) && pbi->common.filter_level)
2131b362b15af34006e6a11974088a46d42b903418eJohann                    top_left = *(xd->recon_left[0] + i - 1);
2141b362b15af34006e6a11974088a46d42b903418eJohann                else
2151b362b15af34006e6a11974088a46d42b903418eJohann                    top_left = Above[-1];
2161b362b15af34006e6a11974088a46d42b903418eJohann
2171b362b15af34006e6a11974088a46d42b903418eJohann                vp8_intra4x4_predict(Above, yleft, left_stride,
2181b362b15af34006e6a11974088a46d42b903418eJohann                                     b_mode, dst, dst_stride, top_left);
2191b362b15af34006e6a11974088a46d42b903418eJohann
2201b362b15af34006e6a11974088a46d42b903418eJohann                if (xd->eobs[i] )
2211b362b15af34006e6a11974088a46d42b903418eJohann                {
2221b362b15af34006e6a11974088a46d42b903418eJohann                    if (xd->eobs[i] > 1)
2231b362b15af34006e6a11974088a46d42b903418eJohann                    {
2241b362b15af34006e6a11974088a46d42b903418eJohann                        vp8_dequant_idct_add(b->qcoeff, DQC, dst, dst_stride);
2251b362b15af34006e6a11974088a46d42b903418eJohann                    }
2261b362b15af34006e6a11974088a46d42b903418eJohann                    else
2271b362b15af34006e6a11974088a46d42b903418eJohann                    {
2281b362b15af34006e6a11974088a46d42b903418eJohann                        vp8_dc_only_idct_add(b->qcoeff[0] * DQC[0],
2291b362b15af34006e6a11974088a46d42b903418eJohann                                             dst, dst_stride, dst, dst_stride);
2305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                        vpx_memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0]));
2311b362b15af34006e6a11974088a46d42b903418eJohann                    }
2321b362b15af34006e6a11974088a46d42b903418eJohann                }
2331b362b15af34006e6a11974088a46d42b903418eJohann            }
2341b362b15af34006e6a11974088a46d42b903418eJohann        }
2351b362b15af34006e6a11974088a46d42b903418eJohann    }
2361b362b15af34006e6a11974088a46d42b903418eJohann    else
2371b362b15af34006e6a11974088a46d42b903418eJohann    {
2381b362b15af34006e6a11974088a46d42b903418eJohann        vp8_build_inter_predictors_mb(xd);
2391b362b15af34006e6a11974088a46d42b903418eJohann    }
2401b362b15af34006e6a11974088a46d42b903418eJohann
2411b362b15af34006e6a11974088a46d42b903418eJohann
2421b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_ERROR_CONCEALMENT
2431b362b15af34006e6a11974088a46d42b903418eJohann    if (corruption_detected)
2441b362b15af34006e6a11974088a46d42b903418eJohann    {
2451b362b15af34006e6a11974088a46d42b903418eJohann        return;
2461b362b15af34006e6a11974088a46d42b903418eJohann    }
2471b362b15af34006e6a11974088a46d42b903418eJohann#endif
2481b362b15af34006e6a11974088a46d42b903418eJohann
2491b362b15af34006e6a11974088a46d42b903418eJohann    if(!xd->mode_info_context->mbmi.mb_skip_coeff)
2501b362b15af34006e6a11974088a46d42b903418eJohann    {
2511b362b15af34006e6a11974088a46d42b903418eJohann        /* dequantization and idct */
2521b362b15af34006e6a11974088a46d42b903418eJohann        if (mode != B_PRED)
2531b362b15af34006e6a11974088a46d42b903418eJohann        {
2541b362b15af34006e6a11974088a46d42b903418eJohann            short *DQC = xd->dequant_y1;
2551b362b15af34006e6a11974088a46d42b903418eJohann
2561b362b15af34006e6a11974088a46d42b903418eJohann            if (mode != SPLITMV)
2571b362b15af34006e6a11974088a46d42b903418eJohann            {
2581b362b15af34006e6a11974088a46d42b903418eJohann                BLOCKD *b = &xd->block[24];
2591b362b15af34006e6a11974088a46d42b903418eJohann
2601b362b15af34006e6a11974088a46d42b903418eJohann                /* do 2nd order transform on the dc block */
2611b362b15af34006e6a11974088a46d42b903418eJohann                if (xd->eobs[24] > 1)
2621b362b15af34006e6a11974088a46d42b903418eJohann                {
2631b362b15af34006e6a11974088a46d42b903418eJohann                    vp8_dequantize_b(b, xd->dequant_y2);
2641b362b15af34006e6a11974088a46d42b903418eJohann
2651b362b15af34006e6a11974088a46d42b903418eJohann                    vp8_short_inv_walsh4x4(&b->dqcoeff[0],
2661b362b15af34006e6a11974088a46d42b903418eJohann                        xd->qcoeff);
2675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    vpx_memset(b->qcoeff, 0, 16 * sizeof(b->qcoeff[0]));
2681b362b15af34006e6a11974088a46d42b903418eJohann                }
2691b362b15af34006e6a11974088a46d42b903418eJohann                else
2701b362b15af34006e6a11974088a46d42b903418eJohann                {
2711b362b15af34006e6a11974088a46d42b903418eJohann                    b->dqcoeff[0] = b->qcoeff[0] * xd->dequant_y2[0];
2721b362b15af34006e6a11974088a46d42b903418eJohann                    vp8_short_inv_walsh4x4_1(&b->dqcoeff[0],
2731b362b15af34006e6a11974088a46d42b903418eJohann                        xd->qcoeff);
2745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    vpx_memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0]));
2751b362b15af34006e6a11974088a46d42b903418eJohann                }
2761b362b15af34006e6a11974088a46d42b903418eJohann
2771b362b15af34006e6a11974088a46d42b903418eJohann                /* override the dc dequant constant in order to preserve the
2781b362b15af34006e6a11974088a46d42b903418eJohann                 * dc components
2791b362b15af34006e6a11974088a46d42b903418eJohann                 */
2801b362b15af34006e6a11974088a46d42b903418eJohann                DQC = xd->dequant_y1_dc;
2811b362b15af34006e6a11974088a46d42b903418eJohann            }
2821b362b15af34006e6a11974088a46d42b903418eJohann
2831b362b15af34006e6a11974088a46d42b903418eJohann            vp8_dequant_idct_add_y_block
2841b362b15af34006e6a11974088a46d42b903418eJohann                            (xd->qcoeff, DQC,
2851b362b15af34006e6a11974088a46d42b903418eJohann                             xd->dst.y_buffer,
2861b362b15af34006e6a11974088a46d42b903418eJohann                             xd->dst.y_stride, xd->eobs);
2871b362b15af34006e6a11974088a46d42b903418eJohann        }
2881b362b15af34006e6a11974088a46d42b903418eJohann
2891b362b15af34006e6a11974088a46d42b903418eJohann        vp8_dequant_idct_add_uv_block
2901b362b15af34006e6a11974088a46d42b903418eJohann                        (xd->qcoeff+16*16, xd->dequant_uv,
2911b362b15af34006e6a11974088a46d42b903418eJohann                         xd->dst.u_buffer, xd->dst.v_buffer,
2921b362b15af34006e6a11974088a46d42b903418eJohann                         xd->dst.uv_stride, xd->eobs+16);
2931b362b15af34006e6a11974088a46d42b903418eJohann    }
2941b362b15af34006e6a11974088a46d42b903418eJohann}
2951b362b15af34006e6a11974088a46d42b903418eJohann
2961b362b15af34006e6a11974088a46d42b903418eJohannstatic void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row)
2971b362b15af34006e6a11974088a46d42b903418eJohann{
2981b362b15af34006e6a11974088a46d42b903418eJohann    volatile const int *last_row_current_mb_col;
2991b362b15af34006e6a11974088a46d42b903418eJohann    volatile int *current_mb_col;
3001b362b15af34006e6a11974088a46d42b903418eJohann    int mb_row;
3011b362b15af34006e6a11974088a46d42b903418eJohann    VP8_COMMON *pc = &pbi->common;
3021b362b15af34006e6a11974088a46d42b903418eJohann    const int nsync = pbi->sync_range;
3031b362b15af34006e6a11974088a46d42b903418eJohann    const int first_row_no_sync_above = pc->mb_cols + nsync;
3041b362b15af34006e6a11974088a46d42b903418eJohann    int num_part = 1 << pbi->common.multi_token_partition;
3051b362b15af34006e6a11974088a46d42b903418eJohann    int last_mb_row = start_mb_row;
3061b362b15af34006e6a11974088a46d42b903418eJohann
3071b362b15af34006e6a11974088a46d42b903418eJohann    YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME];
3081b362b15af34006e6a11974088a46d42b903418eJohann    YV12_BUFFER_CONFIG *yv12_fb_lst = pbi->dec_fb_ref[LAST_FRAME];
3091b362b15af34006e6a11974088a46d42b903418eJohann
3101b362b15af34006e6a11974088a46d42b903418eJohann    int recon_y_stride = yv12_fb_new->y_stride;
3111b362b15af34006e6a11974088a46d42b903418eJohann    int recon_uv_stride = yv12_fb_new->uv_stride;
3121b362b15af34006e6a11974088a46d42b903418eJohann
3131b362b15af34006e6a11974088a46d42b903418eJohann    unsigned char *ref_buffer[MAX_REF_FRAMES][3];
3141b362b15af34006e6a11974088a46d42b903418eJohann    unsigned char *dst_buffer[3];
3151b362b15af34006e6a11974088a46d42b903418eJohann    int i;
3161b362b15af34006e6a11974088a46d42b903418eJohann    int ref_fb_corrupted[MAX_REF_FRAMES];
3171b362b15af34006e6a11974088a46d42b903418eJohann
3181b362b15af34006e6a11974088a46d42b903418eJohann    ref_fb_corrupted[INTRA_FRAME] = 0;
3191b362b15af34006e6a11974088a46d42b903418eJohann
3201b362b15af34006e6a11974088a46d42b903418eJohann    for(i = 1; i < MAX_REF_FRAMES; i++)
3211b362b15af34006e6a11974088a46d42b903418eJohann    {
3221b362b15af34006e6a11974088a46d42b903418eJohann        YV12_BUFFER_CONFIG *this_fb = pbi->dec_fb_ref[i];
3231b362b15af34006e6a11974088a46d42b903418eJohann
3241b362b15af34006e6a11974088a46d42b903418eJohann        ref_buffer[i][0] = this_fb->y_buffer;
3251b362b15af34006e6a11974088a46d42b903418eJohann        ref_buffer[i][1] = this_fb->u_buffer;
3261b362b15af34006e6a11974088a46d42b903418eJohann        ref_buffer[i][2] = this_fb->v_buffer;
3271b362b15af34006e6a11974088a46d42b903418eJohann
3281b362b15af34006e6a11974088a46d42b903418eJohann        ref_fb_corrupted[i] = this_fb->corrupted;
3291b362b15af34006e6a11974088a46d42b903418eJohann    }
3301b362b15af34006e6a11974088a46d42b903418eJohann
3311b362b15af34006e6a11974088a46d42b903418eJohann    dst_buffer[0] = yv12_fb_new->y_buffer;
3321b362b15af34006e6a11974088a46d42b903418eJohann    dst_buffer[1] = yv12_fb_new->u_buffer;
3331b362b15af34006e6a11974088a46d42b903418eJohann    dst_buffer[2] = yv12_fb_new->v_buffer;
3341b362b15af34006e6a11974088a46d42b903418eJohann
3351b362b15af34006e6a11974088a46d42b903418eJohann    xd->up_available = (start_mb_row != 0);
3361b362b15af34006e6a11974088a46d42b903418eJohann
3371b362b15af34006e6a11974088a46d42b903418eJohann    for (mb_row = start_mb_row; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
3381b362b15af34006e6a11974088a46d42b903418eJohann    {
3391b362b15af34006e6a11974088a46d42b903418eJohann       int recon_yoffset, recon_uvoffset;
3401b362b15af34006e6a11974088a46d42b903418eJohann       int mb_col;
3411b362b15af34006e6a11974088a46d42b903418eJohann       int filter_level;
3421b362b15af34006e6a11974088a46d42b903418eJohann       loop_filter_info_n *lfi_n = &pc->lf_info;
3431b362b15af34006e6a11974088a46d42b903418eJohann
3441b362b15af34006e6a11974088a46d42b903418eJohann       /* save last row processed by this thread */
3451b362b15af34006e6a11974088a46d42b903418eJohann       last_mb_row = mb_row;
3461b362b15af34006e6a11974088a46d42b903418eJohann       /* select bool coder for current partition */
3471b362b15af34006e6a11974088a46d42b903418eJohann       xd->current_bc =  &pbi->mbc[mb_row%num_part];
3481b362b15af34006e6a11974088a46d42b903418eJohann
3491b362b15af34006e6a11974088a46d42b903418eJohann       if (mb_row > 0)
3501b362b15af34006e6a11974088a46d42b903418eJohann           last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
3511b362b15af34006e6a11974088a46d42b903418eJohann       else
3521b362b15af34006e6a11974088a46d42b903418eJohann           last_row_current_mb_col = &first_row_no_sync_above;
3531b362b15af34006e6a11974088a46d42b903418eJohann
3541b362b15af34006e6a11974088a46d42b903418eJohann       current_mb_col = &pbi->mt_current_mb_col[mb_row];
3551b362b15af34006e6a11974088a46d42b903418eJohann
3561b362b15af34006e6a11974088a46d42b903418eJohann       recon_yoffset = mb_row * recon_y_stride * 16;
3571b362b15af34006e6a11974088a46d42b903418eJohann       recon_uvoffset = mb_row * recon_uv_stride * 8;
3581b362b15af34006e6a11974088a46d42b903418eJohann
3591b362b15af34006e6a11974088a46d42b903418eJohann       /* reset contexts */
3601b362b15af34006e6a11974088a46d42b903418eJohann       xd->above_context = pc->above_context;
3611b362b15af34006e6a11974088a46d42b903418eJohann       vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
3621b362b15af34006e6a11974088a46d42b903418eJohann
3631b362b15af34006e6a11974088a46d42b903418eJohann       xd->left_available = 0;
3641b362b15af34006e6a11974088a46d42b903418eJohann
3651b362b15af34006e6a11974088a46d42b903418eJohann       xd->mb_to_top_edge = -((mb_row * 16)) << 3;
3661b362b15af34006e6a11974088a46d42b903418eJohann       xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
3671b362b15af34006e6a11974088a46d42b903418eJohann
3681b362b15af34006e6a11974088a46d42b903418eJohann       if (pbi->common.filter_level)
3691b362b15af34006e6a11974088a46d42b903418eJohann       {
3701b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[0] = pbi->mt_yabove_row[mb_row] + 0*16 +32;
3711b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[1] = pbi->mt_uabove_row[mb_row] + 0*8 +16;
3721b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[2] = pbi->mt_vabove_row[mb_row] + 0*8 +16;
3731b362b15af34006e6a11974088a46d42b903418eJohann
3741b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left[0] = pbi->mt_yleft_col[mb_row];
3751b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left[1] = pbi->mt_uleft_col[mb_row];
3761b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left[2] = pbi->mt_vleft_col[mb_row];
3771b362b15af34006e6a11974088a46d42b903418eJohann
3781b362b15af34006e6a11974088a46d42b903418eJohann          /* TODO: move to outside row loop */
3791b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left_stride[0] = 1;
3801b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left_stride[1] = 1;
3811b362b15af34006e6a11974088a46d42b903418eJohann       }
3821b362b15af34006e6a11974088a46d42b903418eJohann       else
3831b362b15af34006e6a11974088a46d42b903418eJohann       {
3841b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[0] = dst_buffer[0] + recon_yoffset;
3851b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[1] = dst_buffer[1] + recon_uvoffset;
3861b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[2] = dst_buffer[2] + recon_uvoffset;
3871b362b15af34006e6a11974088a46d42b903418eJohann
3881b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left[0] = xd->recon_above[0] - 1;
3891b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left[1] = xd->recon_above[1] - 1;
3901b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left[2] = xd->recon_above[2] - 1;
3911b362b15af34006e6a11974088a46d42b903418eJohann
3921b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[0] -= xd->dst.y_stride;
3931b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[1] -= xd->dst.uv_stride;
3941b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_above[2] -= xd->dst.uv_stride;
3951b362b15af34006e6a11974088a46d42b903418eJohann
3961b362b15af34006e6a11974088a46d42b903418eJohann          /* TODO: move to outside row loop */
3971b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left_stride[0] = xd->dst.y_stride;
3981b362b15af34006e6a11974088a46d42b903418eJohann          xd->recon_left_stride[1] = xd->dst.uv_stride;
3991b362b15af34006e6a11974088a46d42b903418eJohann
4001b362b15af34006e6a11974088a46d42b903418eJohann          setup_intra_recon_left(xd->recon_left[0], xd->recon_left[1],
4011b362b15af34006e6a11974088a46d42b903418eJohann                                 xd->recon_left[2], xd->dst.y_stride,
4021b362b15af34006e6a11974088a46d42b903418eJohann                                 xd->dst.uv_stride);
4031b362b15af34006e6a11974088a46d42b903418eJohann       }
4041b362b15af34006e6a11974088a46d42b903418eJohann
4051b362b15af34006e6a11974088a46d42b903418eJohann       for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
4061b362b15af34006e6a11974088a46d42b903418eJohann       {
4071b362b15af34006e6a11974088a46d42b903418eJohann           *current_mb_col = mb_col - 1;
4081b362b15af34006e6a11974088a46d42b903418eJohann
4091b362b15af34006e6a11974088a46d42b903418eJohann           if ((mb_col & (nsync - 1)) == 0)
4101b362b15af34006e6a11974088a46d42b903418eJohann           {
4111b362b15af34006e6a11974088a46d42b903418eJohann               while (mb_col > (*last_row_current_mb_col - nsync))
4121b362b15af34006e6a11974088a46d42b903418eJohann               {
4131b362b15af34006e6a11974088a46d42b903418eJohann                   x86_pause_hint();
4141b362b15af34006e6a11974088a46d42b903418eJohann                   thread_sleep(0);
4151b362b15af34006e6a11974088a46d42b903418eJohann               }
4161b362b15af34006e6a11974088a46d42b903418eJohann           }
4171b362b15af34006e6a11974088a46d42b903418eJohann
4181b362b15af34006e6a11974088a46d42b903418eJohann           /* Distance of MB to the various image edges.
4191b362b15af34006e6a11974088a46d42b903418eJohann            * These are specified to 8th pel as they are always
4201b362b15af34006e6a11974088a46d42b903418eJohann            * compared to values that are in 1/8th pel units.
4211b362b15af34006e6a11974088a46d42b903418eJohann            */
4221b362b15af34006e6a11974088a46d42b903418eJohann           xd->mb_to_left_edge = -((mb_col * 16) << 3);
4231b362b15af34006e6a11974088a46d42b903418eJohann           xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
4241b362b15af34006e6a11974088a46d42b903418eJohann
4251b362b15af34006e6a11974088a46d42b903418eJohann    #if CONFIG_ERROR_CONCEALMENT
4261b362b15af34006e6a11974088a46d42b903418eJohann           {
4271b362b15af34006e6a11974088a46d42b903418eJohann               int corrupt_residual =
4281b362b15af34006e6a11974088a46d42b903418eJohann                           (!pbi->independent_partitions &&
4291b362b15af34006e6a11974088a46d42b903418eJohann                           pbi->frame_corrupt_residual) ||
4301b362b15af34006e6a11974088a46d42b903418eJohann                           vp8dx_bool_error(xd->current_bc);
4311b362b15af34006e6a11974088a46d42b903418eJohann               if (pbi->ec_active &&
4321b362b15af34006e6a11974088a46d42b903418eJohann                   (xd->mode_info_context->mbmi.ref_frame ==
4331b362b15af34006e6a11974088a46d42b903418eJohann                                                    INTRA_FRAME) &&
4341b362b15af34006e6a11974088a46d42b903418eJohann                   corrupt_residual)
4351b362b15af34006e6a11974088a46d42b903418eJohann               {
4361b362b15af34006e6a11974088a46d42b903418eJohann                   /* We have an intra block with corrupt
4371b362b15af34006e6a11974088a46d42b903418eJohann                    * coefficients, better to conceal with an inter
4381b362b15af34006e6a11974088a46d42b903418eJohann                    * block.
4391b362b15af34006e6a11974088a46d42b903418eJohann                    * Interpolate MVs from neighboring MBs
4401b362b15af34006e6a11974088a46d42b903418eJohann                    *
4411b362b15af34006e6a11974088a46d42b903418eJohann                    * Note that for the first mb with corrupt
4421b362b15af34006e6a11974088a46d42b903418eJohann                    * residual in a frame, we might not discover
4431b362b15af34006e6a11974088a46d42b903418eJohann                    * that before decoding the residual. That
4441b362b15af34006e6a11974088a46d42b903418eJohann                    * happens after this check, and therefore no
4451b362b15af34006e6a11974088a46d42b903418eJohann                    * inter concealment will be done.
4461b362b15af34006e6a11974088a46d42b903418eJohann                    */
4471b362b15af34006e6a11974088a46d42b903418eJohann                   vp8_interpolate_motion(xd,
4481b362b15af34006e6a11974088a46d42b903418eJohann                                          mb_row, mb_col,
4491b362b15af34006e6a11974088a46d42b903418eJohann                                          pc->mb_rows, pc->mb_cols,
4501b362b15af34006e6a11974088a46d42b903418eJohann                                          pc->mode_info_stride);
4511b362b15af34006e6a11974088a46d42b903418eJohann               }
4521b362b15af34006e6a11974088a46d42b903418eJohann           }
4531b362b15af34006e6a11974088a46d42b903418eJohann    #endif
4541b362b15af34006e6a11974088a46d42b903418eJohann
4551b362b15af34006e6a11974088a46d42b903418eJohann
4561b362b15af34006e6a11974088a46d42b903418eJohann           xd->dst.y_buffer = dst_buffer[0] + recon_yoffset;
4571b362b15af34006e6a11974088a46d42b903418eJohann           xd->dst.u_buffer = dst_buffer[1] + recon_uvoffset;
4581b362b15af34006e6a11974088a46d42b903418eJohann           xd->dst.v_buffer = dst_buffer[2] + recon_uvoffset;
4591b362b15af34006e6a11974088a46d42b903418eJohann
4601b362b15af34006e6a11974088a46d42b903418eJohann           xd->pre.y_buffer = ref_buffer[xd->mode_info_context->mbmi.ref_frame][0] + recon_yoffset;
4611b362b15af34006e6a11974088a46d42b903418eJohann           xd->pre.u_buffer = ref_buffer[xd->mode_info_context->mbmi.ref_frame][1] + recon_uvoffset;
4621b362b15af34006e6a11974088a46d42b903418eJohann           xd->pre.v_buffer = ref_buffer[xd->mode_info_context->mbmi.ref_frame][2] + recon_uvoffset;
4631b362b15af34006e6a11974088a46d42b903418eJohann
4641b362b15af34006e6a11974088a46d42b903418eJohann           /* propagate errors from reference frames */
4651b362b15af34006e6a11974088a46d42b903418eJohann           xd->corrupted |= ref_fb_corrupted[xd->mode_info_context->mbmi.ref_frame];
4661b362b15af34006e6a11974088a46d42b903418eJohann
4671b362b15af34006e6a11974088a46d42b903418eJohann           mt_decode_macroblock(pbi, xd, 0);
4681b362b15af34006e6a11974088a46d42b903418eJohann
4691b362b15af34006e6a11974088a46d42b903418eJohann           xd->left_available = 1;
4701b362b15af34006e6a11974088a46d42b903418eJohann
4711b362b15af34006e6a11974088a46d42b903418eJohann           /* check if the boolean decoder has suffered an error */
4721b362b15af34006e6a11974088a46d42b903418eJohann           xd->corrupted |= vp8dx_bool_error(xd->current_bc);
4731b362b15af34006e6a11974088a46d42b903418eJohann
4741b362b15af34006e6a11974088a46d42b903418eJohann           xd->recon_above[0] += 16;
4751b362b15af34006e6a11974088a46d42b903418eJohann           xd->recon_above[1] += 8;
4761b362b15af34006e6a11974088a46d42b903418eJohann           xd->recon_above[2] += 8;
4771b362b15af34006e6a11974088a46d42b903418eJohann
4781b362b15af34006e6a11974088a46d42b903418eJohann           if (!pbi->common.filter_level)
4791b362b15af34006e6a11974088a46d42b903418eJohann           {
4801b362b15af34006e6a11974088a46d42b903418eJohann              xd->recon_left[0] += 16;
4811b362b15af34006e6a11974088a46d42b903418eJohann              xd->recon_left[1] += 8;
4821b362b15af34006e6a11974088a46d42b903418eJohann              xd->recon_left[2] += 8;
4831b362b15af34006e6a11974088a46d42b903418eJohann           }
4841b362b15af34006e6a11974088a46d42b903418eJohann
4851b362b15af34006e6a11974088a46d42b903418eJohann           if (pbi->common.filter_level)
4861b362b15af34006e6a11974088a46d42b903418eJohann           {
4871b362b15af34006e6a11974088a46d42b903418eJohann               int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
4881b362b15af34006e6a11974088a46d42b903418eJohann                               xd->mode_info_context->mbmi.mode != SPLITMV &&
4891b362b15af34006e6a11974088a46d42b903418eJohann                               xd->mode_info_context->mbmi.mb_skip_coeff);
4901b362b15af34006e6a11974088a46d42b903418eJohann
4911b362b15af34006e6a11974088a46d42b903418eJohann               const int mode_index = lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode];
4921b362b15af34006e6a11974088a46d42b903418eJohann               const int seg = xd->mode_info_context->mbmi.segment_id;
4931b362b15af34006e6a11974088a46d42b903418eJohann               const int ref_frame = xd->mode_info_context->mbmi.ref_frame;
4941b362b15af34006e6a11974088a46d42b903418eJohann
4951b362b15af34006e6a11974088a46d42b903418eJohann               filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
4961b362b15af34006e6a11974088a46d42b903418eJohann
4971b362b15af34006e6a11974088a46d42b903418eJohann               if( mb_row != pc->mb_rows-1 )
4981b362b15af34006e6a11974088a46d42b903418eJohann               {
4991b362b15af34006e6a11974088a46d42b903418eJohann                   /* Save decoded MB last row data for next-row decoding */
5001b362b15af34006e6a11974088a46d42b903418eJohann                   vpx_memcpy((pbi->mt_yabove_row[mb_row + 1] + 32 + mb_col*16), (xd->dst.y_buffer + 15 * recon_y_stride), 16);
5011b362b15af34006e6a11974088a46d42b903418eJohann                   vpx_memcpy((pbi->mt_uabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
5021b362b15af34006e6a11974088a46d42b903418eJohann                   vpx_memcpy((pbi->mt_vabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.v_buffer + 7 * recon_uv_stride), 8);
5031b362b15af34006e6a11974088a46d42b903418eJohann               }
5041b362b15af34006e6a11974088a46d42b903418eJohann
5051b362b15af34006e6a11974088a46d42b903418eJohann               /* save left_col for next MB decoding */
5061b362b15af34006e6a11974088a46d42b903418eJohann               if(mb_col != pc->mb_cols-1)
5071b362b15af34006e6a11974088a46d42b903418eJohann               {
5081b362b15af34006e6a11974088a46d42b903418eJohann                   MODE_INFO *next = xd->mode_info_context +1;
5091b362b15af34006e6a11974088a46d42b903418eJohann
5101b362b15af34006e6a11974088a46d42b903418eJohann                   if (next->mbmi.ref_frame == INTRA_FRAME)
5111b362b15af34006e6a11974088a46d42b903418eJohann                   {
5121b362b15af34006e6a11974088a46d42b903418eJohann                       for (i = 0; i < 16; i++)
5131b362b15af34006e6a11974088a46d42b903418eJohann                           pbi->mt_yleft_col[mb_row][i] = xd->dst.y_buffer [i* recon_y_stride + 15];
5141b362b15af34006e6a11974088a46d42b903418eJohann                       for (i = 0; i < 8; i++)
5151b362b15af34006e6a11974088a46d42b903418eJohann                       {
5161b362b15af34006e6a11974088a46d42b903418eJohann                           pbi->mt_uleft_col[mb_row][i] = xd->dst.u_buffer [i* recon_uv_stride + 7];
5171b362b15af34006e6a11974088a46d42b903418eJohann                           pbi->mt_vleft_col[mb_row][i] = xd->dst.v_buffer [i* recon_uv_stride + 7];
5181b362b15af34006e6a11974088a46d42b903418eJohann                       }
5191b362b15af34006e6a11974088a46d42b903418eJohann                   }
5201b362b15af34006e6a11974088a46d42b903418eJohann               }
5211b362b15af34006e6a11974088a46d42b903418eJohann
5221b362b15af34006e6a11974088a46d42b903418eJohann               /* loopfilter on this macroblock. */
5231b362b15af34006e6a11974088a46d42b903418eJohann               if (filter_level)
5241b362b15af34006e6a11974088a46d42b903418eJohann               {
5251b362b15af34006e6a11974088a46d42b903418eJohann                   if(pc->filter_type == NORMAL_LOOPFILTER)
5261b362b15af34006e6a11974088a46d42b903418eJohann                   {
5271b362b15af34006e6a11974088a46d42b903418eJohann                       loop_filter_info lfi;
5281b362b15af34006e6a11974088a46d42b903418eJohann                       FRAME_TYPE frame_type = pc->frame_type;
5291b362b15af34006e6a11974088a46d42b903418eJohann                       const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
5301b362b15af34006e6a11974088a46d42b903418eJohann                       lfi.mblim = lfi_n->mblim[filter_level];
5311b362b15af34006e6a11974088a46d42b903418eJohann                       lfi.blim = lfi_n->blim[filter_level];
5321b362b15af34006e6a11974088a46d42b903418eJohann                       lfi.lim = lfi_n->lim[filter_level];
5331b362b15af34006e6a11974088a46d42b903418eJohann                       lfi.hev_thr = lfi_n->hev_thr[hev_index];
5341b362b15af34006e6a11974088a46d42b903418eJohann
5351b362b15af34006e6a11974088a46d42b903418eJohann                       if (mb_col > 0)
5361b362b15af34006e6a11974088a46d42b903418eJohann                           vp8_loop_filter_mbv
5371b362b15af34006e6a11974088a46d42b903418eJohann                           (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
5381b362b15af34006e6a11974088a46d42b903418eJohann
5391b362b15af34006e6a11974088a46d42b903418eJohann                       if (!skip_lf)
5401b362b15af34006e6a11974088a46d42b903418eJohann                           vp8_loop_filter_bv
5411b362b15af34006e6a11974088a46d42b903418eJohann                           (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
5421b362b15af34006e6a11974088a46d42b903418eJohann
5431b362b15af34006e6a11974088a46d42b903418eJohann                       /* don't apply across umv border */
5441b362b15af34006e6a11974088a46d42b903418eJohann                       if (mb_row > 0)
5451b362b15af34006e6a11974088a46d42b903418eJohann                           vp8_loop_filter_mbh
5461b362b15af34006e6a11974088a46d42b903418eJohann                           (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
5471b362b15af34006e6a11974088a46d42b903418eJohann
5481b362b15af34006e6a11974088a46d42b903418eJohann                       if (!skip_lf)
5491b362b15af34006e6a11974088a46d42b903418eJohann                           vp8_loop_filter_bh
5501b362b15af34006e6a11974088a46d42b903418eJohann                           (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer,  recon_y_stride, recon_uv_stride, &lfi);
5511b362b15af34006e6a11974088a46d42b903418eJohann                   }
5521b362b15af34006e6a11974088a46d42b903418eJohann                   else
5531b362b15af34006e6a11974088a46d42b903418eJohann                   {
5541b362b15af34006e6a11974088a46d42b903418eJohann                       if (mb_col > 0)
5551b362b15af34006e6a11974088a46d42b903418eJohann                           vp8_loop_filter_simple_mbv
5561b362b15af34006e6a11974088a46d42b903418eJohann                           (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
5571b362b15af34006e6a11974088a46d42b903418eJohann
5581b362b15af34006e6a11974088a46d42b903418eJohann                       if (!skip_lf)
5591b362b15af34006e6a11974088a46d42b903418eJohann                           vp8_loop_filter_simple_bv
5601b362b15af34006e6a11974088a46d42b903418eJohann                           (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
5611b362b15af34006e6a11974088a46d42b903418eJohann
5621b362b15af34006e6a11974088a46d42b903418eJohann                       /* don't apply across umv border */
5631b362b15af34006e6a11974088a46d42b903418eJohann                       if (mb_row > 0)
5641b362b15af34006e6a11974088a46d42b903418eJohann                           vp8_loop_filter_simple_mbh
5651b362b15af34006e6a11974088a46d42b903418eJohann                           (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
5661b362b15af34006e6a11974088a46d42b903418eJohann
5671b362b15af34006e6a11974088a46d42b903418eJohann                       if (!skip_lf)
5681b362b15af34006e6a11974088a46d42b903418eJohann                           vp8_loop_filter_simple_bh
5691b362b15af34006e6a11974088a46d42b903418eJohann                           (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
5701b362b15af34006e6a11974088a46d42b903418eJohann                   }
5711b362b15af34006e6a11974088a46d42b903418eJohann               }
5721b362b15af34006e6a11974088a46d42b903418eJohann
5731b362b15af34006e6a11974088a46d42b903418eJohann           }
5741b362b15af34006e6a11974088a46d42b903418eJohann
5751b362b15af34006e6a11974088a46d42b903418eJohann           recon_yoffset += 16;
5761b362b15af34006e6a11974088a46d42b903418eJohann           recon_uvoffset += 8;
5771b362b15af34006e6a11974088a46d42b903418eJohann
5781b362b15af34006e6a11974088a46d42b903418eJohann           ++xd->mode_info_context;  /* next mb */
5791b362b15af34006e6a11974088a46d42b903418eJohann
5801b362b15af34006e6a11974088a46d42b903418eJohann           xd->above_context++;
5811b362b15af34006e6a11974088a46d42b903418eJohann       }
5821b362b15af34006e6a11974088a46d42b903418eJohann
5831b362b15af34006e6a11974088a46d42b903418eJohann       /* adjust to the next row of mbs */
5841b362b15af34006e6a11974088a46d42b903418eJohann       if (pbi->common.filter_level)
5851b362b15af34006e6a11974088a46d42b903418eJohann       {
5861b362b15af34006e6a11974088a46d42b903418eJohann           if(mb_row != pc->mb_rows-1)
5871b362b15af34006e6a11974088a46d42b903418eJohann           {
5881b362b15af34006e6a11974088a46d42b903418eJohann               int lasty = yv12_fb_lst->y_width + VP8BORDERINPIXELS;
5891b362b15af34006e6a11974088a46d42b903418eJohann               int lastuv = (yv12_fb_lst->y_width>>1) + (VP8BORDERINPIXELS>>1);
5901b362b15af34006e6a11974088a46d42b903418eJohann
5911b362b15af34006e6a11974088a46d42b903418eJohann               for (i = 0; i < 4; i++)
5921b362b15af34006e6a11974088a46d42b903418eJohann               {
5931b362b15af34006e6a11974088a46d42b903418eJohann                   pbi->mt_yabove_row[mb_row +1][lasty + i] = pbi->mt_yabove_row[mb_row +1][lasty -1];
5941b362b15af34006e6a11974088a46d42b903418eJohann                   pbi->mt_uabove_row[mb_row +1][lastuv + i] = pbi->mt_uabove_row[mb_row +1][lastuv -1];
5951b362b15af34006e6a11974088a46d42b903418eJohann                   pbi->mt_vabove_row[mb_row +1][lastuv + i] = pbi->mt_vabove_row[mb_row +1][lastuv -1];
5961b362b15af34006e6a11974088a46d42b903418eJohann               }
5971b362b15af34006e6a11974088a46d42b903418eJohann           }
5981b362b15af34006e6a11974088a46d42b903418eJohann       }
5991b362b15af34006e6a11974088a46d42b903418eJohann       else
6001b362b15af34006e6a11974088a46d42b903418eJohann           vp8_extend_mb_row(yv12_fb_new, xd->dst.y_buffer + 16,
6011b362b15af34006e6a11974088a46d42b903418eJohann                             xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
6021b362b15af34006e6a11974088a46d42b903418eJohann
6031b362b15af34006e6a11974088a46d42b903418eJohann       /* last MB of row is ready just after extension is done */
6041b362b15af34006e6a11974088a46d42b903418eJohann       *current_mb_col = mb_col + nsync;
6051b362b15af34006e6a11974088a46d42b903418eJohann
6061b362b15af34006e6a11974088a46d42b903418eJohann       ++xd->mode_info_context;      /* skip prediction column */
6071b362b15af34006e6a11974088a46d42b903418eJohann       xd->up_available = 1;
6081b362b15af34006e6a11974088a46d42b903418eJohann
6091b362b15af34006e6a11974088a46d42b903418eJohann       /* since we have multithread */
6101b362b15af34006e6a11974088a46d42b903418eJohann       xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
6111b362b15af34006e6a11974088a46d42b903418eJohann    }
6121b362b15af34006e6a11974088a46d42b903418eJohann
6131b362b15af34006e6a11974088a46d42b903418eJohann    /* signal end of frame decoding if this thread processed the last mb_row */
6141b362b15af34006e6a11974088a46d42b903418eJohann    if (last_mb_row == (pc->mb_rows - 1))
6151b362b15af34006e6a11974088a46d42b903418eJohann        sem_post(&pbi->h_event_end_decoding);
6161b362b15af34006e6a11974088a46d42b903418eJohann
6171b362b15af34006e6a11974088a46d42b903418eJohann}
6181b362b15af34006e6a11974088a46d42b903418eJohann
6191b362b15af34006e6a11974088a46d42b903418eJohann
6201b362b15af34006e6a11974088a46d42b903418eJohannstatic THREAD_FUNCTION thread_decoding_proc(void *p_data)
6211b362b15af34006e6a11974088a46d42b903418eJohann{
6221b362b15af34006e6a11974088a46d42b903418eJohann    int ithread = ((DECODETHREAD_DATA *)p_data)->ithread;
6231b362b15af34006e6a11974088a46d42b903418eJohann    VP8D_COMP *pbi = (VP8D_COMP *)(((DECODETHREAD_DATA *)p_data)->ptr1);
6241b362b15af34006e6a11974088a46d42b903418eJohann    MB_ROW_DEC *mbrd = (MB_ROW_DEC *)(((DECODETHREAD_DATA *)p_data)->ptr2);
6251b362b15af34006e6a11974088a46d42b903418eJohann    ENTROPY_CONTEXT_PLANES mb_row_left_context;
6261b362b15af34006e6a11974088a46d42b903418eJohann
6271b362b15af34006e6a11974088a46d42b903418eJohann    while (1)
6281b362b15af34006e6a11974088a46d42b903418eJohann    {
6291b362b15af34006e6a11974088a46d42b903418eJohann        if (pbi->b_multithreaded_rd == 0)
6301b362b15af34006e6a11974088a46d42b903418eJohann            break;
6311b362b15af34006e6a11974088a46d42b903418eJohann
6321b362b15af34006e6a11974088a46d42b903418eJohann        if (sem_wait(&pbi->h_event_start_decoding[ithread]) == 0)
6331b362b15af34006e6a11974088a46d42b903418eJohann        {
6341b362b15af34006e6a11974088a46d42b903418eJohann            if (pbi->b_multithreaded_rd == 0)
6351b362b15af34006e6a11974088a46d42b903418eJohann                break;
6361b362b15af34006e6a11974088a46d42b903418eJohann            else
6371b362b15af34006e6a11974088a46d42b903418eJohann            {
6381b362b15af34006e6a11974088a46d42b903418eJohann                MACROBLOCKD *xd = &mbrd->mbd;
6391b362b15af34006e6a11974088a46d42b903418eJohann                xd->left_context = &mb_row_left_context;
6401b362b15af34006e6a11974088a46d42b903418eJohann
6411b362b15af34006e6a11974088a46d42b903418eJohann                mt_decode_mb_rows(pbi, xd, ithread+1);
6421b362b15af34006e6a11974088a46d42b903418eJohann            }
6431b362b15af34006e6a11974088a46d42b903418eJohann        }
6441b362b15af34006e6a11974088a46d42b903418eJohann    }
6451b362b15af34006e6a11974088a46d42b903418eJohann
6461b362b15af34006e6a11974088a46d42b903418eJohann    return 0 ;
6471b362b15af34006e6a11974088a46d42b903418eJohann}
6481b362b15af34006e6a11974088a46d42b903418eJohann
6491b362b15af34006e6a11974088a46d42b903418eJohann
6501b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_decoder_create_threads(VP8D_COMP *pbi)
6511b362b15af34006e6a11974088a46d42b903418eJohann{
6521b362b15af34006e6a11974088a46d42b903418eJohann    int core_count = 0;
6531b362b15af34006e6a11974088a46d42b903418eJohann    unsigned int ithread;
6541b362b15af34006e6a11974088a46d42b903418eJohann
6551b362b15af34006e6a11974088a46d42b903418eJohann    pbi->b_multithreaded_rd = 0;
6561b362b15af34006e6a11974088a46d42b903418eJohann    pbi->allocated_decoding_thread_count = 0;
6571b362b15af34006e6a11974088a46d42b903418eJohann
6581b362b15af34006e6a11974088a46d42b903418eJohann    /* limit decoding threads to the max number of token partitions */
6591b362b15af34006e6a11974088a46d42b903418eJohann    core_count = (pbi->max_threads > 8) ? 8 : pbi->max_threads;
6601b362b15af34006e6a11974088a46d42b903418eJohann
6611b362b15af34006e6a11974088a46d42b903418eJohann    /* limit decoding threads to the available cores */
6621b362b15af34006e6a11974088a46d42b903418eJohann    if (core_count > pbi->common.processor_core_count)
6631b362b15af34006e6a11974088a46d42b903418eJohann        core_count = pbi->common.processor_core_count;
6641b362b15af34006e6a11974088a46d42b903418eJohann
6651b362b15af34006e6a11974088a46d42b903418eJohann    if (core_count > 1)
6661b362b15af34006e6a11974088a46d42b903418eJohann    {
6671b362b15af34006e6a11974088a46d42b903418eJohann        pbi->b_multithreaded_rd = 1;
6681b362b15af34006e6a11974088a46d42b903418eJohann        pbi->decoding_thread_count = core_count - 1;
6691b362b15af34006e6a11974088a46d42b903418eJohann
6701b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->h_decoding_thread, pbi->decoding_thread_count);
6711b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->h_event_start_decoding, pbi->decoding_thread_count);
6721b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY_ALIGNED(pbi->mb_row_di, pbi->decoding_thread_count, 32);
6731b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->de_thread_data, pbi->decoding_thread_count);
6741b362b15af34006e6a11974088a46d42b903418eJohann
6751b362b15af34006e6a11974088a46d42b903418eJohann        for (ithread = 0; ithread < pbi->decoding_thread_count; ithread++)
6761b362b15af34006e6a11974088a46d42b903418eJohann        {
6771b362b15af34006e6a11974088a46d42b903418eJohann            sem_init(&pbi->h_event_start_decoding[ithread], 0, 0);
6781b362b15af34006e6a11974088a46d42b903418eJohann
6791b362b15af34006e6a11974088a46d42b903418eJohann            vp8_setup_block_dptrs(&pbi->mb_row_di[ithread].mbd);
6801b362b15af34006e6a11974088a46d42b903418eJohann
6811b362b15af34006e6a11974088a46d42b903418eJohann            pbi->de_thread_data[ithread].ithread  = ithread;
6821b362b15af34006e6a11974088a46d42b903418eJohann            pbi->de_thread_data[ithread].ptr1     = (void *)pbi;
6831b362b15af34006e6a11974088a46d42b903418eJohann            pbi->de_thread_data[ithread].ptr2     = (void *) &pbi->mb_row_di[ithread];
6841b362b15af34006e6a11974088a46d42b903418eJohann
6851b362b15af34006e6a11974088a46d42b903418eJohann            pthread_create(&pbi->h_decoding_thread[ithread], 0, thread_decoding_proc, (&pbi->de_thread_data[ithread]));
6861b362b15af34006e6a11974088a46d42b903418eJohann        }
6871b362b15af34006e6a11974088a46d42b903418eJohann
6881b362b15af34006e6a11974088a46d42b903418eJohann        sem_init(&pbi->h_event_end_decoding, 0, 0);
6891b362b15af34006e6a11974088a46d42b903418eJohann
6901b362b15af34006e6a11974088a46d42b903418eJohann        pbi->allocated_decoding_thread_count = pbi->decoding_thread_count;
6911b362b15af34006e6a11974088a46d42b903418eJohann    }
6921b362b15af34006e6a11974088a46d42b903418eJohann}
6931b362b15af34006e6a11974088a46d42b903418eJohann
6941b362b15af34006e6a11974088a46d42b903418eJohann
6951b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8mt_de_alloc_temp_buffers(VP8D_COMP *pbi, int mb_rows)
6961b362b15af34006e6a11974088a46d42b903418eJohann{
6971b362b15af34006e6a11974088a46d42b903418eJohann    int i;
6981b362b15af34006e6a11974088a46d42b903418eJohann
6991b362b15af34006e6a11974088a46d42b903418eJohann    if (pbi->b_multithreaded_rd)
7001b362b15af34006e6a11974088a46d42b903418eJohann    {
7011b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->mt_current_mb_col);
7021b362b15af34006e6a11974088a46d42b903418eJohann            pbi->mt_current_mb_col = NULL ;
7031b362b15af34006e6a11974088a46d42b903418eJohann
7041b362b15af34006e6a11974088a46d42b903418eJohann        /* Free above_row buffers. */
7051b362b15af34006e6a11974088a46d42b903418eJohann        if (pbi->mt_yabove_row)
7061b362b15af34006e6a11974088a46d42b903418eJohann        {
7071b362b15af34006e6a11974088a46d42b903418eJohann            for (i=0; i< mb_rows; i++)
7081b362b15af34006e6a11974088a46d42b903418eJohann            {
7091b362b15af34006e6a11974088a46d42b903418eJohann                    vpx_free(pbi->mt_yabove_row[i]);
7101b362b15af34006e6a11974088a46d42b903418eJohann                    pbi->mt_yabove_row[i] = NULL ;
7111b362b15af34006e6a11974088a46d42b903418eJohann            }
7121b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->mt_yabove_row);
7131b362b15af34006e6a11974088a46d42b903418eJohann            pbi->mt_yabove_row = NULL ;
7141b362b15af34006e6a11974088a46d42b903418eJohann        }
7151b362b15af34006e6a11974088a46d42b903418eJohann
7161b362b15af34006e6a11974088a46d42b903418eJohann        if (pbi->mt_uabove_row)
7171b362b15af34006e6a11974088a46d42b903418eJohann        {
7181b362b15af34006e6a11974088a46d42b903418eJohann            for (i=0; i< mb_rows; i++)
7191b362b15af34006e6a11974088a46d42b903418eJohann            {
7201b362b15af34006e6a11974088a46d42b903418eJohann                    vpx_free(pbi->mt_uabove_row[i]);
7211b362b15af34006e6a11974088a46d42b903418eJohann                    pbi->mt_uabove_row[i] = NULL ;
7221b362b15af34006e6a11974088a46d42b903418eJohann            }
7231b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->mt_uabove_row);
7241b362b15af34006e6a11974088a46d42b903418eJohann            pbi->mt_uabove_row = NULL ;
7251b362b15af34006e6a11974088a46d42b903418eJohann        }
7261b362b15af34006e6a11974088a46d42b903418eJohann
7271b362b15af34006e6a11974088a46d42b903418eJohann        if (pbi->mt_vabove_row)
7281b362b15af34006e6a11974088a46d42b903418eJohann        {
7291b362b15af34006e6a11974088a46d42b903418eJohann            for (i=0; i< mb_rows; i++)
7301b362b15af34006e6a11974088a46d42b903418eJohann            {
7311b362b15af34006e6a11974088a46d42b903418eJohann                    vpx_free(pbi->mt_vabove_row[i]);
7321b362b15af34006e6a11974088a46d42b903418eJohann                    pbi->mt_vabove_row[i] = NULL ;
7331b362b15af34006e6a11974088a46d42b903418eJohann            }
7341b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->mt_vabove_row);
7351b362b15af34006e6a11974088a46d42b903418eJohann            pbi->mt_vabove_row = NULL ;
7361b362b15af34006e6a11974088a46d42b903418eJohann        }
7371b362b15af34006e6a11974088a46d42b903418eJohann
7381b362b15af34006e6a11974088a46d42b903418eJohann        /* Free left_col buffers. */
7391b362b15af34006e6a11974088a46d42b903418eJohann        if (pbi->mt_yleft_col)
7401b362b15af34006e6a11974088a46d42b903418eJohann        {
7411b362b15af34006e6a11974088a46d42b903418eJohann            for (i=0; i< mb_rows; i++)
7421b362b15af34006e6a11974088a46d42b903418eJohann            {
7431b362b15af34006e6a11974088a46d42b903418eJohann                    vpx_free(pbi->mt_yleft_col[i]);
7441b362b15af34006e6a11974088a46d42b903418eJohann                    pbi->mt_yleft_col[i] = NULL ;
7451b362b15af34006e6a11974088a46d42b903418eJohann            }
7461b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->mt_yleft_col);
7471b362b15af34006e6a11974088a46d42b903418eJohann            pbi->mt_yleft_col = NULL ;
7481b362b15af34006e6a11974088a46d42b903418eJohann        }
7491b362b15af34006e6a11974088a46d42b903418eJohann
7501b362b15af34006e6a11974088a46d42b903418eJohann        if (pbi->mt_uleft_col)
7511b362b15af34006e6a11974088a46d42b903418eJohann        {
7521b362b15af34006e6a11974088a46d42b903418eJohann            for (i=0; i< mb_rows; i++)
7531b362b15af34006e6a11974088a46d42b903418eJohann            {
7541b362b15af34006e6a11974088a46d42b903418eJohann                    vpx_free(pbi->mt_uleft_col[i]);
7551b362b15af34006e6a11974088a46d42b903418eJohann                    pbi->mt_uleft_col[i] = NULL ;
7561b362b15af34006e6a11974088a46d42b903418eJohann            }
7571b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->mt_uleft_col);
7581b362b15af34006e6a11974088a46d42b903418eJohann            pbi->mt_uleft_col = NULL ;
7591b362b15af34006e6a11974088a46d42b903418eJohann        }
7601b362b15af34006e6a11974088a46d42b903418eJohann
7611b362b15af34006e6a11974088a46d42b903418eJohann        if (pbi->mt_vleft_col)
7621b362b15af34006e6a11974088a46d42b903418eJohann        {
7631b362b15af34006e6a11974088a46d42b903418eJohann            for (i=0; i< mb_rows; i++)
7641b362b15af34006e6a11974088a46d42b903418eJohann            {
7651b362b15af34006e6a11974088a46d42b903418eJohann                    vpx_free(pbi->mt_vleft_col[i]);
7661b362b15af34006e6a11974088a46d42b903418eJohann                    pbi->mt_vleft_col[i] = NULL ;
7671b362b15af34006e6a11974088a46d42b903418eJohann            }
7681b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->mt_vleft_col);
7691b362b15af34006e6a11974088a46d42b903418eJohann            pbi->mt_vleft_col = NULL ;
7701b362b15af34006e6a11974088a46d42b903418eJohann        }
7711b362b15af34006e6a11974088a46d42b903418eJohann    }
7721b362b15af34006e6a11974088a46d42b903418eJohann}
7731b362b15af34006e6a11974088a46d42b903418eJohann
7741b362b15af34006e6a11974088a46d42b903418eJohann
7751b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows)
7761b362b15af34006e6a11974088a46d42b903418eJohann{
7771b362b15af34006e6a11974088a46d42b903418eJohann    VP8_COMMON *const pc = & pbi->common;
7781b362b15af34006e6a11974088a46d42b903418eJohann    int i;
7791b362b15af34006e6a11974088a46d42b903418eJohann    int uv_width;
7801b362b15af34006e6a11974088a46d42b903418eJohann
7811b362b15af34006e6a11974088a46d42b903418eJohann    if (pbi->b_multithreaded_rd)
7821b362b15af34006e6a11974088a46d42b903418eJohann    {
7831b362b15af34006e6a11974088a46d42b903418eJohann        vp8mt_de_alloc_temp_buffers(pbi, prev_mb_rows);
7841b362b15af34006e6a11974088a46d42b903418eJohann
7851b362b15af34006e6a11974088a46d42b903418eJohann        /* our internal buffers are always multiples of 16 */
7861b362b15af34006e6a11974088a46d42b903418eJohann        if ((width & 0xf) != 0)
7871b362b15af34006e6a11974088a46d42b903418eJohann            width += 16 - (width & 0xf);
7881b362b15af34006e6a11974088a46d42b903418eJohann
7891b362b15af34006e6a11974088a46d42b903418eJohann        if (width < 640) pbi->sync_range = 1;
7901b362b15af34006e6a11974088a46d42b903418eJohann        else if (width <= 1280) pbi->sync_range = 8;
7911b362b15af34006e6a11974088a46d42b903418eJohann        else if (width <= 2560) pbi->sync_range =16;
7921b362b15af34006e6a11974088a46d42b903418eJohann        else pbi->sync_range = 32;
7931b362b15af34006e6a11974088a46d42b903418eJohann
7941b362b15af34006e6a11974088a46d42b903418eJohann        uv_width = width >>1;
7951b362b15af34006e6a11974088a46d42b903418eJohann
7961b362b15af34006e6a11974088a46d42b903418eJohann        /* Allocate an int for each mb row. */
7971b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->mt_current_mb_col, pc->mb_rows);
7981b362b15af34006e6a11974088a46d42b903418eJohann
7991b362b15af34006e6a11974088a46d42b903418eJohann        /* Allocate memory for above_row buffers. */
8001b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->mt_yabove_row, pc->mb_rows);
8011b362b15af34006e6a11974088a46d42b903418eJohann        for (i = 0; i < pc->mb_rows; i++)
8021b362b15af34006e6a11974088a46d42b903418eJohann            CHECK_MEM_ERROR(pbi->mt_yabove_row[i], vpx_memalign(16,sizeof(unsigned char) * (width + (VP8BORDERINPIXELS<<1))));
8031b362b15af34006e6a11974088a46d42b903418eJohann
8041b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->mt_uabove_row, pc->mb_rows);
8051b362b15af34006e6a11974088a46d42b903418eJohann        for (i = 0; i < pc->mb_rows; i++)
8061b362b15af34006e6a11974088a46d42b903418eJohann            CHECK_MEM_ERROR(pbi->mt_uabove_row[i], vpx_memalign(16,sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS)));
8071b362b15af34006e6a11974088a46d42b903418eJohann
8081b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->mt_vabove_row, pc->mb_rows);
8091b362b15af34006e6a11974088a46d42b903418eJohann        for (i = 0; i < pc->mb_rows; i++)
8101b362b15af34006e6a11974088a46d42b903418eJohann            CHECK_MEM_ERROR(pbi->mt_vabove_row[i], vpx_memalign(16,sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS)));
8111b362b15af34006e6a11974088a46d42b903418eJohann
8121b362b15af34006e6a11974088a46d42b903418eJohann        /* Allocate memory for left_col buffers. */
8131b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->mt_yleft_col, pc->mb_rows);
8141b362b15af34006e6a11974088a46d42b903418eJohann        for (i = 0; i < pc->mb_rows; i++)
8151b362b15af34006e6a11974088a46d42b903418eJohann            CHECK_MEM_ERROR(pbi->mt_yleft_col[i], vpx_calloc(sizeof(unsigned char) * 16, 1));
8161b362b15af34006e6a11974088a46d42b903418eJohann
8171b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->mt_uleft_col, pc->mb_rows);
8181b362b15af34006e6a11974088a46d42b903418eJohann        for (i = 0; i < pc->mb_rows; i++)
8191b362b15af34006e6a11974088a46d42b903418eJohann            CHECK_MEM_ERROR(pbi->mt_uleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));
8201b362b15af34006e6a11974088a46d42b903418eJohann
8211b362b15af34006e6a11974088a46d42b903418eJohann        CALLOC_ARRAY(pbi->mt_vleft_col, pc->mb_rows);
8221b362b15af34006e6a11974088a46d42b903418eJohann        for (i = 0; i < pc->mb_rows; i++)
8231b362b15af34006e6a11974088a46d42b903418eJohann            CHECK_MEM_ERROR(pbi->mt_vleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));
8241b362b15af34006e6a11974088a46d42b903418eJohann    }
8251b362b15af34006e6a11974088a46d42b903418eJohann}
8261b362b15af34006e6a11974088a46d42b903418eJohann
8271b362b15af34006e6a11974088a46d42b903418eJohann
8281b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_decoder_remove_threads(VP8D_COMP *pbi)
8291b362b15af34006e6a11974088a46d42b903418eJohann{
8301b362b15af34006e6a11974088a46d42b903418eJohann    /* shutdown MB Decoding thread; */
8311b362b15af34006e6a11974088a46d42b903418eJohann    if (pbi->b_multithreaded_rd)
8321b362b15af34006e6a11974088a46d42b903418eJohann    {
8331b362b15af34006e6a11974088a46d42b903418eJohann        int i;
8341b362b15af34006e6a11974088a46d42b903418eJohann
8351b362b15af34006e6a11974088a46d42b903418eJohann        pbi->b_multithreaded_rd = 0;
8361b362b15af34006e6a11974088a46d42b903418eJohann
8371b362b15af34006e6a11974088a46d42b903418eJohann        /* allow all threads to exit */
8381b362b15af34006e6a11974088a46d42b903418eJohann        for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
8391b362b15af34006e6a11974088a46d42b903418eJohann        {
8401b362b15af34006e6a11974088a46d42b903418eJohann            sem_post(&pbi->h_event_start_decoding[i]);
8411b362b15af34006e6a11974088a46d42b903418eJohann            pthread_join(pbi->h_decoding_thread[i], NULL);
8421b362b15af34006e6a11974088a46d42b903418eJohann        }
8431b362b15af34006e6a11974088a46d42b903418eJohann
8441b362b15af34006e6a11974088a46d42b903418eJohann        for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
8451b362b15af34006e6a11974088a46d42b903418eJohann        {
8461b362b15af34006e6a11974088a46d42b903418eJohann            sem_destroy(&pbi->h_event_start_decoding[i]);
8471b362b15af34006e6a11974088a46d42b903418eJohann        }
8481b362b15af34006e6a11974088a46d42b903418eJohann
8491b362b15af34006e6a11974088a46d42b903418eJohann        sem_destroy(&pbi->h_event_end_decoding);
8501b362b15af34006e6a11974088a46d42b903418eJohann
8511b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->h_decoding_thread);
8521b362b15af34006e6a11974088a46d42b903418eJohann            pbi->h_decoding_thread = NULL;
8531b362b15af34006e6a11974088a46d42b903418eJohann
8541b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->h_event_start_decoding);
8551b362b15af34006e6a11974088a46d42b903418eJohann            pbi->h_event_start_decoding = NULL;
8561b362b15af34006e6a11974088a46d42b903418eJohann
8571b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->mb_row_di);
8581b362b15af34006e6a11974088a46d42b903418eJohann            pbi->mb_row_di = NULL ;
8591b362b15af34006e6a11974088a46d42b903418eJohann
8601b362b15af34006e6a11974088a46d42b903418eJohann            vpx_free(pbi->de_thread_data);
8611b362b15af34006e6a11974088a46d42b903418eJohann            pbi->de_thread_data = NULL;
8621b362b15af34006e6a11974088a46d42b903418eJohann    }
8631b362b15af34006e6a11974088a46d42b903418eJohann}
8641b362b15af34006e6a11974088a46d42b903418eJohann
8651b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
8661b362b15af34006e6a11974088a46d42b903418eJohann{
8671b362b15af34006e6a11974088a46d42b903418eJohann    VP8_COMMON *pc = &pbi->common;
8681b362b15af34006e6a11974088a46d42b903418eJohann    unsigned int i;
8691b362b15af34006e6a11974088a46d42b903418eJohann    int j;
8701b362b15af34006e6a11974088a46d42b903418eJohann
8711b362b15af34006e6a11974088a46d42b903418eJohann    int filter_level = pc->filter_level;
8721b362b15af34006e6a11974088a46d42b903418eJohann    YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME];
8731b362b15af34006e6a11974088a46d42b903418eJohann
8741b362b15af34006e6a11974088a46d42b903418eJohann    if (filter_level)
8751b362b15af34006e6a11974088a46d42b903418eJohann    {
8761b362b15af34006e6a11974088a46d42b903418eJohann        /* Set above_row buffer to 127 for decoding first MB row */
8771b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS-1, 127, yv12_fb_new->y_width + 5);
8781b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (yv12_fb_new->y_width>>1) +5);
8791b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (yv12_fb_new->y_width>>1) +5);
8801b362b15af34006e6a11974088a46d42b903418eJohann
8811b362b15af34006e6a11974088a46d42b903418eJohann        for (j=1; j<pc->mb_rows; j++)
8821b362b15af34006e6a11974088a46d42b903418eJohann        {
8831b362b15af34006e6a11974088a46d42b903418eJohann            vpx_memset(pbi->mt_yabove_row[j] + VP8BORDERINPIXELS-1, (unsigned char)129, 1);
8841b362b15af34006e6a11974088a46d42b903418eJohann            vpx_memset(pbi->mt_uabove_row[j] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
8851b362b15af34006e6a11974088a46d42b903418eJohann            vpx_memset(pbi->mt_vabove_row[j] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
8861b362b15af34006e6a11974088a46d42b903418eJohann        }
8871b362b15af34006e6a11974088a46d42b903418eJohann
8881b362b15af34006e6a11974088a46d42b903418eJohann        /* Set left_col to 129 initially */
8891b362b15af34006e6a11974088a46d42b903418eJohann        for (j=0; j<pc->mb_rows; j++)
8901b362b15af34006e6a11974088a46d42b903418eJohann        {
8911b362b15af34006e6a11974088a46d42b903418eJohann            vpx_memset(pbi->mt_yleft_col[j], (unsigned char)129, 16);
8921b362b15af34006e6a11974088a46d42b903418eJohann            vpx_memset(pbi->mt_uleft_col[j], (unsigned char)129, 8);
8931b362b15af34006e6a11974088a46d42b903418eJohann            vpx_memset(pbi->mt_vleft_col[j], (unsigned char)129, 8);
8941b362b15af34006e6a11974088a46d42b903418eJohann        }
8951b362b15af34006e6a11974088a46d42b903418eJohann
8961b362b15af34006e6a11974088a46d42b903418eJohann        /* Initialize the loop filter for this frame. */
8971b362b15af34006e6a11974088a46d42b903418eJohann        vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level);
8981b362b15af34006e6a11974088a46d42b903418eJohann    }
8991b362b15af34006e6a11974088a46d42b903418eJohann    else
9001b362b15af34006e6a11974088a46d42b903418eJohann        vp8_setup_intra_recon_top_line(yv12_fb_new);
9011b362b15af34006e6a11974088a46d42b903418eJohann
9021b362b15af34006e6a11974088a46d42b903418eJohann    setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count);
9031b362b15af34006e6a11974088a46d42b903418eJohann
9041b362b15af34006e6a11974088a46d42b903418eJohann    for (i = 0; i < pbi->decoding_thread_count; i++)
9051b362b15af34006e6a11974088a46d42b903418eJohann        sem_post(&pbi->h_event_start_decoding[i]);
9061b362b15af34006e6a11974088a46d42b903418eJohann
9071b362b15af34006e6a11974088a46d42b903418eJohann    mt_decode_mb_rows(pbi, xd, 0);
9081b362b15af34006e6a11974088a46d42b903418eJohann
9091b362b15af34006e6a11974088a46d42b903418eJohann    sem_wait(&pbi->h_event_end_decoding);   /* add back for each frame */
9101b362b15af34006e6a11974088a46d42b903418eJohann}
911