[FFmpeg-devel] [PATCH] lavd/lavfi: add shortest option
Stefano Sabatini
stefasab at gmail.com
Fri Jun 1 18:43:31 CEST 2012
---
doc/indevs.texi | 5 +++++
libavdevice/lavfi.c | 32 +++++++++++++++++++++++++++++---
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/doc/indevs.texi b/doc/indevs.texi
index e699e11..88f2d44 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -254,6 +254,11 @@ label, but all the others need to be specified explicitly.
If not specified defaults to the filename specified for the input
device.
+
+ at item shortest
+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.
+Default value is 1.
@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;
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 },
};
--
1.7.5.4
More information about the ffmpeg-devel
mailing list