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
120120 return AVERROR(ENOMEM);
121121 s->block = s->blocks[0];
122122
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−
135123 return 0;
136124 }
137125
@@ -171,7 +159,6 @@ static av_cold void free_duplicate_context(MpegEncContext *s) · 33 unmodified lines
171159 s->sc.linesize = 0;
172160
173161 av_freep(&s->blocks);
174− av_freep(&s->ac_val_base);
175162 s->block = NULL;
176163 }
177164
@@ -192,7 +179,6 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src) · 14 unmodified lines
192179 COPY(block);
193180 COPY(start_mb_y);
194181 COPY(end_mb_y);
195− COPY(ac_val_base);
196182 COPY(ac_val);
197183 #undef COPY
198184 }
@@ -245,15 +231,34 @@ static av_cold void free_buffer_pools(BufferPoolContext *pools) · 46 unmodified lines
245231
246232 av_cold int ff_mpv_init_context_frame(MpegEncContext *s)
247233 {
234+ int nb_slices = (HAVE_THREADS &&
235+ s->avctx->active_thread_type & FF_THREAD_SLICE) ?
236+ s->avctx->thread_count : 1;
248237 BufferPoolContext *const pools = &s->buffer_pools;
249238 int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y;
250239 int mb_height;
251240
241+ if (s->encoding && s->avctx->slices)
242+ nb_slices = s->avctx->slices;
243+
252244 if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
253245 s->mb_height = (s->height + 31) / 32 * 2;
254246 else
255247 s->mb_height = (s->height + 15) / 16;
256248
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+
257262 /* VC-1 can change from being progressive to interlaced on a per-frame
258263 * basis. We therefore allocate certain buffers so big that they work
259264 * in both instances. */
@@ -332,6 +337,14 @@ av_cold int ff_mpv_init_context_frame(MpegEncContext *s) · 72 unmodified lines
332337 }
333338
334339 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+
335348 /* dc values */
336349 // MN: we need these for error resilience of intra-frames
337350 // Allocating them unconditionally for decoders also means
@@ -381,14 +394,8 @@ av_cold int ff_mpv_init_context_frame(MpegEncContext *s) · 43 unmodified lines
381394 */
382395 av_cold int ff_mpv_common_init(MpegEncContext *s)
383396 {
384− int nb_slices = (HAVE_THREADS &&
385− s->avctx->active_thread_type & FF_THREAD_SLICE) ?
386− s->avctx->thread_count : 1;
387397 int ret;
388398
389− if (s->encoding && s->avctx->slices)
390− nb_slices = s->avctx->slices;
391−
392399 if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) {
393400 av_log(s->avctx, AV_LOG_ERROR,
394401 "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
411418 if ((ret = ff_mpv_init_context_frame(s)))
412419 goto fail;
413420
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−
425421 s->context_initialized = 1;
426422 s->thread_context[0] = s;
427− s->slice_context_count = nb_slices;
428423
429424 // if (s->width && s->height) {
430425 if (!s->encoding) {
@@ -450,6 +445,7 @@ av_cold void ff_mpv_free_context_frame(MpegEncContext *s) · 19 unmodified lines
450445 for (int j = 0; j < 2; j++)
451446 s->p_field_mv_table[i][j] = NULL;
452447
448+ av_freep(&s->ac_val_base);
453449 av_freep(&s->dc_val_base);
454450 av_freep(&s->coded_block_base);
455451 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
518518 static_assert(DCT_ERROR_SIZE * MAX_THREADS + ALIGN - 1 <= SIZE_MAX,
519519 "Need checks for potential overflow.");
520520 unsigned nb_slices = s->c.slice_context_count;
521+ char *dct_error = NULL;
521522
522− if (!m->noise_reduction)
523− return 0;
523+ if (m->noise_reduction) {
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+ }
524532
525− if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2))
526− return AVERROR(ENOMEM);
527− char *dct_error = av_mallocz(ALIGN - 1 + nb_slices * DCT_ERROR_SIZE);
528− if (!dct_error)
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;
533+ const int y_size = s->c.b8_stride * (2 * s->c.mb_height + 1);
534+ const int c_size = s->c.mb_stride * (s->c.mb_height + 1);
535+ const int yc_size = y_size + 2 * c_size;
536+ ptrdiff_t offset = 0;
532537
533538 for (unsigned i = 0; i < nb_slices; ++i) {
534539 MPVEncContext *const s2 = s->c.enc_contexts[i];
535540
536− s2->dct_offset = s->dct_offset;
537− s2->dct_error_sum = (void*)dct_error;
538− dct_error += DCT_ERROR_SIZE;
541+ if (dct_error) {
542+ s2->dct_offset = s->dct_offset;
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+ }
539551 }
540552 return 0;
541553 }

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