Commit 94ebf556 authored by Anton Khirnov's avatar Anton Khirnov

avconv: restructure sending EOF to filters

Be more careful when an input stream encounters EOF when its filtergraph
has not been configured yet. The current code would immediately mark the
corresponding output streams as finished, while there may still be
buffered frames waiting for frames to appear on other filtergraph
inputs.

This should fix the random FATE failures for complex filtergraph tests
after a3a0230a
parent d2e56cf7
......@@ -1242,6 +1242,34 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
return 0;
}
static int ifilter_send_eof(InputFilter *ifilter)
{
int i, j, ret;
ifilter->eof = 1;
if (ifilter->filter) {
ret = av_buffersrc_add_frame(ifilter->filter, NULL);
if (ret < 0)
return ret;
} else {
// the filtergraph was never configured
FilterGraph *fg = ifilter->graph;
for (i = 0; i < fg->nb_inputs; i++)
if (!fg->inputs[i]->eof)
break;
if (i == fg->nb_inputs) {
// All the input streams have finished without the filtergraph
// ever being configured.
// Mark the output streams as finished.
for (j = 0; j < fg->nb_outputs; j++)
finish_output_stream(fg->outputs[j]->ost);
}
}
return 0;
}
// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2.
// There is the following difference: if you got a frame, you must call
// it again with pkt=NULL. pkt==NULL is treated differently from pkt.size==0
......@@ -1415,18 +1443,11 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
static int send_filter_eof(InputStream *ist)
{
int i, j, ret;
int i, ret;
for (i = 0; i < ist->nb_filters; i++) {
if (ist->filters[i]->filter) {
ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
if (ret < 0)
return ret;
} else {
// the filtergraph was never configured
FilterGraph *fg = ist->filters[i]->graph;
for (j = 0; j < fg->nb_outputs; j++)
finish_output_stream(fg->outputs[j]->ost);
}
ret = ifilter_send_eof(ist->filters[i]);
if (ret < 0)
return ret;
}
return 0;
}
......
......@@ -212,6 +212,8 @@ typedef struct InputFilter {
uint64_t channel_layout;
AVBufferRef *hw_frames_ctx;
int eof;
} InputFilter;
typedef struct OutputFilter {
......
......@@ -780,6 +780,15 @@ int configure_filtergraph(FilterGraph *fg)
}
}
/* send the EOFs for the finished inputs */
for (i = 0; i < fg->nb_inputs; i++) {
if (fg->inputs[i]->eof) {
ret = av_buffersrc_add_frame(fg->inputs[i]->filter, NULL);
if (ret < 0)
return ret;
}
}
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment