[FFmpeg-cvslog] avcodec/mpegvideo_enc: Simplify allocating non-slice buffers
Andreas Rheinhardt
git at videolan.org
Sat Jun 21 23:20:55 EEST 2025
ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinhardt at outlook.com> | Wed Apr 30 03:23:01 2025 +0200| [822be72f0a9dcbc8279d9d2f8983a5c53015dd2d] | committer: Andreas Rheinhardt
avcodec/mpegvideo_enc: Simplify allocating non-slice buffers
Allocate them before the slice contexts, so that they are automatically
copied to the slice contexts. This avoids having to set them in a loop.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=822be72f0a9dcbc8279d9d2f8983a5c53015dd2d
---
libavcodec/mpegvideo_enc.c | 148 ++++++++++++++++++++++-----------------------
1 file changed, 73 insertions(+), 75 deletions(-)
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 1fae5fbeb0..60abe08d7a 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -444,50 +444,33 @@ static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avc
return 0;
}
-static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avctx)
+static av_cold int init_buffers(MPVMainEncContext *const m)
{
MPVEncContext *const s = &m->s;
- // Align the following per-thread buffers to avoid false sharing.
- enum {
-#ifndef _MSC_VER
- /// The number is supposed to match/exceed the cache-line size.
- ALIGN = FFMAX(128, _Alignof(max_align_t)),
-#else
- ALIGN = 128,
-#endif
- DCT_ERROR_SIZE = FFALIGN(2 * sizeof(*s->dct_error_sum), ALIGN),
- };
- static_assert(DCT_ERROR_SIZE * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
- "Need checks for potential overflow.");
- unsigned nb_slices = s->c.slice_context_count, mv_table_size, mb_array_size;
- char *dct_error = NULL;
- int has_b_frames = !!m->max_b_frames, nb_mv_tables = 1 + 5 * has_b_frames;
+ int has_b_frames = !!m->max_b_frames;
int16_t (*mv_table)[2];
- if (m->noise_reduction) {
- if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
- return AVERROR(ENOMEM);
- dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);
- if (!dct_error)
- return AVERROR(ENOMEM);
- m->dct_error_sum_base = dct_error;
- dct_error += FFALIGN((uintptr_t)dct_error, ALIGN) - (uintptr_t)dct_error;
- }
-
/* Allocate MB type table */
- mb_array_size = s->c.mb_stride * s->c.mb_height;
+ unsigned mb_array_size = s->c.mb_stride * s->c.mb_height;
s->mb_type = av_calloc(mb_array_size, 3 * sizeof(*s->mb_type) + sizeof(*s->mb_mean));
if (!s->mb_type)
return AVERROR(ENOMEM);
+ s->mc_mb_var = s->mb_type + mb_array_size;
+ s->mb_var = s->mc_mb_var + mb_array_size;
+ s->mb_mean = (uint8_t*)(s->mb_var + mb_array_size);
+
if (!FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size))
return AVERROR(ENOMEM);
- mv_table_size = (s->c.mb_height + 2) * s->c.mb_stride + 1;
+ unsigned mv_table_size = (s->c.mb_height + 2) * s->c.mb_stride + 1;
+ unsigned nb_mv_tables = 1 + 5 * has_b_frames;
if (s->c.codec_id == AV_CODEC_ID_MPEG4 ||
(s->c.avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
nb_mv_tables += 8 * has_b_frames;
- if (!ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * (2 + 4 * has_b_frames), mv_table_size))
+ s->p_field_select_table[0] = av_calloc(mv_table_size, 2 * (2 + 4 * has_b_frames));
+ if (!s->p_field_select_table[0])
return AVERROR(ENOMEM);
+ s->p_field_select_table[1] = s->p_field_select_table[0] + 2 * mv_table_size;
}
mv_table = av_calloc(mv_table_size, nb_mv_tables * sizeof(*mv_table));
@@ -496,43 +479,21 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
m->mv_table_base = mv_table;
mv_table += s->c.mb_stride + 1;
- for (unsigned i = 0; i < nb_slices; ++i) {
- MPVEncContext *const s2 = s->c.enc_contexts[i];
- int16_t (*tmp_mv_table)[2] = mv_table;
-
- if (dct_error) {
- s2->dct_offset = s->dct_offset;
- s2->dct_error_sum = (void*)dct_error;
- dct_error += DCT_ERROR_SIZE;
- }
-
- s2->mb_type = s->mb_type;
- s2->mc_mb_var = s2->mb_type + mb_array_size;
- s2->mb_var = s2->mc_mb_var + mb_array_size;
- s2->mb_mean = (uint8_t*)(s2->mb_var + mb_array_size);
- s2->lambda_table = s->lambda_table;
-
- s2->p_mv_table = tmp_mv_table;
- if (has_b_frames) {
- s2->b_forw_mv_table = tmp_mv_table += mv_table_size;
- s2->b_back_mv_table = tmp_mv_table += mv_table_size;
- s2->b_bidir_forw_mv_table = tmp_mv_table += mv_table_size;
- s2->b_bidir_back_mv_table = tmp_mv_table += mv_table_size;
- s2->b_direct_mv_table = tmp_mv_table += mv_table_size;
- }
-
- if (s->p_field_select_table[0]) { // MPEG-4 or INTERLACED_ME above
- uint8_t *field_select = s->p_field_select_table[0];
- s2->p_field_select_table[0] = field_select;
- s2->p_field_select_table[1] = field_select += 2 * mv_table_size;
-
- if (has_b_frames) {
- for (int j = 0; j < 2; j++) {
- for (int k = 0; k < 2; k++) {
- for (int l = 0; l < 2; l++)
- s2->b_field_mv_table[j][k][l] = tmp_mv_table += mv_table_size;
- s2->b_field_select_table[j][k] = field_select += 2 * mv_table_size;
- }
+ s->p_mv_table = mv_table;
+ if (has_b_frames) {
+ s->b_forw_mv_table = mv_table += mv_table_size;
+ s->b_back_mv_table = mv_table += mv_table_size;
+ s->b_bidir_forw_mv_table = mv_table += mv_table_size;
+ s->b_bidir_back_mv_table = mv_table += mv_table_size;
+ s->b_direct_mv_table = mv_table += mv_table_size;
+
+ if (s->p_field_select_table[1]) { // MPEG-4 or INTERLACED_ME above
+ uint8_t *field_select = s->p_field_select_table[1];
+ for (int j = 0; j < 2; j++) {
+ for (int k = 0; k < 2; k++) {
+ for (int l = 0; l < 2; l++)
+ s->b_field_mv_table[j][k][l] = mv_table += mv_table_size;
+ s->b_field_select_table[j][k] = field_select += 2 * mv_table_size;
}
}
}
@@ -541,6 +502,44 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct
return 0;
}
+static av_cold int init_slice_buffers(MPVMainEncContext *const m)
+{
+ MPVEncContext *const s = &m->s;
+ // Align the following per-thread buffers to avoid false sharing.
+ enum {
+#ifndef _MSC_VER
+ /// The number is supposed to match/exceed the cache-line size.
+ ALIGN = FFMAX(128, _Alignof(max_align_t)),
+#else
+ ALIGN = 128,
+#endif
+ DCT_ERROR_SIZE = FFALIGN(2 * sizeof(*s->dct_error_sum), ALIGN),
+ };
+ static_assert(DCT_ERROR_SIZE * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
+ "Need checks for potential overflow.");
+ unsigned nb_slices = s->c.slice_context_count;
+
+ if (!m->noise_reduction)
+ return 0;
+
+ if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
+ return AVERROR(ENOMEM);
+ char *dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);
+ if (!dct_error)
+ return AVERROR(ENOMEM);
+ m->dct_error_sum_base = dct_error;
+ dct_error += FFALIGN((uintptr_t)dct_error, ALIGN) - (uintptr_t)dct_error;
+
+ for (unsigned i = 0; i < nb_slices; ++i) {
+ MPVEncContext *const s2 = s->c.enc_contexts[i];
+
+ s2->dct_offset = s->dct_offset;
+ s2->dct_error_sum = (void*)dct_error;
+ dct_error += DCT_ERROR_SIZE;
+ }
+ return 0;
+}
+
/* init video encoder */
av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
{
@@ -1059,20 +1058,19 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
ret = ff_mpv_common_init(&s->c);
if (ret < 0)
return ret;
- ret = ff_mpv_init_duplicate_contexts(&s->c);
+ ret = init_buffers(m);
if (ret < 0)
return ret;
-
if (s->c.slice_context_count > 1) {
- for (int i = 0; i < s->c.slice_context_count; ++i) {
- s->c.enc_contexts[i]->rtp_mode = 1;
-
- if (avctx->codec_id == AV_CODEC_ID_H263P)
- s->c.enc_contexts[i]->c.h263_slice_structured = 1;
- }
+ s->rtp_mode = 1;
+ if (avctx->codec_id == AV_CODEC_ID_H263P)
+ s->c.h263_slice_structured = 1;
}
+ ret = ff_mpv_init_duplicate_contexts(&s->c);
+ if (ret < 0)
+ return ret;
- ret = init_buffers(m, avctx);
+ ret = init_slice_buffers(m);
if (ret < 0)
return ret;
More information about the ffmpeg-cvslog
mailing list