threading.c 38.4 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9 10 11
 */


12
#if !defined(WIN32) && CONFIG_OS_SUPPORT == 1
John Koleszar's avatar
John Koleszar committed
13 14 15 16
# include <unistd.h>
#endif
#include "onyxd_int.h"
#include "vpx_mem/vpx_mem.h"
John Koleszar's avatar
John Koleszar committed
17
#include "vp8/common/threading.h"
John Koleszar's avatar
John Koleszar committed
18

John Koleszar's avatar
John Koleszar committed
19 20
#include "vp8/common/loopfilter.h"
#include "vp8/common/extend.h"
John Koleszar's avatar
John Koleszar committed
21
#include "vpx_ports/vpx_timer.h"
22
#include "detokenize.h"
John Koleszar's avatar
John Koleszar committed
23
#include "vp8/common/reconinter.h"
24
#include "reconintra_mt.h"
25 26 27
#if CONFIG_ERROR_CONCEALMENT
#include "error_concealment.h"
#endif
John Koleszar's avatar
John Koleszar committed
28

29 30
extern void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd);
extern void clamp_mvs(MACROBLOCKD *xd);
John Koleszar's avatar
John Koleszar committed
31 32
extern void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel);

33 34 35 36 37
#if CONFIG_RUNTIME_CPU_DETECT
#define RTCD_VTABLE(x) (&(pbi)->common.rtcd.x)
#else
#define RTCD_VTABLE(x) NULL
#endif
38

39
static void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
John Koleszar's avatar
John Koleszar committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
{
    VP8_COMMON *const pc = & pbi->common;
    int i, j;

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

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

        mbd->frame_type = pc->frame_type;
        mbd->frames_since_golden      = pc->frames_since_golden;
        mbd->frames_till_alt_ref_frame  = pc->frames_till_alt_ref_frame;

62 63
        mbd->pre = pc->yv12_fb[pc->lst_fb_idx];
        mbd->dst = pc->yv12_fb[pc->new_fb_idx];
John Koleszar's avatar
John Koleszar committed
64 65 66 67 68 69 70

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

71
        /*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/
72
        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
        vpx_memcpy(mbd->mode_lf_deltas, xd->mode_lf_deltas, sizeof(xd->mode_lf_deltas));
75 76
        /*unsigned char mode_ref_lf_delta_enabled;
        unsigned char mode_ref_lf_delta_update;*/
77 78 79
        mbd->mode_ref_lf_delta_enabled    = xd->mode_ref_lf_delta_enabled;
        mbd->mode_ref_lf_delta_update    = xd->mode_ref_lf_delta_update;

John Koleszar's avatar
John Koleszar committed
80 81 82 83 84 85 86 87
        mbd->current_bc = &pbi->bc2;

        for (j = 0; j < 25; j++)
        {
            mbd->block[j].dequant = xd->block[j].dequant;
        }
    }

88
    for (i=0; i< pc->mb_rows; i++)
89
        pbi->mt_current_mb_col[i]=-1;
John Koleszar's avatar
John Koleszar committed
90 91
}

92

93
static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col)
94
{
95 96
    int eobtotal = 0;
    int i, do_clamp = xd->mode_info_context->mbmi.need_to_clamp_mvs;
97

98
    if (xd->mode_info_context->mbmi.mb_skip_coeff)
99
    {
100 101 102 103 104 105
        vp8_reset_mb_tokens_context(xd);
    }
    else
    {
        eobtotal = vp8_decode_mb_tokens(pbi, xd);
    }
106

107
    /* Perform temporary clamping of the MV to be used for prediction */
108 109 110 111
    if (do_clamp)
    {
        clamp_mvs(xd);
    }
112

113 114 115
    eobtotal |= (xd->mode_info_context->mbmi.mode == B_PRED ||
                  xd->mode_info_context->mbmi.mode == SPLITMV);
    if (!eobtotal)
116
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
117 118 119 120 121
        /* Special case:  Force the loopfilter to skip when eobtotal and
         * mb_skip_coeff are zero.
         * */
        xd->mode_info_context->mbmi.mb_skip_coeff = 1;

122
        /*mt_skip_recon_mb(pbi, xd, mb_row, mb_col);*/
123
        if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
124 125 126 127 128 129
        {
            vp8mt_build_intra_predictors_mbuv_s(pbi, xd, mb_row, mb_col);
            vp8mt_build_intra_predictors_mby_s(pbi, xd, mb_row, mb_col);
        }
        else
        {
130 131 132
            vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
                                               xd->dst.u_buffer, xd->dst.v_buffer,
                                               xd->dst.y_stride, xd->dst.uv_stride);
133 134 135
        }
        return;
    }
136

137 138
    if (xd->segmentation_enabled)
        mb_init_dequantizer(pbi, xd);
139

140
    /* do prediction */
141
    if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
142 143 144 145 146 147 148 149 150 151 152 153 154 155
    {
        vp8mt_build_intra_predictors_mbuv(pbi, xd, mb_row, mb_col);

        if (xd->mode_info_context->mbmi.mode != B_PRED)
        {
            vp8mt_build_intra_predictors_mby(pbi, xd, mb_row, mb_col);
        } else {
            vp8mt_intra_prediction_down_copy(pbi, xd, mb_row, mb_col);
        }
    }
    else
    {
        vp8_build_inter_predictors_mb(xd);
    }
156

157 158 159 160 161 162 163 164 165 166 167 168 169 170
#if CONFIG_ERROR_CONCEALMENT
    if (pbi->ec_enabled &&
        (mb_row * pbi->common.mb_cols + mb_col >= pbi->mvs_corrupt_from_mb ||
        vp8dx_bool_error(xd->current_bc)))
    {
        /* MB with corrupt residuals or corrupt mode/motion vectors.
         * Better to use the predictor as reconstruction.
         */
        vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
        vp8_conceal_corrupt_mb(xd);
        return;
    }
#endif

171
    /* dequantization and idct */
172 173 174 175
    if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV)
    {
        BLOCKD *b = &xd->block[24];
        DEQUANT_INVOKE(&pbi->dequant, block)(b);
176

177
        /* do 2nd order transform on the dc block */
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
        if (xd->eobs[24] > 1)
        {
            IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], b->diff);
            ((int *)b->qcoeff)[0] = 0;
            ((int *)b->qcoeff)[1] = 0;
            ((int *)b->qcoeff)[2] = 0;
            ((int *)b->qcoeff)[3] = 0;
            ((int *)b->qcoeff)[4] = 0;
            ((int *)b->qcoeff)[5] = 0;
            ((int *)b->qcoeff)[6] = 0;
            ((int *)b->qcoeff)[7] = 0;
        }
        else
        {
            IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], b->diff);
            ((int *)b->qcoeff)[0] = 0;
        }

        DEQUANT_INVOKE (&pbi->dequant, dc_idct_add_y_block)
197
                        (xd->qcoeff, xd->block[0].dequant,
198 199
                         xd->predictor, xd->dst.y_buffer,
                         xd->dst.y_stride, xd->eobs, xd->block[24].diff);
200
    }
201
    else if (xd->mode_info_context->mbmi.mode == B_PRED)
202 203 204 205
    {
        for (i = 0; i < 16; i++)
        {
            BLOCKD *b = &xd->block[i];
Scott LaVarnway's avatar
Scott LaVarnway committed
206 207 208

            vp8mt_predict_intra4x4(pbi, xd, b->bmi.as_mode, b->predictor, mb_row, mb_col, i);

209 210 211
            if (xd->eobs[i] > 1)
            {
                DEQUANT_INVOKE(&pbi->dequant, idct_add)
212
                    (b->qcoeff, b->dequant,  b->predictor,
213 214 215 216 217
                    *(b->base_dst) + b->dst, 16, b->dst_stride);
            }
            else
            {
                IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar_add)
218
                    (b->qcoeff[0] * b->dequant[0], b->predictor,
219 220 221 222 223 224 225 226
                    *(b->base_dst) + b->dst, 16, b->dst_stride);
                ((int *)b->qcoeff)[0] = 0;
            }
        }
    }
    else
    {
        DEQUANT_INVOKE (&pbi->dequant, idct_add_y_block)
227
                        (xd->qcoeff, xd->block[0].dequant,
228 229 230 231 232
                         xd->predictor, xd->dst.y_buffer,
                         xd->dst.y_stride, xd->eobs);
    }

    DEQUANT_INVOKE (&pbi->dequant, idct_add_uv_block)
233
                    (xd->qcoeff+16*16, xd->block[16].dequant,
234 235
                     xd->predictor+16*16, xd->dst.u_buffer, xd->dst.v_buffer,
                     xd->dst.uv_stride, xd->eobs+16);
236
}
John Koleszar's avatar
John Koleszar committed
237

238

239
static THREAD_FUNCTION thread_decoding_proc(void *p_data)
John Koleszar's avatar
John Koleszar committed
240 241 242 243
{
    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);
244
    ENTROPY_CONTEXT_PLANES mb_row_left_context;
John Koleszar's avatar
John Koleszar committed
245 246 247 248 249 250

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

251
        /*if(WaitForSingleObject(pbi->h_event_start_decoding[ithread], INFINITE) == WAIT_OBJECT_0)*/
252
        if (sem_wait(&pbi->h_event_start_decoding[ithread]) == 0)
John Koleszar's avatar
John Koleszar committed
253 254 255 256 257 258 259 260
        {
            if (pbi->b_multithreaded_rd == 0)
                break;
            else
            {
                VP8_COMMON *pc = &pbi->common;
                MACROBLOCKD *xd = &mbrd->mbd;

261 262
                int mb_row;
                int num_part = 1 << pbi->common.multi_token_partition;
John Koleszar's avatar
John Koleszar committed
263
                volatile int *last_row_current_mb_col;
264
                int nsync = pbi->sync_range;
John Koleszar's avatar
John Koleszar committed
265

266
                for (mb_row = ithread+1; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
John Koleszar's avatar
John Koleszar committed
267
                {
268 269 270 271 272 273 274 275
                    int i;
                    int recon_yoffset, recon_uvoffset;
                    int mb_col;
                    int ref_fb_idx = pc->lst_fb_idx;
                    int dst_fb_idx = pc->new_fb_idx;
                    int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
                    int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;

276 277 278 279 280
                    int filter_level;
                    loop_filter_info *lfi = pc->lf_info;
                    int alt_flt_enabled = xd->segmentation_enabled;
                    int Segment;

281 282 283
                    pbi->mb_row_di[ithread].mb_row = mb_row;
                    pbi->mb_row_di[ithread].mbd.current_bc =  &pbi->mbc[mb_row%num_part];

284
                    last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
285 286 287

                    recon_yoffset = mb_row * recon_y_stride * 16;
                    recon_uvoffset = mb_row * recon_uv_stride * 8;
288
                    /* reset above block coeffs */
289

290 291 292
                    xd->above_context = pc->above_context;
                    xd->left_context = &mb_row_left_context;
                    vpx_memset(&mb_row_left_context, 0, sizeof(mb_row_left_context));
293 294 295 296 297 298
                    xd->up_available = (mb_row != 0);

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

                    for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
John Koleszar's avatar
John Koleszar committed
299
                    {
300
                        if ((mb_col & (nsync-1)) == 0)
301
                        {
302
                            while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != pc->mb_cols - 1)
303 304 305 306 307
                            {
                                x86_pause_hint();
                                thread_sleep(0);
                            }
                        }
John Koleszar's avatar
John Koleszar committed
308

Scott LaVarnway's avatar
Scott LaVarnway committed
309
                        update_blockd_bmi(xd);
John Koleszar's avatar
John Koleszar committed
310

311 312 313
                        /* 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.
314
                         */
315 316
                        xd->mb_to_left_edge = -((mb_col * 16) << 3);
                        xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
John Koleszar's avatar
John Koleszar committed
317

318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
#if CONFIG_ERROR_CONCEALMENT
                        if (pbi->ec_enabled &&
                            (xd->mode_info_context->mbmi.ref_frame ==
                                                                 INTRA_FRAME) &&
                            vp8dx_bool_error(xd->current_bc))
                        {
                            /* We have an intra block with corrupt coefficients,
                             * better to conceal with an inter block.
                             * Interpolate MVs from neighboring MBs
                             *
                             * Note that for the first mb with corrupt residual
                             * in a frame, we might not discover that before
                             * decoding the residual. That happens after this
                             * check, and therefore no inter concealment will be
                             * done.
                             */
                            vp8_interpolate_motion(xd,
                                                   mb_row, mb_col,
                                                   pc->mb_rows, pc->mb_cols,
                                                   pc->mode_info_stride);
                        }
#endif


342 343 344
                        xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
                        xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
                        xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
345

346
                        xd->left_available = (mb_col != 0);
347

348
                        /* Select the appropriate reference frame for this MB */
349
                        if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
350
                            ref_fb_idx = pc->lst_fb_idx;
351
                        else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
352 353 354
                            ref_fb_idx = pc->gld_fb_idx;
                        else
                            ref_fb_idx = pc->alt_fb_idx;
John Koleszar's avatar
John Koleszar committed
355

356 357 358
                        xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
                        xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
                        xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
359

360
                        vp8_build_uvmvs(xd, pc->full_pixel);
361
                        decode_macroblock(pbi, xd, mb_row, mb_col);
John Koleszar's avatar
John Koleszar committed
362

363 364
                        if (pbi->common.filter_level)
                        {
365
                            int skip_lf;
366 367
                            if( mb_row != pc->mb_rows-1 )
                            {
368
                                /* Save decoded MB last row data for next-row decoding */
369 370 371 372 373
                                vpx_memcpy((pbi->mt_yabove_row[mb_row + 1] + 32 + mb_col*16), (xd->dst.y_buffer + 15 * recon_y_stride), 16);
                                vpx_memcpy((pbi->mt_uabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
                                vpx_memcpy((pbi->mt_vabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.v_buffer + 7 * recon_uv_stride), 8);
                            }

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

379
                                if (next->mbmi.ref_frame == INTRA_FRAME)
380 381 382 383 384 385 386 387 388 389 390
                                {
                                    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];
                                    }
                                }
                            }

Ralph Giles's avatar
Ralph Giles committed
391 392
                            /* update loopfilter info */
                            Segment = (alt_flt_enabled) ? xd->mode_info_context->mbmi.segment_id : 0;
393 394 395 396
                            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);

Ralph Giles's avatar
Ralph Giles committed
397 398 399 400 401 402 403 404
                            filter_level = pbi->mt_baseline_filter_level[Segment];
                            /* 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
                             * Apply any context driven MB level adjustment
                             */
                            filter_level = vp8_adjust_mb_lf_value(xd, filter_level);

                            /* loopfilter on this macroblock. */
405 406 407
                            if (filter_level)
                            {
                                if (mb_col > 0)
Johann's avatar
Johann committed
408
                                    pc->lf_mbv(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
409

410
                                if (!skip_lf)
Johann's avatar
Johann committed
411
                                    pc->lf_bv(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
412

413
                                /* don't apply across umv border */
414
                                if (mb_row > 0)
Johann's avatar
Johann committed
415
                                    pc->lf_mbh(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
416

417
                                if (!skip_lf)
Johann's avatar
Johann committed
418
                                    pc->lf_bh(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
419 420
                            }
                        }
John Koleszar's avatar
John Koleszar committed
421

422 423
                        recon_yoffset += 16;
                        recon_uvoffset += 8;
John Koleszar's avatar
John Koleszar committed
424

425
                        ++xd->mode_info_context;  /* next mb */
John Koleszar's avatar
John Koleszar committed
426

427
                        xd->above_context++;
John Koleszar's avatar
John Koleszar committed
428

429
                        /*pbi->mb_row_di[ithread].current_mb_col = mb_col;*/
430
                        pbi->mt_current_mb_col[mb_row] = mb_col;
431
                    }
John Koleszar's avatar
John Koleszar committed
432

433
                    /* adjust to the next row of mbs */
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
                    if (pbi->common.filter_level)
                    {
                        if(mb_row != pc->mb_rows-1)
                        {
                            int lasty = pc->yv12_fb[ref_fb_idx].y_width + VP8BORDERINPIXELS;
                            int lastuv = (pc->yv12_fb[ref_fb_idx].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(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
John Koleszar's avatar
John Koleszar committed
450

451
                    ++xd->mode_info_context;      /* skip prediction column */
John Koleszar's avatar
John Koleszar committed
452

453
                    /* since we have multithread */
454
                    xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
John Koleszar's avatar
John Koleszar committed
455 456 457
                }
            }
        }
458
        /*  add this to each frame */
459 460
        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))
        {
461
            /*SetEvent(pbi->h_event_end_decoding);*/
462 463 464
            sem_post(&pbi->h_event_end_decoding);
        }
    }
John Koleszar's avatar
John Koleszar committed
465 466 467 468

    return 0 ;
}

469

470
void vp8_decoder_create_threads(VP8D_COMP *pbi)
John Koleszar's avatar
John Koleszar committed
471
{
472 473
    int core_count = 0;
    int ithread;
John Koleszar's avatar
John Koleszar committed
474

475 476
    pbi->b_multithreaded_rd = 0;
    pbi->allocated_decoding_thread_count = 0;
477 478 479 480 481 482 483

    /* 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;
John Koleszar's avatar
John Koleszar committed
484

485 486 487
    if (core_count > 1)
    {
        pbi->b_multithreaded_rd = 1;
488
        pbi->decoding_thread_count = core_count - 1;
John Koleszar's avatar
John Koleszar committed
489

490 491 492 493 494
        CHECK_MEM_ERROR(pbi->h_decoding_thread, vpx_malloc(sizeof(pthread_t) * pbi->decoding_thread_count));
        CHECK_MEM_ERROR(pbi->h_event_start_decoding, vpx_malloc(sizeof(sem_t) * pbi->decoding_thread_count));
        CHECK_MEM_ERROR(pbi->mb_row_di, vpx_memalign(32, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count));
        vpx_memset(pbi->mb_row_di, 0, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count);
        CHECK_MEM_ERROR(pbi->de_thread_data, vpx_malloc(sizeof(DECODETHREAD_DATA) * pbi->decoding_thread_count));
John Koleszar's avatar
John Koleszar committed
495

496 497 498
        for (ithread = 0; ithread < pbi->decoding_thread_count; ithread++)
        {
            sem_init(&pbi->h_event_start_decoding[ithread], 0, 0);
John Koleszar's avatar
John Koleszar committed
499

500 501 502
            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];
John Koleszar's avatar
John Koleszar committed
503

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

507
        sem_init(&pbi->h_event_end_decoding, 0, 0);
John Koleszar's avatar
John Koleszar committed
508

509 510 511
        pbi->allocated_decoding_thread_count = pbi->decoding_thread_count;
    }
}
John Koleszar's avatar
John Koleszar committed
512 513


514 515 516
void vp8mt_de_alloc_temp_buffers(VP8D_COMP *pbi, int mb_rows)
{
    int i;
John Koleszar's avatar
John Koleszar committed
517

518 519 520 521
    if (pbi->b_multithreaded_rd)
    {
            vpx_free(pbi->mt_current_mb_col);
            pbi->mt_current_mb_col = NULL ;
John Koleszar's avatar
John Koleszar committed
522

523
        /* Free above_row buffers. */
524 525 526 527 528 529 530 531 532 533
        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 ;
        }
John Koleszar's avatar
John Koleszar committed
534

535 536 537 538 539 540 541 542 543 544
        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 ;
        }
John Koleszar's avatar
John Koleszar committed
545

546 547 548 549 550 551 552 553 554 555
        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 ;
        }
John Koleszar's avatar
John Koleszar committed
556

557
        /* Free left_col buffers. */
558 559 560 561 562 563 564 565 566 567
        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 ;
        }
John Koleszar's avatar
John Koleszar committed
568

569 570 571 572 573 574
        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 ;
575
            }
576 577
            vpx_free(pbi->mt_uleft_col);
            pbi->mt_uleft_col = NULL ;
John Koleszar's avatar
John Koleszar committed
578 579
        }

580
        if (pbi->mt_vleft_col)
581
        {
582 583 584 585 586 587 588
            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 ;
589
        }
590
    }
John Koleszar's avatar
John Koleszar committed
591 592
}

593

594
void vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows)
John Koleszar's avatar
John Koleszar committed
595
{
596 597 598
    VP8_COMMON *const pc = & pbi->common;
    int i;
    int uv_width;
John Koleszar's avatar
John Koleszar committed
599

600
    if (pbi->b_multithreaded_rd)
John Koleszar's avatar
John Koleszar committed
601
    {
602
        vp8mt_de_alloc_temp_buffers(pbi, prev_mb_rows);
John Koleszar's avatar
John Koleszar committed
603

604
        /* our internal buffers are always multiples of 16 */
605 606
        if ((width & 0xf) != 0)
            width += 16 - (width & 0xf);
John Koleszar's avatar
John Koleszar committed
607

608 609 610 611 612
        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;

613
        uv_width = width >>1;
614

615
        /* Allocate an int for each mb row. */
616
        CHECK_MEM_ERROR(pbi->mt_current_mb_col, vpx_malloc(sizeof(int) * pc->mb_rows));
John Koleszar's avatar
John Koleszar committed
617

618
        /* Allocate memory for above_row buffers. */
619 620 621
        CHECK_MEM_ERROR(pbi->mt_yabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
        for (i=0; i< pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_yabove_row[i], vpx_calloc(sizeof(unsigned char) * (width + (VP8BORDERINPIXELS<<1)), 1));
John Koleszar's avatar
John Koleszar committed
622

623 624 625
        CHECK_MEM_ERROR(pbi->mt_uabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
        for (i=0; i< pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_uabove_row[i], vpx_calloc(sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS), 1));
John Koleszar's avatar
John Koleszar committed
626

627 628 629
        CHECK_MEM_ERROR(pbi->mt_vabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
        for (i=0; i< pc->mb_rows; i++)
            CHECK_MEM_ERROR(pbi->mt_vabove_row[i], vpx_calloc(sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS), 1));
630

631
        /* Allocate memory for left_col buffers. */
632 633 634
        CHECK_MEM_ERROR(pbi->mt_yleft_col, vpx_malloc(sizeof(unsigned char *) * 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));
John Koleszar's avatar
John Koleszar committed
635

636 637 638 639 640 641 642 643
        CHECK_MEM_ERROR(pbi->mt_uleft_col, vpx_malloc(sizeof(unsigned char *) * 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));

        CHECK_MEM_ERROR(pbi->mt_vleft_col, vpx_malloc(sizeof(unsigned char *) * 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));
    }
John Koleszar's avatar
John Koleszar committed
644 645
}

646

John Koleszar's avatar
John Koleszar committed
647 648
void vp8_decoder_remove_threads(VP8D_COMP *pbi)
{
649
    /* shutdown MB Decoding thread; */
John Koleszar's avatar
John Koleszar committed
650 651
    if (pbi->b_multithreaded_rd)
    {
652 653
        int i;

John Koleszar's avatar
John Koleszar committed
654
        pbi->b_multithreaded_rd = 0;
655

656
        /* allow all threads to exit */
657
        for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
John Koleszar's avatar
John Koleszar committed
658
        {
659 660
            sem_post(&pbi->h_event_start_decoding[i]);
            pthread_join(pbi->h_decoding_thread[i], NULL);
John Koleszar's avatar
John Koleszar committed
661 662
        }

663 664 665
        for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
        {
            sem_destroy(&pbi->h_event_start_decoding[i]);
John Koleszar's avatar
John Koleszar committed
666 667
        }

668
        sem_destroy(&pbi->h_event_end_decoding);
John Koleszar's avatar
John Koleszar committed
669 670 671 672

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

673 674 675
            vpx_free(pbi->h_event_start_decoding);
            pbi->h_event_start_decoding = NULL;

John Koleszar's avatar
John Koleszar committed
676 677 678 679 680
            vpx_free(pbi->mb_row_di);
            pbi->mb_row_di = NULL ;

            vpx_free(pbi->de_thread_data);
            pbi->de_thread_data = NULL;
681
    }
John Koleszar's avatar
John Koleszar committed
682 683 684
}


685
static void lpf_init( VP8D_COMP *pbi, int default_filt_lvl)
John Koleszar's avatar
John Koleszar committed
686
{
687 688
    VP8_COMMON *cm  = &pbi->common;
    MACROBLOCKD *mbd = &pbi->mb;
689
    /*YV12_BUFFER_CONFIG *post = &cm->new_frame;*/  /*frame_to_show;*/
690
    loop_filter_info *lfi = cm->lf_info;
691
    FRAME_TYPE frame_type = cm->frame_type;
John Koleszar's avatar
John Koleszar committed
692

693 694 695
    /*int mb_row;
    int mb_col;
    int baseline_filter_level[MAX_MB_SEGMENTS];*/
696
    int alt_flt_enabled = mbd->segmentation_enabled;
John Koleszar's avatar
John Koleszar committed
697

698
    int i;
699
    /*unsigned char *y_ptr, *u_ptr, *v_ptr;*/
John Koleszar's avatar
John Koleszar committed
700

701
    /* Note the baseline filter values for each segment */
702 703 704 705
    if (alt_flt_enabled)
    {
        for (i = 0; i < MAX_MB_SEGMENTS; i++)
        {
706
            /* Abs value */
707 708
            if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
                pbi->mt_baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
709
            /* Delta Value */
710 711 712
            else
            {
                pbi->mt_baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
713
                pbi->mt_baseline_filter_level[i] = (pbi->mt_baseline_filter_level[i] >= 0) ? ((pbi->mt_baseline_filter_level[i] <= MAX_LOOP_FILTER) ? pbi->mt_baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  /* Clamp to valid range */
714 715 716 717 718 719 720 721
            }
        }
    }
    else
    {
        for (i = 0; i < MAX_MB_SEGMENTS; i++)
            pbi->mt_baseline_filter_level[i] = default_filt_lvl;
    }
John Koleszar's avatar
John Koleszar committed
722

723
    /* Initialize the loop filter for this frame. */
724 725 726 727
    if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
        vp8_init_loop_filter(cm);
    else if (frame_type != cm->last_frame_type)
        vp8_frame_init_loop_filter(lfi, frame_type);
John Koleszar's avatar
John Koleszar committed
728 729 730
}


731
void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
John Koleszar's avatar
John Koleszar committed
732 733 734 735 736
{
    int mb_row;
    VP8_COMMON *pc = &pbi->common;

    int num_part = 1 << pbi->common.multi_token_partition;
Henrik Lundin's avatar
Henrik Lundin committed
737
    int i;
738
    volatile int *last_row_current_mb_col = NULL;
739
    int nsync = pbi->sync_range;
John Koleszar's avatar
John Koleszar committed
740

741 742 743 744 745 746 747
    int filter_level;
    loop_filter_info *lfi = pc->lf_info;
    int alt_flt_enabled = xd->segmentation_enabled;
    int Segment;

    if(pbi->common.filter_level)
    {
748
        /* Set above_row buffer to 127 for decoding first MB row */
749 750 751 752 753 754 755 756 757 758 759
        vpx_memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS-1, 127, pc->yv12_fb[pc->lst_fb_idx].y_width + 5);
        vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
        vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);

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

760
        /* Set left_col to 129 initially */
761 762 763 764 765 766
        for (i=0; i<pc->mb_rows; i++)
        {
            vpx_memset(pbi->mt_yleft_col[i], (unsigned char)129, 16);
            vpx_memset(pbi->mt_uleft_col[i], (unsigned char)129, 8);
            vpx_memset(pbi->mt_vleft_col[i], (unsigned char)129, 8);
        }
767
        lpf_init(pbi, pc->filter_level);
768 769
    }

770
    setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count);
John Koleszar's avatar
John Koleszar committed
771

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

John Koleszar's avatar
John Koleszar committed
775 776 777
    for (mb_row = 0; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
    {

778
        xd->current_bc = &pbi->mbc[mb_row%num_part];
John Koleszar's avatar
John Koleszar committed
779

780
        /* vp8_decode_mb_row(pbi, pc, mb_row, xd); */
John Koleszar's avatar
John Koleszar committed
781
        {
782 783 784 785 786 787 788 789
            int i;
            int recon_yoffset, recon_uvoffset;
            int mb_col;
            int ref_fb_idx = pc->lst_fb_idx;
            int dst_fb_idx = pc->new_fb_idx;
            int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
            int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;

790
           /* volatile int *last_row_current_mb_col = NULL; */
791
            if (mb_row > 0)
792
                last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
793

794
            vpx_memset(&pc->left_context, 0, sizeof(pc->left_context));
795 796
            recon_yoffset = mb_row * recon_y_stride * 16;
            recon_uvoffset = mb_row * recon_uv_stride * 8;
797
            /* reset above block coeffs */
798

799
            xd->above_context = pc->above_context;
800 801 802 803 804 805 806
            xd->up_available = (mb_row != 0);

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

            for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
            {
807 808
                if ( mb_row > 0 && (mb_col & (nsync-1)) == 0){
                    while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != pc->mb_cols - 1)
809 810 811 812
                    {
                        x86_pause_hint();
                        thread_sleep(0);
                    }
813
                }
John Koleszar's avatar
John Koleszar committed
814

Scott LaVarnway's avatar
Scott LaVarnway committed
815
                update_blockd_bmi(xd);
816

817 818 819
                /* 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.
820
                 */
821 822 823
                xd->mb_to_left_edge = -((mb_col * 16) << 3);
                xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;

824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845
#if CONFIG_ERROR_CONCEALMENT
                if (pbi->ec_enabled &&
                    (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) &&
                    vp8dx_bool_error(xd->current_bc))
                {
                    /* We have an intra block with corrupt coefficients, better
                     * to conceal with an inter block. Interpolate MVs from
                     * neighboring MBs
                     *
                     * Note that for the first mb with corrupt residual in a
                     * frame, we might not discover that before decoding the
                     * residual. That happens after this check, and therefore no
                     * inter concealment will be done.
                     */
                    vp8_interpolate_motion(xd,
                                           mb_row, mb_col,
                                           pc->mb_rows, pc->mb_cols,
                                           pc->mode_info_stride);
                }
#endif


846 847 848 849 850 851
                xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
                xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
                xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;

                xd->left_available = (mb_col != 0);

852
                /* Select the appropriate reference frame for this MB */
853
                if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
854
                    ref_fb_idx = pc->lst_fb_idx;
855
                else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
856 857 858 859 860 861 862 863
                    ref_fb_idx = pc->gld_fb_idx;
                else
                    ref_fb_idx = pc->alt_fb_idx;

                xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
                xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
                xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;

864 865 866 867 868 869
                if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME)
                {
                    /* propagate errors from reference frames */
                    xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
                }

870
                vp8_build_uvmvs(xd, pc->full_pixel);
871
                decode_macroblock(pbi, xd, mb_row, mb_col);
872

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

876 877
                if (pbi->common.filter_level)
                {
878
                    int skip_lf;
879
                    /* Save decoded MB last row data for next-row decoding */
880 881 882 883 884 885 886
                    if(mb_row != pc->mb_rows-1)
                    {
                        vpx_memcpy((pbi->mt_yabove_row[mb_row +1] + 32 + mb_col*16), (xd->dst.y_buffer + 15 * recon_y_stride), 16);
                        vpx_memcpy((pbi->mt_uabove_row[mb_row +1] + 16 + mb_col*8), (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
                        vpx_memcpy((pbi->mt_vabove_row[mb_row +1] + 16 + mb_col*8), (xd->dst.v_buffer + 7 * recon_uv_stride), 8);
                    }

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

892
                        if (next->mbmi.ref_frame == INTRA_FRAME)
893 894 895 896 897 898 899 900 901 902 903
                        {
                            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];
                            }
                        }
                    }

Ralph Giles's avatar
Ralph Giles committed
904 905
                    /* update loopfilter info */
                    Segment = (alt_flt_enabled) ? xd->mode_info_context->mbmi.segment_id : 0;
906 907 908
                    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);
Ralph Giles's avatar
Ralph Giles committed
909 910 911 912 913