diff --git a/doc/multithreading.txt b/doc/multithreading.txt index 6c65ca9651..842d331e4f 100644 --- a/doc/multithreading.txt +++ b/doc/multithreading.txt @@ -36,9 +36,9 @@ Frame threading - * Codecs similar to ffv1, whose streams don't reset across frames, will not work because their bitstreams cannot be decoded in parallel. -* The contents of buffers must not be read before ff_thread_await_progress() +* The contents of buffers must not be read before ff_progress_frame_await() has been called on them. reget_buffer() and buffer age optimizations no longer work. -* The contents of buffers must not be written to after ff_thread_report_progress() +* The contents of buffers must not be written to after ff_progress_frame_report() has been called on them. This includes draw_edges(). Porting codecs to frame threading @@ -53,14 +53,13 @@ thread. Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little speed gain at this point but it should work. -If there are inter-frame dependencies, so the codec calls -ff_thread_report/await_progress(), set FF_CODEC_CAP_ALLOCATE_PROGRESS in -FFCodec.caps_internal and use ff_thread_get_buffer() to allocate frames. -Otherwise decode directly into the user-supplied frames. +Use ff_thread_get_buffer() (or ff_progress_frame_get_buffer() +in case you have inter-frame dependencies and use the ProgressFrame API) +to allocate frame buffers. -Call ff_thread_report_progress() after some part of the current picture has decoded. +Call ff_progress_frame_report() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn't called anywhere, as it's useful too and the implementation is trivial when you're doing this. Note that draw_edges() needs to be called before reporting progress. -Before accessing a reference frame or its MVs, call ff_thread_await_progress(). +Before accessing a reference frame or its MVs, call ff_progress_frame_await(). diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h index 832e6440d7..1cd1f684f9 100644 --- a/libavcodec/codec_internal.h +++ b/libavcodec/codec_internal.h @@ -65,12 +65,7 @@ /** * The decoder might make use of the ProgressFrame API. */ -#define FF_CODEC_CAP_USES_PROGRESSFRAMES (1 << 11) -/* - * The codec supports frame threading and has inter-frame dependencies, so it - * uses ff_thread_report/await_progress(). - */ -#define FF_CODEC_CAP_ALLOCATE_PROGRESS (1 << 6) +#define FF_CODEC_CAP_USES_PROGRESSFRAMES (1 << 6) /** * Codec handles avctx->thread_count == 0 (auto) internally. */ diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index ba535e800d..dd594e3f9f 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -1129,6 +1129,5 @@ const FFCodec ff_ffv1_decoder = { UPDATE_THREAD_CONTEXT(update_thread_context), .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | - FF_CODEC_CAP_ALLOCATE_PROGRESS, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 0b111b5b99..fd23e367b4 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -1164,7 +1164,7 @@ const FFCodec ff_h264_decoder = { NULL }, .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | - FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP, + FF_CODEC_CAP_INIT_CLEANUP, .flush = h264_decode_flush, UPDATE_THREAD_CONTEXT(ff_h264_update_thread_context), UPDATE_THREAD_CONTEXT_FOR_USER(ff_h264_update_thread_context_for_user), diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 007eae6a1e..d787c7a52d 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -3720,7 +3720,7 @@ const FFCodec ff_hevc_decoder = { .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | - FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP, + FF_CODEC_CAP_INIT_CLEANUP, .p.profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles), .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_HEVC_DXVA2_HWACCEL diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 07de5d6d91..6a7a37e817 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -3861,8 +3861,7 @@ const FFCodec ff_mpeg4_decoder = { FF_CODEC_DECODE_CB(ff_h263_decode_frame), .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | - FF_CODEC_CAP_ALLOCATE_PROGRESS, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = ff_mpeg_flush, .p.max_lowres = 3, .p.profiles = NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles), diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 16e35a8cc6..5a99b4a1c4 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -1940,7 +1940,6 @@ const FFCodec ff_apng_decoder = { UPDATE_THREAD_CONTEXT(update_thread_context), .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | - FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_ICC_PROFILES, }; #endif @@ -1958,7 +1957,7 @@ const FFCodec ff_png_decoder = { UPDATE_THREAD_CONTEXT(update_thread_context), .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | - FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP | + FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_ICC_PROFILES, }; #endif diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index b0dbde1017..a30312021e 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -991,14 +991,12 @@ int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) if (!(avctx->active_thread_type & FF_THREAD_FRAME)) return ff_get_buffer(avctx, f->f, flags); - if (ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS) { - f->progress = ff_refstruct_allocz(sizeof(*f->progress)); - if (!f->progress) - return AVERROR(ENOMEM); + f->progress = ff_refstruct_allocz(sizeof(*f->progress)); + if (!f->progress) + return AVERROR(ENOMEM); - atomic_init(&f->progress->progress[0], -1); - atomic_init(&f->progress->progress[1], -1); - } + atomic_init(&f->progress->progress[0], -1); + atomic_init(&f->progress->progress[1], -1); ret = ff_thread_get_buffer(avctx, f->f, flags); if (ret) diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index 9e13e71805..316962fbbb 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -304,5 +304,4 @@ const FFCodec ff_rv30_decoder = { AV_CODEC_CAP_FRAME_THREADS, .flush = ff_mpeg_flush, UPDATE_THREAD_CONTEXT(ff_rv34_decode_update_thread_context), - .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index e48aa1f684..19d4e742df 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -582,5 +582,4 @@ const FFCodec ff_rv40_decoder = { AV_CODEC_CAP_FRAME_THREADS, .flush = ff_mpeg_flush, UPDATE_THREAD_CONTEXT(ff_rv34_decode_update_thread_context), - .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/tests/avcodec.c b/libavcodec/tests/avcodec.c index 58f54cac74..cd949f6385 100644 --- a/libavcodec/tests/avcodec.c +++ b/libavcodec/tests/avcodec.c @@ -142,7 +142,6 @@ int main(void){ } } if (codec2->caps_internal & (FF_CODEC_CAP_USES_PROGRESSFRAMES | - FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_EXPORTS_CROPPING | @@ -172,10 +171,6 @@ int main(void){ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE | AV_CODEC_CAP_ENCODER_FLUSH)) ERR("Decoder %s has encoder-only capabilities\n"); - if (codec2->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS && - !(codec->capabilities & AV_CODEC_CAP_FRAME_THREADS)) - ERR("Decoder %s wants allocated progress without supporting" - "frame threads\n"); if (codec2->cb_type != FF_CODEC_CB_TYPE_DECODE && codec2->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS) ERR("Decoder %s is marked as setting pkt_dts when it doesn't have"