From 131cab7c27cfc64976d91ec40033894ca21ca918 Mon Sep 17 00:00:00 2001 From: hkuang Date: Tue, 26 May 2015 11:52:10 -0700 Subject: [PATCH] Add error handling when running out of free frame buffers. Change-Id: If28b59b9521204a6e3aecedcf75932d76a752567 --- vp9/common/vp9_onyxc_int.h | 10 ++++++++-- vp9/decoder/vp9_decoder.c | 6 ++++++ vp9/encoder/vp9_encoder.c | 10 ++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index 5179c6906..563096cd3 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -14,6 +14,7 @@ #include "./vpx_config.h" #include "vpx/internal/vpx_codec_internal.h" #include "./vp9_rtcd.h" +#include "vp9/common/vp9_alloccommon.h" #include "vp9/common/vp9_loopfilter.h" #include "vp9/common/vp9_entropymv.h" #include "vp9/common/vp9_entropy.h" @@ -305,8 +306,13 @@ static INLINE int get_free_fb(VP9_COMMON *cm) { if (frame_bufs[i].ref_count == 0) break; - assert(i < FRAME_BUFFERS); - frame_bufs[i].ref_count = 1; + if (i != FRAME_BUFFERS) { + frame_bufs[i].ref_count = 1; + } else { + // Reset i to be INVALID_IDX to indicate no free buffer found. + i = INVALID_IDX; + } + unlock_buffer_pool(cm->buffer_pool); return i; } diff --git a/vp9/decoder/vp9_decoder.c b/vp9/decoder/vp9_decoder.c index 288d8690c..ff46e87ec 100644 --- a/vp9/decoder/vp9_decoder.c +++ b/vp9/decoder/vp9_decoder.c @@ -212,6 +212,9 @@ vpx_codec_err_t vp9_set_reference_dec(VP9_COMMON *cm, // Find an empty frame buffer. const int free_fb = get_free_fb(cm); + if (cm->new_fb_idx == INVALID_IDX) + return VPX_CODEC_MEM_ERROR; + // Decrease ref_count since it will be increased again in // ref_cnt_fb() below. --frame_bufs[free_fb].ref_count; @@ -299,7 +302,10 @@ int vp9_receive_compressed_data(VP9Decoder *pbi, && frame_bufs[cm->new_fb_idx].ref_count == 0) pool->release_fb_cb(pool->cb_priv, &frame_bufs[cm->new_fb_idx].raw_frame_buffer); + // Find a free frame buffer. Return error if can not find any. cm->new_fb_idx = get_free_fb(cm); + if (cm->new_fb_idx == INVALID_IDX) + return VPX_CODEC_MEM_ERROR; // Assign a MV array to the frame buffer. cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx]; diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index e89ee5eb7..04e33d183 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -2714,7 +2714,10 @@ void vp9_scale_references(VP9_COMP *cpi) { #if CONFIG_VP9_HIGHBITDEPTH if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) { const int new_fb = get_free_fb(cm); - RefCntBuffer *const new_fb_ptr = &pool->frame_bufs[new_fb]; + RefCntBuffer *new_fb_ptr = NULL; + if (cm->new_fb_idx == INVALID_IDX) + return; + new_fb_ptr = &pool->frame_bufs[new_fb]; cm->cur_frame = &pool->frame_bufs[new_fb]; vp9_realloc_frame_buffer(&pool->frame_bufs[new_fb].buf, cm->width, cm->height, @@ -2726,7 +2729,10 @@ void vp9_scale_references(VP9_COMP *cpi) { #else if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) { const int new_fb = get_free_fb(cm); - RefCntBuffer *const new_fb_ptr = &pool->frame_bufs[new_fb]; + RefCntBuffer *new_fb_ptr = NULL; + if (cm->new_fb_idx == INVALID_IDX) + return; + new_fb_ptr = &pool->frame_bufs[new_fb]; vp9_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height, cm->subsampling_x, cm->subsampling_y,