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 720659 - avimux generates wrong 'blockalign'
avimux generates wrong 'blockalign'
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other Linux
: Normal normal
: 1.2.3
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2013-12-18 09:29 UTC by Michael Olbrich
Modified: 2016-05-02 06:11 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Michael Olbrich 2013-12-18 09:29:39 UTC
From what I can tell the avi muxer generates the wrong 'blockalign' in some
situations. I observed this with a audio/mpeg stream generated by voaacenc.
The relevant code is in gst_avi_mux_audsink_set_fields():
[...]
    /* FIXME ?? some rumours say this should be largest audio chunk size */
    avipad->auds.blockalign = avipad->parent.hdr.scale;
[...]
The comment is at least partially correct: If blockalign is smaller than
the largest audio chunk size then the demuxer gets it wrong. In my case
blockalign is 1024 and sometimes a block is larger than 1024 bytes (this
probably happens because I use voaacenc with bitrate=256000).

The demuxer parses the index and does this in gst_avi_demux_add_index():
[...]
    blockalign = stream->strf.auds->blockalign;
    if (blockalign > 0)
      stream->total_blocks += DIV_ROUND_UP (entry->size, blockalign);
[...]
For any block that is larger than 1024 this results in
"stream->total_blocks += 2" (or more). This is wrong as the block only
contains 1024 samples. As a result, any following block is delayed by the
duration of one block.
It is a cumulative effect. In my use-case this results in an delay of 2
seconds after one hour.
I'm not sure, what the correct value for blockalign is. I see the problem
when playing the relevant files with VLC, MPlayer and GStreamer. I 'fixed'
the Problem by setting:
[...]
avipad->auds.blockalign = avipad->parent.hdr.scale * avipad->auds.channels;
[...]
I'm not sure what the correct value is. For GStreamer any value larger than
the largest audio block size is fine. I have no idea what other
implementations need.
Comment 1 Sebastian Dröge (slomo) 2014-01-03 09:06:12 UTC
Yes, there seems to be something broken around that. Also check the blockalign handling in libgstriff for some inspiration :)
Comment 2 Mark Nauwelaerts 2014-01-19 17:19:22 UTC
IIRC, I put that comment there once, so I guess it's about time to really fix it ;)

commit 3ea338ce271e1f6a96d2ed49d4472b091f6f8b7e
Author: Mark Nauwelaerts <mnauw@users.sourceforge.net>
Date:   Sun Jan 19 17:38:59 2014 +0100

    avimux: write correct blockalign for vbr audio
    
    Fixes https://bugzilla.gnome.org/show_bug.cgi?id=720659

Also pushed to 1.2
Comment 3 Sebastian Dröge (slomo) 2016-04-27 11:17:02 UTC
This causes regressions with MP2 at least, and is fixed by

commit e538608b3f90539003de21c1db238f3c9b946e30
Author: Sebastian Dröge <sebastian@centricular.com>
Date:   Wed Apr 27 14:09:03 2016 +0300

    avimux: Don't override maximum audio chunk size with the scale again just before writing it
    
    set_fields() should only be called in the beginning, otherwise we will never
    remember the maximum audio chunk size and write a wrong block align... which
    then causes wrong timestamps and other problems.

commit 34dc1298e9c03a6f2f8f367b344b4c6525bd1d83
Author: Sebastian Dröge <sebastian@centricular.com>
Date:   Wed Apr 27 13:53:00 2016 +0300

    avimux: Actually store the largest audio chunk size for the VBR case of MP2/MP3
    
    3ea338ce271e1f6a96d2ed49d4472b091f6f8b7e changed avimux to do that, but it
    never actually kept track of the max audio chunk for MP3 and MP2. These are
    knowing the hdr.scale only after parsing the frames instead of at setcaps
    time.
Comment 4 Mark Nauwelaerts 2016-05-01 13:18:59 UTC
Unfortunately the above commit introduced a slight functional change.  In case of audio CBR, the audio bps in question is only (reliably) calculated at the end, and the proper fields need to be updated, some of which being done by set_fields(), so that still needs to be handled:

commit eb336a804b4b4214f3db3d99c0630e1c50a3e1aa
Author: Mark Nauwelaerts <mnauw@users.sourceforge.net>
Date:   Sun May 1 15:09:27 2016 +0200

    avimux: set audio header rate according to calculated bps in stop_file
    
    ... now that set_fields is no longer called there by
    e538608b3f90539003de21c1db238f3c9b946e30
Comment 5 Sebastian Dröge (slomo) 2016-05-02 06:11:21 UTC
Thanks for taking a look :)