| @@ -33,6 +33,7 @@ · 32 unmodified lines |
| 33 | | 33 | |
| 34 | #include "config_components.h" | 34 | #include "config_components.h" |
| 35 | | 35 | |
| | 36 | #include <assert.h> |
| 36 | #include <stdint.h> | 37 | #include <stdint.h> |
| 37 | | 38 | |
| 38 | #include "libavutil/emms.h" | 39 | #include "libavutil/emms.h" |
| @@ -420,6 +421,53 @@ static av_cold int init_matrices(MPVMainEncContext *const m, AVCodecContext *avc · 381 unmodified lines |
| 420 | return 0; | 421 | return 0; |
| 421 | } | 422 | } |
| 422 | | 423 | |
| | 424 | static av_cold int init_buffers(MPVMainEncContext *const m, AVCodecContext *avctx) |
| | 425 | { |
| | 426 | MpegEncContext *const s = &m->s; |
| | 427 | // Align the following per-thread buffers to avoid false sharing. |
| | 428 | enum { |
| | 429 | #ifndef _MSC_VER |
| | 430 | /// The number is supposed to match/exceed the cache-line size. |
| | 431 | ALIGN = FFMAX(128, _Alignof(max_align_t)), |
| | 432 | #else |
| | 433 | ALIGN = 128, |
| | 434 | #endif |
| | 435 | ME_MAP_ALLOC_SIZE = FFALIGN(2 * ME_MAP_SIZE * sizeof(*s->me.map), ALIGN), |
| | 436 | DCT_ERROR_SIZE = FFALIGN(2 * sizeof(*s->dct_error_sum), ALIGN), |
| | 437 | }; |
| | 438 | static_assert(FFMAX(ME_MAP_ALLOC_SIZE, DCT_ERROR_SIZE) * MAX_THREADS + ALIGN - 1 <= SIZE_MAX, |
| | 439 | "Need checks for potential overflow."); |
| | 440 | unsigned nb_slices = s->slice_context_count; |
| | 441 | char *dct_error = NULL, *me_map; |
| | 442 | |
| | 443 | if (s->noise_reduction) { |
| | 444 | dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE); |
| | 445 | if (!dct_error) |
| | 446 | return AVERROR(ENOMEM); |
| | 447 | m->dct_error_sum_base = dct_error; |
| | 448 | dct_error += FFALIGN((uintptr_t)dct_error, ALIGN) - (uintptr_t)dct_error; |
| | 449 | } |
| | 450 | me_map = av_mallocz(ALIGN - 1 + nb_slices * ME_MAP_ALLOC_SIZE); |
| | 451 | if (!me_map) |
| | 452 | return AVERROR(ENOMEM); |
| | 453 | m->me_map_base = me_map; |
| | 454 | me_map += FFALIGN((uintptr_t)me_map, ALIGN) - (uintptr_t)me_map; |
| | 455 | |
| | 456 | for (unsigned i = 0; i < nb_slices; ++i) { |
| | 457 | MpegEncContext *const s2 = s->thread_context[i]; |
| | 458 | |
| | 459 | if (dct_error) { |
| | 460 | s2->dct_error_sum = (void*)dct_error; |
| | 461 | dct_error += DCT_ERROR_SIZE; |
| | 462 | } |
| | 463 | s2->me.map = (uint32_t*)me_map; |
| | 464 | s2->me.score_map = s2->me.map + ME_MAP_SIZE; |
| | 465 | me_map += ME_MAP_ALLOC_SIZE; |
| | 466 | } |
| | 467 | |
| | 468 | return 0; |
| | 469 | } |
| | 470 | |
| 423 | /* init video encoder */ | 471 | /* init video encoder */ |
| 424 | av_cold int ff_mpv_encode_init(AVCodecContext *avctx) | 472 | av_cold int ff_mpv_encode_init(AVCodecContext *avctx) |
| 425 | { | 473 | { |
| @@ -923,6 +971,10 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) · 497 unmodified lines |
| 923 | if (ret < 0) | 971 | if (ret < 0) |
| 924 | return ret; | 972 | return ret; |
| 925 | | 973 | |
| | 974 | ret = init_buffers(m, avctx); |
| | 975 | if (ret < 0) |
| | 976 | return ret; |
| | 977 | |
| 926 | /* Allocate MV tables; the MV and MB tables will be copied | 978 | /* Allocate MV tables; the MV and MB tables will be copied |
| 927 | * to slice contexts by ff_update_duplicate_context(). */ | 979 | * to slice contexts by ff_update_duplicate_context(). */ |
| 928 | mv_table_size = (s->mb_height + 2) * s->mb_stride + 1; | 980 | mv_table_size = (s->mb_height + 2) * s->mb_stride + 1; |
| @@ -1067,6 +1119,8 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx) · 138 unmodified lines |
| 1067 | av_freep(&s->b_field_mv_table_base); | 1119 | av_freep(&s->b_field_mv_table_base); |
| 1068 | av_freep(&s->b_field_select_table[0][0]); | 1120 | av_freep(&s->b_field_select_table[0][0]); |
| 1069 | av_freep(&s->p_field_select_table[0]); | 1121 | av_freep(&s->p_field_select_table[0]); |
| | 1122 | av_freep(&m->dct_error_sum_base); |
| | 1123 | av_freep(&m->me_map_base); |
| 1070 | | 1124 | |
| 1071 | av_freep(&s->mb_type); | 1125 | av_freep(&s->mb_type); |
| 1072 | av_freep(&s->lambda_table); | 1126 | av_freep(&s->lambda_table); |