[FFmpeg-devel] [libav-devel] [PATCH] movie source add repeat count parameter
Stefano Sabatini
stefasab at gmail.com
Wed Feb 29 13:19:38 CET 2012
On date Tuesday 2012-02-28 19:02:35 +0800, William Yu encoded:
> I think movie source can add a repeat count for read source several times.
> When repeat count is zero, then repeat again and again.
> repeat count parameter has an alias "rc"
>
>
> Signed-off-by: William Yu <genwillyu at gmail.com>
> ---
> libavfilter/src_movie.c | 33 ++++++++++++++++++++++++++++-----
> 1 files changed, 28 insertions(+), 5 deletions(-)
> diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c
> index a0b427d..0b27e07 100644
> --- a/libavfilter/src_movie.c
> +++ b/libavfilter/src_movie.c
> @@ -46,6 +46,7 @@ typedef struct {
> char *format_name;
> char *file_name;
> int stream_index;
> + int repeat_count;
>
> AVFormatContext *format_ctx;
> AVCodecContext *codec_ctx;
> @@ -71,6 +72,8 @@ 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 },
> +{"repeat_count", "set repeat count", OFFSET(repeat_count), AV_OPT_TYPE_INT, {.dbl = 1}, 0, INT_MAX },
> +{"rc", "set repeat count", OFFSET(repeat_count), AV_OPT_TYPE_INT, {.dbl = 1}, 0, INT_MAX },
> {NULL},
> };
Maybe you can call it "loop" or add that alias, for consistency with the
image2 demuxer. Also please update the docs in filters.texi.
>
> @@ -245,7 +248,31 @@ 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->repeat_count != 1) {
> + if (movie->seek_point > 0)
> + timestamp = movie->seek_point;
> + else
> + timestamp = 0;
timestamp = movie->seek_point;
should be enough, since movie->seek_point is always >= 0.
> + 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->repeat_count>1)
> + movie->repeat_count -= 1;
> + 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 +311,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;
> }
Also I see a synch problem here, when you repeat the source, the
timestamp is reset to the original time, while we should probably have a
timestamp_offset and add that to the movie timestamp in the subsequent
plays, so that we have a monotonically increasing timestamp sequence.
Also did you test with image files?
Thanks.
More information about the ffmpeg-devel
mailing list