ethreading.c 21 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
 */

#include "onyx_int.h"
John Koleszar's avatar
John Koleszar committed
12 13 14
#include "vp8/common/threading.h"
#include "vp8/common/common.h"
#include "vp8/common/extend.h"
John Koleszar's avatar
John Koleszar committed
15

16 17
#if CONFIG_MULTITHREAD

Attila Nagy's avatar
Attila Nagy committed
18 19 20 21 22
extern int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
                                         TOKENEXTRA **t, int recon_yoffset,
                                         int recon_uvoffset);
extern int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x,
                                          TOKENEXTRA **t);
John Koleszar's avatar
John Koleszar committed
23 24 25 26
extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
extern void vp8_build_block_offsets(MACROBLOCK *x);
extern void vp8_setup_block_ptrs(MACROBLOCK *x);

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
extern void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);

static THREAD_FUNCTION loopfilter_thread(void *p_data)
{
    VP8_COMP *cpi = (VP8_COMP *)(((LPFTHREAD_DATA *)p_data)->ptr1);
    VP8_COMMON *cm = &cpi->common;

    while (1)
    {
        if (cpi->b_multi_threaded == 0)
            break;

        if (sem_wait(&cpi->h_event_start_lpf) == 0)
        {
            if (cpi->b_multi_threaded == FALSE) // we're shutting down
                break;

            loopfilter_frame(cpi, cm);

            sem_post(&cpi->h_event_end_lpf);
        }
    }

    return 0;
}

John Koleszar's avatar
John Koleszar committed
53 54 55 56
static
THREAD_FUNCTION thread_encoding_proc(void *p_data)
{
    int ithread = ((ENCODETHREAD_DATA *)p_data)->ithread;
Attila Nagy's avatar
Attila Nagy committed
57
    VP8_COMP *cpi = (VP8_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr1);
John Koleszar's avatar
John Koleszar committed
58
    MB_ROW_COMP *mbri = (MB_ROW_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr2);
59
    ENTROPY_CONTEXT_PLANES mb_row_left_context;
John Koleszar's avatar
John Koleszar committed
60

Attila Nagy's avatar
Attila Nagy committed
61
    const int nsync = cpi->mt_sync_range;
John Koleszar's avatar
John Koleszar committed
62 63 64 65 66 67 68 69
    //printf("Started thread %d\n", ithread);

    while (1)
    {
        if (cpi->b_multi_threaded == 0)
            break;

        //if(WaitForSingleObject(cpi->h_event_mbrencoding[ithread], INFINITE) == WAIT_OBJECT_0)
Attila Nagy's avatar
Attila Nagy committed
70
        if (sem_wait(&cpi->h_event_start_encoding[ithread]) == 0)
John Koleszar's avatar
John Koleszar committed
71
        {
Attila Nagy's avatar
Attila Nagy committed
72 73 74 75 76 77 78 79 80
            VP8_COMMON *cm = &cpi->common;
            int mb_row;
            MACROBLOCK *x = &mbri->mb;
            MACROBLOCKD *xd = &x->e_mbd;
            TOKENEXTRA *tp ;

            int *segment_counts = mbri->segment_counts;
            int *totalrate = &mbri->totalrate;

John Koleszar's avatar
John Koleszar committed
81 82
            if (cpi->b_multi_threaded == FALSE) // we're shutting down
                break;
Attila Nagy's avatar
Attila Nagy committed
83 84

            for (mb_row = ithread + 1; mb_row < cm->mb_rows; mb_row += (cpi->encoding_thread_count + 1))
John Koleszar's avatar
John Koleszar committed
85 86
            {

Attila Nagy's avatar
Attila Nagy committed
87 88 89 90 91 92 93 94 95
                int i;
                int recon_yoffset, recon_uvoffset;
                int mb_col;
                int ref_fb_idx = cm->lst_fb_idx;
                int dst_fb_idx = cm->new_fb_idx;
                int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
                int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
                volatile int *last_row_current_mb_col;
                INT64 activity_sum = 0;
John Koleszar's avatar
John Koleszar committed
96

Attila Nagy's avatar
Attila Nagy committed
97
                tp = cpi->tok + (mb_row * (cm->mb_cols * 16 * 24));
John Koleszar's avatar
John Koleszar committed
98

Attila Nagy's avatar
Attila Nagy committed
99
                last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1];
John Koleszar's avatar
John Koleszar committed
100

Attila Nagy's avatar
Attila Nagy committed
101 102 103
                // reset above block coeffs
                xd->above_context = cm->above_context;
                xd->left_context = &mb_row_left_context;
John Koleszar's avatar
John Koleszar committed
104

Attila Nagy's avatar
Attila Nagy committed
105
                vp8_zero(mb_row_left_context);
John Koleszar's avatar
John Koleszar committed
106

Attila Nagy's avatar
Attila Nagy committed
107 108 109
                xd->up_available = (mb_row != 0);
                recon_yoffset = (mb_row * recon_y_stride * 16);
                recon_uvoffset = (mb_row * recon_uv_stride * 8);
John Koleszar's avatar
John Koleszar committed
110

Attila Nagy's avatar
Attila Nagy committed
111
                cpi->tplist[mb_row].start = tp;
John Koleszar's avatar
John Koleszar committed
112

Attila Nagy's avatar
Attila Nagy committed
113
                //printf("Thread mb_row = %d\n", mb_row);
John Koleszar's avatar
John Koleszar committed
114

Attila Nagy's avatar
Attila Nagy committed
115 116 117 118 119 120 121 122
                // for each macroblock col in image
                for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
                {
                    int seg_map_index = (mb_row * cm->mb_cols);

                    if ((mb_col & (nsync - 1)) == 0)
                    {
                        while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != cm->mb_cols - 1)
John Koleszar's avatar
John Koleszar committed
123 124 125 126
                        {
                            x86_pause_hint();
                            thread_sleep(0);
                        }
Attila Nagy's avatar
Attila Nagy committed
127
                    }
John Koleszar's avatar
John Koleszar committed
128

Attila Nagy's avatar
Attila Nagy committed
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
                    // Distance of Mb to the various image edges.
                    // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
                    xd->mb_to_left_edge = -((mb_col * 16) << 3);
                    xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
                    xd->mb_to_top_edge = -((mb_row * 16) << 3);
                    xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;

                    // Set up limit values for motion vectors used to prevent them extending outside the UMV borders
                    x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
                    x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
                    x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
                    x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);

                    xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
                    xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
                    xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
                    xd->left_available = (mb_col != 0);

                    x->rddiv = cpi->RDDIV;
                    x->rdmult = cpi->RDMULT;

                    if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
                        activity_sum += vp8_activity_masking(cpi, x);

                    // Is segmentation enabled
                    // MB level adjutment to quantizer
                    if (xd->segmentation_enabled)
                    {
                        // Code to set segment id in xd->mbmi.segment_id for current MB (with range checking)
                        if (cpi->segmentation_map[seg_map_index + mb_col] <= 3)
                            xd->mode_info_context->mbmi.segment_id = cpi->segmentation_map[seg_map_index + mb_col];
John Koleszar's avatar
John Koleszar committed
160
                        else
Attila Nagy's avatar
Attila Nagy committed
161
                            xd->mode_info_context->mbmi.segment_id = 0;
John Koleszar's avatar
John Koleszar committed
162

Attila Nagy's avatar
Attila Nagy committed
163 164 165 166
                        vp8cx_mb_init_quantizer(cpi, x);
                    }
                    else
                        xd->mode_info_context->mbmi.segment_id = 0; // Set to Segment 0 by default
John Koleszar's avatar
John Koleszar committed
167

Attila Nagy's avatar
Attila Nagy committed
168 169 170 171 172
                    x->active_ptr = cpi->active_map + seg_map_index + mb_col;

                    if (cm->frame_type == KEY_FRAME)
                    {
                        *totalrate += vp8cx_encode_intra_macro_block(cpi, x, &tp);
John Koleszar's avatar
John Koleszar committed
173
#ifdef MODE_STATS
Attila Nagy's avatar
Attila Nagy committed
174
                        y_modes[xd->mbmi.mode] ++;
John Koleszar's avatar
John Koleszar committed
175
#endif
Attila Nagy's avatar
Attila Nagy committed
176 177 178 179
                    }
                    else
                    {
                        *totalrate += vp8cx_encode_inter_macroblock(cpi, x, &tp, recon_yoffset, recon_uvoffset);
John Koleszar's avatar
John Koleszar committed
180 181

#ifdef MODE_STATS
Attila Nagy's avatar
Attila Nagy committed
182
                        inter_y_modes[xd->mbmi.mode] ++;
John Koleszar's avatar
John Koleszar committed
183

Attila Nagy's avatar
Attila Nagy committed
184 185 186
                        if (xd->mbmi.mode == SPLITMV)
                        {
                            int b;
John Koleszar's avatar
John Koleszar committed
187

Attila Nagy's avatar
Attila Nagy committed
188 189 190
                            for (b = 0; b < xd->mbmi.partition_count; b++)
                            {
                                inter_b_modes[x->partition->bmi[b].mode] ++;
John Koleszar's avatar
John Koleszar committed
191
                            }
Attila Nagy's avatar
Attila Nagy committed
192
                        }
John Koleszar's avatar
John Koleszar committed
193 194 195

#endif

Attila Nagy's avatar
Attila Nagy committed
196 197 198
                        // Count of last ref frame 0,0 useage
                        if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
                            cpi->inter_zz_count++;
John Koleszar's avatar
John Koleszar committed
199

Attila Nagy's avatar
Attila Nagy committed
200 201 202 203 204 205 206 207 208 209 210 211 212 213
                        // Special case code for cyclic refresh
                        // If cyclic update enabled then copy xd->mbmi.segment_id; (which may have been updated based on mode
                        // during vp8cx_encode_inter_macroblock()) back into the global sgmentation map
                        if (cpi->cyclic_refresh_mode_enabled && xd->segmentation_enabled)
                        {
                            const MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
                            cpi->segmentation_map[seg_map_index + mb_col] = mbmi->segment_id;

                            // If the block has been refreshed mark it as clean (the magnitude of the -ve influences how long it will be before we consider another refresh):
                            // Else if it was coded (last frame 0,0) and has not already been refreshed then mark it as a candidate for cleanup next time (marked 0)
                            // else mark it as dirty (1).
                            if (mbmi->segment_id)
                                cpi->cyclic_refresh_map[seg_map_index + mb_col] = -1;
                            else if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame == LAST_FRAME))
214
                            {
Attila Nagy's avatar
Attila Nagy committed
215 216
                                if (cpi->cyclic_refresh_map[seg_map_index + mb_col] == 1)
                                    cpi->cyclic_refresh_map[seg_map_index + mb_col] = 0;
217
                            }
Attila Nagy's avatar
Attila Nagy committed
218 219
                            else
                                cpi->cyclic_refresh_map[seg_map_index + mb_col] = 1;
John Koleszar's avatar
John Koleszar committed
220

Attila Nagy's avatar
Attila Nagy committed
221 222 223
                        }
                    }
                    cpi->tplist[mb_row].stop = tp;
John Koleszar's avatar
John Koleszar committed
224

Attila Nagy's avatar
Attila Nagy committed
225
                    x->gf_active_ptr++; // Increment pointer into gf useage flags structure for next mb
John Koleszar's avatar
John Koleszar committed
226

Attila Nagy's avatar
Attila Nagy committed
227 228
                    for (i = 0; i < 16; i++)
                        vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi));
John Koleszar's avatar
John Koleszar committed
229

Attila Nagy's avatar
Attila Nagy committed
230 231 232 233
                    // adjust to the next column of macroblocks
                    x->src.y_buffer += 16;
                    x->src.u_buffer += 8;
                    x->src.v_buffer += 8;
John Koleszar's avatar
John Koleszar committed
234

Attila Nagy's avatar
Attila Nagy committed
235 236
                    recon_yoffset += 16;
                    recon_uvoffset += 8;
John Koleszar's avatar
John Koleszar committed
237

Attila Nagy's avatar
Attila Nagy committed
238 239
                    // Keep track of segment useage
                    segment_counts[xd->mode_info_context->mbmi.segment_id]++;
John Koleszar's avatar
John Koleszar committed
240

Attila Nagy's avatar
Attila Nagy committed
241
                    // skip to next mb
John Koleszar's avatar
John Koleszar committed
242
                    xd->mode_info_context++;
243
                    x->partition_info++;
Attila Nagy's avatar
Attila Nagy committed
244
                    xd->above_context++;
John Koleszar's avatar
John Koleszar committed
245

Attila Nagy's avatar
Attila Nagy committed
246 247
                    cpi->mt_current_mb_col[mb_row] = mb_col;
                }
John Koleszar's avatar
John Koleszar committed
248

Attila Nagy's avatar
Attila Nagy committed
249 250 251 252 253 254
                //extend the recon for intra prediction
                vp8_extend_mb_row(
                    &cm->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
255

Attila Nagy's avatar
Attila Nagy committed
256 257 258 259
                // this is to account for the border
                xd->mode_info_context++;
                x->partition_info++;
                x->activity_sum += activity_sum;
John Koleszar's avatar
John Koleszar committed
260

Attila Nagy's avatar
Attila Nagy committed
261 262 263
                x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
                x->src.u_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
                x->src.v_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
John Koleszar's avatar
John Koleszar committed
264

Attila Nagy's avatar
Attila Nagy committed
265 266 267 268 269 270 271 272
                xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count;
                x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count;

                if (mb_row == cm->mb_rows - 1)
                {
                    //SetEvent(cpi->h_event_main);
                    sem_post(&cpi->h_event_end_encoding); /* signal frame encoding end */
                }
John Koleszar's avatar
John Koleszar committed
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
            }
        }
    }

    //printf("exit thread %d\n", ithread);
    return 0;
}

static void setup_mbby_copy(MACROBLOCK *mbdst, MACROBLOCK *mbsrc)
{

    MACROBLOCK *x = mbsrc;
    MACROBLOCK *z = mbdst;
    int i;

    z->ss               = x->ss;
    z->ss_count          = x->ss_count;
    z->searches_per_step  = x->searches_per_step;
    z->errorperbit      = x->errorperbit;

    z->sadperbit16      = x->sadperbit16;
    z->sadperbit4       = x->sadperbit4;
    z->errthresh        = x->errthresh;

    /*
    z->mv_col_min    = x->mv_col_min;
    z->mv_col_max    = x->mv_col_max;
    z->mv_row_min    = x->mv_row_min;
    z->mv_row_max    = x->mv_row_max;
    z->vector_range = x->vector_range ;
    */

    z->vp8_short_fdct4x4     = x->vp8_short_fdct4x4;
    z->vp8_short_fdct8x4     = x->vp8_short_fdct8x4;
    z->short_walsh4x4    = x->short_walsh4x4;
    z->quantize_b        = x->quantize_b;
309
    z->optimize          = x->optimize;
John Koleszar's avatar
John Koleszar committed
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336

    /*
    z->mvc              = x->mvc;
    z->src.y_buffer      = x->src.y_buffer;
    z->src.u_buffer      = x->src.u_buffer;
    z->src.v_buffer      = x->src.v_buffer;
    */


    vpx_memcpy(z->mvcosts,          x->mvcosts,         sizeof(x->mvcosts));
    z->mvcost[0] = &z->mvcosts[0][mv_max+1];
    z->mvcost[1] = &z->mvcosts[1][mv_max+1];
    z->mvsadcost[0] = &z->mvsadcosts[0][mv_max+1];
    z->mvsadcost[1] = &z->mvsadcosts[1][mv_max+1];


    vpx_memcpy(z->token_costs,       x->token_costs,      sizeof(x->token_costs));
    vpx_memcpy(z->inter_bmode_costs,  x->inter_bmode_costs, sizeof(x->inter_bmode_costs));
    //memcpy(z->mvcosts,            x->mvcosts,         sizeof(x->mvcosts));
    //memcpy(z->mvcost,         x->mvcost,          sizeof(x->mvcost));
    vpx_memcpy(z->mbmode_cost,       x->mbmode_cost,      sizeof(x->mbmode_cost));
    vpx_memcpy(z->intra_uv_mode_cost,  x->intra_uv_mode_cost, sizeof(x->intra_uv_mode_cost));
    vpx_memcpy(z->bmode_costs,       x->bmode_costs,      sizeof(x->bmode_costs));

    for (i = 0; i < 25; i++)
    {
        z->block[i].quant           = x->block[i].quant;
337
        z->block[i].quant_fast      = x->block[i].quant_fast;
338
        z->block[i].quant_shift     = x->block[i].quant_shift;
John Koleszar's avatar
John Koleszar committed
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
        z->block[i].zbin            = x->block[i].zbin;
        z->block[i].zrun_zbin_boost   = x->block[i].zrun_zbin_boost;
        z->block[i].round           = x->block[i].round;
        /*
        z->block[i].src             = x->block[i].src;
        */
        z->block[i].src_stride       = x->block[i].src_stride;
        z->block[i].force_empty      = x->block[i].force_empty;

    }

    {
        MACROBLOCKD *xd = &x->e_mbd;
        MACROBLOCKD *zd = &z->e_mbd;

        /*
        zd->mode_info_context = xd->mode_info_context;
        zd->mode_info        = xd->mode_info;

        zd->mode_info_stride  = xd->mode_info_stride;
        zd->frame_type       = xd->frame_type;
        zd->up_available     = xd->up_available   ;
        zd->left_available   = xd->left_available;
        zd->left_context     = xd->left_context;
        zd->last_frame_dc     = xd->last_frame_dc;
        zd->last_frame_dccons = xd->last_frame_dccons;
        zd->gold_frame_dc     = xd->gold_frame_dc;
        zd->gold_frame_dccons = xd->gold_frame_dccons;
        zd->mb_to_left_edge    = xd->mb_to_left_edge;
        zd->mb_to_right_edge   = xd->mb_to_right_edge;
        zd->mb_to_top_edge     = xd->mb_to_top_edge   ;
        zd->mb_to_bottom_edge  = xd->mb_to_bottom_edge;
        zd->gf_active_ptr     = xd->gf_active_ptr;
        zd->frames_since_golden       = xd->frames_since_golden;
        zd->frames_till_alt_ref_frame   = xd->frames_till_alt_ref_frame;
        */
        zd->subpixel_predict         = xd->subpixel_predict;
        zd->subpixel_predict8x4      = xd->subpixel_predict8x4;
        zd->subpixel_predict8x8      = xd->subpixel_predict8x8;
        zd->subpixel_predict16x16    = xd->subpixel_predict16x16;
        zd->segmentation_enabled     = xd->segmentation_enabled;
        zd->mb_segement_abs_delta      = xd->mb_segement_abs_delta;
        vpx_memcpy(zd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));

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

void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
                               MACROBLOCK *x,
                               MB_ROW_COMP *mbr_ei,
                               int mb_row,
                               int count
                              )
{

    VP8_COMMON *const cm = & cpi->common;
    MACROBLOCKD *const xd = & x->e_mbd;
    int i;
    (void) mb_row;

    for (i = 0; i < count; i++)
    {
        MACROBLOCK *mb = & mbr_ei[i].mb;
        MACROBLOCKD *mbd = &mb->e_mbd;

        mbd->subpixel_predict        = xd->subpixel_predict;
        mbd->subpixel_predict8x4     = xd->subpixel_predict8x4;
        mbd->subpixel_predict8x8     = xd->subpixel_predict8x8;
        mbd->subpixel_predict16x16   = xd->subpixel_predict16x16;
#if CONFIG_RUNTIME_CPU_DETECT
        mbd->rtcd                   = xd->rtcd;
#endif
415
        mb->gf_active_ptr            = x->gf_active_ptr;
John Koleszar's avatar
John Koleszar committed
416 417 418 419 420 421

        mb->vector_range             = 32;

        vpx_memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts));
        mbr_ei[i].totalrate = 0;

422 423
        mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1);

John Koleszar's avatar
John Koleszar committed
424 425 426 427 428 429 430 431 432
        mbd->mode_info_context = cm->mi   + x->e_mbd.mode_info_stride * (i + 1);
        mbd->mode_info_stride  = cm->mode_info_stride;

        mbd->frame_type = cm->frame_type;

        mbd->frames_since_golden = cm->frames_since_golden;
        mbd->frames_till_alt_ref_frame = cm->frames_till_alt_ref_frame;

        mb->src = * cpi->Source;
433 434
        mbd->pre = cm->yv12_fb[cm->lst_fb_idx];
        mbd->dst = cm->yv12_fb[cm->new_fb_idx];
John Koleszar's avatar
John Koleszar committed
435 436 437 438 439 440 441 442 443 444 445

        mb->src.y_buffer += 16 * x->src.y_stride * (i + 1);
        mb->src.u_buffer +=  8 * x->src.uv_stride * (i + 1);
        mb->src.v_buffer +=  8 * x->src.uv_stride * (i + 1);

        vp8_build_block_offsets(mb);

        vp8_setup_block_dptrs(mbd);

        vp8_setup_block_ptrs(mb);

446
        mb->activity_sum = 0;
John Koleszar's avatar
John Koleszar committed
447

448
        mbd->left_context = &cm->left_context;
John Koleszar's avatar
John Koleszar committed
449 450 451 452 453 454 455 456 457
        mb->mvc = cm->fc.mvc;

        setup_mbby_copy(&mbr_ei[i].mb, x);

    }
}

void vp8cx_create_encoder_threads(VP8_COMP *cpi)
{
458
    const VP8_COMMON * cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
459

460 461
    cpi->b_multi_threaded = 0;
    cpi->encoding_thread_count = 0;
John Koleszar's avatar
John Koleszar committed
462

463
    if (cm->processor_core_count > 1 && cpi->oxcf.multi_threaded > 1)
John Koleszar's avatar
John Koleszar committed
464 465
    {
        int ithread;
466
        int th_count = cpi->oxcf.multi_threaded - 1;
John Koleszar's avatar
John Koleszar committed
467

468 469 470
        /* don't allocate more threads than cores available */
        if (cpi->oxcf.multi_threaded > cm->processor_core_count)
            th_count = cm->processor_core_count - 1;
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490

        /* we have th_count + 1 (main) threads processing one row each */
        /* no point to have more threads than the sync range allows */
        if(th_count > ((cm->mb_cols / cpi->mt_sync_range) - 1))
        {
            th_count = (cm->mb_cols / cpi->mt_sync_range) - 1;
        }

        if(th_count == 0)
            return;

        CHECK_MEM_ERROR(cpi->h_encoding_thread, vpx_malloc(sizeof(pthread_t) * th_count));
        CHECK_MEM_ERROR(cpi->h_event_start_encoding, vpx_malloc(sizeof(sem_t) * th_count));
        CHECK_MEM_ERROR(cpi->mb_row_ei, vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count));
        vpx_memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * th_count);
        CHECK_MEM_ERROR(cpi->en_thread_data,
                        vpx_malloc(sizeof(ENCODETHREAD_DATA) * th_count));
        CHECK_MEM_ERROR(cpi->mt_current_mb_col,
                        vpx_malloc(sizeof(*cpi->mt_current_mb_col) * cm->mb_rows));

Attila Nagy's avatar
Attila Nagy committed
491
        sem_init(&cpi->h_event_end_encoding, 0, 0);
John Koleszar's avatar
John Koleszar committed
492 493

        cpi->b_multi_threaded = 1;
494
        cpi->encoding_thread_count = th_count;
John Koleszar's avatar
John Koleszar committed
495

496 497 498 499
        /*
        printf("[VP8:] multi_threaded encoding is enabled with %d threads\n\n",
               (cpi->encoding_thread_count +1));
        */
John Koleszar's avatar
John Koleszar committed
500

501
        for (ithread = 0; ithread < th_count; ithread++)
John Koleszar's avatar
John Koleszar committed
502
        {
Attila Nagy's avatar
Attila Nagy committed
503 504 505 506 507 508
            ENCODETHREAD_DATA * ethd = &cpi->en_thread_data[ithread];

            sem_init(&cpi->h_event_start_encoding[ithread], 0, 0);
            ethd->ithread = ithread;
            ethd->ptr1 = (void *)cpi;
            ethd->ptr2 = (void *)&cpi->mb_row_ei[ithread];
John Koleszar's avatar
John Koleszar committed
509

Attila Nagy's avatar
Attila Nagy committed
510
            pthread_create(&cpi->h_encoding_thread[ithread], 0, thread_encoding_proc, ethd);
John Koleszar's avatar
John Koleszar committed
511 512
        }

513 514 515 516 517 518 519 520 521
        {
            LPFTHREAD_DATA * lpfthd = &cpi->lpf_thread_data;

            sem_init(&cpi->h_event_start_lpf, 0, 0);
            sem_init(&cpi->h_event_end_lpf, 0, 0);

            lpfthd->ptr1 = (void *)cpi;
            pthread_create(&cpi->h_filter_thread, 0, loopfilter_thread, lpfthd);
        }
John Koleszar's avatar
John Koleszar committed
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
    }

}

void vp8cx_remove_encoder_threads(VP8_COMP *cpi)
{
    if (cpi->b_multi_threaded)
    {
        //shutdown other threads
        cpi->b_multi_threaded = 0;
        {
            int i;

            for (i = 0; i < cpi->encoding_thread_count; i++)
            {
                //SetEvent(cpi->h_event_mbrencoding[i]);
Attila Nagy's avatar
Attila Nagy committed
538
                sem_post(&cpi->h_event_start_encoding[i]);
John Koleszar's avatar
John Koleszar committed
539 540
                pthread_join(cpi->h_encoding_thread[i], 0);

Attila Nagy's avatar
Attila Nagy committed
541 542
                sem_destroy(&cpi->h_event_start_encoding[i]);
            }
543 544 545

            sem_post(&cpi->h_event_start_lpf);
            pthread_join(cpi->h_filter_thread, 0);
John Koleszar's avatar
John Koleszar committed
546
        }
Attila Nagy's avatar
Attila Nagy committed
547 548

        sem_destroy(&cpi->h_event_end_encoding);
549 550
        sem_destroy(&cpi->h_event_end_lpf);
        sem_destroy(&cpi->h_event_start_lpf);
Attila Nagy's avatar
Attila Nagy committed
551

John Koleszar's avatar
John Koleszar committed
552
        //free thread related resources
Attila Nagy's avatar
Attila Nagy committed
553
        vpx_free(cpi->h_event_start_encoding);
John Koleszar's avatar
John Koleszar committed
554 555 556
        vpx_free(cpi->h_encoding_thread);
        vpx_free(cpi->mb_row_ei);
        vpx_free(cpi->en_thread_data);
Attila Nagy's avatar
Attila Nagy committed
557
        vpx_free(cpi->mt_current_mb_col);
John Koleszar's avatar
John Koleszar committed
558 559
    }
}
560
#endif