diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-08-08 21:03:27 +0200 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2024-06-12 11:08:19 +0200 |
commit | 788892d647636b314fa23df8eaaa3f016809ce0a (patch) | |
tree | 2cc6e0e12efe820f83cd1f393061b80395173f0a /libavcodec/mpegvideo.c | |
parent | a95591dbfde3a9347cdfe6537243957e65d2d8ea (diff) | |
download | ffmpeg-788892d647636b314fa23df8eaaa3f016809ce0a.tar.gz |
avcodec/mpegvideo, mpegpicture: Add buffer pool
This avoids constant allocations+frees and will also allow
to simply switch to the RefStruct API, thereby avoiding
the overhead of the AVBuffer API.
It also simplifies the code, because it removes the "needs_realloc"
field: It was added in 435c0b87d28b48dc2e0360adc404a0e2d66d16a0,
before the introduction of the AVBuffer API: given that these buffers
may be used by different threads, they were not freed immediately
and instead were marked as being freed later by setting needs_realloc.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec/mpegvideo.c')
-rw-r--r-- | libavcodec/mpegvideo.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index ce1edca95d..5728f4cee3 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -534,8 +534,19 @@ void ff_mpv_common_defaults(MpegEncContext *s) s->slice_context_count = 1; } +static void free_buffer_pools(BufferPoolContext *pools) +{ + av_buffer_pool_uninit(&pools->mbskip_table_pool); + av_buffer_pool_uninit(&pools->qscale_table_pool); + av_buffer_pool_uninit(&pools->mb_type_pool); + av_buffer_pool_uninit(&pools->motion_val_pool); + av_buffer_pool_uninit(&pools->ref_index_pool); + pools->alloc_mb_height = pools->alloc_mb_width = pools->alloc_mb_stride = 0; +} + int ff_mpv_init_context_frame(MpegEncContext *s) { + BufferPoolContext *const pools = &s->buffer_pools; int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; int mb_height; @@ -630,11 +641,36 @@ int ff_mpv_init_context_frame(MpegEncContext *s) return AVERROR(ENOMEM); memset(s->mbintra_table, 1, mb_array_size); +#define ALLOC_POOL(name, size) do { \ + pools->name ##_pool = av_buffer_pool_init((size), av_buffer_allocz); \ + if (!pools->name ##_pool) \ + return AVERROR(ENOMEM); \ +} while (0) + + ALLOC_POOL(mbskip_table, mb_array_size + 2); + ALLOC_POOL(qscale_table, mv_table_size); + ALLOC_POOL(mb_type, mv_table_size * sizeof(uint32_t)); + + if (s->out_format == FMT_H263 || s->encoding || + (s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) { + const int b8_array_size = s->b8_stride * mb_height * 2; + int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); + int ref_index_size = 4 * mb_array_size; + + ALLOC_POOL(motion_val, mv_size); + ALLOC_POOL(ref_index, ref_index_size); + } +#undef ALLOC_POOL + pools->alloc_mb_width = s->mb_width; + pools->alloc_mb_height = mb_height; + pools->alloc_mb_stride = s->mb_stride; + return !CONFIG_MPEGVIDEODEC || s->encoding ? 0 : ff_mpeg_er_init(s); } static void clear_context(MpegEncContext *s) { + memset(&s->buffer_pools, 0, sizeof(s->buffer_pools)); memset(&s->next_picture, 0, sizeof(s->next_picture)); memset(&s->last_picture, 0, sizeof(s->last_picture)); memset(&s->current_picture, 0, sizeof(s->current_picture)); @@ -762,6 +798,7 @@ void ff_mpv_free_context_frame(MpegEncContext *s) { free_duplicate_contexts(s); + free_buffer_pools(&s->buffer_pools); av_freep(&s->p_field_mv_table_base); for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) |