lavfi/movie: add loop parameter

Signed-off-by: William Yu <genwillyu@gmail.com>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
This commit is contained in:
William Yu 2012-03-15 19:45:26 +08:00 committed by Stefano Sabatini
parent 0ca15aa066
commit d19d52d4a1
3 changed files with 31 additions and 6 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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, \