[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