[FFmpeg-devel] [PATCH 2/5] lavfi/buffersrc: add add av_buffersrc_close().
Nicolas George
george at nsup.org
Sun Aug 3 15:15:37 CEST 2014
Also deprecate adding a NULL frame to mark EOF.
TODO APIchanges entry, version bump.
Signed-off-by: Nicolas George <george at nsup.org>
---
libavfilter/buffersrc.c | 40 ++++++++++++++++++++++++++++++----------
libavfilter/buffersrc.h | 15 +++++++++++++++
2 files changed, 45 insertions(+), 10 deletions(-)
Note: relying on the frame duration for the end timestamp would be fragile
(no filters update it), and technically an API break.
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index 27d3db0..6d71587 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -63,6 +63,7 @@ typedef struct BufferSourceContext {
char *channel_layout_str;
int eof;
+ int64_t eof_pts;
} BufferSourceContext;
#define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format)\
@@ -77,6 +78,27 @@ typedef struct BufferSourceContext {
return AVERROR(EINVAL);\
}
+static int push_if_flag(AVFilterContext *ctx, int flags)
+{
+ return (flags & AV_BUFFERSRC_FLAG_PUSH) ?
+ ctx->output_pads[0].request_frame(ctx->outputs[0]) : 0;
+}
+
+int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, int flags)
+{
+ BufferSourceContext *s = ctx->priv;
+
+ if (pts == AV_NOPTS_VALUE) {
+ av_log(ctx, AV_LOG_WARNING, "No EOF timestamp\n");
+ /* FIXME use duration for audio */
+ pts = av_rescale_q(ctx->outputs[0]->current_pts,
+ AV_TIME_BASE_Q, ctx->outputs[0]->time_base) + 1;
+ }
+ s->eof_pts = pts;
+ s->eof = 1;
+ return push_if_flag(ctx, flags);
+}
+
int attribute_align_arg av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
{
return av_buffersrc_add_frame_flags(ctx, (AVFrame *)frame,
@@ -125,8 +147,7 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
s->nb_failed_requests = 0;
if (!frame) {
- s->eof = 1;
- return 0;
+ return av_buffersrc_close(ctx, AV_NOPTS_VALUE, flags);
} else if (s->eof)
return AVERROR(EINVAL);
@@ -177,11 +198,7 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
return ret;
}
- if ((flags & AV_BUFFERSRC_FLAG_PUSH))
- if ((ret = ctx->output_pads[0].request_frame(ctx->outputs[0])) < 0)
- return ret;
-
- return 0;
+ return push_if_flag(ctx, flags);
}
#if FF_API_AVFILTERBUFFER
@@ -211,8 +228,7 @@ int av_buffersrc_add_ref(AVFilterContext *ctx, AVFilterBufferRef *buf,
int ret = 0, planes, i;
if (!buf) {
- s->eof = 1;
- return 0;
+ return av_buffersrc_close(ctx, AV_NOPTS_VALUE, flags);
} else if (s->eof)
return AVERROR(EINVAL);
@@ -487,10 +503,14 @@ static int request_frame(AVFilterLink *link)
{
BufferSourceContext *c = link->src->priv;
AVFrame *frame;
+ int ret;
if (!av_fifo_size(c->fifo)) {
- if (c->eof)
+ if (c->eof) {
+ if ((ret = ff_filter_link_close(link, c->eof_pts)) < 0)
+ return ret;
return AVERROR_EOF;
+ }
c->nb_failed_requests++;
return AVERROR(EAGAIN);
}
diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h
index ea34c04..28ca545 100644
--- a/libavfilter/buffersrc.h
+++ b/libavfilter/buffersrc.h
@@ -145,6 +145,8 @@ int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame);
*
* @param buffer_src pointer to a buffer source context
* @param frame a frame, or NULL to mark EOF
+ * (Using NULL to mark EOF is deprecated, use
+ * av_buffersrc_close() instead.)
* @param flags a combination of AV_BUFFERSRC_FLAG_*
* @return >= 0 in case of success, a negative AVERROR code
* in case of failure
@@ -154,6 +156,19 @@ int av_buffersrc_add_frame_flags(AVFilterContext *buffer_src,
/**
+ * Close a buffer source.
+ *
+ * This cause EOF to be propagated along the filter graph.
+ *
+ * @param buffer_src pointer to a buffer source context
+ * @param pts the timestamp of the end of stream
+ * @param flags a combination of AV_BUFFERSRC_FLAG_*
+ * @return >= 0 in case of success, a negative AVERROR code
+ * in case of failure
+ */
+int av_buffersrc_close(AVFilterContext *buffer_src, int64_t pts, int flags);
+
+/**
* @}
*/
--
2.0.1
More information about the ffmpeg-devel
mailing list