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().
Showing the changes to libavcodec (3 of 3 files). Show all
Unified · Split
| @@ -207,14 +207,7 @@ typedef struct MpegEncContext { · 206 unmodified lines | |||
| 207 | H263DSPContext h263dsp; | 207 | H263DSPContext h263dsp; |
| 208 | int f_code; ///< forward MV resolution | 208 | 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 encoding | 211 | 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 encoding | 212 | 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 encoding | 213 | 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 encoding | 217 | 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 encoding | 218 | 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 allocated | 219 | 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 |
| 228 | 221 | ||
| 229 | /* The following fields are encoder-only */ | 222 | /* The following fields are encoder-only */ |
| 230 | uint16_t *mb_var; ///< Table for MB variances | 223 | uint16_t *mb_var; ///< Table for MB variances |
| @@ -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); |
| @@ -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_sum | 103 | char *dct_error_sum_base; ///< backs dct_error_sum |
| 104 | int16_t (*mv_table_base)[2]; | ||
| 104 | } MPVMainEncContext; | 105 | } MPVMainEncContext; |
| 105 | 106 | ||
| 106 | static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s) | 107 | static inline const MPVMainEncContext *slice_to_mainenc(const MpegEncContext *s) |