summaryrefslogtreecommitdiff
path: root/vp9/decoder/vp9_decodeframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/decoder/vp9_decodeframe.c')
-rw-r--r--vp9/decoder/vp9_decodeframe.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index d0e896c13..9c793f710 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -1148,9 +1148,15 @@ static void resize_context_buffers(VP9_COMMON *cm, int width, int height) {
// Allocations in vp9_alloc_context_buffers() depend on individual
// dimensions as well as the overall size.
if (new_mi_cols > cm->mi_cols || new_mi_rows > cm->mi_rows) {
- if (vp9_alloc_context_buffers(cm, width, height))
+ if (vp9_alloc_context_buffers(cm, width, height)) {
+ // The cm->mi_* values have been cleared and any existing context
+ // buffers have been freed. Clear cm->width and cm->height to be
+ // consistent and to force a realloc next time.
+ cm->width = 0;
+ cm->height = 0;
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate context buffers");
+ }
} else {
vp9_set_mb_mi(cm, width, height);
}
@@ -1528,7 +1534,7 @@ static int tile_worker_hook(void *arg1, void *arg2) {
static int compare_tile_buffers(const void *a, const void *b) {
const TileBuffer *const buf1 = (const TileBuffer *)a;
const TileBuffer *const buf2 = (const TileBuffer *)b;
- return (int)(buf2->size - buf1->size);
+ return (int)((int64_t)buf2->size - buf1->size);
}
static const uint8_t *decode_tiles_mt(VP9Decoder *pbi, const uint8_t *data,
@@ -1724,6 +1730,21 @@ static void read_bitdepth_colorspace_sampling(VP9_COMMON *cm,
}
}
+static INLINE void flush_all_fb_on_key(VP9_COMMON *cm) {
+ if (cm->frame_type == KEY_FRAME && cm->current_video_frame > 0) {
+ RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
+ BufferPool *const pool = cm->buffer_pool;
+ int i;
+ for (i = 0; i < FRAME_BUFFERS; ++i) {
+ frame_bufs[i].ref_count = 0;
+ if (!frame_bufs[i].released) {
+ pool->release_fb_cb(pool->cb_priv, &frame_bufs[i].raw_frame_buffer);
+ frame_bufs[i].released = 1;
+ }
+ }
+ }
+}
+
static size_t read_uncompressed_header(VP9Decoder *pbi,
struct vpx_read_bit_buffer *rb) {
VP9_COMMON *const cm = &pbi->common;
@@ -1788,6 +1809,7 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
setup_frame_size(cm, rb);
if (pbi->need_resync) {
memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
+ flush_all_fb_on_key(cm);
pbi->need_resync = 0;
}
} else {