diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-10-30 01:33:41 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-10-30 01:33:41 +0200 |
commit | d17e7070a099af04a1dc7bc9ddd82f67bfcf9827 (patch) | |
tree | 4be589d09939bead88ef3d4e1d5e90fe0348af6c /libavcodec/vp8.c | |
parent | 1af3571e05522df4e71a5b33de05bdb9e953a6c4 (diff) | |
parent | 7d1b17b83330aefe2f32a66fe84effe46ae51014 (diff) | |
download | ffmpeg-d17e7070a099af04a1dc7bc9ddd82f67bfcf9827.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (51 commits)
cin audio: use sign_extend() instead of casting to int16_t
cin audio: restructure decoding loop to avoid a separate counter variable
cin audio: use local variable for delta value
cin audio: remove unneeded cast from void*
cin audio: validate the channel count
cin audio: remove unneeded AVCodecContext pointer from CinAudioContext
dsicin: fix several audio-related fields in the CIN demuxer
flacdec: use av_get_bytes_per_sample() to get sample size
dca: handle errors from dca_decode_block()
dca: return error if the frame header is invalid
dca: return proper error codes instead of -1
utvideo: handle empty Huffman trees
binkaudio: change short to int16_t
binkaudio: only decode one block at a time.
binkaudio: store interleaved overlap samples in BinkAudioContext.
binkaudio: pre-calculate quantization factors
binkaudio: add some buffer overread checks.
atrac3: support float or int16 output using request_sample_fmt
atrac3: add CODEC_CAP_SUBFRAMES capability
atrac3: return appropriate error codes instead of -1
...
Conflicts:
libavcodec/atrac1.c
libavcodec/dca.c
libavformat/mov.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/vp8.c')
-rw-r--r-- | libavcodec/vp8.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 9b07608078..37bdcf7525 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -50,7 +50,8 @@ static int vp8_alloc_frame(VP8Context *s, AVFrame *f) int ret; if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0) return ret; - if (!s->maps_are_invalid && s->num_maps_to_be_freed) { + if (s->num_maps_to_be_freed) { + assert(!s->maps_are_invalid); f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed]; } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) { ff_thread_release_buffer(s->avctx, f); @@ -59,39 +60,50 @@ static int vp8_alloc_frame(VP8Context *s, AVFrame *f) return 0; } -static void vp8_release_frame(VP8Context *s, AVFrame *f, int is_close) +static void vp8_release_frame(VP8Context *s, AVFrame *f, int prefer_delayed_free, int can_direct_free) { - if (!is_close) { - if (f->ref_index[0]) { - assert(s->num_maps_to_be_freed < FF_ARRAY_ELEMS(s->segmentation_maps)); - s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0]; + if (f->ref_index[0]) { + if (prefer_delayed_free) { + /* Upon a size change, we want to free the maps but other threads may still + * be using them, so queue them. Upon a seek, all threads are inactive so + * we want to cache one to prevent re-allocation in the next decoding + * iteration, but the rest we can free directly. */ + int max_queued_maps = can_direct_free ? 1 : FF_ARRAY_ELEMS(s->segmentation_maps); + if (s->num_maps_to_be_freed < max_queued_maps) { + s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0]; + } else if (can_direct_free) /* vp8_decode_flush(), but our queue is full */ { + av_free(f->ref_index[0]); + } /* else: MEMLEAK (should never happen, but better that than crash) */ f->ref_index[0] = NULL; + } else /* vp8_decode_free() */ { + av_free(f->ref_index[0]); } - } else { - av_freep(&f->ref_index[0]); } ff_thread_release_buffer(s->avctx, f); } -static void vp8_decode_flush_impl(AVCodecContext *avctx, int force, int is_close) +static void vp8_decode_flush_impl(AVCodecContext *avctx, + int prefer_delayed_free, int can_direct_free, int free_mem) { VP8Context *s = avctx->priv_data; int i; - if (!avctx->is_copy || force) { + if (!avctx->is_copy) { for (i = 0; i < 5; i++) if (s->frames[i].data[0]) - vp8_release_frame(s, &s->frames[i], is_close); + vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_direct_free); } memset(s->framep, 0, sizeof(s->framep)); - free_buffers(s); - s->maps_are_invalid = 1; + if (free_mem) { + free_buffers(s); + s->maps_are_invalid = 1; + } } static void vp8_decode_flush(AVCodecContext *avctx) { - vp8_decode_flush_impl(avctx, 0, 0); + vp8_decode_flush_impl(avctx, 1, 1, 0); } static int update_dimensions(VP8Context *s, int width, int height) @@ -101,7 +113,7 @@ static int update_dimensions(VP8Context *s, int width, int height) if (av_image_check_size(width, height, 0, s->avctx)) return AVERROR_INVALIDDATA; - vp8_decode_flush_impl(s->avctx, 1, 0); + vp8_decode_flush_impl(s->avctx, 1, 0, 1); avcodec_set_dimensions(s->avctx, width, height); } @@ -1581,7 +1593,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) - vp8_release_frame(s, &s->frames[i], 0); + vp8_release_frame(s, &s->frames[i], 1, 0); // find a free buffer for (i = 0; i < 5; i++) @@ -1597,7 +1609,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, abort(); } if (curframe->data[0]) - ff_thread_release_buffer(avctx, curframe); + vp8_release_frame(s, curframe, 1, 0); curframe->key_frame = s->keyframe; curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; @@ -1778,7 +1790,7 @@ static av_cold int vp8_decode_init(AVCodecContext *avctx) static av_cold int vp8_decode_free(AVCodecContext *avctx) { - vp8_decode_flush_impl(avctx, 0, 1); + vp8_decode_flush_impl(avctx, 0, 1, 1); release_queued_segmaps(avctx->priv_data, 1); return 0; } |