[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