diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-06-14 21:19:02 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-06-23 01:38:47 +0200 |
commit | fde1bc64adbec49301c665efab2b49b94bb39c23 (patch) | |
tree | fb3cc9843435870852b113e3cb742278a6776f07 /libavcodec/utils.c | |
parent | 0c851e464229f50c440968c4c94b672e23f691af (diff) | |
download | ffmpeg-fde1bc64adbec49301c665efab2b49b94bb39c23.tar.gz |
lavc: add frame multithreading capability (currently intra only)
Compared to the decoder side, this code is able to change both the
delay and the number of threads seamlessly during encoding. Also
any idle thread can pick up tasks, the strict round robin in order
limit is gone too.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r-- | libavcodec/utils.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index e3a4e93883..39a208d74e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -40,6 +40,7 @@ #include "libavutil/opt.h" #include "imgconvert.h" #include "thread.h" +#include "frame_thread_encoder.h" #include "audioconvert.h" #include "internal.h" #include "bytestream.h" @@ -851,7 +852,14 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD if (!HAVE_THREADS) av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n"); - if (HAVE_THREADS && !avctx->thread_opaque) { + entangled_thread_counter--; //we will instanciate a few encoders thus kick the counter to prevent false detection of a problem + ret = ff_frame_thread_encoder_init(avctx); + entangled_thread_counter++; + if (ret < 0) + goto free_and_end; + + if (HAVE_THREADS && !avctx->thread_opaque + && !(avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) { ret = ff_thread_init(avctx); if (ret < 0) { goto free_and_end; @@ -931,7 +939,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD avctx->pts_correction_last_pts = avctx->pts_correction_last_dts = INT64_MIN; - if(avctx->codec->init && !(avctx->active_thread_type&FF_THREAD_FRAME)){ + if(avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) || avctx->internal->frame_thread_encoder)){ ret = avctx->codec->init(avctx); if (ret < 0) { goto free_and_end; @@ -1301,6 +1309,9 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, *got_packet_ptr = 0; + if(avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME)) + return ff_thread_video_encode_frame(avctx, avpkt, frame, got_packet_ptr); + if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { av_free_packet(avpkt); av_init_packet(avpkt); @@ -1661,6 +1672,11 @@ av_cold int avcodec_close(AVCodecContext *avctx) } if (avcodec_is_open(avctx)) { + if (avctx->internal->frame_thread_encoder && avctx->thread_count > 1) { + entangled_thread_counter --; + ff_frame_thread_encoder_free(avctx); + entangled_thread_counter ++; + } if (HAVE_THREADS && avctx->thread_opaque) ff_thread_free(avctx); if (avctx->codec && avctx->codec->close) |