[FFmpeg-devel] [PATCH] lavd/lavfi: add shortest option

Nicolas George nicolas.george at normalesup.org
Mon Jun 4 00:16:45 CEST 2012


Le quartidi 14 prairial, an CCXX, Stefano Sabatini a écrit :
> +If set to 1, signal the end when the shortest input ends. If set to 0,
> +will continue to output frames until the last stream is ended.

Can you explain the purpose?

> +Default value is 1.

Seems strange and counter-intuitive. It looks that it was the current
behaviour by some kind of happenstance, but IMHO fixing the default
behaviour is more sensible than keeping compatibility 

>  @end table
>  
>  @subsection Examples
> diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c
> index bdc5f58..790df1e 100644
> --- a/libavdevice/lavfi.c
> +++ b/libavdevice/lavfi.c
> @@ -47,6 +47,9 @@ typedef struct {
>      AVFilterContext **sinks;
>      int *sink_stream_map;
>      int *stream_sink_map;
> +    int shortest;
> +    int *stream_is_ended;
> +    int stream_is_ended_count;
>  } LavfiContext;
>  
>  static int *create_all_formats(int n)
> @@ -73,6 +76,7 @@ av_cold static int lavfi_read_close(AVFormatContext *avctx)
>  
>      av_freep(&lavfi->sink_stream_map);
>      av_freep(&lavfi->stream_sink_map);
> +    av_freep(&lavfi->stream_is_ended);
>      av_freep(&lavfi->sinks);
>      avfilter_graph_free(&lavfi->graph);
>  
> @@ -122,6 +126,9 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx)
>          FAIL(AVERROR(ENOMEM));
>      if (!(lavfi->stream_sink_map = av_malloc(sizeof(int) * n)))
>          FAIL(AVERROR(ENOMEM));
> +    if (!(lavfi->stream_is_ended = av_mallocz(sizeof(int) * n)))
> +        FAIL(AVERROR(ENOMEM));
> +    lavfi->stream_is_ended_count = 0;

All that code could be simpler if sinks, sink_stream_map, stream_sink_map,
and now stream_is_ended were grouped in a single structure field.

>  
>      for (i = 0; i < n; i++)
>          lavfi->stream_sink_map[i] = -1;
> @@ -287,15 +294,33 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
>      int ret, i;
>      int size = 0;
>  
> +    if (lavfi->stream_is_ended_count == avctx->nb_streams ||
> +        (lavfi->stream_is_ended_count && lavfi->shortest))
> +        return AVERROR_EOF;
> +
>      /* iterate through all the graph sinks. Select the sink with the
>       * minimum PTS */
>      for (i = 0; i < avctx->nb_streams; i++) {
>          AVRational tb = lavfi->sinks[i]->inputs[0]->time_base;
>          double d;
> -        int ret = av_buffersink_get_buffer_ref(lavfi->sinks[i],
> -                                               &ref, AV_BUFFERSINK_FLAG_PEEK);
> -        if (ret < 0)
> +        int ret;
> +        if (lavfi->stream_is_ended[i])
> +            continue;
> +        ret = av_buffersink_get_buffer_ref(lavfi->sinks[i], &ref, AV_BUFFERSINK_FLAG_PEEK);
> +
> +        if (ret == AVERROR_EOF) {
> +            lavfi->stream_is_ended[i] = 1;
> +            lavfi->stream_is_ended_count++;
> +            if (lavfi->stream_is_ended_count == avctx->nb_streams)
> +                return ret;
> +            else
> +                continue;
> +        } else if (ret < 0) {
> +            char buf[128];
> +            av_strerror(ret, buf, sizeof(buf));
> +            av_log(avctx, AV_LOG_ERROR, "Error occurred with stream %d: %s\n", i, buf);
>              return ret;
> +        }
>          d = av_rescale_q(ref->pts, tb, AV_TIME_BASE_Q);
>          av_dlog(avctx, "sink_idx:%d time:%f\n", i, d);
>  
> @@ -344,6 +369,7 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
>  static const AVOption options[] = {
>      { "graph", "Libavfilter graph", OFFSET(graph_str),  AV_OPT_TYPE_STRING, {.str = NULL }, 0,  0, DEC },
>      { "dumpgraph", "Dump graph to stderr", OFFSET(dump_graph), AV_OPT_TYPE_STRING, {.str = NULL}, 0,  0, DEC },
> +    { "shortest", "signal end when the shortest input ends", OFFSET(shortest), AV_OPT_TYPE_INT, {.dbl=1}, 0, 1, DEC },
>      { NULL },
>  };

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120604/bad148e6/attachment.asc>


More information about the ffmpeg-devel mailing list