After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 433119 - wavparse causes skipping for MPEG-encoded RIFF Wav files with incorrect headers
wavparse causes skipping for MPEG-encoded RIFF Wav files with incorrect headers
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
0.10.5
Other All
: Normal normal
: 0.10.6
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on: 433135
Blocks:
 
 
Reported: 2007-04-24 22:15 UTC by dynamotwain
Modified: 2007-04-26 08:40 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Example of MP3 that plays incorrectly (CC-licensed) (879.08 KB, audio/mpeg)
2007-04-24 22:47 UTC, dynamotwain
Details

Description dynamotwain 2007-04-24 22:15:39 UTC
Please describe the problem:
I have some MP3s that cause synchronization problems in almost all gstreamer-based player I've used. Audacious, mplayer, Totem, and Xine can all play them fine.

Gnome-sound-recorder and Rhythmbox cannot play them without skipping about once a second.

Examining the header differences between good and bad mp3s from the same collection made it apparent that all mp3s that skipped while playing had RIFF Wave headers. Further experimentation with adding RIFF headers to valid mp3s
demonstrated that an invalid 'dwAvgBytesPerSec' value is what causes synchronization issues that result in skipping every second or so, with the following messages:

WARNING: from element /pipeline0/gconfaudiosink0/bin0/alsasink0: Compensating for audio synchronisation problems
Additional debug info:
gstbaseaudiosink.c(860): gst_base_audio_sink_render (): /pipeline0/gconfaudiosink0/bin0/alsasink0:
Unexpected discontinuity in audio timestamps of more than half a second (0:00:00.553333333), resyncing
WARNING: from element /pipeline0/gconfaudiosink0/bin0/alsasink0: Compensating for audio synchronisation problems
Additional debug info:
gstbaseaudiosink.c(860): gst_base_audio_sink_render (): /pipeline0/gconfaudiosink0/bin0/alsasink0:
Unexpected discontinuity in audio timestamps of more than half a second (0:00:00.553287981), resyncing


Steps to reproduce:
1. Choose any invalid RIFF-encoded mp3 file; to create your own invalid mp3 file for testing:
1a. Take mp3 file.
1b. Add RIFF header
1c. Alter header so that 'dwAvgBytesPerSec' actually specifies the samplerate.
2. Play the file using a gstreamer-based application.

Actual results:
Audio skips about once a second or so

Expected results:
Audio plays fine

Does this happen every time?
Yes

Other information:
I tried to emulate 'playbin' in gst-launch to find exactly what in the
gstreamer pipeline was causing these issues...

This plays the file perfectly fine:
>> gst-launch-0.10 filesrc location=BrokenFile.mp3 ! mad ! audioconvert ! audioresample ! volume ! gconfaudiosink

Changing 'mad' to 'decodebin' reintroduces the skipping
>> gst-launch-0.10 filesrc location=BrokenFile.mp3 ! decodebin ! audioconvert ! audioresample ! volume ! gconfaudiosink

Viewing verbose output shows that gstreamer uses 'id3demux' and 'wavparse' before sending data to 'mad' when using 'decodebin', so I stripped the ID3 data and tried:
>> gst-launch-0.10 filesrc location=BrokenFile.mp3 ! wavparse ! mad ! audioconvert ! audioresample ! volume ! gconfaudiosink
and the skipping was back.

Using verbose debug output from mplayer I tried to find what discrepancies
in header data caused the problem.


>>mplayer -v BrokenFile.mp3
lists the following in the output:
======= WAVE Format =======
Format Tag: 85 (0x55)
Channels: 1
Samplerate: 22050
avg byte/sec: 44100
Block align: 2
bits/sample: 16
cbSize: 0
...
MPEG 1.0, Layer III, 44100 Hz 128 kbit Joint-Stereo, BPF: 417
Channels: 2, copyright: No, original: Yes, CRC: No, emphasis: 0
AUDIO: 44100 Hz, 2 ch, s16le, 128.0 kbit/9.07% (ratio: 16000->176400)
Selected audio codec: [mp3] afm: mp3lib (mp3lib MPEG layer-2, layer-3)

After noting the discrepancies in the WAVE header, I managed to reproduce the problem on every mp3 file I have by adding a RIFF wave header and setting the
'dwAvgBytesPerSec' field to the # of samples per second.
Comment 1 dynamotwain 2007-04-24 22:47:14 UTC
Created attachment 86957 [details]
Example of MP3 that plays incorrectly (CC-licensed)

I've 'produced' a CC-licensed MP3 file that exemplifies this bug from an abridged version of 'Code Monkey' (Jonathan Coulton's Thing A Week series: http://www.jonathancoulton.com/2006/04/14/thing-a-week-29-code-monkey/) by
1. Stripping the ID3v2 tag  via 'id3v2 -D' (because I can't get id3demux to pass audio data to wavparse via gst-launch)
2. Run 'riffmp3 -l 0 -b 352.8 -o BrokenFile.mp3' on the valid mp3 file to add a broken header (352.8 = 44100 * 8 bits/byte / 1000, which matches the broken mp3 files I have. This number isn't magic; I would imagine any number significantly larger than the 'correct' 160 kbits/s would cause the same issues)

As a side note, does anybody know of a program for Linux that is able to remove the RIFF header between ID3 data and the mp3 data so I can just get rid of this annoying problem (and save a couple kilobytes of disk space too)?
Comment 2 Wim Taymans 2007-04-26 08:40:09 UTC
        * gst/wavparse/gstwavparse.c: (gst_wavparse_perform_seek),
        (gst_wavparse_stream_headers), (gst_wavparse_stream_data):
        * gst/wavparse/gstwavparse.h:
        Apply DISCONT to buffers.
        Only apply timestamp to the first sample after a DISCONT, too many VBR
        files cause random jitter in the timestamps. Fixes #433119.