aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/mpegvideo.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-08-08 21:03:27 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2024-06-12 11:08:19 +0200
commit788892d647636b314fa23df8eaaa3f016809ce0a (patch)
tree2cc6e0e12efe820f83cd1f393061b80395173f0a /libavcodec/mpegvideo.c
parenta95591dbfde3a9347cdfe6537243957e65d2d8ea (diff)
downloadffmpeg-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.c37
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++)