void vp8_fix_contexts(MACROBLOCKD *x) { /* Clear entropy contexts for Y2 blocks */ if (x->mode_info_context->mbmi.mode != B_PRED && x->mode_info_context->mbmi.mode != SPLITMV) { vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); } else { vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1); vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1); } }
void vp8_dequant_idct_add_y_block_mmx (short *q, short *dq, unsigned char *dst, int stride, char *eobs) { int i; for (i = 0; i < 4; i++) { if (eobs[0] > 1) vp8_dequant_idct_add_mmx (q, dq, dst, stride); else if (eobs[0] == 1) { vp8_dc_only_idct_add_mmx (q[0]*dq[0], dst, stride, dst, stride); vpx_memset(q, 0, 2 * sizeof(q[0])); } if (eobs[1] > 1) vp8_dequant_idct_add_mmx (q+16, dq, dst+4, stride); else if (eobs[1] == 1) { vp8_dc_only_idct_add_mmx (q[16]*dq[0], dst+4, stride, dst+4, stride); vpx_memset(q + 16, 0, 2 * sizeof(q[0])); } if (eobs[2] > 1) vp8_dequant_idct_add_mmx (q+32, dq, dst+8, stride); else if (eobs[2] == 1) { vp8_dc_only_idct_add_mmx (q[32]*dq[0], dst+8, stride, dst+8, stride); vpx_memset(q + 32, 0, 2 * sizeof(q[0])); } if (eobs[3] > 1) vp8_dequant_idct_add_mmx (q+48, dq, dst+12, stride); else if (eobs[3] == 1) { vp8_dc_only_idct_add_mmx (q[48]*dq[0], dst+12, stride, dst+12, stride); vpx_memset(q + 48, 0, 2 * sizeof(q[0])); } q += 64; dst += 4*stride; eobs += 4; } }
void vp9_transform_mby_4x4(MACROBLOCK *x) { int i; MACROBLOCKD *xd = &x->e_mbd; int has_2nd_order = get_2nd_order_usage(xd); for (i = 0; i < 16; i++) { BLOCK *b = &x->block[i]; TX_TYPE tx_type = get_tx_type_4x4(xd, &xd->block[i]); if (tx_type != DCT_DCT) { assert(has_2nd_order == 0); vp9_fht_c(b->src_diff, 32, b->coeff, tx_type, 4); } else { x->vp9_short_fdct4x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32); } } if (has_2nd_order) { // build dc block from 16 y dc values build_dcblock_4x4(x); // do 2nd order transform on the dc block x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8); } else { vpx_memset(x->block[24].coeff, 0, 16 * sizeof(x->block[24].coeff[0])); } }
// Based on set of segment counts calculate a probability tree static void calc_segtree_probs(MACROBLOCKD *xd, int *segcounts, vp9_prob *segment_tree_probs) { int count1, count2; int tot_count; int i; // Blank the strtucture to start with vpx_memset(segment_tree_probs, 0, MB_FEATURE_TREE_PROBS * sizeof(*segment_tree_probs)); // Total count for all segments count1 = segcounts[0] + segcounts[1]; count2 = segcounts[2] + segcounts[3]; tot_count = count1 + count2; // Work out probabilities of each segment if (tot_count) segment_tree_probs[0] = (count1 * 255) / tot_count; if (count1 > 0) segment_tree_probs[1] = (segcounts[0] * 255) / count1; if (count2 > 0) segment_tree_probs[2] = (segcounts[2] * 255) / count2; // Clamp probabilities to minimum allowed value for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) { if (segment_tree_probs[i] == 0) segment_tree_probs[i] = 1; } }
void vp9_create_encoding_threads(VP9_COMP *cpi) { VP9_COMMON * const cm = &cpi->common; const VP9WorkerInterface * const winterface = vp9_get_worker_interface(); int i; CHECK_MEM_ERROR(cm, cpi->enc_thread_hndl, vpx_malloc(sizeof(*cpi->enc_thread_hndl) * cpi->max_threads)); for (i = 0; i < cpi->max_threads; ++i) { VP9Worker * const worker = &cpi->enc_thread_hndl[i]; winterface->init(worker); CHECK_MEM_ERROR(cm, worker->data1, vpx_memalign(32, sizeof(thread_context))); worker->data2 = NULL; if (i < cpi->max_threads - 1 && !winterface->reset(worker)) { vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Tile decoder thread creation failed"); } } // set row encoding hook for (i = 0; i < cpi->max_threads; ++i) { winterface->sync(&cpi->enc_thread_hndl[i]); cpi->enc_thread_hndl[i].hook = (VP9WorkerHook) encoding_thread_process; } CHECK_MEM_ERROR(cm, cpi->cur_sb_col, vpx_malloc(sizeof(*cpi->cur_sb_col) * cm->sb_rows)); // init cur sb col vpx_memset(cpi->cur_sb_col, -1, (sizeof(*cpi->cur_sb_col) * cm->sb_rows)); // set up nsync (currently unused). cpi->sync_range = get_sync_range(cpi->oxcf.width); }
// VP9 Encoder: Implement multi-threaded loopfilter that uses the threads // used for encoding. void vp9e_loop_filter_frame_mt(VP9_COMP *cpi, int frame_filter_level, int y_only, int partial_frame) { VP9_COMMON *const cm = &cpi->common; const int sb_rows = cm->sb_rows; const int num_threads = cpi->max_threads; const VP9WorkerInterface *const winterface = vp9_get_worker_interface(); int thread_id; int start_mi_row = 0, end_mi_row, mi_rows_to_filter = cm->mi_rows; if (!frame_filter_level) return; // Initialize cur_sb_col to -1 for all SB rows. vpx_memset(cpi->cur_sb_col, -1, sizeof(*cpi->cur_sb_col) * sb_rows); if (partial_frame && cm->mi_rows > 8) { int i; start_mi_row = cm->mi_rows >> 1; start_mi_row &= 0xfffffff8; mi_rows_to_filter = MAX(cm->mi_rows / 8, 8); // Initialize cur_sb_col to sb_cols for top SB rows indicating // that deblocking is done. for (i = 0; i < start_mi_row >> MI_BLOCK_SIZE_LOG2; i++) cpi->cur_sb_col[i] = cm->sb_cols - 1; }
static void extend_plane(uint8_t *s, /* source */ int sp, /* source pitch */ int w, /* width */ int h, /* height */ int et, /* extend top border */ int el, /* extend left border */ int eb, /* extend bottom border */ int er) { /* extend right border */ int i; uint8_t *src_ptr1, *src_ptr2; uint8_t *dest_ptr1, *dest_ptr2; int linesize; /* copy the left and right most columns out */ src_ptr1 = s; src_ptr2 = s + w - 1; dest_ptr1 = s - el; dest_ptr2 = s + w; for (i = 0; i < h; i++) { vpx_memset(dest_ptr1, src_ptr1[0], el); vpx_memset(dest_ptr2, src_ptr2[0], er); src_ptr1 += sp; src_ptr2 += sp; dest_ptr1 += sp; dest_ptr2 += sp; } /* Now copy the top and bottom lines into each line of the respective * borders */ src_ptr1 = s - el; src_ptr2 = s + sp * (h - 1) - el; dest_ptr1 = s + sp * (-et) - el; dest_ptr2 = s + sp * (h) - el; linesize = el + er + w; for (i = 0; i < et; i++) { vpx_memcpy(dest_ptr1, src_ptr1, linesize); dest_ptr1 += sp; } for (i = 0; i < eb; i++) { vpx_memcpy(dest_ptr2, src_ptr2, linesize); dest_ptr2 += sp; } }
static void loop_filter_rows_mt(YV12_BUFFER_CONFIG *frame, VP9_COMMON *cm, struct macroblockd_plane planes[MAX_MB_PLANE], int start, int stop, int y_only, VP9Worker *workers, int nworkers, VP9LfSync *lf_sync) { const VP9WorkerInterface *const winterface = vp9_get_worker_interface(); // Number of superblock rows and cols const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; // Decoder may allocate more threads than number of tiles based on user's // input. const int tile_cols = 1 << cm->log2_tile_cols; const int num_workers = MIN(nworkers, tile_cols); int i; if (!lf_sync->sync_range || sb_rows != lf_sync->rows || num_workers > lf_sync->num_workers) { vp9_loop_filter_dealloc(lf_sync); vp9_loop_filter_alloc(lf_sync, cm, sb_rows, cm->width, num_workers); } // Initialize cur_sb_col to -1 for all SB rows. vpx_memset(lf_sync->cur_sb_col, -1, sizeof(*lf_sync->cur_sb_col) * sb_rows); // Set up loopfilter thread data. // The decoder is capping num_workers because it has been observed that using // more threads on the loopfilter than there are cores will hurt performance // on Android. This is because the system will only schedule the tile decode // workers on cores equal to the number of tile columns. Then if the decoder // tries to use more threads for the loopfilter, it will hurt performance // because of contention. If the multithreading code changes in the future // then the number of workers used by the loopfilter should be revisited. for (i = 0; i < num_workers; ++i) { VP9Worker *const worker = &workers[i]; LFWorkerData *const lf_data = &lf_sync->lfdata[i]; worker->hook = (VP9WorkerHook)loop_filter_row_worker; worker->data1 = lf_sync; worker->data2 = lf_data; // Loopfilter data vp9_loop_filter_data_reset(lf_data, frame, cm, planes); lf_data->start = start + i * MI_BLOCK_SIZE; lf_data->stop = stop; lf_data->y_only = y_only; // Start loopfiltering if (i == num_workers - 1) { winterface->execute(worker); } else { winterface->launch(worker); } } // Wait till all rows are finished for (i = 0; i < num_workers; ++i) { winterface->sync(&workers[i]); } }
static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block, BLOCK_SIZE plane_bsize, TX_SIZE tx_size) { struct macroblockd_plane *const pd = &xd->plane[plane]; int16_t* const qcoeff = BLOCK_OFFSET(pd->qcoeff, block); const int stride = pd->dst.stride; const int eob = pd->eobs[block]; if (eob > 0) { TX_TYPE tx_type; const int raster_block = txfrm_block_to_raster_block(plane_bsize, tx_size, block); uint8_t* const dst = raster_block_offset_uint8(plane_bsize, raster_block, pd->dst.buf, stride); switch (tx_size) { case TX_4X4: tx_type = get_tx_type_4x4(pd->plane_type, xd, raster_block); if (tx_type == DCT_DCT) xd->itxm_add(qcoeff, dst, stride, eob); else vp9_iht4x4_add(tx_type, qcoeff, dst, stride, eob); break; case TX_8X8: tx_type = get_tx_type_8x8(pd->plane_type, xd); vp9_iht8x8_add(tx_type, qcoeff, dst, stride, eob); break; case TX_16X16: tx_type = get_tx_type_16x16(pd->plane_type, xd); vp9_iht16x16_add(tx_type, qcoeff, dst, stride, eob); break; case TX_32X32: tx_type = DCT_DCT; vp9_idct32x32_add(qcoeff, dst, stride, eob); break; default: assert(!"Invalid transform size"); } if (eob == 1) { vpx_memset(qcoeff, 0, 2 * sizeof(qcoeff[0])); } else { if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10) vpx_memset(qcoeff, 0, 4 * (4 << tx_size) * sizeof(qcoeff[0])); else vpx_memset(qcoeff, 0, (16 << (tx_size << 1)) * sizeof(qcoeff[0])); } } }
void vp9_setup_past_independence(VP9_COMMON *cm) { // Reset the segment feature data to the default stats: // Features disabled, 0, with delta coding (Default state). struct loopfilter *const lf = &cm->lf; int i; vp9_clearall_segfeatures(&cm->seg); cm->seg.abs_delta = SEGMENT_DELTADATA; if (cm->last_frame_seg_map) vpx_memset(cm->last_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols)); // Reset the mode ref deltas for loop filter vp9_zero(lf->last_ref_deltas); vp9_zero(lf->last_mode_deltas); set_default_lf_deltas(lf); // To force update of the sharpness lf->last_sharpness_level = -1; vp9_default_coef_probs(cm); vp9_init_mbmode_probs(cm); vp9_init_mv_probs(cm); vp9_copy(cm->fc.inter_mode_probs, default_inter_mode_probs); if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode || cm->reset_frame_context == 3) { // Reset all frame contexts. for (i = 0; i < NUM_FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = cm->fc; } else if (cm->reset_frame_context == 2) { // Reset only the frame context specified in the frame header. cm->frame_contexts[cm->frame_context_idx] = cm->fc; } vpx_memset(cm->prev_mip, 0, cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); vpx_memset(cm->mip, 0, cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); vp9_update_mode_info_border(cm, cm->mip); vp9_update_mode_info_border(cm, cm->prev_mip); vp9_zero(cm->ref_frame_sign_bias); cm->frame_context_idx = 0; }
void vp8cx_create_encoder_threads(VP8_COMP *cpi) { cpi->b_multi_threaded = 0; cpi->processor_core_count = 32; //vp8_get_proc_core_count(); CHECK_MEM_ERROR(cpi->tplist, vpx_malloc(sizeof(TOKENLIST) * cpi->common.mb_rows)); #if CONFIG_MULTITHREAD if (cpi->processor_core_count > 1 && cpi->oxcf.multi_threaded > 1) { int ithread; if (cpi->oxcf.multi_threaded > cpi->processor_core_count) cpi->encoding_thread_count = cpi->processor_core_count - 1; else cpi->encoding_thread_count = cpi->oxcf.multi_threaded - 1; CHECK_MEM_ERROR(cpi->h_encoding_thread, vpx_malloc(sizeof(pthread_t) * cpi->encoding_thread_count)); CHECK_MEM_ERROR(cpi->h_event_mbrencoding, vpx_malloc(sizeof(sem_t) * cpi->encoding_thread_count)); CHECK_MEM_ERROR(cpi->mb_row_ei, vpx_memalign(32, sizeof(MB_ROW_COMP) * cpi->encoding_thread_count)); vpx_memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * cpi->encoding_thread_count); CHECK_MEM_ERROR(cpi->en_thread_data, vpx_malloc(sizeof(ENCODETHREAD_DATA) * cpi->encoding_thread_count)); //cpi->h_event_main = CreateEvent(NULL, FALSE, FALSE, NULL); sem_init(&cpi->h_event_main, 0, 0); cpi->b_multi_threaded = 1; //printf("[VP8:] multi_threaded encoding is enabled with %d threads\n\n", (cpi->encoding_thread_count +1)); for (ithread = 0; ithread < cpi->encoding_thread_count; ithread++) { //cpi->h_event_mbrencoding[ithread] = CreateEvent(NULL, FALSE, FALSE, NULL); sem_init(&cpi->h_event_mbrencoding[ithread], 0, 0); cpi->en_thread_data[ithread].ithread = ithread; cpi->en_thread_data[ithread].ptr1 = (void *)cpi; cpi->en_thread_data[ithread].ptr2 = (void *)&cpi->mb_row_ei[ithread]; //printf(" call begin thread %d \n", ithread); //cpi->h_encoding_thread[ithread] = (HANDLE)_beginthreadex( // NULL, // security // 0, // stksize // thread_encoding_proc, // (&cpi->en_thread_data[ithread]), // Thread data // 0, // NULL); pthread_create(&cpi->h_encoding_thread[ithread], 0, thread_encoding_proc, (&cpi->en_thread_data[ithread])); } } #endif }
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; } }
static int update_fragments(vpx_codec_alg_priv_t *ctx, const uint8_t *data, unsigned int data_sz, vpx_codec_err_t *res) { *res = VPX_CODEC_OK; if (ctx->fragments.count == 0) { /* New frame, reset fragment pointers and sizes */ vpx_memset((void*)ctx->fragments.ptrs, 0, sizeof(ctx->fragments.ptrs)); vpx_memset(ctx->fragments.sizes, 0, sizeof(ctx->fragments.sizes)); } if (ctx->fragments.enabled && !(data == NULL && data_sz == 0)) { /* Store a pointer to this fragment and return. We haven't * received the complete frame yet, so we will wait with decoding. */ ctx->fragments.ptrs[ctx->fragments.count] = data; ctx->fragments.sizes[ctx->fragments.count] = data_sz; ctx->fragments.count++; if (ctx->fragments.count > (1 << EIGHT_PARTITION) + 1) { ctx->fragments.count = 0; *res = VPX_CODEC_INVALID_PARAM; return -1; } return 0; } if (!ctx->fragments.enabled && (data == NULL && data_sz == 0)) { return 0; } if (!ctx->fragments.enabled) { ctx->fragments.ptrs[0] = data; ctx->fragments.sizes[0] = data_sz; ctx->fragments.count = 1; } return 1; }
void vp8_setup_intra_recon(YV12_BUFFER_CONFIG *ybf) { int i; /* set up frame new frame for intra coded blocks */ vpx_memset(ybf->y_buffer - 1 - ybf->y_stride, 127, ybf->y_width + 5); for (i = 0; i < ybf->y_height; i++) ybf->y_buffer[ybf->y_stride *i - 1] = (unsigned char) 129; vpx_memset(ybf->u_buffer - 1 - ybf->uv_stride, 127, ybf->uv_width + 5); for (i = 0; i < ybf->uv_height; i++) ybf->u_buffer[ybf->uv_stride *i - 1] = (unsigned char) 129; vpx_memset(ybf->v_buffer - 1 - ybf->uv_stride, 127, ybf->uv_width + 5); for (i = 0; i < ybf->uv_height; i++) ybf->v_buffer[ybf->uv_stride *i - 1] = (unsigned char) 129; }
void vp9_setup_key_frame(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; // Setup for Key frame: vp9_default_coef_probs(& cpi->common); vp9_kf_default_bmode_probs(cpi->common.kf_bmode_prob); vp9_init_mbmode_probs(& cpi->common); vp9_default_bmode_probs(cm->fc.bmode_prob); if(cm->last_frame_seg_map) vpx_memset(cm->last_frame_seg_map, 0, (cm->mb_rows * cm->mb_cols)); vp9_init_mv_probs(& cpi->common); // cpi->common.filter_level = 0; // Reset every key frame. cpi->common.filter_level = cpi->common.base_qindex * 3 / 8; // interval before next GF cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; cpi->common.refresh_golden_frame = TRUE; cpi->common.refresh_alt_ref_frame = TRUE; vp9_init_mode_contexts(&cpi->common); vpx_memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc)); vpx_memcpy(&cpi->common.lfc_a, &cpi->common.fc, sizeof(cpi->common.fc)); vpx_memset(cm->prev_mip, 0, (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO)); vpx_memset(cm->mip, 0, (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO)); vp9_update_mode_info_border(cm, cm->mip); vp9_update_mode_info_in_image(cm, cm->mi); #if CONFIG_NEW_MVREF if (1) { MACROBLOCKD *xd = &cpi->mb.e_mbd; // Defaults probabilities for encoding the MV ref id signal vpx_memset(xd->mb_mv_ref_probs, VP9_DEFAULT_MV_REF_PROB, sizeof(xd->mb_mv_ref_probs)); } #endif }
static struct VP8D_COMP * create_decompressor(VP8D_CONFIG *oxcf) { VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP)); if (!pbi) return NULL; vpx_memset(pbi, 0, sizeof(VP8D_COMP)); if (setjmp(pbi->common.error.jmp)) { pbi->common.error.setjmp = 0; remove_decompressor(pbi); return 0; } pbi->common.error.setjmp = 1; vp8_create_common(&pbi->common); pbi->common.current_video_frame = 0; pbi->ready_for_new_data = 1; /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid * unnecessary calling of vp8cx_init_de_quantizer() for every frame. */ vp8cx_init_de_quantizer(pbi); vp8_loop_filter_init(&pbi->common); pbi->common.error.setjmp = 0; #if CONFIG_ERROR_CONCEALMENT pbi->ec_enabled = oxcf->error_concealment; pbi->overlaps = NULL; #else pbi->ec_enabled = 0; #endif /* Error concealment is activated after a key frame has been * decoded without errors when error concealment is enabled. */ pbi->ec_active = 0; pbi->decoded_key_frame = 0; /* Independent partitions is activated when a frame updates the * token probability table to have equal probabilities over the * PREV_COEF context. */ pbi->independent_partitions = 0; vp8_setup_block_dptrs(&pbi->mb); return pbi; }
void vp8_dequant_idct_c(short *input, short *dq, short *output, int pitch) { int i; for (i = 0; i < 16; i++) { input[i] = dq[i] * input[i]; } vp8_short_idct4x4llm_c(input, output, pitch); vpx_memset(input, 0, 32); }
static void extend_plane(uint8_t *const src, int src_stride, int width, int height, int extend_top, int extend_left, int extend_bottom, int extend_right) { int i; const int linesize = extend_left + extend_right + width; /* copy the left and right most columns out */ uint8_t *src_ptr1 = src; uint8_t *src_ptr2 = src + width - 1; uint8_t *dst_ptr1 = src - extend_left; uint8_t *dst_ptr2 = src + width; for (i = 0; i < height; ++i) { vpx_memset(dst_ptr1, src_ptr1[0], extend_left); vpx_memset(dst_ptr2, src_ptr2[0], extend_right); src_ptr1 += src_stride; src_ptr2 += src_stride; dst_ptr1 += src_stride; dst_ptr2 += src_stride; } /* Now copy the top and bottom lines into each line of the respective * borders */ src_ptr1 = src - extend_left; src_ptr2 = src + src_stride * (height - 1) - extend_left; dst_ptr1 = src + src_stride * -extend_top - extend_left; dst_ptr2 = src + src_stride * height - extend_left; for (i = 0; i < extend_top; ++i) { vpx_memcpy(dst_ptr1, src_ptr1, linesize); dst_ptr1 += src_stride; } for (i = 0; i < extend_bottom; ++i) { vpx_memcpy(dst_ptr2, src_ptr2, linesize); dst_ptr2 += src_stride; } }
VP9Decoder *vp9_decoder_create() { VP9Decoder *const pbi = vpx_memalign(32, sizeof(*pbi)); VP9_COMMON *const cm = pbi ? &pbi->common : NULL; if (!cm) return NULL; vp9_zero(*pbi); if (setjmp(cm->error.jmp)) { cm->error.setjmp = 0; vp9_decoder_remove(pbi); return NULL; } cm->error.setjmp = 1; CHECK_MEM_ERROR(cm, cm->fc, (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc))); CHECK_MEM_ERROR(cm, cm->frame_contexts, (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS, sizeof(*cm->frame_contexts))); pbi->need_resync = 1; initialize_dec(); // Initialize the references to not point to any frame buffers. vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); cm->current_video_frame = 0; pbi->ready_for_new_data = 1; cm->bit_depth = VPX_BITS_8; cm->dequant_bit_depth = VPX_BITS_8; cm->alloc_mi = vp9_dec_alloc_mi; cm->free_mi = vp9_dec_free_mi; cm->setup_mi = vp9_dec_setup_mi; // vp9_init_dequantizer() is first called here. Add check in // frame_init_dequantizer() to avoid unnecessary calling of // vp9_init_dequantizer() for every frame. vp9_init_dequantizer(cm); vp9_loop_filter_init(cm); cm->error.setjmp = 0; vp9_get_worker_interface()->init(&pbi->lf_worker); return pbi; }
void vp8_update_gf_useage_maps(VP8_COMMON *cm, MACROBLOCKD *xd) { int mb_row, mb_col; MODE_INFO *this_mb_mode_info = cm->mi; xd->gf_active_ptr = (signed char *)cm->gf_active_flags; if ((cm->frame_type == KEY_FRAME) || (cm->refresh_golden_frame)) { // Reset Gf useage monitors vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); cm->gf_active_count = cm->mb_rows * cm->mb_cols; } else { // for each macroblock row in image for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { // for each macroblock col in image for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { // If using golden then set GF active flag if not already set. // If using last frame 0,0 mode then leave flag as it is // else if using non 0,0 motion or intra modes then clear flag if it is currently set if ((this_mb_mode_info->mbmi.ref_frame == GOLDEN_FRAME) || (this_mb_mode_info->mbmi.ref_frame == ALTREF_FRAME)) { if (*(xd->gf_active_ptr) == 0) { *(xd->gf_active_ptr) = 1; cm->gf_active_count ++; } } else if ((this_mb_mode_info->mbmi.mode != ZEROMV) && *(xd->gf_active_ptr)) { *(xd->gf_active_ptr) = 0; cm->gf_active_count--; } xd->gf_active_ptr++; // Step onto next entry this_mb_mode_info++; // skip to next mb } // this is to account for the border this_mb_mode_info++; } } }
static void extend_plane(uint8_t *const src, int src_stride, int width, int height, int extend_top, int extend_left, int extend_bottom, int extend_right) { int i; const int linesize = extend_left + extend_right + width; uint8_t *src_ptr1 = src; uint8_t *src_ptr2 = src + width - 1; uint8_t *dst_ptr1 = src - extend_left; uint8_t *dst_ptr2 = src + width; for (i = 0; i < height; ++i) { vpx_memset(dst_ptr1, src_ptr1[0], extend_left); vpx_memset(dst_ptr2, src_ptr2[0], extend_right); src_ptr1 += src_stride; src_ptr2 += src_stride; dst_ptr1 += src_stride; dst_ptr2 += src_stride; } src_ptr1 = src - extend_left; src_ptr2 = src + src_stride * (height - 1) - extend_left; dst_ptr1 = src + src_stride * -extend_top - extend_left; dst_ptr2 = src + src_stride * height - extend_left; for (i = 0; i < extend_top; ++i) { vpx_memcpy(dst_ptr1, src_ptr1, linesize); dst_ptr1 += src_stride; } for (i = 0; i < extend_bottom; ++i) { vpx_memcpy(dst_ptr2, src_ptr2, linesize); dst_ptr2 += src_stride; } }
void vp8_dequant_idct_add_c(short *input, short *dq, unsigned char *dest, int stride) { int i; for (i = 0; i < 16; i++) { input[i] = dq[i] * input[i]; } vp8_short_idct4x4llm_c(input, dest, stride, dest, stride); vpx_memset(input, 0, 32); }
int vp9_gpu_get_frame_buffer(void *cb_priv, size_t min_size, vpx_codec_frame_buffer_t *fb) { gpu_cb_priv *const priv = (gpu_cb_priv *)cb_priv; VP9_COMMON *cm = priv->cm; fb->data = cm->gpu.alloc_frame_buffers(cm, min_size, &priv->ybf->gpu_mem); priv->ybf->buffer_alloc_sz = min_size; fb->size = min_size; fb->priv = NULL; vpx_memset(fb->data, 0, min_size); return 0; }
VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf) { VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP)); if (!pbi) return NULL; vpx_memset(pbi, 0, sizeof(VP8D_COMP)); if (setjmp(pbi->common.error.jmp)) { pbi->common.error.setjmp = 0; vp8dx_remove_decompressor(pbi); return 0; } pbi->common.error.setjmp = 1; vp8dx_initialize(); vp8_create_common(&pbi->common); vp8_dmachine_specific_config(pbi); pbi->common.current_video_frame = 0; pbi->ready_for_new_data = 1; pbi->CPUFreq = 0; /*vp8_get_processor_freq();*/ #if CONFIG_MULTITHREAD pbi->max_threads = oxcf->max_threads; vp8_decoder_create_threads(pbi); #endif /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid * unnecessary calling of vp8cx_init_de_quantizer() for every frame. */ vp8cx_init_de_quantizer(pbi); { VP8_COMMON *cm = &pbi->common; vp8_init_loop_filter(cm); cm->last_frame_type = KEY_FRAME; cm->last_filter_type = cm->filter_type; cm->last_sharpness_level = cm->sharpness_level; } pbi->common.error.setjmp = 0; return (VP8D_PTR) pbi; }
int vp9_gpu_free_frame_buffer(VP9_COMMON *cm, YV12_BUFFER_CONFIG *ybf) { if (ybf) { if (ybf->buffer_alloc_sz > 0) { cm->gpu.release_frame_buffers(cm, &ybf->gpu_mem, (void **)&ybf->buffer_alloc); } /* buffer_alloc isn't accessed by most functions. Rather y_buffer, * u_buffer and v_buffer point to buffer_alloc and are used. Clear out * all of this so that a freed pointer isn't inadvertently used */ vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); } else { return -1; } return 0; }
int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) { if (ybf) { if (ybf->buffer_alloc_sz > 0) { vpx_free(ybf->buffer_alloc); } /* buffer_alloc isn't accessed by most functions. Rather y_buffer, u_buffer and v_buffer point to buffer_alloc and are used. Clear out all of this so that a freed pointer isn't inadvertently used */ vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); } else { return -1; } return 0; }
void init_context_counters(void) { FILE *f = fopen("context.bin", "rb"); if (!f) { vp9_zero(context_counters); } else { fread(context_counters, sizeof(context_counters), 1, f); fclose(f); } f = fopen("treeupdate.bin", "rb"); if (!f) { vpx_memset(tree_update_hist, 0, sizeof(tree_update_hist)); } else { fread(tree_update_hist, sizeof(tree_update_hist), 1, f); fclose(f); } }
int vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) { if (ybf) { // If libvpx is using frame buffer callbacks then buffer_alloc_sz must // not be set. if (ybf->buffer_alloc_sz > 0) { vpx_free(ybf->buffer_alloc); } /* buffer_alloc isn't accessed by most functions. Rather y_buffer, u_buffer and v_buffer point to buffer_alloc and are used. Clear out all of this so that a freed pointer isn't inadvertently used */ vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); } else { return -1; } return 0; }
void vp9_update_mbgraph_stats ( VP9_COMP *cpi ) { VP9_COMMON *const cm = &cpi->common; int i, n_frames = vp9_lookahead_depth(cpi->lookahead); YV12_BUFFER_CONFIG *golden_ref = &cm->yv12_fb[cm->gld_fb_idx]; // we need to look ahead beyond where the ARF transitions into // being a GF - so exit if we don't look ahead beyond that if (n_frames <= cpi->frames_till_gf_update_due) return; if (n_frames > (int)cpi->common.frames_till_alt_ref_frame) n_frames = cpi->common.frames_till_alt_ref_frame; if (n_frames > MAX_LAG_BUFFERS) n_frames = MAX_LAG_BUFFERS; cpi->mbgraph_n_frames = n_frames; for (i = 0; i < n_frames; i++) { MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i]; vpx_memset(frame_stats->mb_stats, 0, cm->mb_rows * cm->mb_cols * sizeof(*cpi->mbgraph_stats[i].mb_stats)); } // do motion search to find contribution of each reference to data // later on in this GF group // FIXME really, the GF/last MC search should be done forward, and // the ARF MC search backwards, to get optimal results for MV caching for (i = 0; i < n_frames; i++) { MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i]; struct lookahead_entry *q_cur = vp9_lookahead_peek(cpi->lookahead, i); assert(q_cur != NULL); update_mbgraph_frame_stats(cpi, frame_stats, &q_cur->img, golden_ref, cpi->Source); } vp9_clear_system_state(); // __asm emms; separate_arf_mbs(cpi); }
VP9Decoder *vp9_decoder_create(const VP9DecoderConfig *oxcf) { VP9Decoder *const pbi = vpx_memalign(32, sizeof(*pbi)); VP9_COMMON *const cm = pbi ? &pbi->common : NULL; if (!cm) return NULL; vp9_zero(*pbi); if (setjmp(cm->error.jmp)) { cm->error.setjmp = 0; vp9_decoder_remove(pbi); return NULL; } cm->error.setjmp = 1; vp9_initialize_dec(); vp9_rtcd(); // Initialize the references to not point to any frame buffers. vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); cm->current_video_frame = 0; pbi->oxcf = *oxcf; pbi->ready_for_new_data = 1; pbi->decoded_key_frame = 0; // vp9_init_dequantizer() is first called here. Add check in // frame_init_dequantizer() to avoid unnecessary calling of // vp9_init_dequantizer() for every frame. vp9_init_dequantizer(cm); vp9_loop_filter_init(cm); cm->error.setjmp = 0; vp9_worker_init(&pbi->lf_worker); return pbi; }