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

Showing the changes to libavcodec (3 of 3 files). Show all

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
207 H263DSPContext h263dsp;207 H263DSPContext h263dsp;
208 int f_code; ///< forward MV resolution208 int f_code; ///< forward MV resolution
209 int b_code; ///< backward MV resolution for B-frames (MPEG-4)209 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];
216 int16_t (*p_field_mv_table_base)[2];210 int16_t (*p_field_mv_table_base)[2];
217 int16_t (*b_field_mv_table_base)[2];
218 int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) P-frame encoding211 int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) P-frame encoding
219 int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode B-frame encoding212 int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode B-frame encoding
220 int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode B-frame encoding213 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
224 int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced P-frame encoding217 int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced P-frame encoding
225 int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced B-frame encoding218 int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced B-frame encoding
226 uint8_t (*p_field_select_table[2]); ///< Only the first element is allocated219 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 allocated220 uint8_t (*b_field_select_table[2][2]); ///< allocated jointly with p_field_select_table
228 221
229 /* The following fields are encoder-only */222 /* The following fields are encoder-only */
230 uint16_t *mb_var; ///< Table for MB variances223 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
437 };437 };
438 static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,438 static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
439 "Need checks for potential overflow.");439 "Need checks for potential overflow.");
440 unsigned nb_slices = s->slice_context_count;440 unsigned nb_slices = s->slice_context_count, mv_table_size;
441 char *dct_error = NULL, *me_map;441 char *dct_error = NULL, *me_map;
442 int nb_mv_tables = 6;
443 int16_t (*mv_table)[2];
442 444
443 if (s->noise_reduction) {445 if (s->noise_reduction) {
444 dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);446 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
453 m->me_map_base = me_map;455 m->me_map_base = me_map;
454 me_map += FFALIGN((uintptr_t)me_map, ALIGN) - (uintptr_t)me_map;456 me_map += FFALIGN((uintptr_t)me_map, ALIGN) - (uintptr_t)me_map;
455 457
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
456 for (unsigned i = 0; i < nb_slices; ++i) {472 for (unsigned i = 0; i < nb_slices; ++i) {
457 MpegEncContext *const s2 = s->thread_context[i];473 MpegEncContext *const s2 = s->thread_context[i];
474 int16_t (*tmp_mv_table)[2] = mv_table;
458 475
459 if (dct_error) {476 if (dct_error) {
460 s2->dct_error_sum = (void*)dct_error;477 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
463 s2->me.map = (uint32_t*)me_map;480 s2->me.map = (uint32_t*)me_map;
464 s2->me.score_map = s2->me.map + ME_MAP_SIZE;481 s2->me.score_map = s2->me.map + ME_MAP_SIZE;
465 me_map += ME_MAP_ALLOC_SIZE;482 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 }
466 }504 }
467 505
468 return 0;506 return 0;
@@ -475,7 +513,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) · 6 unmodified lines
475 MpegEncContext *const s = &m->s;513 MpegEncContext *const s = &m->s;
476 AVCPBProperties *cpb_props;514 AVCPBProperties *cpb_props;
477 int i, ret;515 int i, ret;
478 int mb_array_size, mv_table_size;516 int mb_array_size;
479 517
480 mpv_encode_defaults(m);518 mpv_encode_defaults(m);
481 519
@@ -975,23 +1013,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) · 493 unmodified lines
975 if (ret < 0)1013 if (ret < 0)
976 return ret;1014 return ret;
977 1015
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
995 /* Allocate MB type table */1016 /* Allocate MB type table */
996 mb_array_size = s->mb_stride * s->mb_height;1017 mb_array_size = s->mb_stride * s->mb_height;
997 if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type, mb_array_size) ||1018 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
1001 !(s->mb_mean = av_mallocz(mb_array_size)))1022 !(s->mb_mean = av_mallocz(mb_array_size)))
1002 return AVERROR(ENOMEM);1023 return AVERROR(ENOMEM);
1003 1024
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
1028 if (s->noise_reduction) {1025 if (s->noise_reduction) {
1029 if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))1026 if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
1030 return AVERROR(ENOMEM);1027 return AVERROR(ENOMEM);
@@ -1110,14 +1107,7 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx) · 79 unmodified lines
1110 1107
1111 av_freep(&avctx->stats_out);1108 av_freep(&avctx->stats_out);
1112 1109
1113 av_freep(&s->p_mv_table_base);1110 av_freep(&m->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]);
1121 av_freep(&s->p_field_select_table[0]);1111 av_freep(&s->p_field_select_table[0]);
1122 av_freep(&m->dct_error_sum_base);1112 av_freep(&m->dct_error_sum_base);
1123 av_freep(&m->me_map_base);1113 av_freep(&m->me_map_base);
libavcodec/mpegvideoenc.h+1−0
@@ -101,6 +101,7 @@ typedef struct MPVMainEncContext { · 100 unmodified lines
101 101
102 char *me_map_base; ///< backs MotionEstContext.(map|score_map)102 char *me_map_base; ///< backs MotionEstContext.(map|score_map)
103 char *dct_error_sum_base; ///< backs dct_error_sum103 char *dct_error_sum_base; ///< backs dct_error_sum
104 int16_t (*mv_table_base)[2];
104} MPVMainEncContext;105} MPVMainEncContext;
105 106
106static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s)107static 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