summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2013-02-06 14:22:17 -0800
committerJohn Koleszar <jkoleszar@google.com>2013-02-08 12:20:30 -0800
commitc03d45def9ff03fd1ee35070f59928f702e7b8e9 (patch)
tree0af950dd7413665deeedcbd3fa41205e430a153b /vp9/encoder
parent88f99f4ec29d1df6cb99e47562734df7bd9a6892 (diff)
downloadlibvpx-c03d45def9ff03fd1ee35070f59928f702e7b8e9.tar
libvpx-c03d45def9ff03fd1ee35070f59928f702e7b8e9.tar.gz
libvpx-c03d45def9ff03fd1ee35070f59928f702e7b8e9.tar.bz2
libvpx-c03d45def9ff03fd1ee35070f59928f702e7b8e9.zip
Avoid allocating memory when resizing frames
As long as the new frame is smaller than the size that was originally allocated, we don't need to free and reallocate the memory allocated. Instead, do the allocation on the size of the first frame. We could make this passed in from the application instead, if we wanted to support external upscaling. Change-Id: I204d17a130728bbd91155bb4bd863a99bb99b038
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_onyx_if.c51
-rw-r--r--vp9/encoder/vp9_onyx_int.h2
-rw-r--r--vp9/encoder/vp9_picklpf.c3
3 files changed, 50 insertions, 6 deletions
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index db6e03e06..e6e9cddd7 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -1187,6 +1187,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.
@@ -1482,14 +1514,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;
@@ -3954,6 +3990,11 @@ 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);
+
vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm);
if (cpi->pass == 1) {
Pass1Encode(cpi, size, dest, frame_flags);
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 4c1113ef2..c4442b4aa 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -677,6 +677,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;