/*
 *  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/common.h"
#include "vp8/common/threading.h"
#include "vp8/common/loopfilter.h"
#include "vp8/common/extend.h"
#include "vpx_ports/vpx_timer.h"
#include "decoderthreading.h"
#include "detokenize.h"
#include "vp8/common/reconintra4x4.h"
#include "vp8/common/reconinter.h"
#include "vp8/common/reconintra.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)

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->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;
    memcpy(mbd->segment_feature_data, xd->segment_feature_data,
           sizeof(xd->segment_feature_data));

    /*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/
    memcpy(mbd->ref_lf_deltas, xd->ref_lf_deltas, sizeof(xd->ref_lf_deltas));
    /*signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];*/
    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];

    memcpy(mbd->dequant_y1_dc, xd->dequant_y1_dc, sizeof(xd->dequant_y1_dc));
    memcpy(mbd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1));
    memcpy(mbd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2));
    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)
    vpx_atomic_store_release(&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;
#else
  (void)mb_idx;
#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;
      memset(xd->qcoeff, 0, sizeof(xd->qcoeff));

      corruption_detected = 1;

      /* force idct to be skipped for B_PRED and use the
       * prediction only for reconstruction
       * */
      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) 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);
            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);
          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);
          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) {
  const vpx_atomic_int *last_row_current_mb_col;
  vpx_atomic_int *current_mb_col;
  int mb_row;
  VP8_COMMON *pc = &pbi->common;
  const int nsync = pbi->sync_range;
  const vpx_atomic_int first_row_no_sync_above =
      VPX_ATOMIC_INIT(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);

  xd->mode_info_context = pc->mi + pc->mode_info_stride * start_mb_row;
  xd->mode_info_stride = pc->mode_info_stride;

  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;
    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) {
      if (((mb_col - 1) % nsync) == 0) {
        vpx_atomic_store_release(current_mb_col, mb_col - 1);
      }

      if (mb_row && !(mb_col & (nsync - 1))) {
        vp8_atomic_spin_wait(mb_col, last_row_current_mb_col, nsync);
      }

      /* 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);
        }
      }
#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;

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

      if (xd->corrupted) {
        // Move current decoding marcoblock to the end of row for all rows
        // assigned to this thread, such that other threads won't be waiting.
        for (; mb_row < pc->mb_rows;
             mb_row += (pbi->decoding_thread_count + 1)) {
          current_mb_col = &pbi->mt_current_mb_col[mb_row];
          vpx_atomic_store_release(current_mb_col, pc->mb_cols + nsync);
        }
        vpx_internal_error(&xd->error_info, VPX_CODEC_CORRUPT_FRAME,
                           "Corrupted reference frame");
      }

      if (xd->mode_info_context->mbmi.ref_frame >= LAST_FRAME) {
        const MV_REFERENCE_FRAME ref = xd->mode_info_context->mbmi.ref_frame;
        xd->pre.y_buffer = ref_buffer[ref][0] + recon_yoffset;
        xd->pre.u_buffer = ref_buffer[ref][1] + recon_uvoffset;
        xd->pre.v_buffer = ref_buffer[ref][2] + recon_uvoffset;
      } else {
        // ref_frame is INTRA_FRAME, pre buffer should not be used.
        xd->pre.y_buffer = 0;
        xd->pre.u_buffer = 0;
        xd->pre.v_buffer = 0;
      }
      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 */
          memcpy((pbi->mt_yabove_row[mb_row + 1] + 32 + mb_col * 16),
                 (xd->dst.y_buffer + 15 * recon_y_stride), 16);
          memcpy((pbi->mt_uabove_row[mb_row + 1] + 16 + mb_col * 8),
                 (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
          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 */
    vpx_atomic_store_release(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 decoding of current thread for current frame */
  if (last_mb_row + (int)pbi->decoding_thread_count + 1 >= pc->mb_rows)
    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 (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd) == 0) break;

    if (sem_wait(&pbi->h_event_start_decoding[ithread]) == 0) {
      if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd) == 0) {
        break;
      } else {
        MACROBLOCKD *xd = &mbrd->mbd;
        xd->left_context = &mb_row_left_context;
        if (setjmp(xd->error_info.jmp)) {
          xd->error_info.setjmp = 0;
          // Signal the end of decoding for current thread.
          sem_post(&pbi->h_event_end_decoding);
          continue;
        }
        xd->error_info.setjmp = 1;
        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;

  vpx_atomic_init(&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) {
    vpx_atomic_init(&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);

    if (sem_init(&pbi->h_event_end_decoding, 0, 0)) {
      vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,
                         "Failed to initialize semaphore");
    }

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

      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];

      if (pthread_create(&pbi->h_decoding_thread[ithread], 0,
                         thread_decoding_proc, &pbi->de_thread_data[ithread])) {
        sem_destroy(&pbi->h_event_start_decoding[ithread]);
        break;
      }
    }

    pbi->allocated_decoding_thread_count = ithread;
    if (pbi->allocated_decoding_thread_count !=
        (int)pbi->decoding_thread_count) {
      /* the remainder of cleanup cases will be handled in
       * vp8_decoder_remove_threads(). */
      if (pbi->allocated_decoding_thread_count == 0) {
        sem_destroy(&pbi->h_event_end_decoding);
      }
      vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,
                         "Failed to create threads");
    }
  }
}

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

  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 (vpx_atomic_load_acquire(&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 a vpx_atomic_int for each mb row. */
    CHECK_MEM_ERROR(pbi->mt_current_mb_col,
                    vpx_malloc(sizeof(*pbi->mt_current_mb_col) * pc->mb_rows));
    for (i = 0; i < pc->mb_rows; ++i)
      vpx_atomic_init(&pbi->mt_current_mb_col[i], 0);

    /* 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))));
      vp8_zero_array(pbi->mt_yabove_row[i], 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)));
      vp8_zero_array(pbi->mt_uabove_row[i], 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)));
      vp8_zero_array(pbi->mt_vabove_row[i], 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 (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd)) {
    int i;
    vpx_atomic_store_release(&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]);
    }

    if (pbi->allocated_decoding_thread_count) {
      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;

    vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
  }
}

int 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 */
    memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS - 1, 127,
           yv12_fb_new->y_width + 5);
    memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS >> 1) - 1, 127,
           (yv12_fb_new->y_width >> 1) + 5);
    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) {
      memset(pbi->mt_yabove_row[j] + VP8BORDERINPIXELS - 1, (unsigned char)129,
             1);
      memset(pbi->mt_uabove_row[j] + (VP8BORDERINPIXELS >> 1) - 1,
             (unsigned char)129, 1);
      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) {
      memset(pbi->mt_yleft_col[j], (unsigned char)129, 16);
      memset(pbi->mt_uleft_col[j], (unsigned char)129, 8);
      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]);
  }

  if (setjmp(xd->error_info.jmp)) {
    xd->error_info.setjmp = 0;
    xd->corrupted = 1;
    // Wait for other threads to finish. This prevents other threads decoding
    // the current frame while the main thread starts decoding the next frame,
    // which causes a data race.
    for (i = 0; i < pbi->decoding_thread_count; ++i)
      sem_wait(&pbi->h_event_end_decoding);
    return -1;
  }

  xd->error_info.setjmp = 1;
  mt_decode_mb_rows(pbi, xd, 0);

  for (i = 0; i < pbi->decoding_thread_count + 1; ++i)
    sem_wait(&pbi->h_event_end_decoding); /* add back for each frame */

  return 0;
}
