This already makes several encoders (namely FLV, H.263, H.263+ and
RealVideo 1.0 and 2.0 and SVQ1) that use this init-threadsafe.
It also makes the Snow encoder init-threadsafe; it was already marked
as such since commit
d49210788b0836d56dd872d517fe73f83b080101, because
it was thought to be harmless if one and the same object was
initialized by multiple threads at the same time.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
.init = ff_mpv_encode_init,
.encode2 = ff_mpv_encode_picture,
.close = ff_mpv_encode_end,
.init = ff_mpv_encode_init,
.encode2 = ff_mpv_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_YUV420P,
AV_PIX_FMT_NONE},
.priv_class = &flv_class,
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE},
.priv_class = &flv_class,
#include <limits.h>
#include "libavutil/attributes.h"
#include <limits.h>
#include "libavutil/attributes.h"
+#include "libavutil/thread.h"
#include "avcodec.h"
#include "mpegvideo.h"
#include "mpegvideodata.h"
#include "avcodec.h"
#include "mpegvideo.h"
#include "mpegvideodata.h"
-static av_cold void init_mv_penalty_and_fcode(MpegEncContext *s)
+static av_cold void init_mv_penalty_and_fcode(void)
-av_cold void ff_h263_encode_init(MpegEncContext *s)
+static av_cold void h263_encode_init_static(void)
+ static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
- if (!done) {
- static uint8_t rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3];
- done = 1;
+ ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
+ ff_h263_init_rl_inter();
- ff_rl_init(&ff_rl_intra_aic, rl_intra_table);
- ff_h263_init_rl_inter();
+ init_uni_h263_rl_tab(&ff_rl_intra_aic, uni_h263_intra_aic_rl_len);
+ init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
- init_uni_h263_rl_tab(&ff_rl_intra_aic, uni_h263_intra_aic_rl_len);
- init_uni_h263_rl_tab(&ff_h263_rl_inter, uni_h263_inter_rl_len);
+ init_mv_penalty_and_fcode();
+}
+
+av_cold void ff_h263_encode_init(MpegEncContext *s)
+{
+ static AVOnce init_static_once = AV_ONCE_INIT;
- init_mv_penalty_and_fcode(s);
- }
s->me.mv_penalty= mv_penalty; // FIXME exact table for MSMPEG4 & H.263+
s->intra_ac_vlc_length =s->inter_ac_vlc_length = uni_h263_inter_rl_len;
s->me.mv_penalty= mv_penalty; // FIXME exact table for MSMPEG4 & H.263+
s->intra_ac_vlc_length =s->inter_ac_vlc_length = uni_h263_inter_rl_len;
s->y_dc_scale_table=
s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
}
s->y_dc_scale_table=
s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
}
+
+ ff_thread_once(&init_static_once, h263_encode_init_static);
}
void ff_h263_encode_mba(MpegEncContext *s)
}
void ff_h263_encode_mba(MpegEncContext *s)
.init = ff_mpv_encode_init,
.encode2 = ff_mpv_encode_picture,
.close = ff_mpv_encode_end,
.init = ff_mpv_encode_init,
.encode2 = ff_mpv_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_YUV420P, AV_PIX_FMT_NONE},
.priv_class = &h263_class,
};
.pix_fmts= (const enum AVPixelFormat[]){AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE},
.priv_class = &h263_class,
};
.encode2 = ff_mpv_encode_picture,
.close = ff_mpv_encode_end,
.capabilities = AV_CODEC_CAP_SLICE_THREADS,
.encode2 = ff_mpv_encode_picture,
.close = ff_mpv_encode_end,
.capabilities = AV_CODEC_CAP_SLICE_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_YUV420P, AV_PIX_FMT_NONE },
.priv_class = &h263p_class,
};
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.priv_class = &h263p_class,
};
.init = ff_mpv_encode_init,
.encode2 = ff_mpv_encode_picture,
.close = ff_mpv_encode_end,
.init = ff_mpv_encode_init,
.encode2 = ff_mpv_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_YUV420P, AV_PIX_FMT_NONE },
.priv_class = &rv10_class,
};
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.priv_class = &rv10_class,
};
.init = ff_mpv_encode_init,
.encode2 = ff_mpv_encode_picture,
.close = ff_mpv_encode_end,
.init = ff_mpv_encode_init,
.encode2 = ff_mpv_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_YUV420P, AV_PIX_FMT_NONE },
.priv_class = &rv20_class,
};
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.priv_class = &rv20_class,
};
.init = svq1_encode_init,
.encode2 = svq1_encode_frame,
.close = svq1_encode_end,
.init = svq1_encode_init,
.encode2 = svq1_encode_frame,
.close = svq1_encode_end,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
AV_PIX_FMT_NONE },
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
AV_PIX_FMT_NONE },
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,