| OLD | NEW |
| (Empty) | |
| 1 Index: a/libavcodec/vp8.c |
| 2 =================================================================== |
| 3 --- a/libavcodec/vp8.c (revision 106016) |
| 4 +++ b/libavcodec/vp8.c (working copy) |
| 5 @@ -50,7 +50,8 @@ |
| 6 int ret; |
| 7 if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0) |
| 8 return ret; |
| 9 - if (!s->maps_are_invalid && s->num_maps_to_be_freed) { |
| 10 + if (s->num_maps_to_be_freed) { |
| 11 + assert(!s->maps_are_invalid); |
| 12 f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed]; |
| 13 } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) { |
| 14 ff_thread_release_buffer(s->avctx, f); |
| 15 @@ -59,39 +60,50 @@ |
| 16 return 0; |
| 17 } |
| 18 |
| 19 -static void vp8_release_frame(VP8Context *s, AVFrame *f, int is_close) |
| 20 +static void vp8_release_frame(VP8Context *s, AVFrame *f, int prefer_delayed_fre
e, int can_direct_free) |
| 21 { |
| 22 - if (!is_close) { |
| 23 - if (f->ref_index[0]) { |
| 24 - assert(s->num_maps_to_be_freed < FF_ARRAY_ELEMS(s->segmentation_map
s)); |
| 25 - s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0]; |
| 26 + if (f->ref_index[0]) { |
| 27 + if (prefer_delayed_free) { |
| 28 + /* Upon a size change, we want to free the maps but other threads m
ay still |
| 29 + * be using them, so queue them. Upon a seek, all threads are inact
ive so |
| 30 + * we want to cache one to prevent re-allocation in the next decodi
ng |
| 31 + * iteration, but the rest we can free directly. */ |
| 32 + int max_queued_maps = can_direct_free ? 1 : FF_ARRAY_ELEMS(s->segme
ntation_maps); |
| 33 + if (s->num_maps_to_be_freed < max_queued_maps) { |
| 34 + s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[
0]; |
| 35 + } else if (can_direct_free) /* vp8_decode_flush(), but our queue is
full */ { |
| 36 + av_free(f->ref_index[0]); |
| 37 + } /* else: MEMLEAK (should never happen, but better that than crash
) */ |
| 38 f->ref_index[0] = NULL; |
| 39 + } else /* vp8_decode_free() */ { |
| 40 + av_free(f->ref_index[0]); |
| 41 } |
| 42 - } else { |
| 43 - av_freep(&f->ref_index[0]); |
| 44 } |
| 45 ff_thread_release_buffer(s->avctx, f); |
| 46 } |
| 47 |
| 48 -static void vp8_decode_flush_impl(AVCodecContext *avctx, int force, int is_clos
e) |
| 49 +static void vp8_decode_flush_impl(AVCodecContext *avctx, |
| 50 + int prefer_delayed_free, int can_direct_free,
int free_mem) |
| 51 { |
| 52 VP8Context *s = avctx->priv_data; |
| 53 int i; |
| 54 |
| 55 - if (!avctx->is_copy || force) { |
| 56 + if (!avctx->is_copy) { |
| 57 for (i = 0; i < 5; i++) |
| 58 if (s->frames[i].data[0]) |
| 59 - vp8_release_frame(s, &s->frames[i], is_close); |
| 60 + vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_di
rect_free); |
| 61 } |
| 62 memset(s->framep, 0, sizeof(s->framep)); |
| 63 |
| 64 - free_buffers(s); |
| 65 - s->maps_are_invalid = 1; |
| 66 + if (free_mem) { |
| 67 + free_buffers(s); |
| 68 + s->maps_are_invalid = 1; |
| 69 + } |
| 70 } |
| 71 |
| 72 static void vp8_decode_flush(AVCodecContext *avctx) |
| 73 { |
| 74 - vp8_decode_flush_impl(avctx, 0, 0); |
| 75 + vp8_decode_flush_impl(avctx, 1, 1, 0); |
| 76 } |
| 77 |
| 78 static int update_dimensions(VP8Context *s, int width, int height) |
| 79 @@ -101,7 +113,7 @@ |
| 80 if (av_image_check_size(width, height, 0, s->avctx)) |
| 81 return AVERROR_INVALIDDATA; |
| 82 |
| 83 - vp8_decode_flush_impl(s->avctx, 1, 0); |
| 84 + vp8_decode_flush_impl(s->avctx, 1, 0, 1); |
| 85 |
| 86 avcodec_set_dimensions(s->avctx, width, height); |
| 87 } |
| 88 @@ -1579,7 +1591,7 @@ |
| 89 &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && |
| 90 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && |
| 91 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) |
| 92 - vp8_release_frame(s, &s->frames[i], 0); |
| 93 + vp8_release_frame(s, &s->frames[i], 1, 0); |
| 94 |
| 95 // find a free buffer |
| 96 for (i = 0; i < 5; i++) |
| 97 @@ -1595,7 +1607,7 @@ |
| 98 abort(); |
| 99 } |
| 100 if (curframe->data[0]) |
| 101 - ff_thread_release_buffer(avctx, curframe); |
| 102 + vp8_release_frame(s, curframe, 1, 0); |
| 103 |
| 104 curframe->key_frame = s->keyframe; |
| 105 curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; |
| 106 @@ -1776,7 +1788,7 @@ |
| 107 |
| 108 static av_cold int vp8_decode_free(AVCodecContext *avctx) |
| 109 { |
| 110 - vp8_decode_flush_impl(avctx, 0, 1); |
| 111 + vp8_decode_flush_impl(avctx, 0, 1, 1); |
| 112 release_queued_segmaps(avctx->priv_data, 1); |
| 113 return 0; |
| 114 } |
| OLD | NEW |