mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
ffmpeg: 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 aftera3a0230a98
This merges Libav commit94ebf55
. It was previously skipped. This is the last filter init related Libav commit that was skipped, so this also removes the commits from doc/libav-merge.txt. Signed-off-by: wm4 <nfxjfg@googlemail.com>
This commit is contained in:
parent
cb884f8d7e
commit
76e13bdeaa
@ -95,7 +95,6 @@ Stuff that didn't reach the codebase:
|
||||
- 0cef06df0 checkasm: add HEVC MC tests
|
||||
- e7078e842 hevcdsp: add x86 SIMD for MC
|
||||
- QSV scaling filter (62c58c5)
|
||||
- ffmpeg.c filter init decoupling (3e265ca,a3a0230,d2e56cf,94ebf55)
|
||||
|
||||
Collateral damage that needs work locally:
|
||||
------------------------------------------
|
||||
|
43
ffmpeg.c
43
ffmpeg.c
@ -2197,6 +2197,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_flags(ifilter->filter, NULL, AV_BUFFERSRC_FLAG_PUSH);
|
||||
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
|
||||
@ -2498,18 +2526,11 @@ out:
|
||||
|
||||
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;
|
||||
}
|
||||
|
2
ffmpeg.h
2
ffmpeg.h
@ -248,6 +248,8 @@ typedef struct InputFilter {
|
||||
uint64_t channel_layout;
|
||||
|
||||
AVBufferRef *hw_frames_ctx;
|
||||
|
||||
int eof;
|
||||
} InputFilter;
|
||||
|
||||
typedef struct OutputFilter {
|
||||
|
@ -1128,6 +1128,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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user