diff mbox series

[FFmpeg-devel,19/39] avcodec/mpegvideo_enc: Make mpv_encode_defaults thread-safe

Message ID 20201210111657.2276739-20-andreas.rheinhardt@gmail.com
State Accepted
Headers show
Series Make mpegvideo encoders init-threadsafe
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. 10, 2020, 11:16 a.m. UTC
This is a prerequisite for making any encoder that uses
ff_mpv_encode_init() init-threadsafe; it already makes the AMV,
the MJPEG and the MPEG-1/2 encoders init-threadsafe.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/mjpegenc.c      |  4 ++--
 libavcodec/mpeg12enc.c     |  4 ++--
 libavcodec/mpegvideo_enc.c | 15 +++++++++++----
 3 files changed, 15 insertions(+), 8 deletions(-)

Comments

Anton Khirnov Jan. 18, 2021, 10:44 a.m. UTC | #1
Quoting Andreas Rheinhardt (2020-12-10 12:16:37)
> This is a prerequisite for making any encoder that uses
> ff_mpv_encode_init() init-threadsafe; it already makes the AMV,
> the MJPEG and the MPEG-1/2 encoders init-threadsafe.
> 
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
> ---
>  libavcodec/mjpegenc.c      |  4 ++--
>  libavcodec/mpeg12enc.c     |  4 ++--
>  libavcodec/mpegvideo_enc.c | 15 +++++++++++----
>  3 files changed, 15 insertions(+), 8 deletions(-)

Ok
diff mbox series

Patch

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 56ccbc5fb1..466f48eba9 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -415,7 +415,7 @@  AVCodec ff_mjpeg_encoder = {
     .encode2        = ff_mpv_encode_picture,
     .close          = ff_mpv_encode_end,
     .capabilities   = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .pix_fmts       = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE
     },
@@ -441,7 +441,7 @@  AVCodec ff_amv_encoder = {
     .init           = ff_mpv_encode_init,
     .encode2        = amv_encode_picture,
     .close          = ff_mpv_encode_end,
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .pix_fmts       = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE
     },
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 5cbcb15630..e38cd074e1 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -1195,7 +1195,7 @@  AVCodec ff_mpeg1video_encoder = {
     .pix_fmts             = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
                                                            AV_PIX_FMT_NONE },
     .capabilities         = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
-    .caps_internal        = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal        = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .priv_class           = &mpeg1_class,
 };
 
@@ -1213,6 +1213,6 @@  AVCodec ff_mpeg2video_encoder = {
                                                            AV_PIX_FMT_YUV422P,
                                                            AV_PIX_FMT_NONE },
     .capabilities         = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
-    .caps_internal        = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal        = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .priv_class           = &mpeg2_class,
 };
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 4cefe05353..061081db08 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -38,6 +38,7 @@ 
 #include "libavutil/mathematics.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/opt.h"
+#include "libavutil/thread.h"
 #include "avcodec.h"
 #include "dct.h"
 #include "idctdsp.h"
@@ -248,18 +249,24 @@  static void update_duplicate_context_after_me(MpegEncContext *dst,
 #undef COPY
 }
 
+static void mpv_encode_init_static(void)
+{
+   for (int i = -16; i < 16; i++)
+        default_fcode_tab[i + MAX_MV] = 1;
+}
+
 /**
  * Set the given MpegEncContext to defaults for encoding.
  * the changed fields will not depend upon the prior state of the MpegEncContext.
  */
 static void mpv_encode_defaults(MpegEncContext *s)
 {
-    int i;
+    static AVOnce init_static_once = AV_ONCE_INIT;
+
     ff_mpv_common_defaults(s);
 
-    for (i = -16; i < 16; i++) {
-        default_fcode_tab[i + MAX_MV] = 1;
-    }
+    ff_thread_once(&init_static_once, mpv_encode_init_static);
+
     s->me.mv_penalty = default_mv_penalty;
     s->fcode_tab     = default_fcode_tab;