Open kasper93 opened 5 days ago
@na-na-hi @ruihe774 Do you have ideas how we can fix untimed ao null? Last time @na-na-hi blamed our mkv demuxer, but it is not the case in this case.
Proposed change by @ruihe774 works, https://github.com/mpv-player/mpv/pull/14079/files#r1593338003 question is this is the best way to handle this.
Basically in non-untimed mode, when we happen to have 0 samples, we trigger audio underrun and this reinits things and trigger EOF. In untimed mode we skip reporting underruns, but then there is no code path to actually trigger EOF.
Help appreciated.
So what's happening here is that the demux layer is reporting EOF, but it doesn't reach to the end of audio filter chain for the first audio frame read (might be decoder's fault but not sure right now). Only after the ao is restarted (because of underrun which happens without --ao-null-untimed
), the next audio frame filtered reports EOF.
For well-formed files and not invalid ones generated by fuzzers, this does not happen: even for a very short audio, the first audio frame already reports EOF.
I think the solution here is that for these malformed files, we have to make sure somehow that the first audio frame reports EOF in this case. If it's not possible, then we have to make ao read a few more frames to determine the EOF status.
For well-formed files and not invalid ones generated by fuzzers, this does not happen: even for a very short audio, the first audio frame already reports EOF.
I think it can still happens, if the last frame fails to decode. Generally, we can have a valid file, corrupted at the and and similar can happen.
If we look at this https://github.com/mpv-player/mpv/blob/cd1b63f628a99d16183961056bb8177511a85888/audio/decode/ad_lavc.c#L194-L201
we can see that we expect AVERROR_EOF
from the decoder, but we don't get it. If I call avcodec_receive_frame
once more we get EOF. So this is what happens after ao reset. I'm not sure yet, why we don't try to read more data. We don't have EOF, but we stop reading, why? ao=null should eat every data and request more.
EDIT:
We get EOF from demuxer, so I think we should already report EOF, if we have no more data to decode. The stream is truncated, decoder doesn't detect EOF, but we never feed more data from demuxer, because there is none.
ffplay has the same issue. It doesn't exit when playing this file. Maybe this needs to be fixed in ffmpeg?
avcodec_receive_frame
here also doesn't signal decoding error in this case.
If I call avcodec_receive_frame once more we get EOF.
Because we send the decoder a NULL packet, which is EOF propagated all the way from the stream layer. It seems that this EOF isn't propagated until we request the frame one more time, which isn't done because we're stuck on the last incomplete frame.
mpv Information
Other Information
Reproduction Steps
mpv --no-config --ao=null --untimed --ao-null-untimed ./clusterfuzz-testcase-minimized-fuzzer_loadfile-4665657266864128
Expected Behavior
mpv exits after playing the file
Actual Behavior
mpv hangs and never reports EOF
Log File
We get one frame of data, eat it, and than loop without any data.
Sample Files
clusterfuzz-testcase-minimized-fuzzer_loadfile-4665657266864128.zip
I carefully read all instruction and confirm that I did the following:
--log-file=output.txt
.