diff options
author | John Koleszar <jkoleszar@google.com> | 2013-02-08 14:20:05 -0800 |
---|---|---|
committer | Gerrit Code Review <gerrit@gerrit.golo.chromium.org> | 2013-02-08 14:20:05 -0800 |
commit | 6dfc95fe63a52945350a7c8a234e87a4a55645db (patch) | |
tree | 9eee00f47c23b412ab1c181e71ffb816ac7b92f1 /vp9/encoder | |
parent | 3de8ee6ba1db38f14643c10793f57ed5d0b7122f (diff) | |
parent | 393b4856273c06aa0e7f0aec90a2b93a19aaf2d2 (diff) | |
download | libvpx-6dfc95fe63a52945350a7c8a234e87a4a55645db.tar libvpx-6dfc95fe63a52945350a7c8a234e87a4a55645db.tar.gz libvpx-6dfc95fe63a52945350a7c8a234e87a4a55645db.tar.bz2 libvpx-6dfc95fe63a52945350a7c8a234e87a4a55645db.zip |
Merge changes Icd1a2a5a,I204d17a1,I3ed92117 into experimental
* changes:
Initial support for resolution changes on P-frames
Avoid allocating memory when resizing frames
Adds a test for the VP8E_SET_SCALEMODE control
Diffstat (limited to 'vp9/encoder')
-rw-r--r-- | vp9/encoder/vp9_bitstream.c | 33 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 73 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_int.h | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_picklpf.c | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 12 |
5 files changed, 99 insertions, 24 deletions
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 71109f8f4..eec83a0a8 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -1532,33 +1532,34 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, * and color type. */ if (oh.type == KEY_FRAME) { - int v; - // Start / synch code cx_data[0] = 0x9D; cx_data[1] = 0x01; cx_data[2] = 0x2a; + extra_bytes_packed = 3; + cx_data += extra_bytes_packed; + } + { + int v; + /* TODO(jkoleszar): support arbitrary resolutions */ v = (pc->horiz_scale << 14) | pc->Width; - cx_data[3] = v; - cx_data[4] = v >> 8; + cx_data[0] = v; + cx_data[1] = v >> 8; v = (pc->vert_scale << 14) | pc->Height; - cx_data[5] = v; - cx_data[6] = v >> 8; + cx_data[2] = v; + cx_data[3] = v >> 8; - extra_bytes_packed = 7; - cx_data += extra_bytes_packed; - - vp9_start_encode(&header_bc, cx_data); + extra_bytes_packed += 4; + cx_data += 4; + } - // signal clr type - vp9_write_bit(&header_bc, pc->clr_type); - vp9_write_bit(&header_bc, pc->clamp_type); + vp9_start_encode(&header_bc, cx_data); - } else { - vp9_start_encode(&header_bc, cx_data); - } + // TODO(jkoleszar): remove these two unused bits? + vp9_write_bit(&header_bc, pc->clr_type); + vp9_write_bit(&header_bc, pc->clamp_type); // error resilient mode vp9_write_bit(&header_bc, pc->error_resilient_mode); diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 280a3224d..3bbe9761c 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -1005,6 +1005,38 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) { } +static void update_frame_size(VP9_COMP *cpi) { + VP9_COMMON *cm = &cpi->common; + + /* our internal buffers are always multiples of 16 */ + int width = (cm->Width + 15) & ~15; + int height = (cm->Height + 15) & ~15; + + cm->mb_rows = height >> 4; + cm->mb_cols = width >> 4; + cm->MBs = cm->mb_rows * cm->mb_cols; + cm->mode_info_stride = cm->mb_cols + 1; + memset(cm->mip, 0, + (cm->mb_cols + 1) * (cm->mb_rows + 1) * sizeof(MODE_INFO)); + vp9_update_mode_info_border(cm, cm->mip); + + cm->mi = cm->mip + cm->mode_info_stride + 1; + cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; + vp9_update_mode_info_in_image(cm, cm->mi); + + /* Update size of buffers local to this frame */ + if (vp8_yv12_realloc_frame_buffer(&cpi->last_frame_uf, + width, height, VP9BORDERINPIXELS)) + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, + "Failed to reallocate last frame buffer"); + + if (vp8_yv12_realloc_frame_buffer(&cpi->scaled_source, + width, height, VP9BORDERINPIXELS)) + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, + "Failed to reallocate scaled source buffer"); +} + + // TODO perhaps change number of steps expose to outside world when setting // max and min limits. Also this will likely want refining for the extended Q // range. @@ -1302,14 +1334,18 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs; } - if (((cm->Width + 15) & 0xfffffff0) != - cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_width || - ((cm->Height + 15) & 0xfffffff0) != - cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_height || - cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_width == 0) { + // Increasing the size of the frame beyond the first seen frame, or some + // otherwise signalled maximum size, is not supported. + // TODO(jkoleszar): exit gracefully. + if (!cpi->initial_width) { alloc_raw_frame_buffers(cpi); vp9_alloc_compressor_data(cpi); + cpi->initial_width = cm->Width; + cpi->initial_height = cm->Height; } + assert(cm->Width <= cpi->initial_width); + assert(cm->Height <= cpi->initial_height); + update_frame_size(cpi); if (cpi->oxcf.fixed_q >= 0) { cpi->last_q[0] = cpi->oxcf.fixed_q; @@ -3776,6 +3812,28 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, cm->fb_idx_ref_cnt[cm->new_fb_idx]--; cm->new_fb_idx = get_free_fb(cm); + /* Reset the frame pointers to the current frame size */ + vp8_yv12_realloc_frame_buffer(&cm->yv12_fb[cm->new_fb_idx], + cm->mb_cols * 16, cm->mb_rows * 16, + VP9BORDERINPIXELS); + + /* Disable any references that have different size */ + if ((cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_width != + cm->yv12_fb[cm->new_fb_idx].y_width) || + (cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_height != + cm->yv12_fb[cm->new_fb_idx].y_height)) + cpi->ref_frame_flags &= ~VP9_LAST_FLAG; + if ((cm->yv12_fb[cm->active_ref_idx[cpi->gld_fb_idx]].y_width != + cm->yv12_fb[cm->new_fb_idx].y_width) || + (cm->yv12_fb[cm->active_ref_idx[cpi->gld_fb_idx]].y_height != + cm->yv12_fb[cm->new_fb_idx].y_height)) + cpi->ref_frame_flags &= ~VP9_GOLD_FLAG; + if ((cm->yv12_fb[cm->active_ref_idx[cpi->alt_fb_idx]].y_width != + cm->yv12_fb[cm->new_fb_idx].y_width) || + (cm->yv12_fb[cm->active_ref_idx[cpi->alt_fb_idx]].y_height != + cm->yv12_fb[cm->new_fb_idx].y_height)) + cpi->ref_frame_flags &= ~VP9_ALT_FLAG; + vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm); if (cpi->pass == 1) { Pass1Encode(cpi, size, dest, frame_flags); @@ -4027,15 +4085,16 @@ int vp9_set_internal_size(VP9_PTR comp, VP9_COMP *cpi = (VP9_COMP *) comp; if (horiz_mode <= ONETWO) - cpi->common.horiz_scale = horiz_mode; + cpi->horiz_scale = horiz_mode; else return -1; if (vert_mode <= ONETWO) - cpi->common.vert_scale = vert_mode; + cpi->vert_scale = vert_mode; else return -1; + vp9_change_config(comp, &cpi->oxcf); return 0; } diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index b7cb558d0..156f86f98 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -678,6 +678,8 @@ typedef struct VP9_COMP { unsigned int mb_mv_ref_count[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; #endif + int initial_width; + int initial_height; } VP9_COMP; void vp9_encode_frame(VP9_COMP *cpi); diff --git a/vp9/encoder/vp9_picklpf.c b/vp9/encoder/vp9_picklpf.c index b443ede6f..6f9333521 100644 --- a/vp9/encoder/vp9_picklpf.c +++ b/vp9/encoder/vp9_picklpf.c @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ - +#include <assert.h> #include "vp9/common/vp9_onyxc_int.h" #include "vp9/encoder/vp9_onyx_int.h" #include "vp9/encoder/vp9_picklpf.h" @@ -27,6 +27,7 @@ void vp9_yv12_copy_partial_frame_c(YV12_BUFFER_CONFIG *src_ybc, int yoffset; int linestocopy; + assert(src_ybc->y_stride == dst_ybc->y_stride); yheight = src_ybc->y_height; ystride = src_ybc->y_stride; diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index c50c55ff9..370374164 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -3517,6 +3517,8 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int64_t *returnintra) { + static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG, + VP9_ALT_FLAG }; VP9_COMMON *cm = &cpi->common; MACROBLOCKD *xd = &x->e_mbd; union b_mode_info best_bmodes[16]; @@ -3684,6 +3686,16 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, if (best_rd <= cpi->rd_threshes[mode_index]) continue; + // Ensure that the references used by this mode are available. + if (mbmi->ref_frame && + !(cpi->ref_frame_flags & flag_list[mbmi->ref_frame])) + continue; + + if (mbmi->second_ref_frame > 0 && + !(cpi->ref_frame_flags & flag_list[mbmi->second_ref_frame])) + continue; + + // current coding mode under rate-distortion optimization test loop #if CONFIG_COMP_INTERINTRA_PRED mbmi->interintra_mode = (MB_PREDICTION_MODE)(DC_PRED - 1); |