summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavfilter/audio.c5
-rw-r--r--libavfilter/avfilter.c9
-rw-r--r--libavfilter/avfilter.h17
-rw-r--r--libavfilter/video.c5
4 files changed, 36 insertions, 0 deletions
diff --git a/libavfilter/audio.c b/libavfilter/audio.c
index 525b471065..e7306b134b 100644
--- a/libavfilter/audio.c
+++ b/libavfilter/audio.c
@@ -172,6 +172,11 @@ int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
FF_TPRINTF_START(NULL, filter_samples); ff_tlog_link(NULL, link, 1);
+ if (link->closed) {
+ avfilter_unref_buffer(samplesref);
+ return AVERROR_EOF;
+ }
+
if (!(filter_samples = dst->filter_samples))
filter_samples = default_filter_samples;
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index b1df5373b3..861a57d400 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -159,6 +159,11 @@ void avfilter_link_free(AVFilterLink **link)
av_freep(link);
}
+void avfilter_link_set_closed(AVFilterLink *link, int closed)
+{
+ link->closed = closed;
+}
+
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
{
@@ -325,6 +330,8 @@ int ff_request_frame(AVFilterLink *link)
int ret = -1;
FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1);
+ if (link->closed)
+ return AVERROR_EOF;
if (link->srcpad->request_frame)
ret = link->srcpad->request_frame(link);
else if (link->src->inputs[0])
@@ -335,6 +342,8 @@ int ff_request_frame(AVFilterLink *link)
ff_filter_samples_framed(link, pbuf);
return 0;
}
+ if (ret == AVERROR_EOF)
+ link->closed = 1;
return ret;
}
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 9891a72227..c0575ce1d1 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -697,6 +697,18 @@ struct AVFilterLink {
* by the filters.
*/
AVFilterBufferRef *cur_buf_copy;
+
+ /**
+ * True if the link is closed.
+ * If set, all attemps of start_frame, filter_samples or request_frame
+ * will fail with AVERROR_EOF, and if necessary the reference will be
+ * destroyed.
+ * If request_frame returns AVERROR_EOF, this flag is set on the
+ * corresponding link.
+ * It can be set also be set by either the source or the destination
+ * filter.
+ */
+ int closed;
};
/**
@@ -717,6 +729,11 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad,
void avfilter_link_free(AVFilterLink **link);
/**
+ * Set the closed field of a link.
+ */
+void avfilter_link_set_closed(AVFilterLink *link, int closed);
+
+/**
* Negotiate the media format, dimensions, etc of all inputs to a filter.
*
* @param filter the filter to negotiate the properties for its inputs
diff --git a/libavfilter/video.c b/libavfilter/video.c
index 86332bcfe2..9ab8edb12c 100644
--- a/libavfilter/video.c
+++ b/libavfilter/video.c
@@ -248,6 +248,11 @@ int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
FF_TPRINTF_START(NULL, start_frame); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " "); ff_tlog_ref(NULL, picref, 1);
+ if (link->closed) {
+ avfilter_unref_buffer(picref);
+ return AVERROR_EOF;
+ }
+
if (!(start_frame = dst->start_frame))
start_frame = default_start_frame;