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.
release/1.0
Stefano Sabatini 12 years ago
parent 98f753ec51
commit 53d71335cb
  1. 21
      libavdevice/lavfi.c
  2. 2
      libavdevice/version.h

@ -46,6 +46,7 @@ typedef struct {
AVFilterGraph *graph; AVFilterGraph *graph;
AVFilterContext **sinks; AVFilterContext **sinks;
int *sink_stream_map; int *sink_stream_map;
int *sink_eof;
int *stream_sink_map; int *stream_sink_map;
} LavfiContext; } LavfiContext;
@ -72,6 +73,7 @@ av_cold static int lavfi_read_close(AVFormatContext *avctx)
LavfiContext *lavfi = avctx->priv_data; LavfiContext *lavfi = avctx->priv_data;
av_freep(&lavfi->sink_stream_map); av_freep(&lavfi->sink_stream_map);
av_freep(&lavfi->sink_eof);
av_freep(&lavfi->stream_sink_map); av_freep(&lavfi->stream_sink_map);
av_freep(&lavfi->sinks); av_freep(&lavfi->sinks);
avfilter_graph_free(&lavfi->graph); 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))) if (!(lavfi->sink_stream_map = av_malloc(sizeof(int) * n)))
FAIL(AVERROR(ENOMEM)); 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))) if (!(lavfi->stream_sink_map = av_malloc(sizeof(int) * n)))
FAIL(AVERROR(ENOMEM)); FAIL(AVERROR(ENOMEM));
@ -284,9 +288,18 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
for (i = 0; i < avctx->nb_streams; i++) { for (i = 0; i < avctx->nb_streams; i++) {
AVRational tb = lavfi->sinks[i]->inputs[0]->time_base; AVRational tb = lavfi->sinks[i]->inputs[0]->time_base;
double d; double d;
int ret = av_buffersink_get_buffer_ref(lavfi->sinks[i], int ret;
if (lavfi->sink_eof[i])
continue;
ret = av_buffersink_get_buffer_ref(lavfi->sinks[i],
&ref, AV_BUFFERSINK_FLAG_PEEK); &ref, AV_BUFFERSINK_FLAG_PEEK);
if (ret < 0) 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; return ret;
d = av_rescale_q(ref->pts, tb, AV_TIME_BASE_Q); d = av_rescale_q(ref->pts, tb, AV_TIME_BASE_Q);
av_dlog(avctx, "sink_idx:%d time:%f\n", i, d); 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; 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_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); 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->pos = ref->pos;
pkt->size = size; pkt->size = size;
avfilter_unref_buffer(ref); avfilter_unref_buffer(ref);
return size; return size;
} }

@ -29,7 +29,7 @@
#define LIBAVDEVICE_VERSION_MAJOR 54 #define LIBAVDEVICE_VERSION_MAJOR 54
#define LIBAVDEVICE_VERSION_MINOR 2 #define LIBAVDEVICE_VERSION_MINOR 2
#define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_MICRO 101
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \ LIBAVDEVICE_VERSION_MINOR, \

Loading…
Cancel
Save