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 755543 - wavparse: plain PCM wav wrongly treated as DTS
wavparse: plain PCM wav wrongly treated as DTS
Status: RESOLVED INVALID
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
1.x
Other Linux
: Normal normal
: NONE
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-09-24 13:58 UTC by Douglas Bagnall
Modified: 2015-09-25 23:50 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
A 5 second wav that won't play properly in Gstreamer (78.17 KB, audio/x-wav)
2015-09-24 13:58 UTC, Douglas Bagnall
Details

Description Douglas Bagnall 2015-09-24 13:58:43 UTC
Created attachment 312059 [details]
A 5 second wav that won't play properly in Gstreamer

I have an 8kHz mono wav (relevant section attached) that happens to contain the
magic bytes 'fe 7f 01 80' near the start:

000008d0  ab fb 10 fb 43 fc 30 fe  c2 fd 60 fc f2 fe 7f 01  |....C.0...`.....|
000008e0  80 02 c3 02 c7 03 23 02  dd 00 29 02 a0 01 fe fe  |......#...).....|


This causes wavparse to treat it as DTS, and use the next few bytes as some
kind of accursed header. In turn it happens to survive this check:

  num_blocks = (hdr[2] >> 2) & 0x7F;
  *frame_size = (((hdr[2] & 0x03) << 12) | (hdr[3] >> 4)) + 1;
  chans = ((hdr[3] & 0x0F) << 2) | (hdr[4] >> 14);
  *sample_rate = sample_rates[(hdr[4] >> 10) & 0x0F];
  lfe = (hdr[5] >> 9) & 0x03;

  if (num_blocks < 5 || *frame_size < 96 || *sample_rate == 0)
    return FALSE;

That's all in -base/gst/typefind, and in wavparse plugin itself there is this:

  /* for maybe, check for at least a valid-looking rate and channels */
  if (!gst_structure_has_field (s, "channels"))
    return FALSE;
  /* and for extra assurance we could also check the rate from the DTS frame
   * against the one in the wav header, but for now let's not do that */
  return gst_structure_has_field (s, "rate");


I'm guessing I want to do that last bit, right?


As GST_DEBUG puts it:

LOG        typefindfunctions gsttypefindfunctions.c:1733:dts_parse_frame_header: dts sync marker 0xfe7f0180 at offset 2225
LOG        typefindfunctions gsttypefindfunctions.c:1754:dts_parse_frame_header: frame header: c302c7022303dd02
...
LOG        wavparse gstwavparse.c:1835:gst_wavparse_add_src_pad: typefind caps = audio/x-dts, rate=(int)44100, channels=(int)5, depth=(int)16, endianness=(int)1234, framed=(boolean)false, P=50
...

and that doesn't want to link. The caps ought to be something like "audio/x-raw,
format=(string)S16LE, layout=(string)interleaved, channels=(int)1, rate=(int)8000".


Nobody else seems to get this wrong. gst123 plays a short little squirting sound and
offers a few of these:

ERROR: block code look-up failed
Didn't get subframe DSYNC


I believe this is the opposite of https://bugzilla.gnome.org/show_bug.cgi?id=636234,
whose incomplete fix caused this.

It might be useful to have a wavparse flag property that meant "trust me, believe
the RIFF header", which would avoid this always and save all that time spent looking for
magic brokenness.
Comment 1 Douglas Bagnall 2015-09-24 14:08:18 UTC
Some comments on the likeliness of this:

There are four different 32 bit signatures, so assuming vaguely random wavs, there is ~1 chance in a billion of a collision per candidate slot. But there are roughly 20000 places it could be, which reduces the chances to 1 in 50 thousand.

I am working on something that listens to in the order of 3000 1-minute wavs, so this will happen to 1 out of 17 people like me -- not, of course, taking into account the second wave of checks which is harder to calculate.
Comment 2 Douglas Bagnall 2015-09-25 23:34:05 UTC
On closer inspection, it seems this has been fixed in master, here:

commit c3bb399fd3e238da77aa3242557eedf3f42d1167
Author: David Schleef <ds@schleef.org>
Date:   Thu Mar 26 12:21:25 2015 -0700

    wavparse: be more strict about typefinding DTS
    
    Code now matches comments.

[...]

   /* DTS at non-0 offsets and without second sync may yield POSSIBLE .. */
-  if (prob < GST_TYPE_FIND_POSSIBLE)
+  if (prob <= GST_TYPE_FIND_POSSIBLE)
     return FALSE;


So I'll close this.
Comment 3 Tim-Philipp Müller 2015-09-25 23:50:43 UTC
Thanks, nothing like bugs that resolve themselves :)