History

avcodec/mpegvideo: Move encoder-only base arrays to MPVMainEncContext

Also allocate them jointly (thereby reducing the number of base arrays considerably) and already set them on all slice contexts; don't rely on ff_update_duplicate_context().

Andreas Rheinhardt committed 1 year ago

Commit 7b5fb2e1 parent a5a2fc03 files · +43 −59Browse files

Unified · Split

3 files
  1. libavcodec/mpegvideo.h +1 −8
  2. libavcodec/mpegvideo_enc.c +41 −51
  3. libavcodec/mpegvideoenc.h +1 −0
libavcodec/mpegvideo.h+1−8
@@ -207,14 +207,7 @@ typedef struct MpegEncContext { · 206 unmodified lines
207207 H263DSPContext h263dsp;
208208 int f_code; ///< forward MV resolution
209209 int b_code; ///< backward MV resolution for B-frames (MPEG-4)
210− int16_t (*p_mv_table_base)[2];
211− int16_t (*b_forw_mv_table_base)[2];
212− int16_t (*b_back_mv_table_base)[2];
213− int16_t (*b_bidir_forw_mv_table_base)[2];
214− int16_t (*b_bidir_back_mv_table_base)[2];
215− int16_t (*b_direct_mv_table_base)[2];
216210 int16_t (*p_field_mv_table_base)[2];
217− int16_t (*b_field_mv_table_base)[2];
218211 int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) P-frame encoding
219212 int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode B-frame encoding
220213 int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode B-frame encoding
@@ -224,7 +217,7 @@ typedef struct MpegEncContext { · 3 unmodified lines
224217 int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced P-frame encoding
225218 int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced B-frame encoding
226219 uint8_t (*p_field_select_table[2]); ///< Only the first element is allocated
227− uint8_t (*b_field_select_table[2][2]); ///< Only the first element is allocated
220+ uint8_t (*b_field_select_table[2][2]); ///< allocated jointly with p_field_select_table
228221
229222 /* The following fields are encoder-only */
230223 uint16_t *mb_var; ///< Table for MB variances
libavcodec/mpegvideo_enc.c+41−51
@@ -437,8 +437,10 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct · 436 unmodified lines
437437 };
438438 static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
439439 "Need checks for potential overflow.");
440− unsigned nb_slices = s->slice_context_count;
440+ unsigned nb_slices = s->slice_context_count, mv_table_size;
441441 char *dct_error = NULL, *me_map;
442+ int nb_mv_tables = 6;
443+ int16_t (*mv_table)[2];
442444
443445 if (s->noise_reduction) {
444446 dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);
@@ -453,8 +455,23 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct · 8 unmodified lines
453455 m->me_map_base = me_map;
454456 me_map += FFALIGN((uintptr_t)me_map, ALIGN) - (uintptr_t)me_map;
455457
458+ mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
459+ if (s->codec_id == AV_CODEC_ID_MPEG4 ||
460+ (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
461+ nb_mv_tables += 8;
462+ if (!ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * (2 + 4), mv_table_size))
463+ return AVERROR(ENOMEM);
464+ }
465+
466+ mv_table = av_calloc(mv_table_size, nb_mv_tables * sizeof(*mv_table));
467+ if (!mv_table)
468+ return AVERROR(ENOMEM);
469+ m->mv_table_base = mv_table;
470+ mv_table += s->mb_stride + 1;
471+
456472 for (unsigned i = 0; i < nb_slices; ++i) {
457473 MpegEncContext *const s2 = s->thread_context[i];
474+ int16_t (*tmp_mv_table)[2] = mv_table;
458475
459476 if (dct_error) {
460477 s2->dct_error_sum = (void*)dct_error;
@@ -463,6 +480,27 @@ static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avct · 2 unmodified lines
463480 s2->me.map = (uint32_t*)me_map;
464481 s2->me.score_map = s2->me.map + ME_MAP_SIZE;
465482 me_map += ME_MAP_ALLOC_SIZE;
483+
484+ s2->p_mv_table = tmp_mv_table;
485+ s2->b_forw_mv_table = tmp_mv_table += mv_table_size;
486+ s2->b_back_mv_table = tmp_mv_table += mv_table_size;
487+ s2->b_bidir_forw_mv_table = tmp_mv_table += mv_table_size;
488+ s2->b_bidir_back_mv_table = tmp_mv_table += mv_table_size;
489+ s2->b_direct_mv_table = tmp_mv_table += mv_table_size;
490+
491+ if (s->p_field_select_table[0]) { // MPEG-4 or INTERLACED_ME above
492+ uint8_t *field_select = s->p_field_select_table[0];
493+ s2->p_field_select_table[0] = field_select;
494+ s2->p_field_select_table[1] = field_select += 2 * mv_table_size;
495+
496+ for (int j = 0; j < 2; j++) {
497+ for (int k = 0; k < 2; k++) {
498+ for (int l = 0; l < 2; l++)
499+ s2->b_field_mv_table[j][k][l] = tmp_mv_table += mv_table_size;
500+ s2->b_field_select_table[j][k] = field_select += 2 * mv_table_size;
501+ }
502+ }
503+ }
466504 }
467505
468506 return 0;
@@ -475,7 +513,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) · 6 unmodified lines
475513 MpegEncContext *const s = &m->s;
476514 AVCPBProperties *cpb_props;
477515 int i, ret;
478− int mb_array_size, mv_table_size;
516+ int mb_array_size;
479517
480518 mpv_encode_defaults(m);
481519
@@ -975,23 +1013,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) · 493 unmodified lines
9751013 if (ret < 0)
9761014 return ret;
9771015
978− /* Allocate MV tables; the MV and MB tables will be copied
979− * to slice contexts by ff_update_duplicate_context(). */
980− mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
981− if (!FF_ALLOCZ_TYPED_ARRAY(s->p_mv_table_base, mv_table_size) ||
982− !FF_ALLOCZ_TYPED_ARRAY(s->b_forw_mv_table_base, mv_table_size) ||
983− !FF_ALLOCZ_TYPED_ARRAY(s->b_back_mv_table_base, mv_table_size) ||
984− !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_forw_mv_table_base, mv_table_size) ||
985− !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_back_mv_table_base, mv_table_size) ||
986− !FF_ALLOCZ_TYPED_ARRAY(s->b_direct_mv_table_base, mv_table_size))
987− return AVERROR(ENOMEM);
988− s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1;
989− s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1;
990− s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1;
991− s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base + s->mb_stride + 1;
992− s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base + s->mb_stride + 1;
993− s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1;
994−
9951016 /* Allocate MB type table */
9961017 mb_array_size = s->mb_stride * s->mb_height;
9971018 if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type, mb_array_size) ||
@@ -1001,30 +1022,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) · 3 unmodified lines
10011022 !(s->mb_mean = av_mallocz(mb_array_size)))
10021023 return AVERROR(ENOMEM);
10031024
1004− if (s->codec_id == AV_CODEC_ID_MPEG4 ||
1005− (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
1006− int16_t (*tmp1)[2];
1007− uint8_t *tmp2;
1008− if (!(tmp1 = ALLOCZ_ARRAYS(s->b_field_mv_table_base, 8, mv_table_size)) ||
1009− !(tmp2 = ALLOCZ_ARRAYS(s->b_field_select_table[0][0], 2 * 4, mv_table_size)) ||
1010− !ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * 2, mv_table_size))
1011− return AVERROR(ENOMEM);
1012−
1013− s->p_field_select_table[1] = s->p_field_select_table[0] + 2 * mv_table_size;
1014− tmp1 += s->mb_stride + 1;
1015−
1016− for (int i = 0; i < 2; i++) {
1017− for (int j = 0; j < 2; j++) {
1018− for (int k = 0; k < 2; k++) {
1019− s->b_field_mv_table[i][j][k] = tmp1;
1020− tmp1 += mv_table_size;
1021− }
1022− s->b_field_select_table[i][j] = tmp2;
1023− tmp2 += 2 * mv_table_size;
1024− }
1025− }
1026− }
1027−
10281025 if (s->noise_reduction) {
10291026 if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
10301027 return AVERROR(ENOMEM);
@@ -1110,14 +1107,7 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx) · 79 unmodified lines
11101107
11111108 av_freep(&avctx->stats_out);
11121109
1113− av_freep(&s->p_mv_table_base);
1114− av_freep(&s->b_forw_mv_table_base);
1115− av_freep(&s->b_back_mv_table_base);
1116− av_freep(&s->b_bidir_forw_mv_table_base);
1117− av_freep(&s->b_bidir_back_mv_table_base);
1118− av_freep(&s->b_direct_mv_table_base);
1119− av_freep(&s->b_field_mv_table_base);
1120− av_freep(&s->b_field_select_table[0][0]);
1110+ av_freep(&m->mv_table_base);
11211111 av_freep(&s->p_field_select_table[0]);
11221112 av_freep(&m->dct_error_sum_base);
11231113 av_freep(&m->me_map_base);
libavcodec/mpegvideoenc.h+1−0
@@ -101,6 +101,7 @@ typedef struct MPVMainEncContext { · 100 unmodified lines
101101
102102 char *me_map_base; ///< backs MotionEstContext.(map|score_map)
103103 char *dct_error_sum_base; ///< backs dct_error_sum
104+ int16_t (*mv_table_base)[2];
104105 } MPVMainEncContext;
105106
106107 static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t