]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/[e]ac3enc: Make encoders init-threadsafe, fix race
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Thu, 3 Dec 2020 01:57:18 +0000 (02:57 +0100)
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Sat, 9 Jan 2021 03:06:31 +0000 (04:06 +0100)
ff_eac3_exponent_init() set values twice when initializing a static
table; ergo the initialization code must not run concurrently with
a running EAC-3 encoder. Yet this code is executed every time an EAC-3
encoder is initialized. So use ff_thread_once() for this and also for a
similar initialization performed for all AC-3 encoders to make them all
init-threadsafe.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
libavcodec/ac3enc.c
libavcodec/ac3enc_fixed.c
libavcodec/ac3enc_float.c
libavcodec/eac3enc.c

index 0afe94a90988e0e3b169abd10748386301fb972f..1a8a530e52891e402f41a3be342a11f81938badf 100644 (file)
@@ -36,6 +36,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/mem_internal.h"
 #include "libavutil/opt.h"
+#include "libavutil/thread.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "me_cmp.h"
@@ -304,7 +305,7 @@ void ff_ac3_apply_rematrixing(AC3EncodeContext *s)
 /*
  * Initialize exponent tables.
  */
-static av_cold void exponent_init(AC3EncodeContext *s)
+static av_cold void exponent_init(void)
 {
     int expstr, i, grpsize;
 
@@ -317,9 +318,6 @@ static av_cold void exponent_init(AC3EncodeContext *s)
     }
     /* LFE */
     exponent_group_tab[0][0][7] = 2;
-
-    if (CONFIG_EAC3_ENCODER && s->eac3)
-        ff_eac3_exponent_init();
 }
 
 
@@ -2409,6 +2407,7 @@ static av_cold int allocate_buffers(AC3EncodeContext *s)
 
 av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
 {
+    static AVOnce init_static_once = AV_ONCE_INIT;
     AC3EncodeContext *s = avctx->priv_data;
     int ret, frame_size_58;
 
@@ -2448,15 +2447,15 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
         s->mdct_init                    = ff_ac3_float_mdct_init;
         s->allocate_sample_buffers      = ff_ac3_float_allocate_sample_buffers;
     }
-    if (CONFIG_EAC3_ENCODER && s->eac3)
+    if (CONFIG_EAC3_ENCODER && s->eac3) {
+        static AVOnce init_static_once = AV_ONCE_INIT;
+        ff_thread_once(&init_static_once, ff_eac3_exponent_init);
         s->output_frame_header = ff_eac3_output_frame_header;
-    else
+    else
         s->output_frame_header = ac3_output_frame_header;
 
     set_bandwidth(s);
 
-    exponent_init(s);
-
     bit_alloc_init(s);
 
     ret = s->mdct_init(s);
@@ -2473,5 +2472,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
 
     dprint_options(s);
 
+    ff_thread_once(&init_static_once, exponent_init);
+
     return 0;
 }
index 428bbfb3c554a8b156f4351ffa9dedb13fcba102..d2e67f3214789028143c8bb041d0425b28abad99 100644 (file)
@@ -155,7 +155,7 @@ AVCodec ff_ac3_fixed_encoder = {
     .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class      = &ac3enc_class,
-    .caps_internal   = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .supported_samplerates = ff_ac3_sample_rate_tab,
     .channel_layouts = ff_ac3_channel_layouts,
     .defaults        = ac3_defaults,
index 99863a9722ab83a109622b9824ae85977903328a..571f6031824db01e2eafe94ef6e40e88cfb74d0f 100644 (file)
@@ -153,5 +153,5 @@ AVCodec ff_ac3_encoder = {
     .supported_samplerates = ff_ac3_sample_rate_tab,
     .channel_layouts = ff_ac3_channel_layouts,
     .defaults        = ac3_defaults,
-    .caps_internal   = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
index 8e1032f268658a22ec9d8fb6b917f350bdfa147a..00721aa645b25b0192b521b51e30ca32139b303d 100644 (file)
@@ -266,5 +266,5 @@ AVCodec ff_eac3_encoder = {
     .supported_samplerates = ff_ac3_sample_rate_tab,
     .channel_layouts = ff_ac3_channel_layouts,
     .defaults        = ac3_defaults,
-    .caps_internal   = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };