History

avcodec/mpegvideo: Allocate ac_val jointly

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().

Andreas Rheinhardt committed 1 year ago

Commit c4ebe551 parent dba10612 files · +52 −44Browse files

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

Unified · Split

2 files
  1. libavcodec/mpegvideo.c +28 −32
  2. libavcodec/mpegvideo_enc.c +24 −12
libavcodec/mpegvideo.c+28−32
@@ -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 COPY183#undef COPY
198}184}
@@ -245,15 +231,34 @@ static av_cold void free_buffer_pools(BufferPoolContext *pools) · 46 unmodified lines
245 231
246av_cold int ff_mpv_init_context_frame(MpegEncContext *s)232av_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 else246 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-frame262 /* VC-1 can change from being progressive to interlaced on a per-frame
258 * basis. We therefore allocate certain buffers so big that they work263 * 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-frames349 // MN: we need these for error resilience of intra-frames
337 // Allocating them unconditionally for decoders also means350 // 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 */
382av_cold int ff_mpv_common_init(MpegEncContext *s)395av_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);
libavcodec/mpegvideo_enc.c+24−12
@@ -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}

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