diff mbox series

[FFmpeg-devel,06/13] fftools/ffmpeg_filter: buffer sub2video heartbeat frames like other frames

Message ID 20231123191524.11296-8-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,01/13] lavfi/buffersink: avoid leaking peeked_frame on uninit | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov Nov. 23, 2023, 7:15 p.m. UTC
Otherwise they'd be silently ignored if received by the filtering thread
before the filtergraph can be initialized, which would make the output
dependent on the order in which frames from different inputs arrive.
---
 fftools/ffmpeg_filter.c | 43 ++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 18 deletions(-)
diff mbox series

Patch

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 1b964fc53f..3bafef9717 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -1769,6 +1769,8 @@  static int graph_is_meta(AVFilterGraph *graph)
     return 1;
 }
 
+static int sub2video_frame(InputFilter *ifilter, AVFrame *frame);
+
 static int configure_filtergraph(FilterGraph *fg, const FilterGraphThread *fgt)
 {
     FilterGraphPriv *fgp = fgp_from_fg(fg);
@@ -1880,7 +1882,7 @@  static int configure_filtergraph(FilterGraph *fg, const FilterGraphThread *fgt)
         AVFrame *tmp;
         while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) {
             if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
-                sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)tmp->buf[0]->data);
+                sub2video_frame(&ifp->ifilter, tmp);
             } else {
                 ret = av_buffersrc_add_frame(ifp->filter, tmp);
             }
@@ -2475,9 +2477,6 @@  static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb
     InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
     int64_t pts2;
 
-    if (!ifilter->graph->graph)
-        return;
-
     /* subtitles seem to be usually muxed ahead of other streams;
        if not, subtracting a larger time here is necessary */
     pts2 = av_rescale_q(pts, tb, ifp->time_base) - 1;
@@ -2495,18 +2494,38 @@  static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb
         sub2video_push_ref(ifp, pts2);
 }
 
-static int sub2video_frame(InputFilter *ifilter, const AVFrame *frame)
+static int sub2video_frame(InputFilter *ifilter, AVFrame *frame)
 {
     InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
     int ret;
 
+    if (!ifilter->graph->graph) {
+        AVFrame *tmp;
+
+        if (!frame)
+            return 0;
+
+        tmp = av_frame_alloc();
+        if (!tmp)
+            return AVERROR(ENOMEM);
+
+        av_frame_move_ref(tmp, frame);
+
+        ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
+        if (ret < 0) {
+            av_frame_free(&tmp);
+            return ret;
+        }
+
+        return 0;
+    }
+
     // heartbeat frame
     if (frame && !frame->buf[0]) {
         sub2video_heartbeat(ifilter, frame->pts, frame->time_base);
         return 0;
     }
 
-    if (ifilter->graph->graph) {
         if (!frame) {
             if (ifp->sub2video.end_pts < INT64_MAX)
                 sub2video_update(ifp, INT64_MAX, NULL);
@@ -2518,18 +2537,6 @@  static int sub2video_frame(InputFilter *ifilter, const AVFrame *frame)
         ifp->height = frame->height ? frame->height : ifp->height;
 
         sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data);
-    } else if (frame) {
-        AVFrame *tmp = av_frame_clone(frame);
-
-        if (!tmp)
-            return AVERROR(ENOMEM);
-
-        ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
-        if (ret < 0) {
-            av_frame_free(&tmp);
-            return ret;
-        }
-    }
 
     return 0;
 }