int vp9_alloc_ref_frame_buffers(VP9_COMMON *cm, int width, int height) { int i; const int ss_x = cm->subsampling_x; const int ss_y = cm->subsampling_y; vp9_free_ref_frame_buffers(cm); for (i = 0; i < FRAME_BUFFERS; ++i) { cm->frame_bufs[i].ref_count = 0; if (vp9_alloc_frame_buffer(&cm->frame_bufs[i].buf, width, height, ss_x, ss_y, #if CONFIG_VP9_HIGHBITDEPTH cm->use_highbitdepth, #endif VP9_ENC_BORDER_IN_PIXELS) < 0) goto fail; } init_frame_bufs(cm); #if CONFIG_INTERNAL_STATS || CONFIG_VP9_POSTPROC if (vp9_alloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y, #if CONFIG_VP9_HIGHBITDEPTH cm->use_highbitdepth, #endif VP9_ENC_BORDER_IN_PIXELS) < 0) goto fail; #endif return 0; fail: vp9_free_ref_frame_buffers(cm); return 1; }
int vp9_alloc_ref_frame_buffers(VP9_COMMON *cm, int width, int height) { int i; const int ss_x = cm->subsampling_x; const int ss_y = cm->subsampling_y; vp9_free_ref_frame_buffers(cm); for (i = 0; i < FRAME_BUFFERS; ++i) { BufferPool *const pool = cm->buffer_pool; pool->frame_bufs[i].ref_count = 0; if (vp9_alloc_frame_buffer(&pool->frame_bufs[i].buf, width, height, ss_x, ss_y, #if CONFIG_VP9_HIGHBITDEPTH cm->use_highbitdepth, #endif VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment) < 0) goto fail; if (pool->frame_bufs[i].mvs == NULL) { pool->frame_bufs[i].mvs = (MV_REF *)vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*pool->frame_bufs[i].mvs)); if (pool->frame_bufs[i].mvs == NULL) goto fail; pool->frame_bufs[i].mi_rows = cm->mi_rows; pool->frame_bufs[i].mi_cols = cm->mi_cols; } } init_frame_bufs(cm); #if CONFIG_VP9_POSTPROC if (vp9_alloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y, #if CONFIG_VP9_HIGHBITDEPTH cm->use_highbitdepth, #endif VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment) < 0) goto fail; #endif return 0; fail: vp9_free_ref_frame_buffers(cm); return 1; }
struct lookahead_ctx *vp9_lookahead_init(unsigned int width, unsigned int height, unsigned int subsampling_x, unsigned int subsampling_y, unsigned int depth) { struct lookahead_ctx *ctx = NULL; // Clamp the lookahead queue depth depth = clamp(depth, 1, MAX_LAG_BUFFERS); // Allocate memory to keep previous source frames available. depth += MAX_PRE_FRAMES; // Allocate the lookahead structures ctx = calloc(1, sizeof(*ctx)); if (ctx) { unsigned int i; ctx->max_sz = depth; ctx->buf = calloc(depth, sizeof(*ctx->buf)); if (!ctx->buf) goto bail; for (i = 0; i < depth; i++) if (vp9_alloc_frame_buffer(&ctx->buf[i].img, width, height, subsampling_x, subsampling_y, VP9_ENC_BORDER_IN_PIXELS)) goto bail; } return ctx; bail: vp9_lookahead_destroy(ctx); return NULL; }
struct lookahead_ctx * vp9_lookahead_init(unsigned int width, unsigned int height, unsigned int subsampling_x, unsigned int subsampling_y, unsigned int depth) { struct lookahead_ctx *ctx = NULL; depth = clamp(depth, 1, MAX_LAG_BUFFERS); ctx = calloc(1, sizeof(*ctx)); if (ctx) { unsigned int i; ctx->max_sz = depth; ctx->buf = calloc(depth, sizeof(*ctx->buf)); if (!ctx->buf) goto bail; for (i = 0; i < depth; i++) if (vp9_alloc_frame_buffer(&ctx->buf[i].img, width, height, subsampling_x, subsampling_y, VP9BORDERINPIXELS)) goto bail; } return ctx; bail: vp9_lookahead_destroy(ctx); return NULL; }
int vp9_alloc_ref_frame_buffers(VP9_COMMON *cm, int width, int height) { int i; const int ss_x = cm->subsampling_x; const int ss_y = cm->subsampling_y; vpx_get_frame_buffer_cb_fn_t cb = NULL; vpx_codec_frame_buffer_t *codec_frame_buffer = NULL; void *cb_priv = NULL; vp9_free_ref_frame_buffers(cm); for (i = 0; i < FRAME_BUFFERS; ++i) { #if CONFIG_GPU_COMPUTE vpx_codec_frame_buffer_t raw_frame_buffer; gpu_cb_priv gpu_priv = {cm, &cm->frame_bufs[i].buf}; if (cm->use_gpu) { cb = vp9_gpu_get_frame_buffer; codec_frame_buffer = &raw_frame_buffer; cb_priv = &gpu_priv; } #if CONFIG_VP9_HIGHBITDEPTH // gpu kernels for now do not support higher bit depths. assert(cm->use_highbitdepth == 0); #endif #endif cm->frame_bufs[i].ref_count = 0; if (&cm->frame_bufs[i].buf) { vp9_free_frame_buffer(&cm->frame_bufs[i].buf); if (vp9_realloc_frame_buffer(&cm->frame_bufs[i].buf, width, height, ss_x, ss_y, #if CONFIG_VP9_HIGHBITDEPTH cm->use_highbitdepth, #endif VP9_ENC_BORDER_IN_PIXELS, codec_frame_buffer, cb, cb_priv)){ goto fail; } } } init_frame_bufs(cm); #if CONFIG_INTERNAL_STATS || CONFIG_VP9_POSTPROC if (vp9_alloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y, #if CONFIG_VP9_HIGHBITDEPTH cm->use_highbitdepth, #endif VP9_ENC_BORDER_IN_PIXELS) < 0) goto fail; #endif return 0; fail: vp9_free_ref_frame_buffers(cm); return 1; }
// For viewing skin map on input source. void vp9_compute_skin_map(VP9_COMP *const cpi, FILE *yuv_skinmap_file) { int i, j, mi_row, mi_col; VP9_COMMON *const cm = &cpi->common; uint8_t *y; const uint8_t *src_y = cpi->Source->y_buffer; const uint8_t *src_u = cpi->Source->u_buffer; const uint8_t *src_v = cpi->Source->v_buffer; const int src_ystride = cpi->Source->y_stride; const int src_uvstride = cpi->Source->uv_stride; YV12_BUFFER_CONFIG skinmap; vpx_memset(&skinmap, 0, sizeof(YV12_BUFFER_CONFIG)); if (vp9_alloc_frame_buffer(&skinmap, cm->width, cm->height, cm->subsampling_x, cm->subsampling_y, VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment)) { vp9_free_frame_buffer(&skinmap); return; } vpx_memset(skinmap.buffer_alloc, 128, skinmap.frame_size); y = skinmap.y_buffer; // Loop through 8x8 blocks and set skin map based on center pixel of block. // Set y to white for skin block, otherwise set to source with gray scale. // Ignore rightmost/bottom boundary blocks. for (mi_row = 0; mi_row < cm->mi_rows - 1; ++mi_row) { for (mi_col = 0; mi_col < cm->mi_cols - 1; ++mi_col) { // Use middle pixel for each 8x8 block for skin detection. // If middle pixel is skin, assign whole 8x8 block to skin. const uint8_t ysource = src_y[4 * src_ystride + 4]; const uint8_t usource = src_u[2 * src_uvstride + 2]; const uint8_t vsource = src_v[2 * src_uvstride + 2]; const int is_skin = vp9_skin_pixel(ysource, usource, vsource); for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { if (is_skin) y[i * src_ystride + j] = 255; else y[i * src_ystride + j] = src_y[i * src_ystride + j]; } } y += 8; src_y += 8; src_u += 4; src_v += 4; } y += (src_ystride << 3) - ((cm->mi_cols - 1) << 3); src_y += (src_ystride << 3) - ((cm->mi_cols - 1) << 3); src_u += (src_uvstride << 2) - ((cm->mi_cols - 1) << 2); src_v += (src_uvstride << 2) - ((cm->mi_cols - 1) << 2); } vp9_write_yuv_frame_420(&skinmap, yuv_skinmap_file); vp9_free_frame_buffer(&skinmap); }