diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-02-11 20:40:59 +0100 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-02-18 20:29:45 +0100 |
commit | 569a0d0012a7d0fe0353c3528a8e6d60ebc10311 (patch) | |
tree | 0a0ab7e4e2c6573f774845756fa8f465549ae7a2 /libavcodec | |
parent | 23b17f96f7cec07ec098838e3cc507507412ce7a (diff) | |
download | ffmpeg-569a0d0012a7d0fe0353c3528a8e6d60ebc10311.tar.gz |
avcodec/msmpeg4dec: Make initializing VLCs thread-safe
This automatically makes the remaining mpegvideo-decoders
(namely msmpeg4v[1-3], mss2, VC-1, VC-1 Image, WMV-[1-3]
and WMV-3 Image) init-threadsafe.
These were the last native codecs that were not init-threadsafe;
only wrappers for external libraries and for hardware accelerations
are now not init-threadsafe.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/msmpeg4dec.c | 47 | ||||
-rw-r--r-- | libavcodec/mss2.c | 1 | ||||
-rw-r--r-- | libavcodec/vc1dec.c | 4 | ||||
-rw-r--r-- | libavcodec/wmv2dec.c | 2 |
4 files changed, 34 insertions, 20 deletions
diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c index a823cc1e12..cd60a85e02 100644 --- a/libavcodec/msmpeg4dec.c +++ b/libavcodec/msmpeg4dec.c @@ -22,6 +22,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/thread.h" + #include "avcodec.h" #include "internal.h" #include "mpegutils.h" @@ -293,22 +295,10 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64]) } /* init all vlc decoding tables */ -av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) +static av_cold void msmpeg4_decode_init_static(void) { - MpegEncContext *s = avctx->priv_data; - static volatile int done = 0; - int ret; MVTable *mv; - if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) - return ret; - - if (ff_h263_decode_init(avctx) < 0) - return -1; - - ff_msmpeg4_common_init(s); - - if (!done) { INIT_FIRST_VLC_RL(ff_rl_table[0], 642); INIT_FIRST_VLC_RL(ff_rl_table[1], 1104); INIT_FIRST_VLC_RL(ff_rl_table[2], 554); @@ -373,8 +363,21 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) INIT_VLC_STATIC(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4, &ff_table_inter_intra[0][1], 2, 1, &ff_table_inter_intra[0][0], 2, 1, 8); - done = 1; - } +} + +av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + MpegEncContext *s = avctx->priv_data; + int ret; + + if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) + return ret; + + if (ff_h263_decode_init(avctx) < 0) + return -1; + + ff_msmpeg4_common_init(s); switch(s->msmpeg4_version){ case 1: @@ -395,6 +398,8 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe + ff_thread_once(&init_static_once, msmpeg4_decode_init_static); + return 0; } @@ -867,7 +872,8 @@ const AVCodec ff_msmpeg4v1_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -885,7 +891,8 @@ const AVCodec ff_msmpeg4v2_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -903,7 +910,8 @@ const AVCodec ff_msmpeg4v3_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -921,7 +929,8 @@ const AVCodec ff_wmv1_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c index 65decf0a3c..630448ddb5 100644 --- a/libavcodec/mss2.c +++ b/libavcodec/mss2.c @@ -856,4 +856,5 @@ const AVCodec ff_mss2_decoder = { .close = mss2_decode_end, .decode = mss2_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 700c787d99..d9939a8ba1 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -1210,6 +1210,7 @@ const AVCodec ff_vc1_decoder = { .decode = vc1_decode_frame, .flush = ff_mpeg_flush, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .pix_fmts = vc1_hwaccel_pixfmt_list_420, .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_VC1_DXVA2_HWACCEL @@ -1247,6 +1248,7 @@ const AVCodec ff_wmv3_decoder = { .decode = vc1_decode_frame, .flush = ff_mpeg_flush, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .pix_fmts = vc1_hwaccel_pixfmt_list_420, .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_WMV3_DXVA2_HWACCEL @@ -1284,6 +1286,7 @@ const AVCodec ff_wmv3image_decoder = { .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .flush = vc1_sprite_flush, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -1303,6 +1306,7 @@ const AVCodec ff_vc1image_decoder = { .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .flush = vc1_sprite_flush, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c index 7121468ae9..736376e5a2 100644 --- a/libavcodec/wmv2dec.c +++ b/libavcodec/wmv2dec.c @@ -601,7 +601,7 @@ const AVCodec ff_wmv2_decoder = { .close = wmv2_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .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_YUV420P, AV_PIX_FMT_NONE }, }; |