diff options
author | Alexander Strange <astrange@ithinksw.com> | 2011-02-07 21:15:44 -0500 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2011-02-09 09:17:28 -0500 |
commit | 37b00b47cbeecd66bb34c5c7c534d016d6e8da24 (patch) | |
tree | dce47f2343f8a0f0f73e09a787aa92f255f9aa0f /libavcodec/utils.c | |
parent | c2bd7578af069206831a9c25fa68c9bbd5004619 (diff) | |
download | ffmpeg-37b00b47cbeecd66bb34c5c7c534d016d6e8da24.tar.gz |
Frame-based multithreading framework using pthreads
See doc/multithreading.txt for details on use in codecs.
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r-- | libavcodec/utils.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index e9db33e9d7..529369bd2a 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -37,6 +37,7 @@ #include "dsputil.h" #include "libavutil/opt.h" #include "imgconvert.h" +#include "thread.h" #include "audioconvert.h" #include "internal.h" #include <stdlib.h> @@ -261,6 +262,11 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ (*picture_number)++; if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ + if(s->active_thread_type&FF_THREAD_FRAME) { + av_log_missing_feature(s, "Width/height changing with frame threads is", 0); + return -1; + } + for(i=0; i<4; i++){ av_freep(&buf->base[i]); buf->data[i]= NULL; @@ -532,13 +538,21 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) goto free_and_end; } avctx->frame_number = 0; + + if (HAVE_THREADS && !avctx->thread_opaque) { + ret = avcodec_thread_init(avctx, avctx->thread_count); + if (ret < 0) { + goto free_and_end; + } + } + if (avctx->codec->max_lowres < avctx->lowres) { av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n", avctx->codec->max_lowres); goto free_and_end; } - if(avctx->codec->init){ + if(avctx->codec->init && !(avctx->active_thread_type&FF_THREAD_FRAME)){ ret = avctx->codec->init(avctx); if (ret < 0) { goto free_and_end; @@ -636,14 +650,18 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi avctx->pkt = avpkt; - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){ - ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - avpkt); + if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){ + if (HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME) + ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, + avpkt); + else { + ret = avctx->codec->decode(avctx, picture, got_picture_ptr, + avpkt); + picture->pkt_dts= avpkt->dts; + } emms_c(); //needed to avoid an emms_c() call before every return; - picture->pkt_dts= avpkt->dts; - if (*got_picture_ptr) avctx->frame_number++; }else @@ -768,6 +786,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) if(avctx->codec && avctx->codec->encode) av_freep(&avctx->extradata); avctx->codec = NULL; + avctx->active_thread_type = 0; entangled_thread_counter--; /* Release any user-supplied mutex. */ @@ -1029,6 +1048,8 @@ void avcodec_init(void) void avcodec_flush_buffers(AVCodecContext *avctx) { + if(HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME) + ff_thread_flush(avctx); if(avctx->codec->flush) avctx->codec->flush(avctx); } @@ -1229,3 +1250,30 @@ unsigned int ff_toupper4(unsigned int x) + (toupper((x>>16)&0xFF)<<16) + (toupper((x>>24)&0xFF)<<24); } + +#if !HAVE_PTHREADS + +int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) +{ + f->owner = avctx; + return avctx->get_buffer(avctx, f); +} + +void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) +{ + f->owner->release_buffer(f->owner, f); +} + +void ff_thread_finish_setup(AVCodecContext *avctx) +{ +} + +void ff_thread_report_progress(AVFrame *f, int progress, int field) +{ +} + +void ff_thread_await_progress(AVFrame *f, int progress, int field) +{ +} + +#endif |