summaryrefslogtreecommitdiff
path: root/libavdevice/lavfi.c
diff options
context:
space:
mode:
authorStefano Sabatini <stefasab@gmail.com>2012-09-20 11:41:11 +0200
committerStefano Sabatini <stefasab@gmail.com>2012-09-20 12:13:17 +0200
commit53d71335cb3652d3fe7936b3bd96418179402285 (patch)
treeccd6742e16bdb7903a6b0d1aa27c5b88f505b153 /libavdevice/lavfi.c
parent98f753ec5198d4f74ba9f68cc85badf8a6257547 (diff)
downloadffmpeg-53d71335cb3652d3fe7936b3bd96418179402285.tar.gz
lavd/lavfi: push frames until the last sink is EOF
Previously the device was returning EOF when the first sink was ending, with the current change the device will continue to return frames until all the sinks are EOF, which seems the most expected behavior.
Diffstat (limited to 'libavdevice/lavfi.c')
-rw-r--r--libavdevice/lavfi.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c
index c75baf91e5..e080857c80 100644
--- a/libavdevice/lavfi.c
+++ b/libavdevice/lavfi.c
@@ -46,6 +46,7 @@ typedef struct {
AVFilterGraph *graph;
AVFilterContext **sinks;
int *sink_stream_map;
+ int *sink_eof;
int *stream_sink_map;
} LavfiContext;
@@ -72,6 +73,7 @@ av_cold static int lavfi_read_close(AVFormatContext *avctx)
LavfiContext *lavfi = avctx->priv_data;
av_freep(&lavfi->sink_stream_map);
+ av_freep(&lavfi->sink_eof);
av_freep(&lavfi->stream_sink_map);
av_freep(&lavfi->sinks);
avfilter_graph_free(&lavfi->graph);
@@ -120,6 +122,8 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx)
if (!(lavfi->sink_stream_map = av_malloc(sizeof(int) * n)))
FAIL(AVERROR(ENOMEM));
+ if (!(lavfi->sink_eof = av_mallocz(sizeof(int) * n)))
+ FAIL(AVERROR(ENOMEM));
if (!(lavfi->stream_sink_map = av_malloc(sizeof(int) * n)))
FAIL(AVERROR(ENOMEM));
@@ -284,9 +288,18 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
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->sink_eof[i])
+ continue;
+
+ ret = av_buffersink_get_buffer_ref(lavfi->sinks[i],
+ &ref, AV_BUFFERSINK_FLAG_PEEK);
+ if (ret == AVERROR_EOF) {
+ av_dlog(avctx, "EOF sink_idx:%d\n", i);
+ lavfi->sink_eof[i] = 1;
+ continue;
+ } else if (ret < 0)
return ret;
d = av_rescale_q(ref->pts, tb, AV_TIME_BASE_Q);
av_dlog(avctx, "sink_idx:%d time:%f\n", i, d);
@@ -296,6 +309,9 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
min_pts_sink_idx = i;
}
}
+ if (min_pts == DBL_MAX)
+ return AVERROR_EOF;
+
av_dlog(avctx, "min_pts_sink_idx:%i\n", min_pts_sink_idx);
av_buffersink_get_buffer_ref(lavfi->sinks[min_pts_sink_idx], &ref, 0);
@@ -325,7 +341,6 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
pkt->pos = ref->pos;
pkt->size = size;
avfilter_unref_buffer(ref);
-
return size;
}