Commit d19d52d4 authored by William Yu's avatar William Yu Committed by Stefano Sabatini

lavfi/movie: add loop parameter

Signed-off-by: 's avatarWilliam Yu <genwillyu@gmail.com>
Signed-off-by: 's avatarStefano Sabatini <stefasab@gmail.com>
parent 0ca15aa0
......@@ -3104,6 +3104,13 @@ Specifies the index of the video stream to read. If the value is -1,
the best suited video stream will be automatically selected. Default
value is "-1".
@item loop
Specifies how many times to read the video stream in sequence.
If the value is less than 1, the stream will be read again and again.
Default value is "1".
Note that when the movie is looped the source timestamps are not
changed, so it will generate non monotonically increasing timestamps.
@end table
This filter allows to overlay a second video on top of main input of
......
......@@ -46,6 +46,7 @@ typedef struct {
char *format_name;
char *file_name;
int stream_index;
int loop_count;
AVFormatContext *format_ctx;
AVCodecContext *codec_ctx;
......@@ -71,6 +72,7 @@ static const AVOption movie_options[]= {
{"si", "set stream index", OFFSET(stream_index), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX },
{"seek_point", "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, (INT64_MAX-1) / 1000000 },
{"sp", "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, (INT64_MAX-1) / 1000000 },
{"loop", "set loop count", OFFSET(loop_count), AV_OPT_TYPE_INT, {.dbl = 1}, 0, INT_MAX },
{NULL},
};
......@@ -245,7 +247,27 @@ static int movie_get_frame(AVFilterLink *outlink)
if (movie->is_done == 1)
return 0;
while ((ret = av_read_frame(movie->format_ctx, &pkt)) >= 0) {
while (1) {
ret = av_read_frame(movie->format_ctx, &pkt);
if (ret == AVERROR_EOF) {
int64_t timestamp;
if (movie->loop_count != 1) {
timestamp = movie->seek_point;
if (movie->format_ctx->start_time != AV_NOPTS_VALUE)
timestamp += movie->format_ctx->start_time;
if (av_seek_frame(movie->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD) < 0) {
movie->is_done = 1;
break;
} else if (movie->loop_count>1)
movie->loop_count--;
continue;
} else {
movie->is_done = 1;
break;
}
} else if (ret < 0)
break;
// Is this a packet from the video stream?
if (pkt.stream_index == movie->stream_index) {
avcodec_decode_video2(movie->codec_ctx, movie->frame, &frame_decoded, &pkt);
......@@ -284,10 +306,6 @@ static int movie_get_frame(AVFilterLink *outlink)
av_free_packet(&pkt);
}
// On multi-frame source we should stop the mixing process when
// the movie source does not have more frames
if (ret == AVERROR_EOF)
movie->is_done = 1;
return ret;
}
......
......@@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 2
#define LIBAVFILTER_VERSION_MINOR 65
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_MICRO 101
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment