They are currently allocated separately per slice; allocating them jointly allows to avoid saving them in ff_update_duplicate_context(). The way it is done also avoids allocating ac_val for encoders that don't need it (e.g. H.263 or H.263+ with AIC). This entailed moving setting nb_slices to ff_mpv_init_context_frame() which is called from ff_mpv_common_frame_size_change(). The resultant nb_slices will always be one when called from a decoder using ff_mpv_common_frame_size_change().
Unified · Split
| @@ -120,18 +120,6 @@ static av_cold int init_duplicate_context(MpegEncContext *s) · 119 unmodified lines | |||
| 120 | return AVERROR(ENOMEM); | 120 | return AVERROR(ENOMEM); |
| 121 | s->block = s->blocks[0]; | 121 | s->block = s->blocks[0]; |
| 122 | 122 | ||
| 123 | if (s->out_format == FMT_H263) { | ||
| 124 | int mb_height = s->msmpeg4_version == MSMP4_VC1 ? | ||
| 125 | FFALIGN(s->mb_height, 2) : s->mb_height; | ||
| 126 | int y_size = s->b8_stride * (2 * mb_height + 1); | ||
| 127 | int c_size = s->mb_stride * (mb_height + 1); | ||
| 128 | int yc_size = y_size + 2 * c_size; | ||
| 129 | /* ac values */ | ||
| 130 | if (!FF_ALLOCZ_TYPED_ARRAY(s->ac_val_base, yc_size)) | ||
| 131 | return AVERROR(ENOMEM); | ||
| 132 | s->ac_val = s->ac_val_base + s->b8_stride + 1; | ||
| 133 | } | ||
| 134 | |||
| 135 | return 0; | 123 | return 0; |
| 136 | } | 124 | } |
| 137 | 125 | ||
| @@ -171,7 +159,6 @@ static av_cold void free_duplicate_context(MpegEncContext *s) · 33 unmodified lines | |||
| 171 | s->sc.linesize = 0; | 159 | s->sc.linesize = 0; |
| 172 | 160 | ||
| 173 | av_freep(&s->blocks); | 161 | av_freep(&s->blocks); |
| 174 | av_freep(&s->ac_val_base); | ||
| 175 | s->block = NULL; | 162 | s->block = NULL; |
| 176 | } | 163 | } |
| 177 | 164 | ||
| @@ -192,7 +179,6 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src) · 14 unmodified lines | |||
| 192 | COPY(block); | 179 | COPY(block); |
| 193 | COPY(start_mb_y); | 180 | COPY(start_mb_y); |
| 194 | COPY(end_mb_y); | 181 | COPY(end_mb_y); |
| 195 | COPY(ac_val_base); | ||
| 196 | COPY(ac_val); | 182 | COPY(ac_val); |
| 197 | #undef COPY | 183 | #undef COPY |
| 198 | } | 184 | } |
| @@ -245,15 +231,34 @@ static av_cold void free_buffer_pools(BufferPoolContext *pools) · 46 unmodified lines | |||
| 245 | 231 | ||
| 246 | av_cold int ff_mpv_init_context_frame(MpegEncContext *s) | 232 | av_cold int ff_mpv_init_context_frame(MpegEncContext *s) |
| 247 | { | 233 | { |
| 234 | int nb_slices = (HAVE_THREADS && | ||
| 235 | s->avctx->active_thread_type & FF_THREAD_SLICE) ? | ||
| 236 | s->avctx->thread_count : 1; | ||
| 248 | BufferPoolContext *const pools = &s->buffer_pools; | 237 | BufferPoolContext *const pools = &s->buffer_pools; |
| 249 | int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; | 238 | int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; |
| 250 | int mb_height; | 239 | int mb_height; |
| 251 | 240 | ||
| 241 | if (s->encoding && s->avctx->slices) | ||
| 242 | nb_slices = s->avctx->slices; | ||
| 243 | |||
| 252 | if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) | 244 | if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) |
| 253 | s->mb_height = (s->height + 31) / 32 * 2; | 245 | s->mb_height = (s->height + 31) / 32 * 2; |
| 254 | else | 246 | else |
| 255 | s->mb_height = (s->height + 15) / 16; | 247 | s->mb_height = (s->height + 15) / 16; |
| 256 | 248 | ||
| 249 | if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) { | ||
| 250 | int max_slices; | ||
| 251 | if (s->mb_height) | ||
| 252 | max_slices = FFMIN(MAX_THREADS, s->mb_height); | ||
| 253 | else | ||
| 254 | max_slices = MAX_THREADS; | ||
| 255 | av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d)," | ||
| 256 | " reducing to %d\n", nb_slices, max_slices); | ||
| 257 | nb_slices = max_slices; | ||
| 258 | } | ||
| 259 | |||
| 260 | s->slice_context_count = nb_slices; | ||
| 261 | |||
| 257 | /* VC-1 can change from being progressive to interlaced on a per-frame | 262 | /* VC-1 can change from being progressive to interlaced on a per-frame |
| 258 | * basis. We therefore allocate certain buffers so big that they work | 263 | * basis. We therefore allocate certain buffers so big that they work |
| 259 | * in both instances. */ | 264 | * in both instances. */ |
| @@ -332,6 +337,14 @@ av_cold int ff_mpv_init_context_frame(MpegEncContext *s) · 72 unmodified lines | |||
| 332 | } | 337 | } |
| 333 | 338 | ||
| 334 | if (s->h263_pred || s->h263_aic || !s->encoding) { | 339 | if (s->h263_pred || s->h263_aic || !s->encoding) { |
| 340 | size_t allslice_yc_size = yc_size * (s->encoding ? nb_slices : 1); | ||
| 341 | if (s->out_format == FMT_H263) { | ||
| 342 | /* ac values */ | ||
| 343 | if (!FF_ALLOCZ_TYPED_ARRAY(s->ac_val_base, allslice_yc_size)) | ||
| 344 | return AVERROR(ENOMEM); | ||
| 345 | s->ac_val = s->ac_val_base + s->b8_stride + 1; | ||
| 346 | } | ||
| 347 | |||
| 335 | /* dc values */ | 348 | /* dc values */ |
| 336 | // MN: we need these for error resilience of intra-frames | 349 | // MN: we need these for error resilience of intra-frames |
| 337 | // Allocating them unconditionally for decoders also means | 350 | // Allocating them unconditionally for decoders also means |
| @@ -381,14 +394,8 @@ av_cold int ff_mpv_init_context_frame(MpegEncContext *s) · 43 unmodified lines | |||
| 381 | */ | 394 | */ |
| 382 | av_cold int ff_mpv_common_init(MpegEncContext *s) | 395 | av_cold int ff_mpv_common_init(MpegEncContext *s) |
| 383 | { | 396 | { |
| 384 | int nb_slices = (HAVE_THREADS && | ||
| 385 | s->avctx->active_thread_type & FF_THREAD_SLICE) ? | ||
| 386 | s->avctx->thread_count : 1; | ||
| 387 | int ret; | 397 | int ret; |
| 388 | 398 | ||
| 389 | if (s->encoding && s->avctx->slices) | ||
| 390 | nb_slices = s->avctx->slices; | ||
| 391 | |||
| 392 | if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) { | 399 | if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) { |
| 393 | av_log(s->avctx, AV_LOG_ERROR, | 400 | av_log(s->avctx, AV_LOG_ERROR, |
| 394 | "decoding to AV_PIX_FMT_NONE is not supported.\n"); | 401 | "decoding to AV_PIX_FMT_NONE is not supported.\n"); |
| @@ -411,20 +418,8 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) · 16 unmodified lines | |||
| 411 | if ((ret = ff_mpv_init_context_frame(s))) | 418 | if ((ret = ff_mpv_init_context_frame(s))) |
| 412 | goto fail; | 419 | goto fail; |
| 413 | 420 | ||
| 414 | if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) { | ||
| 415 | int max_slices; | ||
| 416 | if (s->mb_height) | ||
| 417 | max_slices = FFMIN(MAX_THREADS, s->mb_height); | ||
| 418 | else | ||
| 419 | max_slices = MAX_THREADS; | ||
| 420 | av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d)," | ||
| 421 | " reducing to %d\n", nb_slices, max_slices); | ||
| 422 | nb_slices = max_slices; | ||
| 423 | } | ||
| 424 | |||
| 425 | s->context_initialized = 1; | 421 | s->context_initialized = 1; |
| 426 | s->thread_context[0] = s; | 422 | s->thread_context[0] = s; |
| 427 | s->slice_context_count = nb_slices; | ||
| 428 | 423 | ||
| 429 | // if (s->width && s->height) { | 424 | // if (s->width && s->height) { |
| 430 | if (!s->encoding) { | 425 | if (!s->encoding) { |
| @@ -450,6 +445,7 @@ av_cold void ff_mpv_free_context_frame(MpegEncContext *s) · 19 unmodified lines | |||
| 450 | for (int j = 0; j < 2; j++) | 445 | for (int j = 0; j < 2; j++) |
| 451 | s->p_field_mv_table[i][j] = NULL; | 446 | s->p_field_mv_table[i][j] = NULL; |
| 452 | 447 | ||
| 448 | av_freep(&s->ac_val_base); | ||
| 453 | av_freep(&s->dc_val_base); | 449 | av_freep(&s->dc_val_base); |
| 454 | av_freep(&s->coded_block_base); | 450 | av_freep(&s->coded_block_base); |
| 455 | av_freep(&s->mbintra_table); | 451 | av_freep(&s->mbintra_table); |
| @@ -518,24 +518,36 @@ static av_cold int init_slice_buffers(MPVMainEncContext *const m) · 517 unmodified lines | |||
| 518 | static_assert(DCT_ERROR_SIZE * MAX_THREADS + ALIGN - 1 <= SIZE_MAX, | 518 | static_assert(DCT_ERROR_SIZE * MAX_THREADS + ALIGN - 1 <= SIZE_MAX, |
| 519 | "Need checks for potential overflow."); | 519 | "Need checks for potential overflow."); |
| 520 | unsigned nb_slices = s->c.slice_context_count; | 520 | unsigned nb_slices = s->c.slice_context_count; |
| 521 | char *dct_error = NULL; | ||
| 521 | 522 | ||
| 522 | if (!m->noise_reduction) | 523 | if (m->noise_reduction) { |
| 523 | return 0; | 524 | if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2)) |
| 525 | return AVERROR(ENOMEM); | ||
| 526 | dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE); | ||
| 527 | if (!dct_error) | ||
| 528 | return AVERROR(ENOMEM); | ||
| 529 | m->dct_error_sum_base = dct_error; | ||
| 530 | dct_error += FFALIGN((uintptr_t)dct_error, ALIGN) - (uintptr_t)dct_error; | ||
| 531 | } | ||
| 524 | 532 | ||
| 525 | if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2)) | 533 | const int y_size = s->c.b8_stride * (2 * s->c.mb_height + 1); |
| 526 | return AVERROR(ENOMEM); | 534 | const int c_size = s->c.mb_stride * (s->c.mb_height + 1); |
| 527 | char *dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE); | 535 | const int yc_size = y_size + 2 * c_size; |
| 528 | if (!dct_error) | 536 | ptrdiff_t offset = 0; |
| 529 | return AVERROR(ENOMEM); | ||
| 530 | m->dct_error_sum_base = dct_error; | ||
| 531 | dct_error += FFALIGN((uintptr_t)dct_error, ALIGN) - (uintptr_t)dct_error; | ||
| 532 | 537 | ||
| 533 | for (unsigned i = 0; i < nb_slices; ++i) { | 538 | for (unsigned i = 0; i < nb_slices; ++i) { |
| 534 | MPVEncContext *const s2 = s->c.enc_contexts[i]; | 539 | MPVEncContext *const s2 = s->c.enc_contexts[i]; |
| 535 | 540 | ||
| 536 | s2->dct_offset = s->dct_offset; | 541 | if (dct_error) { |
| 537 | s2->dct_error_sum = (void*)dct_error; | 542 | s2->dct_offset = s->dct_offset; |
| 538 | dct_error += DCT_ERROR_SIZE; | 543 | s2->dct_error_sum = (void*)dct_error; |
| 544 | dct_error += DCT_ERROR_SIZE; | ||
| 545 | } | ||
| 546 | |||
| 547 | if (s2->c.ac_val) { | ||
| 548 | s2->c.ac_val += offset; | ||
| 549 | offset += yc_size; | ||
| 550 | } | ||
| 539 | } | 551 | } |
| 540 | return 0; | 552 | return 0; |
| 541 | } | 553 | } |