diff mbox series

[FFmpeg-devel,1/7] avcodec/[e]ac3enc: Make encoders init-threadsafe, fix race

Message ID 20201205203340.19357-1-andreas.rheinhardt@gmail.com
State Accepted
Headers show
Series [FFmpeg-devel,1/7] avcodec/[e]ac3enc: Make encoders init-threadsafe, fix race
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished

Commit Message

Andreas Rheinhardt Dec. 5, 2020, 8:33 p.m. UTC
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       | 17 +++++++++--------
 libavcodec/ac3enc_fixed.c |  2 +-
 libavcodec/ac3enc_float.c |  2 +-
 libavcodec/eac3enc.c      |  2 +-
 4 files changed, 12 insertions(+), 11 deletions(-)

Comments

Andreas Rheinhardt Jan. 8, 2021, 10:59 p.m. UTC | #1
Andreas Rheinhardt:
> 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       | 17 +++++++++--------
>  libavcodec/ac3enc_fixed.c |  2 +-
>  libavcodec/ac3enc_float.c |  2 +-
>  libavcodec/eac3enc.c      |  2 +-
>  4 files changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
> index 37dc0fb2ef..3354bf6b45 100644
> --- a/libavcodec/ac3enc.c
> +++ b/libavcodec/ac3enc.c
> @@ -35,6 +35,7 @@
>  #include "libavutil/crc.h"
>  #include "libavutil/internal.h"
>  #include "libavutil/opt.h"
> +#include "libavutil/thread.h"
>  #include "avcodec.h"
>  #include "internal.h"
>  #include "me_cmp.h"
> @@ -303,7 +304,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;
>  
> @@ -316,9 +317,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();
>  }
>  
>  
> @@ -2408,6 +2406,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;
>  
> @@ -2447,15 +2446,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);
> @@ -2472,5 +2471,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
>  
>      dprint_options(s);
>  
> +    ff_thread_once(&init_static_once, exponent_init);
> +
>      return 0;
>  }
> diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
> index 428bbfb3c5..d2e67f3214 100644
> --- a/libavcodec/ac3enc_fixed.c
> +++ b/libavcodec/ac3enc_fixed.c
> @@ -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,
> diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
> index 99863a9722..571f603182 100644
> --- a/libavcodec/ac3enc_float.c
> +++ b/libavcodec/ac3enc_float.c
> @@ -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,
>  };
> diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
> index 8e1032f268..00721aa645 100644
> --- a/libavcodec/eac3enc.c
> +++ b/libavcodec/eac3enc.c
> @@ -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,
>  };
> 
Will apply this patchset tomorrow unless there are objections.

- Andreas
diff mbox series

Patch

diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 37dc0fb2ef..3354bf6b45 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -35,6 +35,7 @@ 
 #include "libavutil/crc.h"
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
+#include "libavutil/thread.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "me_cmp.h"
@@ -303,7 +304,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;
 
@@ -316,9 +317,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();
 }
 
 
@@ -2408,6 +2406,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;
 
@@ -2447,15 +2446,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);
@@ -2472,5 +2471,7 @@  av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
 
     dprint_options(s);
 
+    ff_thread_once(&init_static_once, exponent_init);
+
     return 0;
 }
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 428bbfb3c5..d2e67f3214 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -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,
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index 99863a9722..571f603182 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -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,
 };
diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
index 8e1032f268..00721aa645 100644
--- a/libavcodec/eac3enc.c
+++ b/libavcodec/eac3enc.c
@@ -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,
 };