Skip to content

ao/pulse may hang when playing videos #13242

Open
@rb-union

Description

Important Information

Information:

  • mpv version
    build from master with default option, commit hash: ab5b250

  • Linux Distribution and Version
    OS: Debian GNU/Linux 12 (bookworm) x86_64
    Kernel: 6.1.0-13-amd64

  • Source of the mpv binary

  • If known which version of mpv introduced the problem

  • Window Manager and version
    kwin 5.27.5-3

  • GPU driver and version
    AMD ATI Radeon 520 OEM (Subsystem: Bitland(ShenZhen) Information Technology Co., Ltd. Radeon 520 OEM)
    Kernel driver in use: radeon
    Kernel modules: radeon, amdgpu
    libdrm-radeon1:amd64 2.4.114-1+b1
    xserver-xorg-video-radeon 1:19.1.0-3

  • Possible screenshot or video of visual glitches

Reproduction steps

Step:

  1. Find a low-performance device (like intel i3 9100f);

  2. Reinstall the system, build mpv from source code;

  3. Play hevc(main 10) yuv420p10le video in a loop;

    • Run ./mpv --msg-level=all=debug,ao=trace --log-file=mpv.log --loop-playlist /home/debian/testcase/P1000070.MP4
  4. Repeat three or more times to run step 3;

  5. Waiting for playback until a certain mpv application freezes;

  6. Check the video playback and log output. When video play freezes, the log prints the same information repeatedly;

    [1186.842][t][ao/pulse] in=0 space=8536307(8536307) pl=1, eof=0
    [1186.906][t][ao/pulse] in=0 space=8539361(8539361) pl=1, eof=0
    [1186.948][t][ao/pulse] in=0 space=8542318(8542318) pl=1, eof=0
    [1186.991][t][ao/pulse] in=0 space=8544354(8544354) pl=1, eof=0
    [1187.032][t][ao/pulse] in=0 space=8546386(8546386) pl=1, eof=0
    [1187.079][t][ao/pulse] in=0 space=8548390(8548390) pl=1, eof=0
    [1187.123][t][ao/pulse] in=0 space=8550394(8550394) pl=1, eof=0
    
  7. After a long time, mpv cannot request too large memory, reports Failed to allocate buffer. and plays the video without audio.

    [3085.852][e][ao/pulse] Failed to allocate buffer.
    [3085.869][e][ao/pulse] Failed to allocate buffer.
    [3085.894][e][ao/pulse] Failed to allocate buffer.
    

Expected behavior

ao/pulse not hangs on play.

Actual behavior

ao/pulse may hang when playing videos.

With read the source code and log output.
When mpv resumes audio from underrun state and receives the first audio data containing EOF,mpv will get stuck in an infinite loop.

// error_mpv_2_3.log
[1008.904][t][ao/pulse] in=0 space=1352(1352) pl=1, eof=0
[1008.920][t][ao/pulse] in=0 space=2432(2432) pl=1, eof=0
[1008.946][t][ao/pulse] in=0 space=2432(2432) pl=1, eof=0
[1008.964][v][ao/pulse] audio end or underrun
[1009.021][v][af] filter input EOF
[1009.021][v][af] filter output EOF
[1009.021][v][cplayer] audio filter EOF
[1009.021][w][cplayer] Audio device underrun detected.
[1009.021][v][cplayer] restarting audio after underrun
[1009.021][v][cplayer] audio draining
[1009.021][v][cplayer] audio EOF reached
[1009.021][v][ao/pulse] starting AO
[1009.023][t][ao/pulse] in=2048 space=4436(4436) pl=1, eof=1
[1009.023][v][ao/pulse] audio end or underrun
[1009.023][t][ao/pulse] in=0 space=4800(4800) pl=1, eof=0
[1009.049][t][ao/pulse] in=0 space=4800(4800) pl=1, eof=0
[1009.055][t][ao/pulse] in=0 space=7159(7159) pl=1, eof=0
[1009.080][t][ao/pulse] in=0 space=7159(7159) pl=1, eof=0
...
[1011.743][v][cplayer] Starting playback...
[1011.743][v][cplayer] blocked, waiting for old audio to play
[1011.745][v][cplayer] blocked, waiting for old audio to play
...
[1295.708][t][ao/pulse] in=0 space=13759573(13759573) pl=1, eof=0
[1295.807][t][ao/pulse] in=0 space=13765586(13765586) pl=1, eof=0
[1295.911][t][ao/pulse] in=0 space=13769649(13769649) pl=1, eof=0
[1295.979][t][ao/pulse] in=0 space=13773691(13773691) pl=1, eof=0

This is the execution flow I trace:

  1. mpv receive underrun event;

  2. ao_pulse.c: ao_play_data() receive new audio data contains EOF.

  3. ao_pluse.c: ao_play_data() try to start. ao->buffer_state->playing = true; buffer.c#L658

         if (!p->streaming) {
             MP_VERBOSE(ao, "starting AO\n");
             ao->driver->start(ao);
             p->streaming = true;
             state.playing = true;
         }
  4. The video has just finished playing. Switch to the next video to play. The previous playback has not ended yet. audio_status = STATUS_SYNCING;

  5. It is judged here that the previous playback has not ended yet. Keeps reporting "Blocked, waiting for old audio to play" error; audio.c#L902

         if (mpctx->ao && ao_is_playing(mpctx->ao) &&
             mpctx->video_status != STATUS_EOF) {
             MP_VERBOSE(mpctx, "blocked, waiting for old audio to play\n");
             ok = false;
         }
  6. Pulse Audio continues to request data and calls stream_request_cb(). pa_stream_writable_size() continues to increase;

    // error_mpv_2_3.log
    [1295.708][t][ao/pulse] in=0 space=13759573(13759573) pl=1, eof=0
    [1295.807][t][ao/pulse] in=0 space=13765586(13765586) pl=1, eof=0
    [1295.911][t][ao/pulse] in=0 space=13769649(13769649) pl=1, eof=0
    [1295.979][t][ao/pulse] in=0 space=13773691(13773691) pl=1, eof=0
    
  7. Until Failed to allocate buffer.

    // error_mpv_1_2.log
    [3025.437][e][ao/pulse] Failed to allocate buffer.
    [3025.462][e][ao/pulse] Failed to allocate buffer.
    [3025.479][e][ao/pulse] Failed to allocate buffer.
    

Another problem

Actually, the problem I encountered in version 0.34 was a little different.
EOF will appear in the middle of video playback (using arm devices), and will also fall into an infinite loop.
Here change the status of audio_status to STATUS_SYNCING. audio.c#L718

            mp_pin_out_unread(f->ppins[0], frame);
            ao_c->start_pts_known = false;
            mpctx->audio_status = STATUS_SYNCING;
            mp_wakeup_core(mpctx);
            MP_VERBOSE(mpctx, "new audio frame after EOF\n");
            return;

But using the latest version does not have this problem. Not sure EOF will no longer appear in the middle of the video in the latest version.

Log file

error_mpv_1_2.log
error_mpv_2_2.log
error_mpv_2_3.log

Sample files

It's a random problem, I reproduced the error with different videos, and here a sample video from the web.
Thanks Andrew Reid !
https://www.eoshd.com/news/download-my-4k-hdr-10bit-h-265-videos-shot-with-the-panasonic-s1-firmware-v1-0/

P1000070.MP4

Finally, here's a PR that might help resolve the issue.
If the first audio data after underrun contains EOF, is it not necessary to start the AO?

Thanks!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions