On Thu, 2 Mar 2017 14:03:18 +0100
Michael Niedermayer <mich...@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.
>From adb5854221bb55d34a225bea9c2c29c7bbbfe8c0 Mon Sep 17 00:00:00 2001
From: wm4 <nfx...@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
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel