Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ao_sndio broken [was: mp3: incomplete frame] #531

Closed
minusf opened this issue Feb 8, 2014 · 13 comments
Closed

ao_sndio broken [was: mp3: incomplete frame] #531

minusf opened this issue Feb 8, 2014 · 13 comments

Comments

@minusf
Copy link

minusf commented Feb 8, 2014

when i use mpv as a music player, on certain mp3 files (perhaps incorrectly encoded) it keeps spinning:

Playing: 03-believe.mp3
[cache] Cache size set to 2048 KiB
Cache fill: 21.97% (460800 bytes)   
[ffmpeg/demuxer] mp3: max_analyze_duration 5000000 reached at 5015510 microseconds
[ffmpeg/demuxer] mp3: Estimating duration from bitrate, this may be inaccurate
Detected file format: MP2/3 (MPEG audio layer 2/3) (libavformat)
Clip info:
 title: believe
 artist: gus gus
 album: polydistortion
 TLEN: 438000
 track: 3
 date: 1996
[stream] Audio (+) --aid=1 (mp3)
Video: no video
Selected audio codec: MP3 (MPEG audio layer 3) [lavc:mp3]
AO: [sndio] 44100Hz stereo 2ch s16
A: 00:07:17 / 00:07:18 (99%) Cache: 0%
[ffmpeg/audio] mp3: incomplete frame
A: 00:07:18 / 00:07:18 (99%) Cache: 0%

i realize the error message is from ffmpeg, but should mpv stop playback and keep spinning like this? (mplayer plays this file fine and moves on)

@ghost
Copy link

ghost commented Feb 8, 2014

Can you upload the file?

@ghost
Copy link

ghost commented Feb 8, 2014

I got the file per mail. I played it, and nothing is unusual. The warning is printed, but that's possibly due to weird non-standard tags at the end of the file.

I suspect the problem is with your AO. I see you use sndio, which hasn't really been battle-tested yet. Especially at the end of a file, corner cases can make the AO freeze. Not sure how to test this, since I don't have access to an OpenBSD system.

@minusf
Copy link
Author

minusf commented Feb 8, 2014

actually, i am told that upstream mplayer has accepted sndiod patches, and they are newer than the one that was merged with mpv... i'd be happy to test it :)

@ghost
Copy link

ghost commented Feb 8, 2014

Yes. I think the mplayer version includes some additional fixes. If anyone wants to merge these changes from mplayer, that would be welcome. (I don't want to do it without testing.)

PS: you can confirm with --ao=null whether decoding or audio output causes the hang. Also try without cache. But I'm pretty sure it's ao_sndio.

@ghost
Copy link

ghost commented Feb 8, 2014

Forgot to mention: the most common reason why an AO would interfere with proper termination is that ao_get_delay() doesn't return 0 when all audio is played.

@minusf
Copy link
Author

minusf commented Feb 8, 2014

i will try to adapt the mplayer patches. this another file stopped with

[ffmpeg/audio] mp3: Header missing

@minusf
Copy link
Author

minusf commented Feb 11, 2014

time for some printf() debugging :] per your comment i started looking at get_delay() and it seems to be spot on. for sndio, delay is zeroed out in reset(), which is called when the AOPLAY_FINAL_CHUNK flag is set. this does not happen for "corrupt" files. here is the trace of playing the end of a "good" file (mpv --no-cache --start 99% -v file.mp3):

[cplayer] audio_eof=0, partial_fill=0
[ao/sndio] get_delay: 0.420000
[statusline] A: 00:05:05 / 00:05:06 (99%)
[cplayer] audio_eof=0, partial_fill=0
[ao/sndio] get_delay: 0.420000
[statusline] A: 00:05:05 / 00:05:06 (99%)
[cplayer] audio_eof=0, partial_fill=0
[ao/sndio] get_delay: 0.420000
[statusline] A: 00:05:06 / 00:05:06 (99%)
[cplayer] audio_eof=0, partial_fill=0
[ao/sndio] get_delay: 0.420000
[statusline] A: 00:05:06 / 00:05:06 (99%)
[lavf] ds_get_packets: EOF reached (stream: audio)
[cplayer] audio_eof=1, partial_fill=1
[ao/sndio] play: AOPLAY_FINAL_CHUNK
[ao/sndio] reset
[ao/sndio] get_delay: 0.000000
[statusline] A: 00:05:06 / 00:05:06 (100%)
[lavf] ds_get_packets: EOF reached (stream: audio)
[ao/sndio] get_delay: 0.000000
[statusline] A: 00:05:06 / 00:05:06 (100%)
[cplayer] EOF code: 1  

and a "bad" file:

[cplayer] audio_eof=0, partial_fill=0
[ao/sndio] get_delay: 0.440000
[statusline] A: 00:07:17 / 00:07:18 (99%)
[cplayer] audio_eof=0, partial_fill=0
[ao/sndio] get_delay: 0.440000
[statusline] A: 00:07:17 / 00:07:18 (99%)
[cplayer] audio_eof=0, partial_fill=0
[ao/sndio] get_delay: 0.440000
[statusline] A: 00:07:17 / 00:07:18 (99%)
[ffmpeg/audio] mp3: incomplete frame
[ad] lavc_audio: error
[cplayer] audio_eof=0, partial_fill=1
[ao/sndio] get_delay: 0.298118
[statusline] A: 00:07:17 / 00:07:18 (99%)
[lavf] ds_get_packets: EOF reached (stream: audio)
[ao/sndio] get_delay: 0.278118
[statusline] A: 00:07:17 / 00:07:18 (99%)
[lavf] ds_get_packets: EOF reached (stream: audio)
[ao/sndio] get_delay: 0.238118
[statusline] A: 00:07:17 / 00:07:18 (99%)
[lavf] ds_get_packets: EOF reached (stream: audio)
[ao/sndio] get_delay: 0.218118
[statusline] A: 00:07:17 / 00:07:18 (99%)
[lavf] ds_get_packets: EOF reached (stream: audio)
[ao/sndio] get_delay: 0.198118
[statusline] A: 00:07:18 / 00:07:18 (99%)
[lavf] ds_get_packets: EOF reached (stream: audio)
[ao/sndio] get_delay: 0.198118
...

shouldn't audio_eof be set? it looks like by the time ds_get_packets() sets the eof flag, nobody is checking for it...

@ghost
Copy link

ghost commented Feb 12, 2014

audio.c does call demux_stream_eof() to check for EOF, but only when the decoder stops returning data.

In general, the player has to deal with an audio pipeline, where each stage can buffer arbitrary amounts of data. For example, even if the demuxer has reached EOF, there can still be data in the demuxer, or in the audio filter chain, or in the AO.

"Real" EOF (as in what fill_audio_out_buffers() returns and signals to the playloop) happens only when all data has been flushed in all stages. Otherwise, the playloop would terminate playback too early, instead of waiting until all buffered audio has been drained.

This also means that when the AO keeps returning a high value with get_delay(), the playloop will not think EOF is reached, even if the demuxer, decoder and audio filter are all out of data. get_delay is like the audio playback position of the AO, and if that is stuck, we can't know when audio actually ends.

I'm not entirely sure why audio_eof is not set in this case, though. It seems the decoder is returning an error, but maybe some other weird logic in dec_audio.c hides the error explicitly in order to drain the remaining buffered audio, making the decode call look like a success. But what happens other that?

Note that ao_alsa doesn't get AOPLAY_FINAL_CHUNK set in this case either. But the AO shouldn't just stop because it gets partially filled and the flag is not set. It's worth noting that the audio uninit code actually does flush some remaining audio and sets AOPLAY_FINAL_CHUNK doing it, but that is after the EOF condition has been detected. (There are complicated interactions with gapless audio...)

You can look at ao_null.c, which tries to emulate an ideal AO.

(Sorry for the late reply.)

@ghost
Copy link

ghost commented Feb 14, 2014

Ping?

@ghost
Copy link

ghost commented Apr 8, 2014

Ping? This is still not solved as far as I know.

@minusf
Copy link
Author

minusf commented Apr 29, 2014

sorry for the delay. thanks for fixing the build with 75d7d87, this was holding me back.
now i need to wait for another release to include that fix so i can ask the sndio devs to have a look at it.

@ghost
Copy link

ghost commented Apr 30, 2014

Made a 0.3.9 release. This still will need --disable-asm on OpenBSD (I think).

@ghost ghost changed the title mp3: incomplete frame ao_sndio broken [was: mp3: incomplete frame] Apr 30, 2014
@ghost
Copy link

ghost commented Mar 27, 2015

Long outdated, also there were more openbsd-specific sndio patches recently.

@ghost ghost closed this as completed Mar 27, 2015
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant