LCOV - code coverage report
Current view: directory - media/libvpx/vp8/decoder - threading.c (source / functions) Found Hit Coverage
Test: app.info Lines: 468 0 0.0 %
Date: 2012-06-02 Functions: 8 0 0.0 %

       1                 : /*
       2                 :  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
       3                 :  *
       4                 :  *  Use of this source code is governed by a BSD-style license
       5                 :  *  that can be found in the LICENSE file in the root of the source
       6                 :  *  tree. An additional intellectual property rights grant can be found
       7                 :  *  in the file PATENTS.  All contributing project authors may
       8                 :  *  be found in the AUTHORS file in the root of the source tree.
       9                 :  */
      10                 : 
      11                 : 
      12                 : #if !defined(WIN32) && CONFIG_OS_SUPPORT == 1
      13                 : # include <unistd.h>
      14                 : #endif
      15                 : #include "onyxd_int.h"
      16                 : #include "vpx_mem/vpx_mem.h"
      17                 : #include "vp8/common/threading.h"
      18                 : 
      19                 : #include "vp8/common/loopfilter.h"
      20                 : #include "vp8/common/extend.h"
      21                 : #include "vpx_ports/vpx_timer.h"
      22                 : #include "detokenize.h"
      23                 : #include "vp8/common/reconinter.h"
      24                 : #include "reconintra_mt.h"
      25                 : #if CONFIG_ERROR_CONCEALMENT
      26                 : #include "error_concealment.h"
      27                 : #endif
      28                 : 
      29                 : extern void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd);
      30                 : extern void clamp_mvs(MACROBLOCKD *xd);
      31                 : extern void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel);
      32                 : 
      33                 : #if CONFIG_RUNTIME_CPU_DETECT
      34                 : #define RTCD_VTABLE(x) (&(pbi)->common.rtcd.x)
      35                 : #else
      36                 : #define RTCD_VTABLE(x) NULL
      37                 : #endif
      38                 : 
      39               0 : static void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
      40                 : {
      41               0 :     VP8_COMMON *const pc = & pbi->common;
      42                 :     int i, j;
      43                 : 
      44               0 :     for (i = 0; i < count; i++)
      45                 :     {
      46               0 :         MACROBLOCKD *mbd = &mbrd[i].mbd;
      47                 : #if CONFIG_RUNTIME_CPU_DETECT
      48               0 :         mbd->rtcd = xd->rtcd;
      49                 : #endif
      50               0 :         mbd->subpixel_predict        = xd->subpixel_predict;
      51               0 :         mbd->subpixel_predict8x4     = xd->subpixel_predict8x4;
      52               0 :         mbd->subpixel_predict8x8     = xd->subpixel_predict8x8;
      53               0 :         mbd->subpixel_predict16x16   = xd->subpixel_predict16x16;
      54                 : 
      55               0 :         mbd->mode_info_context = pc->mi   + pc->mode_info_stride * (i + 1);
      56               0 :         mbd->mode_info_stride  = pc->mode_info_stride;
      57                 : 
      58               0 :         mbd->frame_type = pc->frame_type;
      59               0 :         mbd->frames_since_golden      = pc->frames_since_golden;
      60               0 :         mbd->frames_till_alt_ref_frame  = pc->frames_till_alt_ref_frame;
      61                 : 
      62               0 :         mbd->pre = pc->yv12_fb[pc->lst_fb_idx];
      63               0 :         mbd->dst = pc->yv12_fb[pc->new_fb_idx];
      64                 : 
      65               0 :         vp8_setup_block_dptrs(mbd);
      66               0 :         vp8_build_block_doffsets(mbd);
      67               0 :         mbd->segmentation_enabled    = xd->segmentation_enabled;
      68               0 :         mbd->mb_segement_abs_delta     = xd->mb_segement_abs_delta;
      69               0 :         vpx_memcpy(mbd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
      70                 : 
      71                 :         /*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/
      72               0 :         vpx_memcpy(mbd->ref_lf_deltas, xd->ref_lf_deltas, sizeof(xd->ref_lf_deltas));
      73                 :         /*signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];*/
      74               0 :         vpx_memcpy(mbd->mode_lf_deltas, xd->mode_lf_deltas, sizeof(xd->mode_lf_deltas));
      75                 :         /*unsigned char mode_ref_lf_delta_enabled;
      76                 :         unsigned char mode_ref_lf_delta_update;*/
      77               0 :         mbd->mode_ref_lf_delta_enabled    = xd->mode_ref_lf_delta_enabled;
      78               0 :         mbd->mode_ref_lf_delta_update    = xd->mode_ref_lf_delta_update;
      79                 : 
      80               0 :         mbd->current_bc = &pbi->bc2;
      81                 : 
      82               0 :         for (j = 0; j < 25; j++)
      83                 :         {
      84               0 :             mbd->block[j].dequant = xd->block[j].dequant;
      85                 :         }
      86                 :     }
      87                 : 
      88               0 :     for (i=0; i< pc->mb_rows; i++)
      89               0 :         pbi->mt_current_mb_col[i]=-1;
      90               0 : }
      91                 : 
      92                 : 
      93               0 : static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col)
      94                 : {
      95               0 :     int eobtotal = 0;
      96               0 :     int throw_residual = 0;
      97               0 :     int i, do_clamp = xd->mode_info_context->mbmi.need_to_clamp_mvs;
      98                 : 
      99               0 :     if (xd->mode_info_context->mbmi.mb_skip_coeff)
     100                 :     {
     101               0 :         vp8_reset_mb_tokens_context(xd);
     102                 :     }
     103                 :     else
     104                 :     {
     105               0 :         eobtotal = vp8_decode_mb_tokens(pbi, xd);
     106                 :     }
     107                 : 
     108                 :     /* Perform temporary clamping of the MV to be used for prediction */
     109               0 :     if (do_clamp)
     110                 :     {
     111               0 :         clamp_mvs(xd);
     112                 :     }
     113                 : 
     114               0 :     eobtotal |= (xd->mode_info_context->mbmi.mode == B_PRED ||
     115               0 :                   xd->mode_info_context->mbmi.mode == SPLITMV);
     116               0 :     if (!eobtotal && !vp8dx_bool_error(xd->current_bc))
     117                 :     {
     118                 :         /* Special case:  Force the loopfilter to skip when eobtotal and
     119                 :          * mb_skip_coeff are zero.
     120                 :          * */
     121               0 :         xd->mode_info_context->mbmi.mb_skip_coeff = 1;
     122                 : 
     123                 :         /*mt_skip_recon_mb(pbi, xd, mb_row, mb_col);*/
     124               0 :         if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
     125                 :         {
     126               0 :             vp8mt_build_intra_predictors_mbuv_s(pbi, xd, mb_row, mb_col);
     127               0 :             vp8mt_build_intra_predictors_mby_s(pbi, xd, mb_row, mb_col);
     128                 :         }
     129                 :         else
     130                 :         {
     131               0 :             vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
     132                 :                                                xd->dst.u_buffer, xd->dst.v_buffer,
     133                 :                                                xd->dst.y_stride, xd->dst.uv_stride);
     134                 :         }
     135               0 :         return;
     136                 :     }
     137                 : 
     138               0 :     if (xd->segmentation_enabled)
     139               0 :         mb_init_dequantizer(pbi, xd);
     140                 : 
     141                 :     /* do prediction */
     142               0 :     if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
     143                 :     {
     144               0 :         vp8mt_build_intra_predictors_mbuv(pbi, xd, mb_row, mb_col);
     145                 : 
     146               0 :         if (xd->mode_info_context->mbmi.mode != B_PRED)
     147                 :         {
     148               0 :             vp8mt_build_intra_predictors_mby(pbi, xd, mb_row, mb_col);
     149                 :         } else {
     150               0 :             vp8mt_intra_prediction_down_copy(pbi, xd, mb_row, mb_col);
     151                 :         }
     152                 :     }
     153                 :     else
     154                 :     {
     155               0 :         vp8_build_inter_predictors_mb(xd);
     156                 :     }
     157                 : 
     158                 :     /* When we have independent partitions we can apply residual even
     159                 :      * though other partitions within the frame are corrupt.
     160                 :      */
     161               0 :     throw_residual = (!pbi->independent_partitions &&
     162               0 :                       pbi->frame_corrupt_residual);
     163               0 :     throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc));
     164                 : 
     165                 : #if CONFIG_ERROR_CONCEALMENT
     166                 :     if (pbi->ec_active &&
     167                 :         (mb_row * pbi->common.mb_cols + mb_col >= pbi->mvs_corrupt_from_mb ||
     168                 :         throw_residual))
     169                 :     {
     170                 :         /* MB with corrupt residuals or corrupt mode/motion vectors.
     171                 :          * Better to use the predictor as reconstruction.
     172                 :          */
     173                 :         pbi->frame_corrupt_residual = 1;
     174                 :         vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
     175                 :         vp8_conceal_corrupt_mb(xd);
     176                 :         return;
     177                 :     }
     178                 : #endif
     179                 : 
     180                 :     /* dequantization and idct */
     181               0 :     if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV)
     182               0 :     {
     183               0 :         BLOCKD *b = &xd->block[24];
     184               0 :         DEQUANT_INVOKE(&pbi->dequant, block)(b);
     185                 : 
     186                 :         /* do 2nd order transform on the dc block */
     187               0 :         if (xd->eobs[24] > 1)
     188                 :         {
     189               0 :             IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], b->diff);
     190               0 :             ((int *)b->qcoeff)[0] = 0;
     191               0 :             ((int *)b->qcoeff)[1] = 0;
     192               0 :             ((int *)b->qcoeff)[2] = 0;
     193               0 :             ((int *)b->qcoeff)[3] = 0;
     194               0 :             ((int *)b->qcoeff)[4] = 0;
     195               0 :             ((int *)b->qcoeff)[5] = 0;
     196               0 :             ((int *)b->qcoeff)[6] = 0;
     197               0 :             ((int *)b->qcoeff)[7] = 0;
     198                 :         }
     199                 :         else
     200                 :         {
     201               0 :             IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], b->diff);
     202               0 :             ((int *)b->qcoeff)[0] = 0;
     203                 :         }
     204                 : 
     205               0 :         DEQUANT_INVOKE (&pbi->dequant, dc_idct_add_y_block)
     206               0 :                         (xd->qcoeff, xd->block[0].dequant,
     207                 :                          xd->predictor, xd->dst.y_buffer,
     208                 :                          xd->dst.y_stride, xd->eobs, xd->block[24].diff);
     209                 :     }
     210               0 :     else if (xd->mode_info_context->mbmi.mode == B_PRED)
     211                 :     {
     212               0 :         for (i = 0; i < 16; i++)
     213                 :         {
     214               0 :             BLOCKD *b = &xd->block[i];
     215                 : 
     216               0 :             vp8mt_predict_intra4x4(pbi, xd, b->bmi.as_mode, b->predictor, mb_row, mb_col, i);
     217                 : 
     218               0 :             if (xd->eobs[i] > 1)
     219                 :             {
     220               0 :                 DEQUANT_INVOKE(&pbi->dequant, idct_add)
     221               0 :                     (b->qcoeff, b->dequant,  b->predictor,
     222               0 :                     *(b->base_dst) + b->dst, 16, b->dst_stride);
     223                 :             }
     224                 :             else
     225                 :             {
     226               0 :                 IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar_add)
     227               0 :                     (b->qcoeff[0] * b->dequant[0], b->predictor,
     228               0 :                     *(b->base_dst) + b->dst, 16, b->dst_stride);
     229               0 :                 ((int *)b->qcoeff)[0] = 0;
     230                 :             }
     231                 :         }
     232                 :     }
     233                 :     else
     234                 :     {
     235               0 :         DEQUANT_INVOKE (&pbi->dequant, idct_add_y_block)
     236               0 :                         (xd->qcoeff, xd->block[0].dequant,
     237                 :                          xd->predictor, xd->dst.y_buffer,
     238                 :                          xd->dst.y_stride, xd->eobs);
     239                 :     }
     240                 : 
     241               0 :     DEQUANT_INVOKE (&pbi->dequant, idct_add_uv_block)
     242               0 :                     (xd->qcoeff+16*16, xd->block[16].dequant,
     243                 :                      xd->predictor+16*16, xd->dst.u_buffer, xd->dst.v_buffer,
     244                 :                      xd->dst.uv_stride, xd->eobs+16);
     245                 : }
     246                 : 
     247                 : 
     248               0 : static THREAD_FUNCTION thread_decoding_proc(void *p_data)
     249                 : {
     250               0 :     int ithread = ((DECODETHREAD_DATA *)p_data)->ithread;
     251               0 :     VP8D_COMP *pbi = (VP8D_COMP *)(((DECODETHREAD_DATA *)p_data)->ptr1);
     252               0 :     MB_ROW_DEC *mbrd = (MB_ROW_DEC *)(((DECODETHREAD_DATA *)p_data)->ptr2);
     253                 :     ENTROPY_CONTEXT_PLANES mb_row_left_context;
     254                 : 
     255                 :     while (1)
     256                 :     {
     257               0 :         if (pbi->b_multithreaded_rd == 0)
     258               0 :             break;
     259                 : 
     260                 :         /*if(WaitForSingleObject(pbi->h_event_start_decoding[ithread], INFINITE) == WAIT_OBJECT_0)*/
     261               0 :         if (sem_wait(&pbi->h_event_start_decoding[ithread]) == 0)
     262                 :         {
     263               0 :             if (pbi->b_multithreaded_rd == 0)
     264               0 :                 break;
     265                 :             else
     266                 :             {
     267               0 :                 VP8_COMMON *pc = &pbi->common;
     268               0 :                 MACROBLOCKD *xd = &mbrd->mbd;
     269                 : 
     270                 :                 int mb_row;
     271               0 :                 int num_part = 1 << pbi->common.multi_token_partition;
     272                 :                 volatile int *last_row_current_mb_col;
     273               0 :                 int nsync = pbi->sync_range;
     274                 : 
     275               0 :                 for (mb_row = ithread+1; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
     276                 :                 {
     277                 :                     int i;
     278                 :                     int recon_yoffset, recon_uvoffset;
     279                 :                     int mb_col;
     280               0 :                     int ref_fb_idx = pc->lst_fb_idx;
     281               0 :                     int dst_fb_idx = pc->new_fb_idx;
     282               0 :                     int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
     283               0 :                     int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
     284                 : 
     285                 :                     int filter_level;
     286               0 :                     loop_filter_info_n *lfi_n = &pc->lf_info;
     287                 : 
     288               0 :                     pbi->mb_row_di[ithread].mb_row = mb_row;
     289               0 :                     pbi->mb_row_di[ithread].mbd.current_bc =  &pbi->mbc[mb_row%num_part];
     290                 : 
     291               0 :                     last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
     292                 : 
     293               0 :                     recon_yoffset = mb_row * recon_y_stride * 16;
     294               0 :                     recon_uvoffset = mb_row * recon_uv_stride * 8;
     295                 :                     /* reset above block coeffs */
     296                 : 
     297               0 :                     xd->above_context = pc->above_context;
     298               0 :                     xd->left_context = &mb_row_left_context;
     299               0 :                     vpx_memset(&mb_row_left_context, 0, sizeof(mb_row_left_context));
     300               0 :                     xd->up_available = (mb_row != 0);
     301                 : 
     302               0 :                     xd->mb_to_top_edge = -((mb_row * 16)) << 3;
     303               0 :                     xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
     304                 : 
     305               0 :                     for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
     306                 :                     {
     307               0 :                         if ((mb_col & (nsync-1)) == 0)
     308                 :                         {
     309               0 :                             while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != pc->mb_cols - 1)
     310                 :                             {
     311               0 :                                 x86_pause_hint();
     312               0 :                                 thread_sleep(0);
     313                 :                             }
     314                 :                         }
     315                 : 
     316               0 :                         update_blockd_bmi(xd);
     317                 : 
     318                 :                         /* Distance of MB to the various image edges.
     319                 :                          * These are specified to 8th pel as they are always
     320                 :                          * compared to values that are in 1/8th pel units.
     321                 :                          */
     322               0 :                         xd->mb_to_left_edge = -((mb_col * 16) << 3);
     323               0 :                         xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
     324                 : 
     325                 : #if CONFIG_ERROR_CONCEALMENT
     326                 :                         {
     327                 :                             int corrupt_residual =
     328                 :                                         (!pbi->independent_partitions &&
     329                 :                                         pbi->frame_corrupt_residual) ||
     330                 :                                         vp8dx_bool_error(xd->current_bc);
     331                 :                             if (pbi->ec_active &&
     332                 :                                 (xd->mode_info_context->mbmi.ref_frame ==
     333                 :                                                                  INTRA_FRAME) &&
     334                 :                                 corrupt_residual)
     335                 :                             {
     336                 :                                 /* We have an intra block with corrupt
     337                 :                                  * coefficients, better to conceal with an inter
     338                 :                                  * block.
     339                 :                                  * Interpolate MVs from neighboring MBs
     340                 :                                  *
     341                 :                                  * Note that for the first mb with corrupt
     342                 :                                  * residual in a frame, we might not discover
     343                 :                                  * that before decoding the residual. That
     344                 :                                  * happens after this check, and therefore no
     345                 :                                  * inter concealment will be done.
     346                 :                                  */
     347                 :                                 vp8_interpolate_motion(xd,
     348                 :                                                        mb_row, mb_col,
     349                 :                                                        pc->mb_rows, pc->mb_cols,
     350                 :                                                        pc->mode_info_stride);
     351                 :                             }
     352                 :                         }
     353                 : #endif
     354                 : 
     355                 : 
     356               0 :                         xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
     357               0 :                         xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
     358               0 :                         xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
     359                 : 
     360               0 :                         xd->left_available = (mb_col != 0);
     361                 : 
     362                 :                         /* Select the appropriate reference frame for this MB */
     363               0 :                         if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
     364               0 :                             ref_fb_idx = pc->lst_fb_idx;
     365               0 :                         else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
     366               0 :                             ref_fb_idx = pc->gld_fb_idx;
     367                 :                         else
     368               0 :                             ref_fb_idx = pc->alt_fb_idx;
     369                 : 
     370               0 :                         xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
     371               0 :                         xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
     372               0 :                         xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
     373                 : 
     374               0 :                         if (xd->mode_info_context->mbmi.ref_frame !=
     375                 :                                 INTRA_FRAME)
     376                 :                         {
     377                 :                             /* propagate errors from reference frames */
     378               0 :                             xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
     379                 :                         }
     380                 : 
     381               0 :                         vp8_build_uvmvs(xd, pc->full_pixel);
     382               0 :                         decode_macroblock(pbi, xd, mb_row, mb_col);
     383                 : 
     384                 :                         /* check if the boolean decoder has suffered an error */
     385               0 :                         xd->corrupted |= vp8dx_bool_error(xd->current_bc);
     386                 : 
     387               0 :                         if (pbi->common.filter_level)
     388                 :                         {
     389               0 :                             int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
     390               0 :                                             xd->mode_info_context->mbmi.mode != SPLITMV &&
     391               0 :                                             xd->mode_info_context->mbmi.mb_skip_coeff);
     392                 : 
     393               0 :                             const int mode_index = lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode];
     394               0 :                             const int seg = xd->mode_info_context->mbmi.segment_id;
     395               0 :                             const int ref_frame = xd->mode_info_context->mbmi.ref_frame;
     396                 : 
     397               0 :                             filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
     398                 : 
     399               0 :                             if( mb_row != pc->mb_rows-1 )
     400                 :                             {
     401                 :                                 /* Save decoded MB last row data for next-row decoding */
     402               0 :                                 vpx_memcpy((pbi->mt_yabove_row[mb_row + 1] + 32 + mb_col*16), (xd->dst.y_buffer + 15 * recon_y_stride), 16);
     403               0 :                                 vpx_memcpy((pbi->mt_uabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
     404               0 :                                 vpx_memcpy((pbi->mt_vabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.v_buffer + 7 * recon_uv_stride), 8);
     405                 :                             }
     406                 : 
     407                 :                             /* save left_col for next MB decoding */
     408               0 :                             if(mb_col != pc->mb_cols-1)
     409                 :                             {
     410               0 :                                 MODE_INFO *next = xd->mode_info_context +1;
     411                 : 
     412               0 :                                 if (next->mbmi.ref_frame == INTRA_FRAME)
     413                 :                                 {
     414               0 :                                     for (i = 0; i < 16; i++)
     415               0 :                                         pbi->mt_yleft_col[mb_row][i] = xd->dst.y_buffer [i* recon_y_stride + 15];
     416               0 :                                     for (i = 0; i < 8; i++)
     417                 :                                     {
     418               0 :                                         pbi->mt_uleft_col[mb_row][i] = xd->dst.u_buffer [i* recon_uv_stride + 7];
     419               0 :                                         pbi->mt_vleft_col[mb_row][i] = xd->dst.v_buffer [i* recon_uv_stride + 7];
     420                 :                                     }
     421                 :                                 }
     422                 :                             }
     423                 : 
     424                 :                             /* loopfilter on this macroblock. */
     425               0 :                             if (filter_level)
     426                 :                             {
     427               0 :                                 if(pc->filter_type == NORMAL_LOOPFILTER)
     428                 :                                 {
     429                 :                                     loop_filter_info lfi;
     430               0 :                                     FRAME_TYPE frame_type = pc->frame_type;
     431               0 :                                     const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
     432               0 :                                     lfi.mblim = lfi_n->mblim[filter_level];
     433               0 :                                     lfi.blim = lfi_n->blim[filter_level];
     434               0 :                                     lfi.lim = lfi_n->lim[filter_level];
     435               0 :                                     lfi.hev_thr = lfi_n->hev_thr[hev_index];
     436                 : 
     437               0 :                                     if (mb_col > 0)
     438               0 :                                         LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_v)
     439               0 :                                         (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
     440                 : 
     441               0 :                                     if (!skip_lf)
     442               0 :                                         LF_INVOKE(&pc->rtcd.loopfilter, normal_b_v)
     443               0 :                                         (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
     444                 : 
     445                 :                                     /* don't apply across umv border */
     446               0 :                                     if (mb_row > 0)
     447               0 :                                         LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_h)
     448               0 :                                         (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
     449                 : 
     450               0 :                                     if (!skip_lf)
     451               0 :                                         LF_INVOKE(&pc->rtcd.loopfilter, normal_b_h)
     452               0 :                                         (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer,  recon_y_stride, recon_uv_stride, &lfi);
     453                 :                                 }
     454                 :                                 else
     455                 :                                 {
     456               0 :                                     if (mb_col > 0)
     457               0 :                                         LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_v)
     458               0 :                                         (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
     459                 : 
     460               0 :                                     if (!skip_lf)
     461               0 :                                         LF_INVOKE(&pc->rtcd.loopfilter, simple_b_v)
     462               0 :                                         (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
     463                 : 
     464                 :                                     /* don't apply across umv border */
     465               0 :                                     if (mb_row > 0)
     466               0 :                                         LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_h)
     467               0 :                                         (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
     468                 : 
     469               0 :                                     if (!skip_lf)
     470               0 :                                         LF_INVOKE(&pc->rtcd.loopfilter, simple_b_h)
     471               0 :                                         (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
     472                 :                                 }
     473                 :                             }
     474                 : 
     475                 :                         }
     476                 : 
     477               0 :                         recon_yoffset += 16;
     478               0 :                         recon_uvoffset += 8;
     479                 : 
     480               0 :                         ++xd->mode_info_context;  /* next mb */
     481                 : 
     482               0 :                         xd->above_context++;
     483                 : 
     484                 :                         /*pbi->mb_row_di[ithread].current_mb_col = mb_col;*/
     485               0 :                         pbi->mt_current_mb_col[mb_row] = mb_col;
     486                 :                     }
     487                 : 
     488                 :                     /* adjust to the next row of mbs */
     489               0 :                     if (pbi->common.filter_level)
     490                 :                     {
     491               0 :                         if(mb_row != pc->mb_rows-1)
     492                 :                         {
     493               0 :                             int lasty = pc->yv12_fb[ref_fb_idx].y_width + VP8BORDERINPIXELS;
     494               0 :                             int lastuv = (pc->yv12_fb[ref_fb_idx].y_width>>1) + (VP8BORDERINPIXELS>>1);
     495                 : 
     496               0 :                             for (i = 0; i < 4; i++)
     497                 :                             {
     498               0 :                                 pbi->mt_yabove_row[mb_row +1][lasty + i] = pbi->mt_yabove_row[mb_row +1][lasty -1];
     499               0 :                                 pbi->mt_uabove_row[mb_row +1][lastuv + i] = pbi->mt_uabove_row[mb_row +1][lastuv -1];
     500               0 :                                 pbi->mt_vabove_row[mb_row +1][lastuv + i] = pbi->mt_vabove_row[mb_row +1][lastuv -1];
     501                 :                             }
     502                 :                         }
     503                 :                     } else
     504               0 :                         vp8_extend_mb_row(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
     505                 : 
     506               0 :                     ++xd->mode_info_context;      /* skip prediction column */
     507                 : 
     508                 :                     /* since we have multithread */
     509               0 :                     xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
     510                 :                 }
     511                 :             }
     512                 :         }
     513                 :         /*  add this to each frame */
     514               0 :         if ((mbrd->mb_row == pbi->common.mb_rows-1) || ((mbrd->mb_row == pbi->common.mb_rows-2) && (pbi->common.mb_rows % (pbi->decoding_thread_count+1))==1))
     515                 :         {
     516                 :             /*SetEvent(pbi->h_event_end_decoding);*/
     517               0 :             sem_post(&pbi->h_event_end_decoding);
     518                 :         }
     519               0 :     }
     520                 : 
     521               0 :     return 0 ;
     522                 : }
     523                 : 
     524                 : 
     525               0 : void vp8_decoder_create_threads(VP8D_COMP *pbi)
     526                 : {
     527               0 :     int core_count = 0;
     528                 :     int ithread;
     529                 : 
     530               0 :     pbi->b_multithreaded_rd = 0;
     531               0 :     pbi->allocated_decoding_thread_count = 0;
     532                 : 
     533                 :     /* limit decoding threads to the max number of token partitions */
     534               0 :     core_count = (pbi->max_threads > 8) ? 8 : pbi->max_threads;
     535                 : 
     536                 :     /* limit decoding threads to the available cores */
     537               0 :     if (core_count > pbi->common.processor_core_count)
     538               0 :         core_count = pbi->common.processor_core_count;
     539                 : 
     540               0 :     if (core_count > 1)
     541                 :     {
     542               0 :         pbi->b_multithreaded_rd = 1;
     543               0 :         pbi->decoding_thread_count = core_count - 1;
     544                 : 
     545               0 :         CHECK_MEM_ERROR(pbi->h_decoding_thread, vpx_malloc(sizeof(pthread_t) * pbi->decoding_thread_count));
     546               0 :         CHECK_MEM_ERROR(pbi->h_event_start_decoding, vpx_malloc(sizeof(sem_t) * pbi->decoding_thread_count));
     547               0 :         CHECK_MEM_ERROR(pbi->mb_row_di, vpx_memalign(32, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count));
     548               0 :         vpx_memset(pbi->mb_row_di, 0, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count);
     549               0 :         CHECK_MEM_ERROR(pbi->de_thread_data, vpx_malloc(sizeof(DECODETHREAD_DATA) * pbi->decoding_thread_count));
     550                 : 
     551               0 :         for (ithread = 0; ithread < pbi->decoding_thread_count; ithread++)
     552                 :         {
     553               0 :             sem_init(&pbi->h_event_start_decoding[ithread], 0, 0);
     554                 : 
     555               0 :             pbi->de_thread_data[ithread].ithread  = ithread;
     556               0 :             pbi->de_thread_data[ithread].ptr1     = (void *)pbi;
     557               0 :             pbi->de_thread_data[ithread].ptr2     = (void *) &pbi->mb_row_di[ithread];
     558                 : 
     559               0 :             pthread_create(&pbi->h_decoding_thread[ithread], 0, thread_decoding_proc, (&pbi->de_thread_data[ithread]));
     560                 :         }
     561                 : 
     562               0 :         sem_init(&pbi->h_event_end_decoding, 0, 0);
     563                 : 
     564               0 :         pbi->allocated_decoding_thread_count = pbi->decoding_thread_count;
     565                 :     }
     566               0 : }
     567                 : 
     568                 : 
     569               0 : void vp8mt_de_alloc_temp_buffers(VP8D_COMP *pbi, int mb_rows)
     570                 : {
     571                 :     int i;
     572                 : 
     573               0 :     if (pbi->b_multithreaded_rd)
     574                 :     {
     575               0 :             vpx_free(pbi->mt_current_mb_col);
     576               0 :             pbi->mt_current_mb_col = NULL ;
     577                 : 
     578                 :         /* Free above_row buffers. */
     579               0 :         if (pbi->mt_yabove_row)
     580                 :         {
     581               0 :             for (i=0; i< mb_rows; i++)
     582                 :             {
     583               0 :                     vpx_free(pbi->mt_yabove_row[i]);
     584               0 :                     pbi->mt_yabove_row[i] = NULL ;
     585                 :             }
     586               0 :             vpx_free(pbi->mt_yabove_row);
     587               0 :             pbi->mt_yabove_row = NULL ;
     588                 :         }
     589                 : 
     590               0 :         if (pbi->mt_uabove_row)
     591                 :         {
     592               0 :             for (i=0; i< mb_rows; i++)
     593                 :             {
     594               0 :                     vpx_free(pbi->mt_uabove_row[i]);
     595               0 :                     pbi->mt_uabove_row[i] = NULL ;
     596                 :             }
     597               0 :             vpx_free(pbi->mt_uabove_row);
     598               0 :             pbi->mt_uabove_row = NULL ;
     599                 :         }
     600                 : 
     601               0 :         if (pbi->mt_vabove_row)
     602                 :         {
     603               0 :             for (i=0; i< mb_rows; i++)
     604                 :             {
     605               0 :                     vpx_free(pbi->mt_vabove_row[i]);
     606               0 :                     pbi->mt_vabove_row[i] = NULL ;
     607                 :             }
     608               0 :             vpx_free(pbi->mt_vabove_row);
     609               0 :             pbi->mt_vabove_row = NULL ;
     610                 :         }
     611                 : 
     612                 :         /* Free left_col buffers. */
     613               0 :         if (pbi->mt_yleft_col)
     614                 :         {
     615               0 :             for (i=0; i< mb_rows; i++)
     616                 :             {
     617               0 :                     vpx_free(pbi->mt_yleft_col[i]);
     618               0 :                     pbi->mt_yleft_col[i] = NULL ;
     619                 :             }
     620               0 :             vpx_free(pbi->mt_yleft_col);
     621               0 :             pbi->mt_yleft_col = NULL ;
     622                 :         }
     623                 : 
     624               0 :         if (pbi->mt_uleft_col)
     625                 :         {
     626               0 :             for (i=0; i< mb_rows; i++)
     627                 :             {
     628               0 :                     vpx_free(pbi->mt_uleft_col[i]);
     629               0 :                     pbi->mt_uleft_col[i] = NULL ;
     630                 :             }
     631               0 :             vpx_free(pbi->mt_uleft_col);
     632               0 :             pbi->mt_uleft_col = NULL ;
     633                 :         }
     634                 : 
     635               0 :         if (pbi->mt_vleft_col)
     636                 :         {
     637               0 :             for (i=0; i< mb_rows; i++)
     638                 :             {
     639               0 :                     vpx_free(pbi->mt_vleft_col[i]);
     640               0 :                     pbi->mt_vleft_col[i] = NULL ;
     641                 :             }
     642               0 :             vpx_free(pbi->mt_vleft_col);
     643               0 :             pbi->mt_vleft_col = NULL ;
     644                 :         }
     645                 :     }
     646               0 : }
     647                 : 
     648                 : 
     649               0 : void vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows)
     650                 : {
     651               0 :     VP8_COMMON *const pc = & pbi->common;
     652                 :     int i;
     653                 :     int uv_width;
     654                 : 
     655               0 :     if (pbi->b_multithreaded_rd)
     656                 :     {
     657               0 :         vp8mt_de_alloc_temp_buffers(pbi, prev_mb_rows);
     658                 : 
     659                 :         /* our internal buffers are always multiples of 16 */
     660               0 :         if ((width & 0xf) != 0)
     661               0 :             width += 16 - (width & 0xf);
     662                 : 
     663               0 :         if (width < 640) pbi->sync_range = 1;
     664               0 :         else if (width <= 1280) pbi->sync_range = 8;
     665               0 :         else if (width <= 2560) pbi->sync_range =16;
     666               0 :         else pbi->sync_range = 32;
     667                 : 
     668               0 :         uv_width = width >>1;
     669                 : 
     670                 :         /* Allocate an int for each mb row. */
     671               0 :         CHECK_MEM_ERROR(pbi->mt_current_mb_col, vpx_malloc(sizeof(int) * pc->mb_rows));
     672                 : 
     673                 :         /* Allocate memory for above_row buffers. */
     674               0 :         CHECK_MEM_ERROR(pbi->mt_yabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
     675               0 :         for (i=0; i< pc->mb_rows; i++)
     676               0 :             CHECK_MEM_ERROR(pbi->mt_yabove_row[i], vpx_calloc(sizeof(unsigned char) * (width + (VP8BORDERINPIXELS<<1)), 1));
     677                 : 
     678               0 :         CHECK_MEM_ERROR(pbi->mt_uabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
     679               0 :         for (i=0; i< pc->mb_rows; i++)
     680               0 :             CHECK_MEM_ERROR(pbi->mt_uabove_row[i], vpx_calloc(sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS), 1));
     681                 : 
     682               0 :         CHECK_MEM_ERROR(pbi->mt_vabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
     683               0 :         for (i=0; i< pc->mb_rows; i++)
     684               0 :             CHECK_MEM_ERROR(pbi->mt_vabove_row[i], vpx_calloc(sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS), 1));
     685                 : 
     686                 :         /* Allocate memory for left_col buffers. */
     687               0 :         CHECK_MEM_ERROR(pbi->mt_yleft_col, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
     688               0 :         for (i=0; i< pc->mb_rows; i++)
     689               0 :             CHECK_MEM_ERROR(pbi->mt_yleft_col[i], vpx_calloc(sizeof(unsigned char) * 16, 1));
     690                 : 
     691               0 :         CHECK_MEM_ERROR(pbi->mt_uleft_col, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
     692               0 :         for (i=0; i< pc->mb_rows; i++)
     693               0 :             CHECK_MEM_ERROR(pbi->mt_uleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));
     694                 : 
     695               0 :         CHECK_MEM_ERROR(pbi->mt_vleft_col, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
     696               0 :         for (i=0; i< pc->mb_rows; i++)
     697               0 :             CHECK_MEM_ERROR(pbi->mt_vleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));
     698                 :     }
     699               0 : }
     700                 : 
     701                 : 
     702               0 : void vp8_decoder_remove_threads(VP8D_COMP *pbi)
     703                 : {
     704                 :     /* shutdown MB Decoding thread; */
     705               0 :     if (pbi->b_multithreaded_rd)
     706                 :     {
     707                 :         int i;
     708                 : 
     709               0 :         pbi->b_multithreaded_rd = 0;
     710                 : 
     711                 :         /* allow all threads to exit */
     712               0 :         for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
     713                 :         {
     714               0 :             sem_post(&pbi->h_event_start_decoding[i]);
     715               0 :             pthread_join(pbi->h_decoding_thread[i], NULL);
     716                 :         }
     717                 : 
     718               0 :         for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
     719                 :         {
     720               0 :             sem_destroy(&pbi->h_event_start_decoding[i]);
     721                 :         }
     722                 : 
     723               0 :         sem_destroy(&pbi->h_event_end_decoding);
     724                 : 
     725               0 :             vpx_free(pbi->h_decoding_thread);
     726               0 :             pbi->h_decoding_thread = NULL;
     727                 : 
     728               0 :             vpx_free(pbi->h_event_start_decoding);
     729               0 :             pbi->h_event_start_decoding = NULL;
     730                 : 
     731               0 :             vpx_free(pbi->mb_row_di);
     732               0 :             pbi->mb_row_di = NULL ;
     733                 : 
     734               0 :             vpx_free(pbi->de_thread_data);
     735               0 :             pbi->de_thread_data = NULL;
     736                 :     }
     737               0 : }
     738                 : 
     739               0 : void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
     740                 : {
     741                 :     int mb_row;
     742               0 :     VP8_COMMON *pc = &pbi->common;
     743                 : 
     744               0 :     int num_part = 1 << pbi->common.multi_token_partition;
     745                 :     int i;
     746               0 :     volatile int *last_row_current_mb_col = NULL;
     747               0 :     int nsync = pbi->sync_range;
     748                 : 
     749               0 :     int filter_level = pc->filter_level;
     750               0 :     loop_filter_info_n *lfi_n = &pc->lf_info;
     751                 : 
     752               0 :     if (filter_level)
     753                 :     {
     754                 :         /* Set above_row buffer to 127 for decoding first MB row */
     755               0 :         vpx_memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS-1, 127, pc->yv12_fb[pc->lst_fb_idx].y_width + 5);
     756               0 :         vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
     757               0 :         vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
     758                 : 
     759               0 :         for (i=1; i<pc->mb_rows; i++)
     760                 :         {
     761               0 :             vpx_memset(pbi->mt_yabove_row[i] + VP8BORDERINPIXELS-1, (unsigned char)129, 1);
     762               0 :             vpx_memset(pbi->mt_uabove_row[i] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
     763               0 :             vpx_memset(pbi->mt_vabove_row[i] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
     764                 :         }
     765                 : 
     766                 :         /* Set left_col to 129 initially */
     767               0 :         for (i=0; i<pc->mb_rows; i++)
     768                 :         {
     769               0 :             vpx_memset(pbi->mt_yleft_col[i], (unsigned char)129, 16);
     770               0 :             vpx_memset(pbi->mt_uleft_col[i], (unsigned char)129, 8);
     771               0 :             vpx_memset(pbi->mt_vleft_col[i], (unsigned char)129, 8);
     772                 :         }
     773                 : 
     774                 :         /* Initialize the loop filter for this frame. */
     775               0 :         vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level);
     776                 :     }
     777                 : 
     778               0 :     setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count);
     779                 : 
     780               0 :     for (i = 0; i < pbi->decoding_thread_count; i++)
     781               0 :         sem_post(&pbi->h_event_start_decoding[i]);
     782                 : 
     783               0 :     for (mb_row = 0; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
     784                 :     {
     785               0 :         xd->current_bc = &pbi->mbc[mb_row%num_part];
     786                 : 
     787                 :         /* vp8_decode_mb_row(pbi, pc, mb_row, xd); */
     788                 :         {
     789                 :             int i;
     790                 :             int recon_yoffset, recon_uvoffset;
     791                 :             int mb_col;
     792               0 :             int ref_fb_idx = pc->lst_fb_idx;
     793               0 :             int dst_fb_idx = pc->new_fb_idx;
     794               0 :             int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
     795               0 :             int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
     796                 : 
     797                 :            /* volatile int *last_row_current_mb_col = NULL; */
     798               0 :             if (mb_row > 0)
     799               0 :                 last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
     800                 : 
     801               0 :             vpx_memset(&pc->left_context, 0, sizeof(pc->left_context));
     802               0 :             recon_yoffset = mb_row * recon_y_stride * 16;
     803               0 :             recon_uvoffset = mb_row * recon_uv_stride * 8;
     804                 :             /* reset above block coeffs */
     805                 : 
     806               0 :             xd->above_context = pc->above_context;
     807               0 :             xd->up_available = (mb_row != 0);
     808                 : 
     809               0 :             xd->mb_to_top_edge = -((mb_row * 16)) << 3;
     810               0 :             xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
     811                 : 
     812               0 :             for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
     813                 :             {
     814               0 :                 if ( mb_row > 0 && (mb_col & (nsync-1)) == 0){
     815               0 :                     while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != pc->mb_cols - 1)
     816                 :                     {
     817               0 :                         x86_pause_hint();
     818               0 :                         thread_sleep(0);
     819                 :                     }
     820                 :                 }
     821                 : 
     822               0 :                 update_blockd_bmi(xd);
     823                 : 
     824                 :                 /* Distance of MB to the various image edges.
     825                 :                  * These are specified to 8th pel as they are always compared to
     826                 :                  * values that are in 1/8th pel units.
     827                 :                  */
     828               0 :                 xd->mb_to_left_edge = -((mb_col * 16) << 3);
     829               0 :                 xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
     830                 : 
     831                 : #if CONFIG_ERROR_CONCEALMENT
     832                 :                 {
     833                 :                     int corrupt_residual = (!pbi->independent_partitions &&
     834                 :                                             pbi->frame_corrupt_residual) ||
     835                 :                                             vp8dx_bool_error(xd->current_bc);
     836                 :                     if (pbi->ec_active &&
     837                 :                         (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) &&
     838                 :                         corrupt_residual)
     839                 :                     {
     840                 :                         /* We have an intra block with corrupt coefficients,
     841                 :                          * better to conceal with an inter block. Interpolate
     842                 :                          * MVs from neighboring MBs
     843                 :                          *
     844                 :                          * Note that for the first mb with corrupt residual in a
     845                 :                          * frame, we might not discover that before decoding the
     846                 :                          * residual. That happens after this check, and
     847                 :                          * therefore no inter concealment will be done.
     848                 :                          */
     849                 :                         vp8_interpolate_motion(xd,
     850                 :                                                mb_row, mb_col,
     851                 :                                                pc->mb_rows, pc->mb_cols,
     852                 :                                                pc->mode_info_stride);
     853                 :                     }
     854                 :                 }
     855                 : #endif
     856                 : 
     857                 : 
     858               0 :                 xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
     859               0 :                 xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
     860               0 :                 xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
     861                 : 
     862               0 :                 xd->left_available = (mb_col != 0);
     863                 : 
     864                 :                 /* Select the appropriate reference frame for this MB */
     865               0 :                 if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
     866               0 :                     ref_fb_idx = pc->lst_fb_idx;
     867               0 :                 else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
     868               0 :                     ref_fb_idx = pc->gld_fb_idx;
     869                 :                 else
     870               0 :                     ref_fb_idx = pc->alt_fb_idx;
     871                 : 
     872               0 :                 xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
     873               0 :                 xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
     874               0 :                 xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
     875                 : 
     876               0 :                 if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME)
     877                 :                 {
     878                 :                     /* propagate errors from reference frames */
     879               0 :                     xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
     880                 :                 }
     881                 : 
     882               0 :                 vp8_build_uvmvs(xd, pc->full_pixel);
     883               0 :                 decode_macroblock(pbi, xd, mb_row, mb_col);
     884                 : 
     885                 :                 /* check if the boolean decoder has suffered an error */
     886               0 :                 xd->corrupted |= vp8dx_bool_error(xd->current_bc);
     887                 : 
     888               0 :                 if (pbi->common.filter_level)
     889                 :                 {
     890               0 :                     int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
     891               0 :                                     xd->mode_info_context->mbmi.mode != SPLITMV &&
     892               0 :                                     xd->mode_info_context->mbmi.mb_skip_coeff);
     893                 : 
     894               0 :                     const int mode_index = lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode];
     895               0 :                     const int seg = xd->mode_info_context->mbmi.segment_id;
     896               0 :                     const int ref_frame = xd->mode_info_context->mbmi.ref_frame;
     897                 : 
     898               0 :                     filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
     899                 : 
     900                 :                     /* Save decoded MB last row data for next-row decoding */
     901               0 :                     if(mb_row != pc->mb_rows-1)
     902                 :                     {
     903               0 :                         vpx_memcpy((pbi->mt_yabove_row[mb_row +1] + 32 + mb_col*16), (xd->dst.y_buffer + 15 * recon_y_stride), 16);
     904               0 :                         vpx_memcpy((pbi->mt_uabove_row[mb_row +1] + 16 + mb_col*8), (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
     905               0 :                         vpx_memcpy((pbi->mt_vabove_row[mb_row +1] + 16 + mb_col*8), (xd->dst.v_buffer + 7 * recon_uv_stride), 8);
     906                 :                     }
     907                 : 
     908                 :                     /* save left_col for next MB decoding */
     909               0 :                     if(mb_col != pc->mb_cols-1)
     910                 :                     {
     911               0 :                         MODE_INFO *next = xd->mode_info_context +1;
     912                 : 
     913               0 :                         if (next->mbmi.ref_frame == INTRA_FRAME)
     914                 :                         {
     915               0 :                             for (i = 0; i < 16; i++)
     916               0 :                                 pbi->mt_yleft_col[mb_row][i] = xd->dst.y_buffer [i* recon_y_stride + 15];
     917               0 :                             for (i = 0; i < 8; i++)
     918                 :                             {
     919               0 :                                 pbi->mt_uleft_col[mb_row][i] = xd->dst.u_buffer [i* recon_uv_stride + 7];
     920               0 :                                 pbi->mt_vleft_col[mb_row][i] = xd->dst.v_buffer [i* recon_uv_stride + 7];
     921                 :                             }
     922                 :                         }
     923                 :                     }
     924                 : 
     925                 :                     /* loopfilter on this macroblock. */
     926               0 :                     if (filter_level)
     927                 :                     {
     928               0 :                         if(pc->filter_type == NORMAL_LOOPFILTER)
     929                 :                         {
     930                 :                             loop_filter_info lfi;
     931               0 :                             FRAME_TYPE frame_type = pc->frame_type;
     932               0 :                             const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
     933               0 :                             lfi.mblim = lfi_n->mblim[filter_level];
     934               0 :                             lfi.blim = lfi_n->blim[filter_level];
     935               0 :                             lfi.lim = lfi_n->lim[filter_level];
     936               0 :                             lfi.hev_thr = lfi_n->hev_thr[hev_index];
     937                 : 
     938               0 :                             if (mb_col > 0)
     939               0 :                                 LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_v)
     940               0 :                                 (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
     941                 : 
     942               0 :                             if (!skip_lf)
     943               0 :                                 LF_INVOKE(&pc->rtcd.loopfilter, normal_b_v)
     944               0 :                                 (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
     945                 : 
     946                 :                             /* don't apply across umv border */
     947               0 :                             if (mb_row > 0)
     948               0 :                                 LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_h)
     949               0 :                                 (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
     950                 : 
     951               0 :                             if (!skip_lf)
     952               0 :                                 LF_INVOKE(&pc->rtcd.loopfilter, normal_b_h)
     953               0 :                                 (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer,  recon_y_stride, recon_uv_stride, &lfi);
     954                 :                         }
     955                 :                         else
     956                 :                         {
     957               0 :                             if (mb_col > 0)
     958               0 :                                 LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_v)
     959               0 :                                 (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
     960                 : 
     961               0 :                             if (!skip_lf)
     962               0 :                                 LF_INVOKE(&pc->rtcd.loopfilter, simple_b_v)
     963               0 :                                 (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
     964                 : 
     965                 :                             /* don't apply across umv border */
     966               0 :                             if (mb_row > 0)
     967               0 :                                 LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_h)
     968               0 :                                 (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
     969                 : 
     970               0 :                             if (!skip_lf)
     971               0 :                                 LF_INVOKE(&pc->rtcd.loopfilter, simple_b_h)
     972               0 :                                 (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
     973                 :                         }
     974                 :                     }
     975                 : 
     976                 :                 }
     977               0 :                 recon_yoffset += 16;
     978               0 :                 recon_uvoffset += 8;
     979                 : 
     980               0 :                 ++xd->mode_info_context;  /* next mb */
     981                 : 
     982               0 :                 xd->above_context++;
     983                 : 
     984               0 :                 pbi->mt_current_mb_col[mb_row] = mb_col;
     985                 :             }
     986                 : 
     987                 :             /* adjust to the next row of mbs */
     988               0 :             if (pbi->common.filter_level)
     989                 :             {
     990               0 :                 if(mb_row != pc->mb_rows-1)
     991                 :                 {
     992               0 :                     int lasty = pc->yv12_fb[ref_fb_idx].y_width + VP8BORDERINPIXELS;
     993               0 :                     int lastuv = (pc->yv12_fb[ref_fb_idx].y_width>>1) + (VP8BORDERINPIXELS>>1);
     994                 : 
     995               0 :                     for (i = 0; i < 4; i++)
     996                 :                     {
     997               0 :                         pbi->mt_yabove_row[mb_row +1][lasty + i] = pbi->mt_yabove_row[mb_row +1][lasty -1];
     998               0 :                         pbi->mt_uabove_row[mb_row +1][lastuv + i] = pbi->mt_uabove_row[mb_row +1][lastuv -1];
     999               0 :                         pbi->mt_vabove_row[mb_row +1][lastuv + i] = pbi->mt_vabove_row[mb_row +1][lastuv -1];
    1000                 :                     }
    1001                 :                 }
    1002                 :             }else
    1003               0 :                 vp8_extend_mb_row(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
    1004                 : 
    1005               0 :             ++xd->mode_info_context;      /* skip prediction column */
    1006                 :         }
    1007               0 :         xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
    1008                 :     }
    1009                 : 
    1010               0 :     sem_wait(&pbi->h_event_end_decoding);   /* add back for each frame */
    1011               0 : }

Generated by: LCOV version 1.7