From 51acb0116731e80a430512351155b29244cb2305 Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Tue, 7 Feb 2012 17:07:49 -0800 Subject: [PATCH] support changing resolution with vpx_codec_enc_config_set Allow the application to change the frame size during encoding. This is only supported when not using lagged compress. Change-Id: I89b585d703d5fd728a9e3dedf997f1b595d0db0f --- vp8/encoder/onyx_if.c | 45 +++++++++++++++++++++++++++++++------------ vp8/vp8_cx_iface.c | 3 ++- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 4b41bbd94..57656bb4f 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -323,6 +323,9 @@ static void setup_features(VP8_COMP *cpi) } +static void dealloc_raw_frame_buffers(VP8_COMP *cpi); + + static void dealloc_compressor_data(VP8_COMP *cpi) { vpx_free(cpi->tplist); @@ -349,10 +352,7 @@ static void dealloc_compressor_data(VP8_COMP *cpi) vp8_yv12_de_alloc_frame_buffer(&cpi->pick_lf_lvl_frame); vp8_yv12_de_alloc_frame_buffer(&cpi->scaled_source); -#if VP8_TEMPORAL_ALT_REF - vp8_yv12_de_alloc_frame_buffer(&cpi->alt_ref_buffer); -#endif - vp8_lookahead_destroy(cpi->lookahead); + dealloc_raw_frame_buffers(cpi); vpx_free(cpi->tok); cpi->tok = 0; @@ -1044,6 +1044,16 @@ static void alloc_raw_frame_buffers(VP8_COMP *cpi) #endif } + +static void dealloc_raw_frame_buffers(VP8_COMP *cpi) +{ +#if VP8_TEMPORAL_ALT_REF + vp8_yv12_de_alloc_frame_buffer(&cpi->alt_ref_buffer); +#endif + vp8_lookahead_destroy(cpi->lookahead); +} + + static int vp8_alloc_partition_data(VP8_COMP *cpi) { vpx_free(cpi->mb.pip); @@ -1387,6 +1397,7 @@ void update_layer_contexts (VP8_COMP *cpi) void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { VP8_COMMON *cm = &cpi->common; + int last_w, last_h; if (!cpi) return; @@ -1594,6 +1605,10 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) cpi->target_bandwidth = cpi->oxcf.target_bandwidth; + + last_w = cm->Width; + last_h = cm->Height; + cm->Width = cpi->oxcf.Width; cm->Height = cpi->oxcf.Height; @@ -1619,6 +1634,9 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs; } + if (last_w != cm->Width || last_h != cm->Height) + cpi->force_next_frame_intra = 1; + if (((cm->Width + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_width || ((cm->Height + 15) & 0xfffffff0) != @@ -3147,15 +3165,9 @@ static void encode_frame_to_data_rate // Test code for segmentation of gf/arf (0,0) //segmentation_test_function( cpi); - if (cpi->compressor_speed == 2) + if(cpi->force_next_frame_intra) { - if(cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME) - { - if(cpi->force_next_frame_intra) - { - cm->frame_type = KEY_FRAME; /* delayed intra frame */ - } - } + cm->frame_type = KEY_FRAME; /* delayed intra frame */ cpi->force_next_frame_intra = 0; } @@ -4550,6 +4562,15 @@ int vp8_receive_raw_frame(VP8_COMP *cpi, unsigned int frame_flags, YV12_BUFFER_C #endif vpx_usec_timer_start(&timer); + + /* Reinit the lookahead buffer if the frame size changes */ + if (sd->y_width != cpi->common.Width || sd->y_height != cpi->common.Height) + { + assert(cpi->oxcf.lag_in_frames < 2); + dealloc_raw_frame_buffers(cpi); + alloc_raw_frame_buffers(cpi); + } + if(vp8_lookahead_push(cpi->lookahead, sd, time_stamp, end_time, frame_flags, cpi->active_map_enabled ? cpi->active_map : NULL)) res = -1; diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index f2f376a7c..42da7be80 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -440,7 +440,8 @@ static vpx_codec_err_t vp8e_set_config(vpx_codec_alg_priv_t *ctx, { vpx_codec_err_t res; - if ((cfg->g_w != ctx->cfg.g_w) || (cfg->g_h != ctx->cfg.g_h)) + if (((cfg->g_w != ctx->cfg.g_w) || (cfg->g_h != ctx->cfg.g_h)) + && cfg->g_lag_in_frames > 1) ERROR("Cannot change width or height after initialization"); /* Prevent increasing lag_in_frames. This check is stricter than it needs