[MPlayer-dev-eng] [PATCH] Fix incorrect channel ordering for various codecs
Jason Tackaberry
tack at urandom.ca
Mon Aug 10 01:47:23 CEST 2009
Patch Overview
--------------
Note: this patch incorporates the previous patch I submitted "Support
32-bit samples in ad_ffmpeg," since the earlier patch fixes a subset of
the larger channel ordering problem addressed by this new patch.
The following codecs/filters are currently broken for >= 5 channels:
ad_ffmpeg (ffac3, ffdca, ffflac, ffaac, mlp/truehd), af_lavcac3enc, and
ae_lavc (ac3). The attached patch fixes channel ordering for these.
Some time over the last year, many ffmpeg codecs adjusted their channel
ordering to conform to a new multichannel audio API introduced in
ffmpeg. See [0] for the thread on ffmpeg-devel. Since that change, the
above listed codecs have had incorrect channel order.
More changes will follow for 8 channel (7.1) support. But I'd like to
get these fixes merged first.
Explanation of Changes
----------------------
The following special cases in ad_ffmpeg were removed:
* AF_CHANNEL_LAYOUT_LAVC_AC3_DEFAULT
* AF_CHANNEL_LAYOUT_LAVC_DCA_DEFAULT
* AF_CHANNEL_LAYOUT_LAVC_LIBA52_DEFAULT (unused)
* AF_CHANNEL_LAYOUT_FLAC_DEFAULT
A new generic lavc channel layout AF_CHANNEL_LAYOUT_LAVC_DEFAULT is now
defined, which uses the SMPTE/ITU-R ordering defined as
AF_CHANNEL_LAYOUT_5_[01]_A. This is the channel ordering specified in
libavcodec/avcodec.h:363 (comment starts "Audio channel masks"). The
bit order indicates the channel order as LSB to MSB (5 channel: L R C Ls
Rs; 6 channel: L R C LFE Ls Rs).
AF_CHANNEL_LAYOUT_VORBIS_DEFAULT is retained, because it seems to be
necessary. (In other words, lavc is not decoding vorbis to the
standardized lavc order yet.)
AAC is a bit more complicated, because -- for 6 channel AAC only -- lavc
decoding, for whatever reason, uses a different channel order than that
used by faad and (oddly) lavc AAC encoding. Consequently, a new layout
AF_CHANNEL_LAYOUT_LAVC_AAC_DEC_DEFAULT was created and is used in
ad_ffmpeg.
This new 6ch AAC layout is defined in libavcodec/aac.c:180 as C L R LFE
Ls Rs. I've defined a corresponding new layout AF_CHANNEL_LAYOUT_5_1_F
and added support for conversion from 5_1_F -> 5_1_B to
reorder_channel_copy() and reorder_channel(). 5 channel AAC is C L R Ls
Rs, which already exists as AF_CHANNEL_LAYOUT_5_0_D.
A Note About Vorbis
-------------------
The 5+ channel situation with Ogg Vorbis could aptly be described as a
clusterfuck.
Channel order is defined in the specification [1], but older versions of
oggenc ignore it, and newer versions don't appear to behave sanely
unless (theoretically, I've not verified) the source wave has a
WAVE_FORMAT_EXTENSIBLE header, which ao_pcm does not output.
There is another encoder, oggenc2 [2], which is a fork (geared to
Windows users) of the official Xiph oggenc from vorbis-tools. According
to [3], in oggenc2, when a WAVE_FORMAT_EXTENSIBLE header is present, it
will remap the channels into the Vorbis defined order [1], and when that
header is not present, it does no mapping, and therefore assumes the
channel order in the wav is already the Vorbis order (L C R RL RR LFE).
The official oggenc (which is standard on Linux distros; I'm using
1.2.0) works in some inscrutable way. I've tried generating a wav file
(from ao_pcm) in both the default Windows (SMPTE/ITU-R) order and the
Vorbis order, encoded with oggenc, and not even ogg123 from the same
source tree can play back in the proper order.
I'll obviously need to RTFS to understand it, but having read several
threads on various forums/lists (hydrogenaudio, doom9, vorbis-dev), it's
clear that channel ordering has been a serious problem with Vorbis for
some time.
What I eventually settled on was using af_channel and ao_pcm to remap
the channels according to the Vorbis specification (and verified in
audacity) and then used the windows binary oggenc2.exe (under wine) to
transcode to vorbis. This plays back in the proper channel order with
MPlayer.
The last thing I'll say on this topic is that my patch doesn't change
the current layout for Vorbis, so even if the method outlined in the
previous paragraph is intrinsically incorrect, we're at least no worse
off than before.
Testing Methodology
-------------------
I tried to be as thorough as possible in testing these changes.
I acquired speaker test files for both DTS and AC3 which just speak out
the channel name (front left, rear right, etc.) in the corresponding
channel. I played back these files using AC3/DTS passthrough to my
Pioneer SC-05 AVR to verify the proper order.
All test files for the various codecs have been generated from these
two, so correctness hinges on my AVR getting the proper channel order
from AC3 and DTS bitstreams. (It's probably a safe bet.)
The following matrix depicts the formats and codecs tested. All test
cases verified working.
Channels | Codec/Filter | Was broken? | Footnote
----------+---------------+---------------+------------
5.1 | pcm | No | [a]
5.1 | a52 | No |
5.1 | ffac3 | Yes |
5.1 | dts | No | [b]
5.1 | ffdca | Yes | [b]
5.1 | ffflac | Yes |
5.1 | tremor | No | [c]
5.1 | ffvorbis | No | [c]
5.1 | faad | No | [d]
5.1 | ffaac | Yes | [d]
5.1 | truehd | Yes | [e]
5.1 | af_lavcac3enc | Yes | [f]
5.1 | ae_lavc/ac3 | Yes | [g]
5.1 | ae_lavc/aac | No | [h]
----------+---------------+---------------+------------
5.0 | pcm | No | [a]
5.0 | a52 | No |
5.0 | ffac3 | Yes |
5.0 | ffflac | No |
5.0 | tremor | No | [c]
5.0 | ffvorbis | No | [c]
5.0 | faad | No | [d]
5.0 | ffaac | Yes | [d]
5.0 | af_lavcac3enc | Yes | [f]
5.0 | ae_lavc/ac3 | Yes | [g]
5.0 | ae_lavc/aac | No | [h]
Footnotes
---------
[0] http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2008-August/052382.html
[1] http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9
[2] http://www.rarewares.org/ogg-oggenc.php
[3] http://www.hydrogenaudio.org/forums/lofiversion/index.php/t16033.html
[4] http://www.nero.com/eng/downloads-nerodigital-nero-aac-codec.php
[a] Generated from speakertest.ac3:
mplayer speakertest.ac3 -channels 6 -ac a52 \
-ao pcm:fast:file=speakertest.wav
(Substitute -channels 5 for the 5.0 channel version.)
[b] 5.0 DTS not tested as I had no samples and no DTS encoder to
generate one. It's probably not unreasonable to infer that it will
work.
[c] Generated wave file with channels in Vorbis order (L C R RL RR LFE)
using:
mplayer speakertest.wav -af channels=6:6:0:0:1:4:2:5:3:2:4:1:5:3 \
-ao pcm:fast:file=speakertest-vorbis-order.wav
I then used oggenc2.exe (under wine) to encode
speakertest-vorbis-order.ogg. This wave file won't have the
WAVE_FORMAT_EXTENSIBLE header, and so oggenc2.exe will not remap the
channels.
[d] 5.1 AAC samples generated using NeroAacEnc [4] and faac.
However, NeroAacEnc segfaults on 5 channel wav, and faac
assumes 4.1 for 5 channel, so 5.0 sample generated using
mencoder -channels 5 -oac lavc -lavcopts acodec=libfaac
[e] I have no TrueHD/MLP encoder to encode speakertest.wav for a
definitive test. Instead I visually compared the resulting waves
from -ao pcm of a film's TrueHD track against its AC3 track.
[f] Used AC3 passthrough to my AVR, and verified on the AVR that it was
receiving either 5.1 or 5.0 AC3 and with proper channel order.
[g] As with [f], except played back the output file generated by mencoder.
[h] Output file tested on playback with both faad and ffaac.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: channel-layout-fixes.patch
Type: text/x-patch
Size: 9199 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20090809/11222736/attachment.bin>
More information about the MPlayer-dev-eng
mailing list