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 628609 - The qtwrapperaudiodec_samr decoder doesn't handle buffers containing many AMR frames properly
The qtwrapperaudiodec_samr decoder doesn't handle buffers containing many AMR...
Status: VERIFIED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
0.10.18
Other Mac OS
: Normal blocker
: 0.10.23
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2010-09-02 11:37 UTC by Martin Storsjö
Modified: 2011-05-30 12:46 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
A GDP dump of AMR packets sent over RTP (13.52 KB, application/octet-stream)
2010-09-02 11:37 UTC, Martin Storsjö
  Details
Patch solving this issue (913 bytes, patch)
2010-09-02 20:45 UTC, Martin Storsjö
none Details | Review
Cleanup patch (1.61 KB, patch)
2011-05-03 22:02 UTC, Martin Storsjö
committed Details | Review
Patch fixing the bug (932 bytes, patch)
2011-05-03 22:02 UTC, Martin Storsjö
committed Details | Review

Description Martin Storsjö 2010-09-02 11:37:45 UTC
Created attachment 169354 [details]
A GDP dump of AMR packets sent over RTP

If decoding the attached sample like this,
gst-launch filesrc location=rtp-amr-dump.gdp ! gdpdepay ! rtpamrdepay ! qtwrapperaudiodec_samr ! wavenc ! filesink location=out-qt.wav
I get a wav file with 2.5 seconds of audio.

If decoding it using ffdec_amrnb instead,
gst-launch filesrc location=rtp-amr-dump.gdp ! gdpdepay ! rtpamrdepay ! ffdec_amrnb ! wavenc ! filesink location=out-ff.wav
I get a wav file that contains 17.5 seconds of audio (which is the correct length).

The RTP packets in this dump contain 35 AMR frames each.

If I split the packets into individual AMR frames, e.g. via this operation, the file decodes fine:
gst-launch filesrc location=rtp-amr-dump.gdp ! gdpdepay ! rtpamrdepay ! ffmux_amr ! filesink location=dump.amr
gst-launch filesrc location=dump.amr ! amrparse ! qtwrapperaudiodec_samr ! wavenc ! filesink location=out-qt2.wav
Comment 1 Martin Storsjö 2010-09-02 11:43:25 UTC
FWIW, it seems that it handles packets with up to 5 frames per packet just fine, if there's any more than that, it decodes too little data.
Comment 2 Martin Storsjö 2010-09-02 20:45:27 UTC
Created attachment 169394 [details] [review]
Patch solving this issue

The attached patch seems to solve the issue. The process_buffer_cb function is called whenever SCAudioFillBuffer needs more data to decode, but even if all input data is returned, SCAudioFillBuffer might  not consume all of it at once. Once it has consumed all input data, and process_buffer_cb has no more data to give, process_buffer_cb returns 42, which is returned from SCAudioFillBuffer as status, indicating that all input data has been consumed.

Alternatively, another solution would be to increase the size of the buffer allocated around lines 658-663:

  /* Create output bufferlist, big enough for 200ms of audio */
  GST_DEBUG_OBJECT (qtwrapper, "Allocating bufferlist for %d channels",
      channels);
  qtwrapper->bufferlist =
      AllocateAudioBufferList (channels,
      qtwrapper->samplerate / 5 * qtwrapper->channels * 4);

Although this seems to be meant to give a buffer size of 200 ms, I'm only able to fill it with 100 ms of audio in practice in this test case. Nevertheless, properly looping until all data has been consumed instead of increasing the buffer size blindly feels more sensible to me.
Comment 3 Tim-Philipp Müller 2010-10-02 09:23:49 UTC
Marking bug as blocker so we don't forget to have a look at it before the next release. Thanks for the patch.
Comment 4 Sebastian Dröge (slomo) 2011-05-03 10:55:28 UTC
Ping? I can't say much about that patch but this all looks a bit hacky ;)
Comment 5 Martin Storsjö 2011-05-03 11:00:49 UTC
It looks a bit hacky yes, but should be correct IMO.

Basically, it's a special return value (which can be chosen quite arbitrarily) signalled from the callback function to the caller.

To clean it up, one could add e.g. #define NO_MORE_INPUT_DATA 42 at the start of the file, and replace all the occurrances of the magic value with the define instead.
Comment 6 Tim-Philipp Müller 2011-05-03 11:06:28 UTC
I keep forgetting to push this until it's too close to the release, sorry. (And I can't test it myself)

Yes, a define for the magic value would definitely be good as well.
Comment 7 Martin Storsjö 2011-05-03 22:02:05 UTC
Created attachment 187156 [details] [review]
Cleanup patch
Comment 8 Martin Storsjö 2011-05-03 22:02:31 UTC
Created attachment 187157 [details] [review]
Patch fixing the bug
Comment 9 Sebastian Dröge (slomo) 2011-05-04 08:30:43 UTC
And 42 can never be returned in normal cases? Other than that this looks good
Comment 10 Martin Storsjö 2011-05-04 09:05:15 UTC
As far as I know, 42 can't be returned in normal cases (I think the return values are 0 or what we return from the callback, or some QT specific error codes which probably can't be 42). I've seen other uses of similar CoreAudio APIs where the value 1 was used for the same purpose.
Comment 11 Sebastian Dröge (slomo) 2011-05-30 06:46:44 UTC
commit d536b73e25403bfbdd6dcc558fb82d0e507ea8b3
Author: Martin Storsjo <martin@martin.st>
Date:   Thu Sep 2 23:31:23 2010 +0300

    qtwrapper: Decode audio until all input data is consumed
    
    The special return value is returned from our buffer callback
    when all input data has been consumed.

commit 02fc41fde55ea777bed6018aa8bef6dbe164405f
Author: Martin Storsjo <martin@martin.st>
Date:   Tue May 3 14:14:20 2011 +0300

    qtwrapper: Replace the hackish 42 magic number with a define
Comment 12 Martin Storsjö 2011-05-30 12:46:20 UTC
Thanks!