return;
av_frame_free(&(*link)->partial_buf);
+ ff_video_frame_pool_uninit((FFVideoFramePool**)&(*link)->video_frame_pool);
av_freep(link);
}
return link->channels;
}
+void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts)
+{
+ ff_avfilter_link_set_out_status(link, status, pts);
+}
+
+void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts)
+{
+ link->status = status;
+ link->frame_wanted_in = link->frame_wanted_out = 0;
+ ff_update_link_current_pts(link, pts);
+}
+
void avfilter_link_set_closed(AVFilterLink *link, int closed)
{
- link->closed = closed;
+ ff_avfilter_link_set_out_status(link, closed ? AVERROR_EOF : 0, AV_NOPTS_VALUE);
}
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
}
inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
- link->current_pts = AV_NOPTS_VALUE;
+ link->current_pts =
+ link->current_pts_us = AV_NOPTS_VALUE;
switch (link->init_state) {
case AVLINK_INIT:
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->status)
+ return link->status;
+ link->frame_wanted_in = 1;
+ link->frame_wanted_out = 1;
+ return 0;
+}
+
+int ff_request_frame_to_filter(AVFilterLink *link)
+{
+ int ret = -1;
+
+ FF_TPRINTF_START(NULL, request_frame_to_filter); ff_tlog_link(NULL, link, 1);
+ link->frame_wanted_in = 0;
if (link->srcpad->request_frame)
ret = link->srcpad->request_frame(link);
else if (link->src->inputs[0])
AVFrame *pbuf = link->partial_buf;
link->partial_buf = NULL;
ret = ff_filter_frame_framed(link, pbuf);
+ ff_avfilter_link_set_in_status(link, AVERROR_EOF, AV_NOPTS_VALUE);
+ link->frame_wanted_out = 0;
+ return ret;
}
if (ret < 0) {
- if (ret == AVERROR_EOF)
- link->closed = 1;
+ if (ret != AVERROR(EAGAIN) && ret != link->status)
+ ff_avfilter_link_set_in_status(link, ret, AV_NOPTS_VALUE);
}
return ret;
}
{
if (pts == AV_NOPTS_VALUE)
return;
- link->current_pts = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
+ link->current_pts = pts;
+ link->current_pts_us = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
/* TODO use duration */
if (link->graph && link->age_index >= 0)
ff_avfilter_graph_update_heap(link->graph, link);
AVFilterCommand *cmd= link->dst->command_queue;
int64_t pts;
- if (link->closed) {
+ if (link->status) {
av_frame_free(&frame);
- return AVERROR_EOF;
+ return link->status;
}
if (!(filter_frame = dst->filter_frame))
if (pbuf->nb_samples >= link->min_samples) {
ret = ff_filter_frame_framed(link, pbuf);
pbuf = NULL;
+ } else {
+ if (link->frame_wanted_out)
+ link->frame_wanted_in = 1;
}
}
av_frame_free(&frame);
}
}
+ link->frame_wanted_out = 0;
/* Go directly to actual filtering if possible */
if (link->type == AVMEDIA_TYPE_AUDIO &&
link->min_samples &&