Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Unified Diff: chromium/patches/to_upstream/45_mkv_fix_segmap_cache_overflow.patch

Issue 9290059: Initial commit of all previous Chrome build scripts. (Closed) Base URL: http://git.chromium.org/chromium/third_party/ffmpeg.git@master
Patch Set: Drop deprecated subfolder. Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chromium/patches/to_upstream/45_mkv_fix_segmap_cache_overflow.patch
diff --git a/chromium/patches/to_upstream/45_mkv_fix_segmap_cache_overflow.patch b/chromium/patches/to_upstream/45_mkv_fix_segmap_cache_overflow.patch
new file mode 100644
index 0000000000000000000000000000000000000000..40cd33eafd34d6a8dba549b5529acb6b17a52019
--- /dev/null
+++ b/chromium/patches/to_upstream/45_mkv_fix_segmap_cache_overflow.patch
@@ -0,0 +1,114 @@
+Index: a/libavcodec/vp8.c
+===================================================================
+--- a/libavcodec/vp8.c (revision 106016)
++++ b/libavcodec/vp8.c (working copy)
+@@ -50,7 +50,8 @@
+ 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 @@
+ 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 @@
+ 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);
+ }
+@@ -1579,7 +1591,7 @@
+ &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++)
+@@ -1595,7 +1607,7 @@
+ 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;
+@@ -1776,7 +1788,7 @@
+
+ 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;
+ }

Powered by Google App Engine
This is Rietveld 408576698