summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2013-02-08 14:20:05 -0800
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2013-02-08 14:20:05 -0800
commit6dfc95fe63a52945350a7c8a234e87a4a55645db (patch)
tree9eee00f47c23b412ab1c181e71ffb816ac7b92f1 /vp9/encoder
parent3de8ee6ba1db38f14643c10793f57ed5d0b7122f (diff)
parent393b4856273c06aa0e7f0aec90a2b93a19aaf2d2 (diff)
downloadlibvpx-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.c33
-rw-r--r--vp9/encoder/vp9_onyx_if.c73
-rw-r--r--vp9/encoder/vp9_onyx_int.h2
-rw-r--r--vp9/encoder/vp9_picklpf.c3
-rw-r--r--vp9/encoder/vp9_rdopt.c12
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);