[FFmpeg-devel] [RFC PATCH] ffmpeg: explicitly handle timestamp re-initialization
Jan Ekström
jeebjp at gmail.com
Sat Feb 23 01:57:22 EET 2019
Now each time as the sub2video structure is initialized, the
current time is updated to the first received heartbeat's PTS.
---
Sending this out as an alternative to the other patch, showing how the
sub2video time can be synchronized to the heartbeat explicitly when the
structure is (re-)initialized.
Jan
fftools/ffmpeg.c | 12 +++++++-----
fftools/ffmpeg.h | 3 ++-
fftools/ffmpeg_filter.c | 8 +++++++-
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 544f1a1cef..4cba08e9b8 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -237,7 +237,7 @@ static void sub2video_push_ref(InputStream *ist, int64_t pts)
}
}
-void sub2video_update(InputStream *ist, AVSubtitle *sub)
+void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub)
{
AVFrame *frame = ist->sub2video.frame;
int8_t *dst;
@@ -254,7 +254,8 @@ void sub2video_update(InputStream *ist, AVSubtitle *sub)
AV_TIME_BASE_Q, ist->st->time_base);
num_rects = sub->num_rects;
} else {
- pts = ist->sub2video.end_pts;
+ pts = ist->sub2video.init_timestamps ?
+ heartbeat_pts : ist->sub2video.end_pts;
end_pts = INT64_MAX;
num_rects = 0;
}
@@ -269,6 +270,7 @@ void sub2video_update(InputStream *ist, AVSubtitle *sub)
sub2video_copy_rect(dst, dst_linesize, frame->width, frame->height, sub->rects[i]);
sub2video_push_ref(ist, pts);
ist->sub2video.end_pts = end_pts;
+ ist->sub2video.init_timestamps = 0;
}
static void sub2video_heartbeat(InputStream *ist, int64_t pts)
@@ -293,7 +295,7 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts)
continue;
if (pts2 >= ist2->sub2video.end_pts ||
(!ist2->sub2video.frame->data[0] && ist2->sub2video.end_pts < INT64_MAX))
- sub2video_update(ist2, NULL);
+ sub2video_update(ist2, pts2 + 1, NULL);
for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++)
nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter);
if (nb_reqs)
@@ -307,7 +309,7 @@ static void sub2video_flush(InputStream *ist)
int ret;
if (ist->sub2video.end_pts < INT64_MAX)
- sub2video_update(ist, NULL);
+ sub2video_update(ist, INT64_MAX, NULL);
for (i = 0; i < ist->nb_filters; i++) {
ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
if (ret != AVERROR_EOF && ret < 0)
@@ -2514,7 +2516,7 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output,
return ret;
if (ist->sub2video.frame) {
- sub2video_update(ist, &subtitle);
+ sub2video_update(ist, INT64_MIN, &subtitle);
} else if (ist->nb_filters) {
if (!ist->sub2video.sub_queue)
ist->sub2video.sub_queue = av_fifo_alloc(8 * sizeof(AVSubtitle));
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index eb1eaf6363..58b52984c3 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -349,6 +349,7 @@ typedef struct InputStream {
AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init
AVFrame *frame;
int w, h;
+ unsigned int init_timestamps; ///< marks if sub2video_update should re-init timestamps
} sub2video;
int dr1;
@@ -646,7 +647,7 @@ 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);
+void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub);
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de1e2..c0119a4676 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -740,6 +740,12 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
return AVERROR(ENOMEM);
ist->sub2video.last_pts = INT64_MIN;
ist->sub2video.end_pts = INT64_MIN;
+
+ /* sub2video structure has been (re-)initialized.
+ Mark it as such so that the current time
+ can be initialized with the first heartbeat. */
+ ist->sub2video.init_timestamps = 1;
+
return 0;
}
@@ -1169,7 +1175,7 @@ int configure_filtergraph(FilterGraph *fg)
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);
+ sub2video_update(ist, INT64_MIN, &tmp);
avsubtitle_free(&tmp);
}
}
--
2.20.1
More information about the ffmpeg-devel
mailing list