#2410 closed defect (fixed)

mplayer frequently hangs at the end of an mp3

Reported by: dstromberg Owned by: beastd
Priority: normal Component: undetermined
Version: unspecified Severity: normal
Keywords: hang mp3 Cc:
Blocked By: Blocking:
Reproduced by developer: no Analyzed by developer: no

Description (last modified by dstromberg)

Summary of the bug:
How to reproduce:

1) mplayer *.mp3 on a MacOS system
2) wait a while
3) It's likely to hang at the end of one of the files

I've left the version unspecified, because it's really 1.5, and that's not in your dropdown menu.

I've been playing my mp3 collection using the mplayer wrapper at https://stromberg.dnsalias.org/~strombrg/play-music-collection/

It works great on Linux, but on MacOS mplayer frequently hangs at the end of a track.

I'm using:

$ brew info mplayer
cmd output started 2023 Wed Feb 22 04:54:59 PM PST
==> mplayer: stable 1.5 (bottled), HEAD
UNIX movie player
https://mplayerhq.hu/
/usr/local/Cellar/mplayer/1.5_1 (11 files, 31MB) *

Poured from bottle using the formulae.brew.sh API on 2023-02-22 at 10:11:13

From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/mplayer.rb
License: GPL-2.0-only and GPL-2.0-or-later
==> Dependencies
Build: pkg-config ✔, yasm ✔
Required: fontconfig ✔, freetype ✔, jpeg-turbo ✔, libcaca ✔
==> Options
--HEAD

Install HEAD version

==> Analytics
install: 954 (30 days), 3,041 (90 days), 18,985 (365 days)
install-on-request: 849 (30 days), 2,669 (90 days), 16,919 (365 days)
build-error: 0 (30 days)

I'm on:
MacBook Pro, 16 inch, 2019
Darwin RE-dastromberg-ML 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:08:47 PST 2022; root:xnu-8792.61.2~4/RELEASE_X86_64 x86_64
ProductName: macOS
ProductVersion: 13.1
BuildVersion: 22C65
AMD Radeon Pro 5500M 4 GB
Intel UHD Graphics 630 1536 MB

mplayer silently hangs at the end of an mp3.

It's not a problem with a specific mp3 or mp3's. It just hangs at random. It _might_ hang more under higher CPU load.

Is this a known issue? Is there anything I can do about it?

Thanks for the cool tool!

Change History (17)

comment:1 by dstromberg, 21 months ago

Description: modified (diff)

comment:2 by reimar, 20 months ago

Which audio output (-ao) is it using? Can you try a different one?

comment:3 by dstromberg, 20 months ago

It's using whatever is the default -ao.

I'm seeing:
$ mplayer -ao help
cmd output started 2023 Thu Mar 23 09:00:49 AM PDT
MPlayer 1.5-14.0.0 (C) 2000-2022 MPlayer Team
Available audio output drivers:

coreaudio Darwin/Mac OS X native audio output
openal OpenAL audio output
mpegpes MPEG-PES audio output
null Null audio output
pcm RAW PCM/WAVE file writer audio output

Is coreaudio the default?

I'll try coreaudio today.

comment:4 by dstromberg, 20 months ago

coreaudio got stuck. Trying openal.

comment:5 by dstromberg, 20 months ago

openal doesn't seem to be getting stuck (I didn't try it all that long though).

openal seems to have a different problem: the two speakers in a stereo system (especially noticeable with headphones) seemed to get a little out of synch with each other, producing an unpleasant echo.

mpegpes didn't appear to produce any output at all.

pcm seems to think it's working, but there's no audio, and the tracks finish much too quickly.

I think that's it for the available audio drivers on a Mac, at least for the homebrew build of mplayer.

comment:6 by reimar, 20 months ago

Thanks, I'll try if I can reproduce, I first need to find some music files though...
Any chance you would be able to run in a debugger (lldb) and produce a backtrace when it hangs?
Or maybe a run with "-msglevel ao=9" provides extra info?
No worries if not, if I can reproduce I can do it myself.

comment:7 by reimar, 20 months ago

Hm, I tried a while and I am not able to reproduce with the mp3 files I have, on an M1 Mac running macOS 13.2.1.
So unfortunately I probably will not be able to collect any additional info that might help to debug this.

comment:8 by reimar, 20 months ago

As to workarounds:
I did commit a patch that makes the OpenAL output behave more as you expect.
Also you might be able to compile MPlayer against libSDL, which should give another option that might work better.

comment:9 by reimar, 20 months ago

Can not reliably reproduce.
So would appreciate testing of below patch whether it helps:

--- libao2/ao_coreaudio.c	(revision 38410)
+++ libao2/ao_coreaudio.c	(working copy)
@@ -159,11 +159,17 @@
 
 	if(amt>req)
  		amt=req;
+	// clear whole buffer since coreaudio seems to have
+	// issues handling data amounts smaller than it requested
+	if (amt < req)
+		memset(ioData->mBuffers[0].mData + amt, 0, req - amt);
 
 	if(amt)
+	{
 		read_buffer((unsigned char *)ioData->mBuffers[0].mData, amt);
-	else audio_pause();
-	ioData->mBuffers[0].mDataByteSize = amt;
+		// Do not set in else case to guarantee progress
+		ioData->mBuffers[0].mDataByteSize = amt;
+	} else audio_pause();
 
  	return noErr;
 }

comment:10 by dstromberg, 20 months ago

Does this help reproduce the problem?

It's a collection of 1000 small .mp3 files, and a script named ./go for mplayer'ing them in order.

https://stromberg.dnsalias.org/~dstromberg/numbers/

comment:11 by dstromberg, 20 months ago

I'm more eager to get this going than it might seem. Things will be pretty busy for me for two weeks - hopefully I can try your patch after that.

comment:12 by reimar, 20 months ago

A bit to my surprise, it seems to have helped in fact.
I think I managed to pin-point the issue, though I am not entirely sure that this isn't a macOS bug.
Below patches seems to work - the one I sent last time did not work.

Index: libao2/ao_coreaudio.c
===================================================================
--- libao2/ao_coreaudio.c	(revision 38410)
+++ libao2/ao_coreaudio.c	(working copy)
@@ -159,13 +159,21 @@
 
 	if(amt>req)
  		amt=req;
+	// clear whole buffer since coreaudio seems to have
+	// issues handling data amounts smaller than it requested
+	if (amt < req)
+		memset(ioData->mBuffers[0].mData + amt, 0, req - amt);
 
 	if(amt)
 		read_buffer((unsigned char *)ioData->mBuffers[0].mData, amt);
-	else audio_pause();
 	ioData->mBuffers[0].mDataByteSize = amt;
 
- 	return noErr;
+	// In theory it might be nicer to call audio_pause if
+	// there is no data, as the code originally did.
+	// However since this runs in a separate thread, this can
+	// trigger a race condition if MPlayer calls AudioOutputUnitStop
+	// for example during uninit, which then causes a hang.
+	return amt ? noErr : kAudioFileEndOfFileError;
 }
 
 static int control(int cmd,void *arg){
@@ -1146,17 +1154,12 @@
     usec_sleep((int)timeleft);
   }
 
+  audio_pause();
   if (!ao->b_digital) {
-      AudioOutputUnitStop(ao->theOutputUnit);
       AudioUnitUninitialize(ao->theOutputUnit);
       CloseComponent(ao->theOutputUnit);
   }
   else {
-      /* Stop device. */
-      err = AudioDeviceStop(ao->i_selected_dev, ao->renderCallback);
-      if (err != noErr)
-          ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err);
-
       /* Remove IOProc callback. */
       err = AudioDeviceDestroyIOProcID(ao->i_selected_dev, ao->renderCallback);
       if (err != noErr)
@@ -1207,6 +1210,9 @@
 {
     OSErr err=noErr;
 
+    if (ao->paused)
+        return;
+
     /* Stop callback. */
     if (!ao->b_digital)
     {

comment:13 by dstromberg, 19 months ago

I was unable to build an unmodified mplayer trunk (from SVN today) on my work Mac.

I was able to build an unmodified mplayer 1.5 on same.

So I applied your patch above to 1.5 and built that. Then I started playing the "numbers" files I shared previously - and the patched mplayer got stuck in the 70's and 90's on two different runs.

Any further suggestions?

comment:14 by dstromberg, 19 months ago

Ah, I just noticed the new patch. I'll try that instead of the first against mplayer 1.5.

Thanks!

comment:15 by dstromberg, 19 months ago

Trying the second patch alone, I got all the way through the 1000 numbered mp3's. :)

I'll run with this for a while with actual music, and let you know if I get further trouble.

But so far: looking good :)

comment:16 by dstromberg, 19 months ago

mplayer is still working nicely. It hasn't gotten stuck in a week. Let's consider the patch a fix. :)

Thanks!

comment:17 by reimar, 19 months ago

Resolution: fixed
Status: newclosed

Fix applied in r38417

Note: See TracTickets for help on using tickets.