GNOME Bugzilla – Bug 746781
a52dec: audio noise/distortions when there are multiple AC-3 streams being decoded in parallel
Last modified: 2015-04-03 09:18:13 UTC
The audio track does not play correctly (distortions, parasites) when I try to play the video with Totem 3.14.2, while it's ok with MPV that uses ffmpeg. http://demo.ovh.eu/download/c8c4dde583a42ed1e5f9cc783589160e/air-anaconda1080-sample.mkv
I can't hear anything wrong with it. Can you hear the same problem playing the video with gst-play-1.0 ?
Yes, I've the same problem $ gst-play-1.0 air-anaconda1080-sample.mkv Now playing air-anaconda1080-sample.mkv Redistribute latency... No accelerated IMDCT transform found No accelerated IMDCT transform found My soundcard : 00:03.0 Audio device: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (rev 06) 00:1b.0 Audio device: Intel Corporation 8 Series/C220 Series Chipset High Definition Audio Controller (rev 05)
Could you make a debug log of the first few seconds: $ GST_DEBUG=*:6 gst-play-1.0 foo.mkv 2>dbg.log .. control-C after noise .. $ xz -9 dbg.log and attach dbg.log.xz here.
Strange. With the sample I sent earlier, I've the problem with gst-play-1.0 file.mkv, but with your command, the problem disappears. Nevertheless, I found another video still problematic http://demo.ovh.eu/download/ea31db09f5441d20a4782e6261c24877/dbg.log.xz
As I found strange that suddenly, it may be ok with your command, I tried to play a problematic video with totem First try, problem Second try, problem ... In the sixth try, the audio was suddenly ok. Then, another try, and problems returned. On the other hand, in every try, the result was not always the same. Sometimes it was just noise, no audible dialogue, sometimes the dialogues were "metallic" and sometimes there was no audio.
I can reproduce the problem with that file.
Seems the issue isn't to do with the sink as I first expected. I get corrupt/missing sound with: gst-launch-1.0 playbin uri=file:///home/v/Downloads/air-anaconda1080-sample.mkv video-sink='fakesink sync=1' flags=2 But not with: gst-launch-1.0 filesrc location=/home/v/Downloads/air-anaconda1080-sample.mkv ! matroskademux name=d d. ! queue ! h264parse ! avdec_h264 ! fakesink d. ! queue ! fakesink d. ! queue ! ac3parse ! a52dec ! audioconvert ! pulsesink And I do get corrupt/missing sound with: gst-play-1.0 --audiosink 'queue ! tee name=t ! queue ! pulsesink t. ! queue ! wavenc ! filesink location=out.wav' file:///home/v/Downloads/air-anaconda1080-sample.mkv Which doesn't involve an audio sink. None of the cores seem maxed when I get the corrupt sound.
I do not get any corruption/missing sound when I try to reproduce the playbin pipeline manually: gst-launch-1.0 filesrc location=/home/v/Downloads/air-anaconda1080-sample.mkv ! typefind ! matroskademux name=d ! multiqueue max-size-time=0 max-size-bytes=2097152 name=mq mq. ! h264parse ! 'video/x-h264' ! avdec_h264 ! input-selector ! queue ! fakesink mq. ! ac3parse ! 'audio/x-ac3' ! a52dec name=A mq. ! ac3parse ! 'audio/x-ac3' ! a52dec ! input-selector name=S S. ! tee ! streamsynchronizer ! queue ! identity ! audioconvert ! audioresample ! pulsesink d. ! mq. d. ! mq. A. ! S. This sounds fine. It corresponds to: gst-launch-1.0 playbin uri=file:///home/v/Downloads/air-anaconda1080-sample.mkv video-sink='fakesink sync=1' flags=2 which does get corrupted. So it's pointing to playbin or decodebin, oddly. Or maybe some timing race that happens to be exposed by using playbin...
Nothing with valgrind, but then it doesn't mean much if it's a race. It looks like a bug in liba52. If I dump the raw buffer contents before sending them to liba52, I get correct AC3 that can be played normally, but if I dump the raw buffer contents when I get decoded audio back from liba52, I get either the distorted version or the correct sounding version. In both the good and bad case, the src caps seem to be exactly the same. If I remove libgsta52dec.* from the plugins directory, I always get good audio (it falls back to the ffmpeg decoder in that case).
Created attachment 300845 [details] [review] For reference - a52_init reentrancy fix
Created attachment 300846 [details] [review] Fix race in a52_init calls It was arguably a bug in liba52dec: a52_init initializes the IMDCT global state as well as creating a new state. When two A52 decoders are created (eg, when two AC3 tracks are contained in a video), calls to a52_init may happen at the same time, and the IMDCT initialization is not reentrant. A patch to liba52dec is attached for reference, but the project seems dead for years. Instead, a patch to the gstreamer element ensures a52_init calls can't be made in parallel. This is consistent with no valgrind issues, race like behavior, and correct playback when first demuxing to a separate AC3 track.
Comment on attachment 300846 [details] [review] Fix race in a52_init calls Oh dear. Nice find. Who would possibly want to decode multiple streams in parallel? :) Could probably move the init mutex into the start function. It doesn't free any global state in a52_free(), does it?
I moved the mutex into the init function and pushed. commit f529481b3da32d9414219784bcee4f042e1dc86c Author: Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> Date: Thu Apr 2 17:24:05 2015 +0100 a52dec: fix race in liba52dec lookup table initialization a52_init initializes the IMDCT global state as well as creating a new state. When two A52 decoders are created (eg, when two AC3 tracks are contained in a video), calls to a52_init may happen at the same time, and the IMDCT initialization is not reentrant. https://bugzilla.gnome.org/show_bug.cgi?id=746781