PR #25098 opened by charlymp
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25098
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25098.patch

When no packet is pending, return the output of the oldest thread once it is 
done, instead of holding it until every thread is busy.
This removes up to thread_count - 1 frames of latency for callers feeding 
packets in real time.


>From c9cb071604c1a164c0d04f7a3673547a89b9bb26 Mon Sep 17 00:00:00 2001
From: Charly Morgand-Poyac <[email protected]>
Date: Thu, 15 Oct 2026 11:44:35 +0200
Subject: [PATCH] avcodec/pthread_frame: return finished frames without waiting
 for new input

When no packet is pending, return the output of the oldest thread once it
is done, instead of holding it until every thread is busy. This removes up
to thread_count - 1 frames of latency for callers feeding packets in real
time.

Signed-off-by: Charly Morgand-Poyac <[email protected]>
---
 doc/multithreading.txt     | 7 ++++---
 libavcodec/pthread_frame.c | 7 +++++++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/doc/multithreading.txt b/doc/multithreading.txt
index 842d331e4f..6319a8b749 100644
--- a/doc/multithreading.txt
+++ b/doc/multithreading.txt
@@ -7,9 +7,10 @@ Slice threading decodes multiple parts of a frame at the same 
time, using
 AVCodecContext execute() and execute2().
 
 Frame threading decodes multiple frames at the same time.
-It accepts N future frames and delays decoded pictures by N-1 frames.
+It accepts N future frames and delays decoded pictures by up to N-1 frames.
 The later frames are decoded in separate threads while the user is
-displaying the current one.
+displaying the current one. A picture is returned without waiting for more
+input once it is decoded and no new packet is pending.
 
 Restrictions on clients
 ==============================================
@@ -21,7 +22,7 @@ Slice threading -
 Frame threading -
 * Restrictions with slice threading also apply.
 * Custom get_buffer2() and get_format() callbacks must be thread-safe.
-* There is one frame of delay added for every thread beyond the first one.
+* There is up to one frame of delay added for every thread beyond the first 
one.
   Clients must be able to handle this; the pkt_dts and pkt_pts fields in
   AVFrame will work as usual.
 
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 5ec9a8a974..6ba8d6d871 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -573,6 +573,13 @@ int ff_thread_receive_frame(AVCodecContext *avctx, AVFrame 
*frame, unsigned flag
         /* get a packet to be submitted to the next thread */
         av_packet_unref(fctx->next_pkt);
         ret = ff_decode_get_packet(avctx, fctx->next_pkt);
+
+        /* without new input, return the output of the oldest thread as soon
+         * as it is done instead of holding it until every thread is busy */
+        if (ret == AVERROR(EAGAIN) &&
+            fctx->next_decoding != fctx->next_finished &&
+            atomic_load(&fctx->threads[fctx->next_finished].state) == 
STATE_INPUT_READY)
+            goto wait_for_result;
         if (ret < 0 && ret != AVERROR_EOF)
             goto finish;
 
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to