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; mb->gf_active_ptr = x->gf_active_ptr; vpx_memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts)); mbr_ei[i].totalrate = 0; mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1); 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; mb->src = * cpi->Source; mbd->pre = cm->yv12_fb[cm->lst_fb_idx]; mbd->dst = cm->yv12_fb[cm->new_fb_idx]; 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); mbd->left_context = &cm->left_context; mb->mvc = cm->fc.mvc; setup_mbby_copy(&mbr_ei[i].mb, x); mbd->fullpixel_mask = 0xffffffff; if(cm->full_pixel) mbd->fullpixel_mask = 0xfffffff8; } }
int vp8cx_create_encoder_threads(VP8_COMP *cpi) { const VP8_COMMON * cm = &cpi->common; cpi->b_multi_threaded = 0; cpi->encoding_thread_count = 0; cpi->b_lpf_running = 0; if (cm->processor_core_count > 1 && cpi->oxcf.multi_threaded > 1) { int ithread; int th_count = cpi->oxcf.multi_threaded - 1; int rc = 0; /* don't allocate more threads than cores available */ if (cpi->oxcf.multi_threaded > cm->processor_core_count) th_count = cm->processor_core_count - 1; /* 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 0; 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)); sem_init(&cpi->h_event_end_encoding, 0, 0); cpi->b_multi_threaded = 1; cpi->encoding_thread_count = th_count; /* printf("[VP8:] multi_threaded encoding is enabled with %d threads\n\n", (cpi->encoding_thread_count +1)); */ for (ithread = 0; ithread < th_count; ithread++) { ENCODETHREAD_DATA *ethd = &cpi->en_thread_data[ithread]; /* Setup block ptrs and offsets */ vp8_setup_block_ptrs(&cpi->mb_row_ei[ithread].mb); vp8_setup_block_dptrs(&cpi->mb_row_ei[ithread].mb.e_mbd); 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]; rc = pthread_create(&cpi->h_encoding_thread[ithread], 0, thread_encoding_proc, ethd); if(rc) break; } if(rc) { /* shutdown other threads */ cpi->b_multi_threaded = 0; for(--ithread; ithread >= 0; ithread--) { pthread_join(cpi->h_encoding_thread[ithread], 0); sem_destroy(&cpi->h_event_start_encoding[ithread]); } sem_destroy(&cpi->h_event_end_encoding); /* free thread related resources */ vpx_free(cpi->h_event_start_encoding); vpx_free(cpi->h_encoding_thread); vpx_free(cpi->mb_row_ei); vpx_free(cpi->en_thread_data); return -1; } { 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; rc = pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter, lpfthd); if(rc) { /* shutdown other threads */ cpi->b_multi_threaded = 0; for(--ithread; ithread >= 0; ithread--) { sem_post(&cpi->h_event_start_encoding[ithread]); pthread_join(cpi->h_encoding_thread[ithread], 0); sem_destroy(&cpi->h_event_start_encoding[ithread]); } sem_destroy(&cpi->h_event_end_encoding); sem_destroy(&cpi->h_event_end_lpf); sem_destroy(&cpi->h_event_start_lpf); /* free thread related resources */ vpx_free(cpi->h_event_start_encoding); vpx_free(cpi->h_encoding_thread); vpx_free(cpi->mb_row_ei); vpx_free(cpi->en_thread_data); return -2; } } } return 0; }
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 mb->gf_active_ptr = x->gf_active_ptr; mb->vector_range = 32; vpx_memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts)); mbr_ei[i].totalrate = 0; mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1); 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; mbd->pre = cm->yv12_fb[cm->lst_fb_idx]; mbd->dst = cm->yv12_fb[cm->new_fb_idx]; 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); mb->rddiv = cpi->RDDIV; mb->rdmult = cpi->RDMULT; mbd->left_context = &cm->left_context; mb->mvc = cm->fc.mvc; setup_mbby_copy(&mbr_ei[i].mb, x); } }