/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


#include "vpx_config.h"
#include "vp8_rtcd.h"
#if !defined(WIN32) && CONFIG_OS_SUPPORT == 1
# include <unistd.h>
#endif
#include "onyxd_int.h"
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/threading.h"

#include "vp8/common/loopfilter.h"
#include "vp8/common/extend.h"
#include "vpx_ports/vpx_timer.h"
#include "detokenize.h"
#include "vp8/common/reconintra4x4.h"
#include "vp8/common/reconinter.h"
#include "vp8/common/setupintrarecon.h"
#if CONFIG_ERROR_CONCEALMENT
#include "error_concealment.h"
#endif

#define CALLOC_ARRAY(p, n) CHECK_MEM_ERROR((p), vpx_calloc(sizeof(*(p)), (n)))
#define CALLOC_ARRAY_ALIGNED(p, n, algn) do {                      \
  CHECK_MEM_ERROR((p), vpx_memalign((algn), sizeof(*(p)) * (n)));  \
  memset((p), 0, (n) * sizeof(*(p)));                              \
} while (0)


void vp8_mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd);

static void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
{
    VP8_COMMON *const pc = & pbi->common;
    int i;

    for (i = 0; i < count; i++)
    {
        MACROBLOCKD *mbd = &mbrd[i].mbd;
        mbd->subpixel_predict        = xd->subpixel_predict;
        mbd->subpixel_predict8x4     = xd->subpixel_predict8x4;
        mbd->subpixel_predict8x8     = xd->subpixel_predict8x8;
        mbd->subpixel_predict16x16   = xd->subpixel_predict16x16;

        mbd->mode_info_context = pc->mi   + pc->mode_info_stride * (i + 1);
        mbd->mode_info_stride  = pc->mode_info_stride;

        mbd->frame_type = pc->frame_type;
        mbd->pre = xd->pre;
        mbd->dst = xd->dst;

        mbd->segmentation_enabled    = xd->segmentation_enabled;
        mbd->mb_segement_abs_delta     = xd->mb_segement_abs_delta;
        vpx_memcpy(mbd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));

        /*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/
        vpx_memcpy(mbd->ref_lf_deltas, xd->ref_lf_deltas, sizeof(xd->ref_lf_deltas));
        /*signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];*/
        vpx_memcpy(mbd->mode_lf_deltas, xd->mode_lf_deltas, sizeof(xd->mode_lf_deltas));
        /*unsigned char mode_ref_lf_delta_enabled;
        unsigned char mode_ref_lf_delta_update;*/
        mbd->mode_ref_lf_delta_enabled    = xd->mode_ref_lf_delta_enabled;
        mbd->mode_ref_lf_delta_update    = xd->mode_ref_lf_delta_update;

        mbd->current_bc = &pbi->mbc[0];

        vpx_memcpy(mbd->dequant_y1_dc, xd->dequant_y1_dc, sizeof(xd->dequant_y1_dc));
        vpx_memcpy(mbd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1));
        vpx_memcpy(mbd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2));
        vpx_memcpy(mbd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv));

        mbd->fullpixel_mask = 0xffffffff;

        if (pc->full_pixel)
            mbd->fullpixel_mask = 0xfffffff8;

    }

    for (i = 0; i < pc->mb_rows; i++)
        pbi->mt_current_mb_col[i] = -1;
}

static void mt_decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
                                 unsigned int mb_idx)
{
    MB_PREDICTION_MODE mode;
    int i;
#if CONFIG_ERROR_CONCEALMENT
    int corruption_detected = 0;
#endif

    if (xd->mode_info_context->mbmi.mb_skip_coeff)
    {
        vp8_reset_mb_tokens_context(xd);
    }
    else if (!vp8dx_bool_error(xd->current_bc))
    {
        int eobtotal;
        eobtotal = vp8_decode_mb_tokens(pbi, xd);

        /* Special case:  Force the loopfilter to skip when eobtotal is zero */
        xd->mode_info_context->mbmi.mb_skip_coeff = (eobtotal==0);
    }

    mode = xd->mode_info_context->mbmi.mode;

    if (xd->segmentation_enabled)
        vp8_mb_init_dequantizer(pbi, xd);


#if CONFIG_ERROR_CONCEALMENT

    if(pbi->ec_active)
    {
        int throw_residual;
        /* When we have independent partitions we can apply residual even
         * though other partitions within the frame are corrupt.
         */
        throw_residual = (!pbi->independent_partitions &&
                          pbi->frame_corrupt_residual);
        throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc));

        if ((mb_idx >= pbi->mvs_corrupt_from_mb || throw_residual))
        {
            /* MB with corrupt residuals or corrupt mode/motion vectors.
             * Better to use the predictor as reconstruction.
             */
            pbi->frame_corrupt_residual = 1;
            vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
            vp8_conceal_corrupt_mb(xd);


            corruption_detected = 1;

            /* force idct to be skipped for B_PRED and use the
             * prediction only for reconstruction
             * */
            vpx_memset(xd->eobs, 0, 25);
        }
    }
#endif

    /* do prediction */
    if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
    {
        vp8_build_intra_predictors_mbuv_s(xd,
                                          xd->recon_above[1],
                                          xd->recon_above[2],
                                          xd->recon_left[1],
                                          xd->recon_left[2],
                                          xd->recon_left_stride[1],
                                          xd->dst.u_buffer, xd->dst.v_buffer,
                                          xd->dst.uv_stride);

        if (mode != B_PRED)
        {
            vp8_build_intra_predictors_mby_s(xd,
                                                 xd->recon_above[0],
                                                 xd->recon_left[0],
                                                 xd->recon_left_stride[0],
                                                 xd->dst.y_buffer,
                                                 xd->dst.y_stride);
        }
        else
        {
            short *DQC = xd->dequant_y1;
            int dst_stride = xd->dst.y_stride;

            /* clear out residual eob info */
            if(xd->mode_info_context->mbmi.mb_skip_coeff)
                vpx_memset(xd->eobs, 0, 25);

            intra_prediction_down_copy(xd, xd->recon_above[0] + 16);

            for (i = 0; i < 16; i++)
            {
                BLOCKD *b = &xd->block[i];
                unsigned char *dst = xd->dst.y_buffer + b->offset;
                B_PREDICTION_MODE b_mode =
                    xd->mode_info_context->bmi[i].as_mode;
                unsigned char *Above;
                unsigned char *yleft;
                int left_stride;
                unsigned char top_left;

                /*Caution: For some b_mode, it needs 8 pixels (4 above + 4 above-right).*/
                if (i < 4 && pbi->common.filter_level)
                    Above = xd->recon_above[0] + b->offset;
                else
                    Above = dst - dst_stride;

                if (i%4==0 && pbi->common.filter_level)
                {
                    yleft = xd->recon_left[0] + i;
                    left_stride = 1;
                }
                else
                {
                    yleft = dst - 1;
                    left_stride = dst_stride;
                }

                if ((i==4 || i==8 || i==12) && pbi->common.filter_level)
                    top_left = *(xd->recon_left[0] + i - 1);
                else
                    top_left = Above[-1];

                vp8_intra4x4_predict(Above, yleft, left_stride,
                                     b_mode, dst, dst_stride, top_left);

                if (xd->eobs[i] )
                {
                    if (xd->eobs[i] > 1)
                    {
                        vp8_dequant_idct_add(b->qcoeff, DQC, dst, dst_stride);
                    }
                    else
                    {
                        vp8_dc_only_idct_add(b->qcoeff[0] * DQC[0],
                                             dst, dst_stride, dst, dst_stride);
                        vpx_memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0]));
                    }
                }
            }
        }
    }
    else
    {
        vp8_build_inter_predictors_mb(xd);
    }


#if CONFIG_ERROR_CONCEALMENT
    if (corruption_detected)
    {
        return;
    }
#endif

    if(!xd->mode_info_context->mbmi.mb_skip_coeff)
    {
        /* dequantization and idct */
        if (mode != B_PRED)
        {
            short *DQC = xd->dequant_y1;

            if (mode != SPLITMV)
            {
                BLOCKD *b = &xd->block[24];

                /* do 2nd order transform on the dc block */
                if (xd->eobs[24] > 1)
                {
                    vp8_dequantize_b(b, xd->dequant_y2);

                    vp8_short_inv_walsh4x4(&b->dqcoeff[0],
                        xd->qcoeff);
                    vpx_memset(b->qcoeff, 0, 16 * sizeof(b->qcoeff[0]));
                }
                else
                {
                    b->dqcoeff[0] = b->qcoeff[0] * xd->dequant_y2[0];
                    vp8_short_inv_walsh4x4_1(&b->dqcoeff[0],
                        xd->qcoeff);
                    vpx_memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0]));
                }

                /* override the dc dequant constant in order to preserve the
                 * dc components
                 */
                DQC = xd->dequant_y1_dc;
            }

            vp8_dequant_idct_add_y_block
                            (xd->qcoeff, DQC,
                             xd->dst.y_buffer,
                             xd->dst.y_stride, xd->eobs);
        }

        vp8_dequant_idct_add_uv_block
                        (xd->qcoeff+16*16, xd->dequant_uv,
                         xd->dst.u_buffer, xd->dst.v_buffer,
                         xd->dst.uv_stride, xd->eobs+16);
    }
}

static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row)
{
    volatile const int *last_row_current_mb_col;
    volatile int *current_mb_col;
    int mb_row;
    VP8_COMMON *pc = &pbi->common;
    const int nsync = pbi->sync_range;
    const int first_row_no_sync_above = pc->mb_cols + nsync;
    int num_part = 1 << pbi->common.multi_token_partition;
    int last_mb_row = start_mb_row;

    YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME];
    YV12_BUFFER_CONFIG *yv12_fb_lst = pbi->dec_fb_ref[LAST_FRAME];

    int recon_y_stride = yv12_fb_new->y_stride;
    int recon_uv_stride = yv12_fb_new->uv_stride;

    unsigned char *ref_buffer[MAX_REF_FRAMES][3];
    unsigned char *dst_buffer[3];
    int i;
    int ref_fb_corrupted[MAX_REF_FRAMES];

    ref_fb_corrupted[INTRA_FRAME] = 0;

    for(i = 1; i < MAX_REF_FRAMES; i++)
    {
        YV12_BUFFER_CONFIG *this_fb = pbi->dec_fb_ref[i];

        ref_buffer[i][0] = this_fb->y_buffer;
        ref_buffer[i][1] = this_fb->u_buffer;
        ref_buffer[i][2] = this_fb->v_buffer;

        ref_fb_corrupted[i] = this_fb->corrupted;
    }

    dst_buffer[0] = yv12_fb_new->y_buffer;
    dst_buffer[1] = yv12_fb_new->u_buffer;
    dst_buffer[2] = yv12_fb_new->v_buffer;

    xd->up_available = (start_mb_row != 0);

    for (mb_row = start_mb_row; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
    {
       int recon_yoffset, recon_uvoffset;
       int mb_col;
       int filter_level;
       loop_filter_info_n *lfi_n = &pc->lf_info;

       /* save last row processed by this thread */
       last_mb_row = mb_row;
       /* select bool coder for current partition */
       xd->current_bc =  &pbi->mbc[mb_row%num_part];

       if (mb_row > 0)
           last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
       else
           last_row_current_mb_col = &first_row_no_sync_above;

       current_mb_col = &pbi->mt_current_mb_col[mb_row];

       recon_yoffset = mb_row * recon_y_stride * 16;
       recon_uvoffset = mb_row * recon_uv_stride * 8;

       /* reset contexts */
       xd->above_context = pc->above_context;
       vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));

       xd->left_available = 0;

       xd->mb_to_top_edge = -((mb_row * 16)) << 3;
       xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;

       if (pbi->common.filter_level)
       {
          xd->recon_above[0] = pbi->mt_yabove_row[mb_row] + 0*16 +32;
          xd->recon_above[1] = pbi->mt_uabove_row[mb_row] + 0*8 +16;
          xd->recon_above[2] = pbi->mt_vabove_row[mb_row] + 0*8 +16;

          xd->recon_left[0] = pbi->mt_yleft_col[mb_row];
          xd->recon_left[1] = pbi->mt_uleft_col[mb_row];
          xd->recon_left[2] = pbi->mt_vleft_col[mb_row];

          /* TODO: move to outside row loop */
          xd->recon_left_stride[0] = 1;
          xd->recon_left_stride[1] = 1;
       }
       else
       {
          xd->recon_above[0] = dst_buffer[0] + recon_yoffset;
          xd->recon_above[1] = dst_buffer[1] + recon_uvoffset;
          xd->recon_above[2] = dst_buffer[2] + recon_uvoffset;

          xd->recon_left[0] = xd->recon_above[0] - 1;
          xd->recon_left[1] = xd->recon_above[1] - 1;
          xd->recon_left[2] = xd->recon_above[2] - 1;

          xd->recon_above[0] -= xd->dst.y_stride;
          xd->recon_above[1] -= xd->dst.uv_stride;
          xd->recon_above[2] -= xd->dst.uv_stride;

          /* TODO: move to outside row loop */
          xd->recon_left_stride[0] = xd->dst.y_stride;
          xd->recon_left_stride[1] = xd->dst.uv_stride;

          setup_intra_recon_left(xd->recon_left[0], xd->recon_left[1],
                                 xd->recon_left[2], xd->dst.y_stride,
                                 xd->dst.uv_stride);
       }

       for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
       {
           *current_mb_col = mb_col - 1;

           if ((mb_col & (nsync - 1)) == 0)
           {
               while (mb_col > (*last_row_current_mb_col - nsync))
               {
                   x86_pause_hint();
                   thread_sleep(0);
               }
           }

           /* Distance of MB to the various image edges.
            * These are specified to 8th pel as they are always
            * compared to values that are in 1/8th pel units.
            */
           xd->mb_to_left_edge = -((mb_col * 16) << 3);
           xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;

    #if CONFIG_ERROR_CONCEALMENT
           {
               int corrupt_residual =
                           (!pbi->independent_partitions &&
                           pbi->frame_corrupt_residual) ||
                           vp8dx_bool_error(xd->current_bc);
               if (pbi->ec_active &&
                   (xd->mode_info_context->mbmi.ref_frame ==
                                                    INTRA_FRAME) &&
                   corrupt_residual)
               {
                   /* We have an intra block with corrupt
                    * coefficients, better to conceal with an inter
                    * block.
                    * Interpolate MVs from neighboring MBs
                    *
                    * Note that for the first mb with corrupt
                    * residual in a frame, we might not discover
                    * that before decoding the residual. That
                    * happens after this check, and therefore no
                    * inter concealment will be done.
                    */
                   vp8_interpolate_motion(xd,
                                          mb_row, mb_col,
                                          pc->mb_rows, pc->mb_cols,
                                          pc->mode_info_stride);
               }
           }
    #endif


           xd->dst.y_buffer = dst_buffer[0] + recon_yoffset;
           xd->dst.u_buffer = dst_buffer[1] + recon_uvoffset;
           xd->dst.v_buffer = dst_buffer[2] + recon_uvoffset;

           xd->pre.y_buffer = ref_buffer[xd->mode_info_context->mbmi.ref_frame][0] + recon_yoffset;
           xd->pre.u_buffer = ref_buffer[xd->mode_info_context->mbmi.ref_frame][1] + recon_uvoffset;
           xd->pre.v_buffer = ref_buffer[xd->mode_info_context->mbmi.ref_frame][2] + recon_uvoffset;

           /* propagate errors from reference frames */
           xd->corrupted |= ref_fb_corrupted[xd->mode_info_context->mbmi.ref_frame];

           mt_decode_macroblock(pbi, xd, 0);

           xd->left_available = 1;

           /* check if the boolean decoder has suffered an error */
           xd->corrupted |= vp8dx_bool_error(xd->current_bc);

           xd->recon_above[0] += 16;
           xd->recon_above[1] += 8;
           xd->recon_above[2] += 8;

           if (!pbi->common.filter_level)
           {
              xd->recon_left[0] += 16;
              xd->recon_left[1] += 8;
              xd->recon_left[2] += 8;
           }

           if (pbi->common.filter_level)
           {
               int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
                               xd->mode_info_context->mbmi.mode != SPLITMV &&
                               xd->mode_info_context->mbmi.mb_skip_coeff);

               const int mode_index = lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode];
               const int seg = xd->mode_info_context->mbmi.segment_id;
               const int ref_frame = xd->mode_info_context->mbmi.ref_frame;

               filter_level = lfi_n->lvl[seg][ref_frame][mode_index];

               if( mb_row != pc->mb_rows-1 )
               {
                   /* Save decoded MB last row data for next-row decoding */
                   vpx_memcpy((pbi->mt_yabove_row[mb_row + 1] + 32 + mb_col*16), (xd->dst.y_buffer + 15 * recon_y_stride), 16);
                   vpx_memcpy((pbi->mt_uabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
                   vpx_memcpy((pbi->mt_vabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.v_buffer + 7 * recon_uv_stride), 8);
               }

               /* save left_col for next MB decoding */
               if(mb_col != pc->mb_cols-1)
               {
                   MODE_INFO *next = xd->mode_info_context +1;

                   if (next->mbmi.ref_frame == INTRA_FRAME)
                   {
                       for (i = 0; i < 16; i++)
                           pbi->mt_yleft_col[mb_row][i] = xd->dst.y_buffer [i* recon_y_stride + 15];
                       for (i = 0; i < 8; i++)
                       {
                           pbi->mt_uleft_col[mb_row][i] = xd->dst.u_buffer [i* recon_uv_stride + 7];
                           pbi->mt_vleft_col[mb_row][i] = xd->dst.v_buffer [i* recon_uv_stride + 7];
                       }
                   }
               }

               /* loopfilter on this macroblock. */
               if (filter_level)
               {
                   if(pc->filter_type == NORMAL_LOOPFILTER)
                   {
                       loop_filter_info lfi;
                       FRAME_TYPE frame_type = pc->frame_type;
                       const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
                       lfi.mblim = lfi_n->mblim[filter_level];
                       lfi.blim = lfi_n->blim[filter_level];
                       lfi.lim = lfi_n->lim[filter_level];
                       lfi.hev_thr = lfi_n->hev_thr[hev_index];

                       if (mb_col > 0)
                           vp8_loop_filter_mbv
                           (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);

                       if (!skip_lf)
                           vp8_loop_filter_bv
                           (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);

                       /* don't apply across umv border */
                       if (mb_row > 0)
                           vp8_loop_filter_mbh
                           (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);

                       if (!skip_lf)
                           vp8_loop_filter_bh
                           (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer,  recon_y_stride, recon_uv_stride, &lfi);
                   }
                   else
                   {
                       if (mb_col > 0)
                           vp8_loop_filter_simple_mbv
                           (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);

                       if (!skip_lf)
                           vp8_loop_filter_simple_bv
                           (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);

                       /* don't apply across umv border */
                       if (mb_row > 0)
                           vp8_loop_filter_simple_mbh
                           (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);

                       if (!skip_lf)
                           vp8_loop_filter_simple_bh
                           (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
                   }
               }

           }

           recon_yoffset += 16;
           recon_uvoffset += 8;

           ++xd->mode_info_context;  /* next mb */

           xd->above_context++;
       }

       /* adjust to the next row of mbs */
       if (pbi->common.filter_level)
       {
           if(mb_row != pc->mb_rows-1)
           {
               int lasty = yv12_fb_lst->y_width + VP8BORDERINPIXELS;
               int lastuv = (yv12_fb_lst->y_width>>1) + (VP8BORDERINPIXELS>>1);

               for (i = 0; i < 4; i++)
               {
                   pbi->mt_yabove_row[mb_row +1][lasty + i] = pbi->mt_yabove_row[mb_row +1][lasty -1];
                   pbi->mt_uabove_row[mb_row +1][lastuv + i] = pbi->mt_uabove_row[mb_row +1][lastuv -1];
                   pbi->mt_vabove_row[mb_row +1][lastuv + i] = pbi->mt_vabove_row[mb_row +1][lastuv -1];
               }
           }
       }
       else
           vp8_extend_mb_row(yv12_fb_new, xd->dst.y_buffer + 16,
                             xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);

       /* last MB of row is ready just after extension is done */
       *current_mb_col = mb_col + nsync;

       ++xd->mode_info_context;      /* skip prediction column */
       xd->up_available = 1;

       /* since we have multithread */
       xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
    }

    /* signal end of frame decoding if this thread processed the last mb_row */
    if (last_mb_row == (pc->mb_rows - 1))
        sem_post(&pbi->h_event_end_decoding);

}


static THREAD_FUNCTION thread_decoding_proc(void *p_data)
{
    int ithread = ((DECODETHREAD_DATA *)p_data)->ithread;
    VP8D_COMP *pbi = (VP8D_COMP *)(((DECODETHREAD_DATA *)p_data)->ptr1);
    MB_ROW_DEC *mbrd = (MB_ROW_DEC *)(((DECODETHREAD_DATA *)p_data)->ptr2);
    ENTROPY_CONTEXT_PLANES mb_row_left_context;

    while (1)
    {
        if (pbi->b_multithreaded_rd == 0)
            break;

        if (sem_wait(&pbi->h_event_start_decoding[ithread]) == 0)
        {
            if (pbi->b_multithreaded_rd == 0)
                break;
            else
            {
                MACROBLOCKD *xd = &mbrd->mbd;
                xd->left_context = &mb_row_left_context;

                mt_decode_mb_rows(pbi, xd, ithread+1);
            }
        }
    }

    return 0 ;
}


void vp8_decoder_create_threads(VP8D_COMP *pbi)
{
    int core_count = 0;
    unsigned int ithread;

    pbi->b_multithreaded_rd = 0;
    pbi->allocated_decoding_thread_count = 0;

    /* limit decoding threads to the max number of token partitions */
    core_count = (pbi->max_threads > 8) ? 8 : pbi->max_threads;

    /* limit decoding threads to the available cores */
    if (core_count > pbi->common.processor_core_count)
        core_count = pbi->common.processor_core_count;

    if (core_count > 1)
    {
        pbi->b_multithreaded_rd = 1;
        pbi->decoding_thread_count = core_count - 1;

        CALLOC_ARRAY(pbi->h_decoding_thread, pbi->decoding_thread_count);
        CALLOC_ARRAY(pbi->h_event_start_decoding, pbi->decoding_thread_count);
        CALLOC_ARRAY_ALIGNED(pbi->mb_row_di, pbi->decoding_thread_count, 32);
        CALLOC_ARRAY(pbi->de_thread_data, pbi->decoding_thread_count);

        for (ithread = 0; ithread < pbi->decoding_thread_count; ithread++)
        {
            sem_init(&pbi->h_event_start_decoding[ithread], 0, 0);

            vp8_setup_block_dptrs(&pbi->mb_row_di[ithread].mbd);

            pbi->de_thread_data[ithread].ithread  = ithread;
            pbi->de_thread_data[ithread].ptr1     = (void *)pbi;
            pbi->de_thread_data[ithread].ptr2     = (void *) &pbi->mb_row_di[ithread];

            pthread_create(&pbi->h_decoding_thread[ithread], 0, thread_decoding_proc, (&pbi->de_thread_data[ithread]));
        }

        sem_init(&pbi->h_event_end_decoding, 0, 0);

        pbi->allocated_decoding_thread_count = pbi->decoding_thread_count;
    }
}


void vp8mt_de_alloc_temp_buffers(VP8D_COMP *pbi, int mb_rows)
{
    int i;

    if (pbi->b_multithreaded_rd)
    {
            vpx_free(pbi->mt_current_mb_col);
            pbi->mt_current_mb_col = NULL ;

        /* Free above_row buffers. */
        if (pbi->mt_yabove_row)
        {
            for (i=0; i< mb_rows; i++)
            {
                    vpx_free(pbi->mt_yabove_row[i]);
                    pbi->mt_yabove_row[i] = NULL ;
            }
            vpx_free(pbi->mt_yabove_row);
            pbi->mt_yabove_row = NULL ;
        }

        if (pbi->mt_uabove_row)
        {
            for (i=0; i< mb_rows; i++)
            {
                    vpx_free(pbi->mt_uabove_row[i]);
                    pbi->mt_uabove_row[i] = NULL ;
            }
            vpx_free(pbi->mt_uabove_row);
            pbi->mt_uabove_row = NULL ;
        }

        if (pbi->mt_vabove_row)
        {
            for (i=0; i< mb_rows; i++)
            {
                    vpx_free(pbi->mt_vabove_row[i]);
                    pbi->mt_vabove_row[i] = NULL ;
            }
            vpx_free(pbi->mt_vabove_row);
            pbi->mt_vabove_row = NULL ;
        }

        /* Free left_col buffers. */
        if (pbi->mt_yleft_col)
        {
            for (i=0; i< mb_rows; i++)
            {
                    vpx_free(pbi->mt_yleft_col[i]);
                    pbi->mt_yleft_col[i] = NULL ;
            }
            vpx_free(pbi->mt_yleft_col);
            pbi->mt_yleft_col = NULL ;
        }

        if (pbi->mt_uleft_col)
        {
            for (i=0; i< mb_rows; i++)
            {
                    vpx_free(pbi->mt_uleft_col[i]);
                    pbi->mt_uleft_col[i] = NULL ;
            }
            vpx_free(pbi->mt_uleft_col);
            pbi->mt_uleft_col = NULL ;
        }

        if (pbi->mt_vleft_col)
        {
            for (i=0; i< mb_rows; i++)
            {
                    vpx_free(pbi->mt_vleft_col[i]);
                    pbi->mt_vleft_col[i] = NULL ;
            }
            vpx_free(pbi->mt_vleft_col);
            pbi->mt_vleft_col = NULL ;
        }
    }
}


void vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows)
{
    VP8_COMMON *const pc = & pbi->common;
    int i;
    int uv_width;

    if (pbi->b_multithreaded_rd)
    {
        vp8mt_de_alloc_temp_buffers(pbi, prev_mb_rows);

        /* our internal buffers are always multiples of 16 */
        if ((width & 0xf) != 0)
            width += 16 - (width & 0xf);

        if (width < 640) pbi->sync_range = 1;
        else if (width <= 1280) pbi->sync_range = 8;
        else if (width <= 2560) pbi->sync_range =16;
        else pbi->sync_range = 32;

        uv_width = width >>1;

        /* Allocate an int for each mb row. */
        CALLOC_ARRAY(pbi->mt_current_mb_col, pc->mb_rows);

        /* Allocate memory for above_row buffers. */
        CALLOC_ARRAY(pbi->mt_yabove_row, pc->mb_rows);
        for (i = 0; i < pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_yabove_row[i], vpx_memalign(16,sizeof(unsigned char) * (width + (VP8BORDERINPIXELS<<1))));

        CALLOC_ARRAY(pbi->mt_uabove_row, pc->mb_rows);
        for (i = 0; i < pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_uabove_row[i], vpx_memalign(16,sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS)));

        CALLOC_ARRAY(pbi->mt_vabove_row, pc->mb_rows);
        for (i = 0; i < pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_vabove_row[i], vpx_memalign(16,sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS)));

        /* Allocate memory for left_col buffers. */
        CALLOC_ARRAY(pbi->mt_yleft_col, pc->mb_rows);
        for (i = 0; i < pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_yleft_col[i], vpx_calloc(sizeof(unsigned char) * 16, 1));

        CALLOC_ARRAY(pbi->mt_uleft_col, pc->mb_rows);
        for (i = 0; i < pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_uleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));

        CALLOC_ARRAY(pbi->mt_vleft_col, pc->mb_rows);
        for (i = 0; i < pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_vleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));
    }
}


void vp8_decoder_remove_threads(VP8D_COMP *pbi)
{
    /* shutdown MB Decoding thread; */
    if (pbi->b_multithreaded_rd)
    {
        int i;

        pbi->b_multithreaded_rd = 0;

        /* allow all threads to exit */
        for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
        {
            sem_post(&pbi->h_event_start_decoding[i]);
            pthread_join(pbi->h_decoding_thread[i], NULL);
        }

        for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
        {
            sem_destroy(&pbi->h_event_start_decoding[i]);
        }

        sem_destroy(&pbi->h_event_end_decoding);

            vpx_free(pbi->h_decoding_thread);
            pbi->h_decoding_thread = NULL;

            vpx_free(pbi->h_event_start_decoding);
            pbi->h_event_start_decoding = NULL;

            vpx_free(pbi->mb_row_di);
            pbi->mb_row_di = NULL ;

            vpx_free(pbi->de_thread_data);
            pbi->de_thread_data = NULL;
    }
}

void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
{
    VP8_COMMON *pc = &pbi->common;
    unsigned int i;
    int j;

    int filter_level = pc->filter_level;
    YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME];

    if (filter_level)
    {
        /* Set above_row buffer to 127 for decoding first MB row */
        vpx_memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS-1, 127, yv12_fb_new->y_width + 5);
        vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (yv12_fb_new->y_width>>1) +5);
        vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (yv12_fb_new->y_width>>1) +5);

        for (j=1; j<pc->mb_rows; j++)
        {
            vpx_memset(pbi->mt_yabove_row[j] + VP8BORDERINPIXELS-1, (unsigned char)129, 1);
            vpx_memset(pbi->mt_uabove_row[j] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
            vpx_memset(pbi->mt_vabove_row[j] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
        }

        /* Set left_col to 129 initially */
        for (j=0; j<pc->mb_rows; j++)
        {
            vpx_memset(pbi->mt_yleft_col[j], (unsigned char)129, 16);
            vpx_memset(pbi->mt_uleft_col[j], (unsigned char)129, 8);
            vpx_memset(pbi->mt_vleft_col[j], (unsigned char)129, 8);
        }

        /* Initialize the loop filter for this frame. */
        vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level);
    }
    else
        vp8_setup_intra_recon_top_line(yv12_fb_new);

    setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count);

    for (i = 0; i < pbi->decoding_thread_count; i++)
        sem_post(&pbi->h_event_start_decoding[i]);

    mt_decode_mb_rows(pbi, xd, 0);

    sem_wait(&pbi->h_event_end_decoding);   /* add back for each frame */
}
