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