[FFmpeg-devel] Handling of mono data in WMA lossless

Jakub Stachowski qbast at go2.pl
Wed May 2 00:53:17 CEST 2012

W dniu 2012-05-01 22:44, Michael Niedermayer pisze:
> On Sun, Apr 29, 2012 at 11:36:15PM +0200, Jakub Stachowski wrote:
>> Hello
>> While testing WMA lossless decoder on various files I found another
>> case when it outputs different data from Microsoft's implementation.
>> I have not been able to fully fix this, so I am sharing what I found
>> so far in hope that someone else will be able to provide additional
>> information.
>> WMAL apparently has special way of dealing with mono (where all
>> samples in both channels are identical) data: only first channel is
>> coded and decoder is expected to copy samples to second channel.
>> Attached testsamples.c creates two files designed to cause encoder
>> to use this mode: samples-equal.pcm have first frame with mono data,
>> in second frame it is different. Decoder should copy data from first
>> channel to second.
>> sample-zero.pcm has data in first channel and zeros in second. In
>> this case decoder should not copy data. I have no found any specific
>> flag which decides that, but it is possible that do_interch_decorr
>> is used.
>> Attached patch makes ffmpeg decode both files ok. It also fixes
>> Mashiat's sample.
>> However it does not work with real world sample (
>> http://stream1.criteriamx.com:8080/part.wma ) . Unfortunately I
>> cannot share whole file.
>> Differences are following:
>> - in my previous samples, copying of data from first to second
>> channel has to be done before all filtering. Otherwise second frame
>> will be broken
>> - however in this sample it is the other way around - samples has to
>> be copied as last step or decoder starts generating wrong data
>> - there are frames which have both channel coded and yet encoder
>> should overwrite data. Which really makes no sense to me.
>> - I decoded the sample into wav and compressed it again with
>> Expression encoder. This time ffmpeg could decode it ok. Maybe
>> behaviour was different in older version of SDK ( ?
> in general stereo codecs that do decorreleation treat a non coded
> second channel like a coded seconded channel with all 0 values.
> the decorrleation will then do the "copy".
> its also possible in some codecs (WMA comes to mind if iam not
> mistaken) that the first channel is not coded but the second is, this
> is rare but that cant be handled by a simply copy.
> not sure if any of this helps ...

This is exactly what I have been missing. I guess it really pays to 
actually have some idea how audio coding works. All my weird attempts to 
copy data were unnecessary, for some reason reverse decorrelation was 
restricted to case when both channels are coded. Removing that check 
fixes my synthetic test files, real world test case and does not break 3 
other random WMA files I tested. Patch is attached.

> [...]
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

-------------- next part --------------
>From af0ed9db02450cb343da2fd781166f8d5a7f3808 Mon Sep 17 00:00:00 2001
From: Jakub Stachowski <qbast at go2.pl>
Date: Wed, 2 May 2012 00:33:17 +0200
Subject: [PATCH] Don't restrict reverse decorrelation to both coded channels.
 It is also used for mono data.

 libavcodec/wmalosslessdec.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index b77d576..7a98b6d 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -793,7 +793,7 @@ static void revert_inter_ch_decorr(WmallDecodeCtx *s, int tile_size)
     if (s->num_channels != 2)
-    else if (s->is_channel_coded[0] && s->is_channel_coded[1]) {
+    else {
         int icoef;
         for (icoef = 0; icoef < tile_size; icoef++) {
             s->channel_residues[0][icoef] -= s->channel_residues[1][icoef] >> 1;

More information about the ffmpeg-devel mailing list