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 699924 - smoothstreaming: no audio with BBC bigbuckbunny stream
smoothstreaming: no audio with BBC bigbuckbunny stream
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
git master
Other All
: Normal normal
: 1.3.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2013-05-08 10:36 UTC by Tim-Philipp Müller
Modified: 2013-11-27 13:08 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
mssdemux: send stream id and newsegment before pushing data (1.61 KB, patch)
2013-05-15 12:15 UTC, Thiago Sousa Santos
committed Details | Review
mssdemux: add bitrate info to audio streams (2.42 KB, patch)
2013-05-15 12:15 UTC, Thiago Sousa Santos
committed Details | Review
mssdemux: parse block_align from waveformatex if possible (3.50 KB, patch)
2013-05-15 12:15 UTC, Thiago Sousa Santos
committed Details | Review
fix setting codec_data when using WaveFormatEx (1.92 KB, patch)
2013-10-16 14:37 UTC, Antonio Ospite
needs-work Details | Review
mssdemux: fix setting codec_data when using WaveFormatEx (4.94 KB, patch)
2013-10-31 17:07 UTC, Antonio Ospite
needs-work Details | Review
mssdemux: fix setting codec_data when using WaveFormatEx, version 2 (5.68 KB, patch)
2013-11-26 22:32 UTC, Antonio Ospite
committed Details | Review

Description Tim-Philipp Müller 2013-05-08 10:36:53 UTC
http://mediadl.microsoft.com/mediadl/iisnet/smoothmedia/Experience/BigBuckBunny_720p.ism/Manifest

No decoder available for type 'audio/x-wma, wmaversion=(int)2, codec_data=(buffer)6201020044ac0000451f0000cf05100012001000030000000000000000000000e00042c0, rate=(int)0, channels=(int)0'.

(not sure why rate + channels fields got added at all here even though there is no channels or rate element in the manifest)
Comment 1 Thiago Sousa Santos 2013-05-14 20:26:47 UTC
I fixed the rate/chanels issue and the warnings about sticky events orderings. But the real issue here is that the caps isn't a subset of the template one:

audio/x-wma, wmaversion=(int)2, block_align=(int)[ 0, 2147483647 ], bitrate=(int)[ 0, 2147483647 ]

audio/x-wma, wmaversion=(int)2, codec_data=(buffer)6201020044ac0000451f0000cf05100012001000030000000000000000000000e00042c0


The docs state that the is_subset function won't work reliably in case there are optional parameters.
Comment 2 Tim-Philipp Müller 2013-05-14 23:00:50 UTC
Those docs are outdated (and have been updated in git I believe), it works fine now :)

The problem here is the missing block_align and bitrate fields. If the template caps have those, the caps must have those fields too, otherwise it won't be a subset.

I am not sure what the expected/best workaround is here. It *looks* like libav needs these values, so we need to get them somewhere. Maybe we can/have to exract them from the codec data if missing?
Comment 3 Thiago Sousa Santos 2013-05-15 12:15:01 UTC
Created attachment 244308 [details] [review]
mssdemux: send stream id and newsegment before pushing data

Fixes sticky events ordering warnings when data is pushed
Comment 4 Thiago Sousa Santos 2013-05-15 12:15:11 UTC
Created attachment 244309 [details] [review]
mssdemux: add bitrate info to audio streams

bitrate info is always present on the QualityLevel xml node as part
of the adaptive selection processing, put it into caps as some
decoders require it (avdec_wmav2 for example)
Comment 5 Thiago Sousa Santos 2013-05-15 12:15:18 UTC
Created attachment 244310 [details] [review]
mssdemux: parse block_align from waveformatex if possible

wma v2 expects block_align field set to its caps. This isn't present
direclty on the manifests, so mssdemux should parse it from the
waveformatex structure
Comment 6 Thiago Sousa Santos 2013-05-15 12:16:10 UTC
These patches add the bitrate and block_align entries. Still failing on caps negotiation. Going to investigate it further later today.
Comment 7 Nicolas Dufresne (ndufresne) 2013-05-15 15:35:02 UTC
This may help:
commit d802c7395aad52aaaa593f5578811c8766437cca
Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
Date:   Wed May 15 17:15:18 2013 +0200

    playback: Only do a subset filtering for the factories if we have fixed caps
    
    Otherwise we're plugging a parser/converter currently and have unfixed caps.
Comment 8 Thiago Sousa Santos 2013-05-16 01:27:31 UTC
Thanks. The element is now being linked and with a few more caps fixes it starts up. The issue now is that the audio is broken. Still investigating what might be causing it
Comment 9 Thiago Sousa Santos 2013-05-16 20:59:42 UTC
I pushed the fixes that make the decoder link properly, but still haven't fixed the garbled sound issue.
Comment 10 Edward Hervey 2013-08-14 06:14:10 UTC
Thiago, any updates ?
Comment 11 Thiago Sousa Santos 2013-08-19 12:13:51 UTC
The mss patches were pushed, the problem is still that the audio isn't playing and libav throws lots of

0:00:17.210740755 23508 0xb5804b20 ERROR                  libav :0:: broken frame: channel len > samples_per_frame

during playback. I'm unassigning myself as I'm not the best person to debug this.
Comment 12 Antonio Ospite 2013-10-16 14:37:51 UTC
Created attachment 257428 [details] [review]
fix setting codec_data when using WaveFormatEx

Hi,

the problem about the audio not playing is that the codec_data passed to the decoder is the whole WaveFormatEx and not just the actual codec private data (which is the data from byte 18 on in WaveFormatEx when the cbSize field is non zero).

The attached patch makes audio work with the bigbuckbunny video from the blender foundation.

The patch is just an ugly hack, as I am not proficient in gstreamer and glib stuff, I'd like someone else to fix it properly or to give me direction about how a final patch should look like.

Thanks,
   Antonio
Comment 13 Antonio Ospite 2013-10-24 10:03:56 UTC
If we can assume the data in WaveFormatEx is actually always a WAVEFORMATEX[1] structure and never a smaller one like WAVEFORMAT[2] or PCMWAVEFORMAT[3] then we can assume the data is always at least 18 bytes and this will simplify the code, anyone knows why the current check is for >= 14?

Has anyone got the specs of the manifest format?

Or if we really want to handle the 14 and 16 bytes cases we can assume that in those cases there will be no codec private data, would that be OK?

[1] http://msdn.microsoft.com/en-us/library/windows/desktop/dd390970%28v=vs.85%29.aspx
[2] http://msdn.microsoft.com/en-us/library/windows/desktop/dd757712%28v=vs.85%29.aspx
[3] http://msdn.microsoft.com/en-us/library/windows/desktop/dd743663%28v=vs.85%29.aspx
Comment 14 Sebastian Dröge (slomo) 2013-10-30 21:05:21 UTC
Review of attachment 257428 [details] [review]:

::: ext/smoothstreaming/gstmssmanifest.c
@@ +612,3 @@
+
+        if (mapinfo.size >= 16) {
+          gint cbSize = GST_READ_UINT16_LE (mapinfo.data + 16);

You need to check that it's >= 18 if you want to read 2 bytes at offset 16

@@ +613,3 @@
+        if (mapinfo.size >= 16) {
+          gint cbSize = GST_READ_UINT16_LE (mapinfo.data + 16);
+          fprintf (stderr, "%s cbSize: %d\n", __func__, cbSize);

You can use GST_DEBUG() here

@@ +619,3 @@
+             * whole "WaveFormatEx" */
+            gst_buffer_resize (codec_data, 18, -1);
+            goto endif;

Best would be without a goto here :) Also won't you still pass the complete struct as codec_data in all other cases?
Comment 15 Antonio Ospite 2013-10-31 10:15:32 UTC
(In reply to comment #14)
> Review of attachment 257428 [details] [review]:
> 
> ::: ext/smoothstreaming/gstmssmanifest.c
> @@ +612,3 @@
> +
> +        if (mapinfo.size >= 16) {
> +          gint cbSize = GST_READ_UINT16_LE (mapinfo.data + 16);
> 
> You need to check that it's >= 18 if you want to read 2 bytes at offset 16
>

Of course, thanks, I spotted this just after I had sent out the patch :)

> @@ +613,3 @@
> +        if (mapinfo.size >= 16) {
> +          gint cbSize = GST_READ_UINT16_LE (mapinfo.data + 16);
> +          fprintf (stderr, "%s cbSize: %d\n", __func__, cbSize);
> 
> You can use GST_DEBUG() here
>

I will, thanks, I am still learning about the infrastructure.

> @@ +619,3 @@
> +             * whole "WaveFormatEx" */
> +            gst_buffer_resize (codec_data, 18, -1);
> +            goto endif;
> 
> Best would be without a goto here :) Also won't you still pass the complete
> struct as codec_data in all other cases?

I want to check with the Microsoft smooth streaming specification before sending an update, chances are that the code can just be simplified: if the wav header is _always_ supposed to be a WAVEFORMATEX (at least 18 bytes), than I'll always consume these 18 bytes and just pass the rest to the decoder in codec_data.

Regards,
   Antonio
Comment 16 Antonio Ospite 2013-10-31 17:07:47 UTC
Created attachment 258677 [details] [review]
mssdemux: fix setting codec_data when using WaveFormatEx

OK, the smoothstreaming specifications[1,2,3] always mention WAVEFORMATEX
and never smaller structures like WAVEFORMAT or PCMWAVEFORMAT, so I think the
buffer can assumed to be at least 18 bytes and always consuming the wav
header gives the (possibly empty) codec private data.

Version 1 (Thanks to the Wayback Machine):
[1] http://web.archive.org/web/20120907004742/http://www.iis.net/community/files/media/smoothspecs/%5BMS-SMTH%5D.pdf

Version 2.1:
[2] http://download.microsoft.com/download/B/0/B/B0B199DB-41E6-400F-90CD-C350D0C14A53/%5BMS-SSTR%5D.pdf

Version 4:
[3] http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-SSTR%5D.pdf

The attached file contains three commits, the first two are preliminary changes, the third one is the actual fix for this issue. The commits can be imported with "git am" of course.

Ciao,
   Antonio
Comment 17 Sebastian Dröge (slomo) 2013-10-31 21:56:52 UTC
Review of attachment 258677 [details] [review]:

Generally looks good

::: ext/smoothstreaming/gstmssmanifest.c
@@ +588,3 @@
   gchar *codec_data_str =
       (gchar *) xmlGetProp (node, (xmlChar *) "CodecPrivateData");
   GstBuffer *codec_data = NULL;

Isn't this causing the < 18 byte codec_data to be used still? Shouldn't it instead really ignore it and not do anything with it?
Comment 18 Antonio Ospite 2013-11-02 14:29:50 UTC
My unde(In reply to comment #17)
> Review of attachment 258677 [details] [review]:
> 
> Generally looks good
> 
> ::: ext/smoothstreaming/gstmssmanifest.c
> @@ +588,3 @@
>    gchar *codec_data_str =
>        (gchar *) xmlGetProp (node, (xmlChar *) "CodecPrivateData");
>    GstBuffer *codec_data = NULL;
> 
> Isn't this causing the < 18 byte codec_data to be used still? Shouldn't it
> instead really ignore it and not do anything with it?

CodecPrivateData may not be present at all.

My understanding is that the WaveFormatEx attribute is used as an
_alternative_ to the CodecPrivateData one in older Manifest files.

So as I see it the rationale of the current code is:

  1. Check if "CodecPrivateData" is there, if so set codec_data:
     ...
     structure = gst_caps_get_structure (caps, 0);
     if (codec_data_str && strlen (codec_data_str)) {
       codec_data = gst_buffer_from_hex_string ((gchar *) codec_data_str);
     }
     ...

  2. if codec_data is still null try and see if there is a WaveFormatEx
     attribute.
     ...
     if (!codec_data) {
       GstMapInfo mapinfo;
       codec_data_str = (gchar *) xmlGetProp (node, (xmlChar *) "WaveFormatEx");
     ...

     [no leaks here, right? because if codec_data is still null then
     codec_data_str was null too]

I think proper handling for "CodecPrivateData" may still be needed to
support other streams, but my patch fixes the issue with WaveFormatEx
which is what this report is really about.

Thanks,
   Antonio
Comment 19 Thiago Sousa Santos 2013-11-12 22:51:13 UTC
I agree with Sebastian, here.

In this case you are handling we know it is marked as a WaveFormatEx structure, so if it is smaller than 18 bytes it is better to ignore it as we don't know what exactly it could be.
Comment 20 Antonio Ospite 2013-11-16 17:23:39 UTC
OK, now I see what you are asking, I misinterpreted Sebastian when he was saying "not do anything with it", I thought it meant "do not parse it, and leave it up to the decoder"

Instead you mean that if the data is < 18 bytes we DROP it and don't pass any codec_data at all to the decoder.

It's OK by me, an update is coming soon.
Comment 21 Thiago Sousa Santos 2013-11-25 15:10:46 UTC
Ping?
Comment 22 Antonio Ospite 2013-11-25 16:25:55 UTC
(In reply to comment #21)
> Ping?

Hey Thiago, I'll try to send the patch for tomorrow.
Comment 23 Antonio Ospite 2013-11-26 22:32:20 UTC
Created attachment 262904 [details] [review]
mssdemux: fix setting codec_data when using WaveFormatEx, version 2

New version attached.

Changes since the previous one:
  - ignore the WaveFormatEx content if it is less than 18 bytes of data.
  - declare GstMapInfo mapinfo in the block it is actually used.

Let me know if you liked a negative check better, like:
  if (!codec_data_str || codec_data_len < 18) {
    /* warning... */
  } else {
    /* common case */
  }

The attached file contains three commits, the first two are preliminary
changes, the third one is the actual fix for this issue. The commits can be
imported with "git am" of course.

Ciao,
   Antonio
Comment 24 Thiago Sousa Santos 2013-11-27 13:08:16 UTC
Commits pushed:
8345c5acfbb7cf9bfcd356682c550a64d6348538
f02e7a24394541c0585dedb53325bb2b5cdf349f
c4fbff50dfa99e0f725a8690b0d0ff8509300a95

Thanks for the patches!