diff mbox series

[FFmpeg-devel,22/29] fftools/ffmpeg: track a list of non-lavfi outputs in InputStream

Message ID 20230409140853.28858-22-anton@khirnov.net
State Accepted
Commit a85e7e5dea542019feb85ab0730338c10c770746
Headers show
Series [FFmpeg-devel,01/29] fftools/ffmpeg: move OutputStream.vsync_frame_number to Encoder | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov April 9, 2023, 2:08 p.m. UTC
Currently, output streams where an input stream is sent directly (i.e.
not through lavfi) are determined by iterating over ALL the output
streams and skipping the irrelevant ones. This is awkward and
inefficient.
---
 fftools/ffmpeg.c          | 21 +++++++++------------
 fftools/ffmpeg.h          | 10 ++++++++++
 fftools/ffmpeg_demux.c    |  7 +++++++
 fftools/ffmpeg_mux_init.c |  3 +++
 4 files changed, 29 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 74aba28a9b..f65ff879c7 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -948,9 +948,6 @@  static int check_output_constraints(InputStream *ist, OutputStream *ost)
 {
     OutputFile *of = output_files[ost->file_index];
 
-    if (ost->ist != ist)
-        return 0;
-
     if (ost->finished & MUXER_FINISHED)
         return 0;
 
@@ -1468,7 +1465,8 @@  static int process_subtitle(InputStream *ist, AVSubtitle *subtitle, int *got_out
     if (!subtitle->num_rects)
         goto out;
 
-    for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+    for (int oidx = 0; oidx < ist->nb_outputs; oidx++) {
+        OutputStream *ost = ist->outputs[oidx];
         if (!check_output_constraints(ist, ost) || !ost->enc_ctx
             || ost->enc_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE)
             continue;
@@ -1830,7 +1828,8 @@  static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
     } else if (!ist->decoding_needed)
         eof_reached = 1;
 
-    for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+    for (int oidx = 0; oidx < ist->nb_outputs; oidx++) {
+        OutputStream *ost = ist->outputs[oidx];
         if (!check_output_constraints(ist, ost) || ost->enc_ctx ||
             (!pkt && no_eof))
             continue;
@@ -2577,13 +2576,11 @@  static int process_input(int file_index)
             }
 
             /* mark all outputs that don't go through lavfi as finished */
-            for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
-                if (ost->ist == ist &&
-                    (!ost->enc_ctx || ost->enc_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
-                    OutputFile *of = output_files[ost->file_index];
-                    close_output_stream(ost);
-                    of_output_packet(of, ost->pkt, ost, 1);
-                }
+            for (int oidx = 0; oidx < ist->nb_outputs; oidx++) {
+                OutputStream *ost = ist->outputs[oidx];
+                OutputFile    *of = output_files[ost->file_index];
+                close_output_stream(ost);
+                of_output_packet(of, ost->pkt, ost, 1);
             }
         }
 
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 80a1192ed0..aef2bbc0df 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -416,6 +416,14 @@  typedef struct InputStream {
     InputFilter **filters;
     int        nb_filters;
 
+    /*
+     * Output targets that do not go through lavfi, i.e. subtitles or
+     * streamcopy. Those two cases are distinguished by the OutputStream
+     * having an encoder or not.
+     */
+    struct OutputStream **outputs;
+    int                nb_outputs;
+
     int reinit_filters;
 
     /* hwaccel options */
@@ -867,6 +875,8 @@  void ifile_close(InputFile **f);
  */
 int ifile_get_packet(InputFile *f, AVPacket **pkt);
 
+void ist_output_add(InputStream *ist, OutputStream *ost);
+
 /* iterate over all input streams in all input files;
  * pass NULL to start iteration */
 InputStream *ist_iter(InputStream *prev);
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 93eed28809..f2da0826ad 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -528,6 +528,7 @@  static void ist_free(InputStream **pist)
     avsubtitle_free(&ist->prev_sub.subtitle);
     av_frame_free(&ist->sub2video.frame);
     av_freep(&ist->filters);
+    av_freep(&ist->outputs);
     av_freep(&ist->hwaccel_device);
     av_freep(&ist->dts_buffer);
 
@@ -559,6 +560,12 @@  void ifile_close(InputFile **pf)
     av_freep(pf);
 }
 
+void ist_output_add(InputStream *ist, OutputStream *ost)
+{
+    GROW_ARRAY(ist->outputs, ist->nb_outputs);
+    ist->outputs[ist->nb_outputs - 1] = ost;
+}
+
 static const AVCodec *choose_decoder(const OptionsContext *o, AVFormatContext *s, AVStream *st,
                                      enum HWAccelID hwaccel_id, enum AVHWDeviceType hwaccel_device_type)
 
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 4b6c704046..62e5643a04 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -647,6 +647,9 @@  static OutputStream *new_output_stream(Muxer *mux, const OptionsContext *o,
     if (ost->ist) {
         ost->ist->discard = 0;
         ost->ist->st->discard = ost->ist->user_set_discard;
+
+        if (!(ost->enc && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)))
+            ist_output_add(ost->ist, ost);
     }
     ost->last_mux_dts = AV_NOPTS_VALUE;