This allows for dropping or duplication to match a particular start time.
---
Modified patch to specify first_pts in seconds. Also added documentation.
doc/filters.texi | 8 ++++++++
libavfilter/vf_fps.c | 15 ++++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index 2ee5ad5..7a8e9f9 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1241,6 +1241,14 @@ This filter accepts the following named parameters:
@item fps
Desired output framerate.
+@item first_pts
+Assume the first pts should be this value, in seconds. This allows for
+padding/trimming at the start of stream. By default, no assumption is made
+about the first frame's expected pts, so no padding or trimming is done.
+For example, this could be set to 0 to pad the beginning with duplicates of
+the first frame if a video stream starts after the audio stream or to trim any
+frames with a negative pts.
+
@end table
@anchor{frei0r}
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index 7f51752..4efac6b 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -40,6 +40,8 @@ typedef struct FPSContext {
int64_t first_pts; ///< pts of the first frame that arrived on this
filter
int64_t pts; ///< pts of the first frame currently in the fifo
+ double first_pts_sec; ///< pts, in seconds, of the expected first frame
+
AVRational framerate; ///< target framerate
char *fps; ///< a string describing target framerate
@@ -54,6 +56,7 @@ typedef struct FPSContext {
#define V AV_OPT_FLAG_VIDEO_PARAM
static const AVOption options[] = {
{ "fps", "A string describing desired output framerate", OFFSET(fps),
AV_OPT_TYPE_STRING, { .str = "25" }, .flags = V },
+ { "first_pts", "Assume the first PTS should be this value.",
OFFSET(first_pts_sec), AV_OPT_TYPE_DOUBLE, { .dbl = AV_NOPTS_VALUE}, INT64_MIN,
INT64_MAX, V },
{ NULL },
};
@@ -78,6 +81,7 @@ static av_cold int init(AVFilterContext *ctx)
return AVERROR(ENOMEM);
s->pts = AV_NOPTS_VALUE;
+ s->first_pts = AV_NOPTS_VALUE;
av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num,
s->framerate.den);
return 0;
@@ -177,7 +181,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
if (ret < 0)
return ret;
- s->first_pts = s->pts = buf->pts;
+ if (s->first_pts_sec != AV_NOPTS_VALUE) {
+ double first_pts = s->first_pts_sec * AV_TIME_BASE;
+ first_pts = FFMIN(FFMAX(first_pts, INT64_MIN), INT64_MAX);
+ s->first_pts = s->pts = av_rescale_q(first_pts, AV_TIME_BASE_Q,
+ inlink->time_base);
+ av_log(ctx, AV_LOG_VERBOSE, "Set first input pts to
%"PRId64"\n",
+ s->first_pts);
+ } else {
+ s->first_pts = s->pts = buf->pts;
+ }
} else {
av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
"timestamp.\n");
--
1.8.1.2
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel