diff mbox

[FFmpeg-devel,v3,0/7] Merge lazy filter initialization in ffmpeg CLI

Message ID 20170302160302.471dc009@debian
State New
Headers show

Commit Message

wm4 March 2, 2017, 3:03 p.m. UTC
On Thu, 2 Mar 2017 14:03:18 +0100
Michael Niedermayer <michael@niedermayer.cc> wrote:

> This one looses the first displayed subtitle (the green "help")
> ./ffmpeg -i ~/tickets/153/bbc_small.ts -filter_complex '[0:v][0:s]overlay' -qscale 2 -t 3 test.avi

Attached patch fixes it. Will push it as part of the series tomorrow.

Comments

Carl Eugen Hoyos March 2, 2017, 4:24 p.m. UTC | #1
2017-03-02 16:03 GMT+01:00 wm4 <nfxjfg@googlemail.com>:
> On Thu, 2 Mar 2017 14:03:18 +0100
> Michael Niedermayer <michael@niedermayer.cc> wrote:
>
>> This one looses the first displayed subtitle (the green "help")
>> ./ffmpeg -i ~/tickets/153/bbc_small.ts -filter_complex '[0:v][0:s]overlay' -qscale 2 -t 3 test.avi
>
> Attached patch fixes it. Will push it as part of the series tomorrow.

Please do not push the set before the crash is fixed.

Carl Eugen
diff mbox

Patch

From adb5854221bb55d34a225bea9c2c29c7bbbfe8c0 Mon Sep 17 00:00:00 2001
From: wm4 <nfxjfg@googlemail.com>
Date: Thu, 2 Mar 2017 16:01:01 +0100
Subject: [PATCH] ffmpeg: delay processing of subtitles before filters are
 initialized

If a subtitle packet came before the first video frame could be fully
decoded, the subtitle packet would get discarded. This puts the subtitle
into a queue instead, and processes it once the attached filter graph is
initialized.
---
 ffmpeg.c        | 22 +++++++++++++++++++---
 ffmpeg.h        |  3 +++
 ffmpeg_filter.c | 13 +++++++++++++
 3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index 27bfc72cff..d232bbd7fd 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -226,7 +226,7 @@  static void sub2video_push_ref(InputStream *ist, int64_t pts)
                                      AV_BUFFERSRC_FLAG_PUSH);
 }
 
-static void sub2video_update(InputStream *ist, AVSubtitle *sub)
+void sub2video_update(InputStream *ist, AVSubtitle *sub)
 {
     AVFrame *frame = ist->sub2video.frame;
     int8_t *dst;
@@ -2468,6 +2468,7 @@  fail:
 static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
 {
     AVSubtitle subtitle;
+    int free_sub = 1;
     int i, ret = avcodec_decode_subtitle2(ist->dec_ctx,
                                           &subtitle, got_output, pkt);
 
@@ -2502,7 +2503,21 @@  static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
     if (!*got_output)
         return ret;
 
-    sub2video_update(ist, &subtitle);
+    if (ist->sub2video.frame) {
+        sub2video_update(ist, &subtitle);
+    } else {
+        if (!ist->sub2video.sub_queue)
+            ist->sub2video.sub_queue = av_fifo_alloc(8 * sizeof(AVSubtitle));
+        if (!ist->sub2video.sub_queue)
+            exit_program(1);
+        if (!av_fifo_space(ist->sub2video.sub_queue)) {
+            ret = av_fifo_realloc2(ist->sub2video.sub_queue, 2 * av_fifo_size(ist->sub2video.sub_queue));
+            if (ret < 0)
+                exit_program(1);
+        }
+        av_fifo_generic_write(ist->sub2video.sub_queue, &subtitle, sizeof(subtitle), NULL);
+        free_sub = 0;
+    }
 
     if (!subtitle.num_rects)
         goto out;
@@ -2520,7 +2535,8 @@  static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
     }
 
 out:
-    avsubtitle_free(&subtitle);
+    if (free_sub)
+        avsubtitle_free(&subtitle);
     return ret;
 }
 
diff --git a/ffmpeg.h b/ffmpeg.h
index 59f6cb3659..06a1251124 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -337,6 +337,7 @@  typedef struct InputStream {
     struct sub2video {
         int64_t last_pts;
         int64_t end_pts;
+        AVFifoBuffer *sub_queue;    ///< queue of AVSubtitle* before filter init
         AVFrame *frame;
         int w, h;
     } sub2video;
@@ -636,6 +637,8 @@  int filtergraph_is_simple(FilterGraph *fg);
 int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
 int init_complex_filtergraph(FilterGraph *fg);
 
+void sub2video_update(InputStream *ist, AVSubtitle *sub);
+
 int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
 
 int ffmpeg_parse_options(int argc, char **argv);
diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c
index 816c906c7e..da2a46d3b7 100644
--- a/ffmpeg_filter.c
+++ b/ffmpeg_filter.c
@@ -1137,6 +1137,19 @@  int configure_filtergraph(FilterGraph *fg)
         }
     }
 
+    /* process queued up subtitle packets */
+    for (i = 0; i < fg->nb_inputs; i++) {
+        InputStream *ist = fg->inputs[i]->ist;
+        if (ist->sub2video.sub_queue && ist->sub2video.frame) {
+            while (av_fifo_size(ist->sub2video.sub_queue)) {
+                AVSubtitle tmp;
+                av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
+                sub2video_update(ist, &tmp);
+                avsubtitle_free(&tmp);
+            }
+        }
+    }
+
     return 0;
 }
 
-- 
2.11.0