[MPlayer-dev-eng] [ffdts] multichannel decode [patch]

Wei Jiang jiangw98 at yahoo.com
Sun Oct 17 02:45:58 CEST 2004


current dts decoder is forced in 2 channal downmix
mode

Due to a bug in libdts-0.0.2 parse.c the mutlichannel
decoder do not process
the bias value
trasfer to decode core, thus the CONVERT function will
not work correctly to
convert to s16

I have reported the patch to original author at
videolan he agreeed to
implement it in their code
their application is not affected because they use
float wav format.

Second issue is per DTS ETSI TS 102 114 1.1.1, the DTS
channel line up is
different from AC3
their Center channel is always first if there is any,
and LFE is always last
if there is any.

So I changed the channel lineup routine, so that the
final out put is

L R SL RL C LFE, and it is been tested correct at XBMC
plantform which use
mplayer.dll as the core player


The bug fix in libdts parse.c
is from line 992 to 1003

    /* Down/Up mixing */
    if (state->prim_channels <
dts_channels[state->output &
DTS_CHANNEL_MASK])
    {
        dts_upmix (state->samples, state->amode,
state->output);
    } else
    if (state->prim_channels >
dts_channels[state->output &
DTS_CHANNEL_MASK])
    {
        dts_downmix (state->samples, state->amode,
state->output,
state->bias,
                     state->clev, state->slev);
    }

==>  else
==>    {
==>     for ( k = 0; k < 256*state->prim_channels; k++
)
==>      state->samples[k] += state->bias;
==>    }


    /* Generate LFE samples for this subsubframe
FIXME!!! */


The above code takes care of the bias for multichannel
situation, downmix
routine can set bias correctly.


here is the diff files for dtsdec.c

cvs diff: Empty password used - try 'cvs login' with a
real password

Index: libavcodec/dtsdec.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/dtsdec.c,v
retrieving revision 1.5
diff -u -r1.5 dtsdec.c
--- libavcodec/dtsdec.c 12 Sep 2004 17:35:54 -0000 1.5
+++ libavcodec/dtsdec.c 13 Oct 2004 11:14:12 -0000
@@ -1,4 +1,4 @@
-/*
+/*
  * dtsdec.c : free DTS Coherent Acoustics stream
decoder.
  * Copyright (C) 2004 Benjamin Zores
<ben at geexbox.org>
  *
@@ -26,15 +26,13 @@
 #include "avcodec.h"
 #include <dts.h>

+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
-#ifdef HAVE_MALLOC_H
 #include <malloc.h>
-#endif

 #define INBUF_SIZE 4096
-#define BUFFER_SIZE 4096
+#define BUFFER_SIZE 8192
 #define HEADER_SIZE 14

 #ifdef LIBDTS_FIXED
@@ -66,7 +64,7 @@
     {
       s16[2*i] = convert (f[i]);
       s16[2*i+1] = convert (f[i+256]);
-    }
+    }
 }

 void
@@ -90,13 +88,13 @@
   int i;
   int32_t * f = (int32_t *) _f;

-  for (i = 0; i < 256; i++)
+  for (i = 0; i < 256; i++)
     {
-      s16[5*i] = convert (f[i]);
-      s16[5*i+1] = convert (f[i+256]);
-      s16[5*i+2] = convert (f[i+512]);
-      s16[5*i+3] = convert (f[i+768]);
-      s16[5*i+4] = convert (f[i+1024]);
+      s16[5*i] = convert (f[i+256]);
+      s16[5*i+1] = convert (f[i+512]);
+      s16[5*i+2] = convert (f[i+768]);
+      s16[5*i+3] = convert (f[i+1024]);
+      s16[5*i+4] = convert (f[i]);
     }
 }

@@ -108,83 +106,137 @@

   switch (flags)
     {
-    case DTS_MONO:
+    case DTS_MONO:   //MON 2
       for (i = 0; i < 256; i++)
         {
-          s16[5*i] = s16[5*i+1] = s16[5*i+2] =
s16[5*i+3] = 0;
-          s16[5*i+4] = convert (f[i]);
+          s16[2*i] = s16[2*i+1] = convert (f[i]);
         }
       break;
-    case DTS_CHANNEL:
+    case DTS_CHANNEL:   //L R 2
     case DTS_STEREO:
-    case DTS_DOLBY:
+    case DTS_STEREO_TOTAL:
       convert2s16_2 (_f, s16);
       break;
-    case DTS_3F:
+    case DTS_STEREO_SUMDIFF:  //L+R L-R 2
       for (i = 0; i < 256; i++)
         {
-          s16[5*i] = convert (f[i]);
+          s16[2*i] = convert (f[i])/2 + convert
(f[i+256])/2;
+          s16[2*i+1] = convert (f[i])/2 - convert
(f[i+256])/2;
+        }
+      break;
+    case DTS_3F:   //C L R 5
+      for (i = 0; i < 256; i++)
+        {
+          s16[5*i] = convert (f[i+256]);
           s16[5*i+1] = convert (f[i+512]);
           s16[5*i+2] = s16[5*i+3] = 0;
-          s16[5*i+4] = convert (f[i+256]);
+          s16[5*i+4] = convert (f[i]);
         }
       break;
-    case DTS_2F2R:
+    case DTS_2F1R:   //L R S 4
+      for (i = 0; i < 256; i++)
+        {
+          s16[4*i] = convert (f[i]);
+          s16[4*i+1] = convert (f[i+256]);
+          s16[4*i+2] = s16[4*i+3] = convert
(f[i+512]);
+        }
+      break;
+    case DTS_3F1R:   //C L R S 5
+      for (i = 0; i < 256; i++)
+        {
+          s16[5*i] = convert (f[i]+256);
+          s16[5*i+1] = convert (f[i+512]);
+          s16[5*i+2] = s16[5*i+3] = convert
(f[i+768]);
+          s16[5*i+4] = convert (f[i]);
+        }
+      break;
+    case DTS_2F2R:   //L R SL SR 4
       convert2s16_4 (_f, s16);
       break;
-    case DTS_3F2R:
+    case DTS_3F2R:   //C L R SL SR 5
       convert2s16_5 (_f, s16);
       break;
-    case DTS_MONO | DTS_LFE:
+    case DTS_MONO | DTS_LFE:  //MON LFE 6
       for (i = 0; i < 256; i++)
         {
           s16[6*i] = s16[6*i+1] = s16[6*i+2] =
s16[6*i+3] = 0;
-          s16[6*i+4] = convert (f[i+256]);
-          s16[6*i+5] = convert (f[i]);
+          s16[6*i+4] = convert (f[i]);
+          s16[6*i+5] = convert (f[i+256]);
         }
       break;
     case DTS_CHANNEL | DTS_LFE:
     case DTS_STEREO | DTS_LFE:
-    case DTS_DOLBY | DTS_LFE:
+    case DTS_STEREO_TOTAL | DTS_LFE: //L R LFE 6
       for (i = 0; i < 256; i++)
         {
-          s16[6*i] = convert (f[i+256]);
-          s16[6*i+1] = convert (f[i+512]);
+          s16[6*i] = convert (f[i]);
+          s16[6*i+1] = convert (f[i+256]);
           s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
-          s16[6*i+5] = convert (f[i]);
+          s16[6*i+5] = convert (f[i+512]);
         }
       break;
-    case DTS_3F | DTS_LFE:
+    case DTS_STEREO_SUMDIFF | DTS_LFE: //L+R L-R LFE
6
+      for (i = 0; i < 256; i++)
+        {
+          s16[6*i] = convert (f[i])/2 + convert
(f[i+256])/2;
+          s16[6*i+1] = convert (f[i])/2 - convert
(f[i+256])/2;
+          s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
+          s16[6*i+5] = convert (f[i+512]);
+        }
+      break;
+    case DTS_3F | DTS_LFE: //C L R LFE 6
       for (i = 0; i < 256; i++)
         {
           s16[6*i] = convert (f[i+256]);
-          s16[6*i+1] = convert (f[i+768]);
+          s16[6*i+1] = convert (f[i+512]);
           s16[6*i+2] = s16[6*i+3] = 0;
-          s16[6*i+4] = convert (f[i+512]);
-          s16[6*i+5] = convert (f[i]);
+          s16[6*i+4] = convert (f[i]);
+          s16[6*i+5] = convert (f[i+768]);
         }
       break;
-    case DTS_2F2R | DTS_LFE:
+    case DTS_2F1R | DTS_LFE: //L R S LFE 6
+      for (i = 0; i < 256; i++)
+        {
+          s16[6*i] = convert (f[i]);
+          s16[6*i+1] = convert (f[i+256]);
+          s16[6*i+2] = s16[6*i+3] = convert
(f[i+512]);
+          s16[6*i+4] = 0;
+          s16[6*i+5] = convert (f[i+768]);
+        }
+      break;
+    case DTS_3F1R | DTS_LFE: //C L R S LFE 6
       for (i = 0; i < 256; i++)
         {
           s16[6*i] = convert (f[i+256]);
           s16[6*i+1] = convert (f[i+512]);
-          s16[6*i+2] = convert (f[i+768]);
-          s16[6*i+3] = convert (f[i+1024]);
+          s16[6*i+2] = s16[6*i+3] = convert
(f[i+768]);
+          s16[6*i+4] = convert (f[i]);
+          s16[6*i+5] = convert (f[i+1024]);
+        }
+      break;
+    case DTS_2F2R | DTS_LFE: //L R SL SR LFE 6
+      for (i = 0; i < 256; i++)
+        {
+          s16[6*i] = convert (f[i]);
+          s16[6*i+1] = convert (f[i+256]);
+          s16[6*i+2] = convert (f[i+512]);
+          s16[6*i+3] = convert (f[i+768]);
           s16[6*i+4] = 0;
-          s16[6*i+5] = convert (f[i]);
+          s16[6*i+5] = convert (f[i+1024]);
         }
       break;
-    case DTS_3F2R | DTS_LFE:
+    case DTS_3F2R | DTS_LFE: //C L R SL SR LFE 6
       for (i = 0; i < 256; i++)
         {
           s16[6*i] = convert (f[i+256]);
-          s16[6*i+1] = convert (f[i+768]);
-          s16[6*i+2] = convert (f[i+1024]);
-          s16[6*i+3] = convert (f[i+1280]);
-          s16[6*i+4] = convert (f[i+512]);
-          s16[6*i+5] = convert (f[i]);
+          s16[6*i+1] = convert (f[i+512]);
+          s16[6*i+2] = convert (f[i+768]);
+          s16[6*i+3] = convert (f[i+1024]);
+          s16[6*i+4] = convert (f[i]);
+          s16[6*i+5] = convert (f[i+1280]);
+
         }
+//    printf("samples %8x %8x %8x %8x %8x %8x", f[0],
f[256], f[512],
f[768], f[1024], f[1280] );
       break;
     }
 }
@@ -192,14 +244,12 @@
 static int
 channels_multi (int flags)
 {
+  static int dts_channels[11] = {2, 2, 2, 2, 2, 5, 4,
5, 4, 5, 6};
+
   if (flags & DTS_LFE)
     return 6;
-  else if (flags & 1) /* center channel */
-    return 5;
-  else if ((flags & DTS_CHANNEL_MASK) == DTS_2F2R)
-    return 4;
-  else
-    return 2;
+  else
+    return dts_channels[flags & DTS_CHANNEL_MASK];
 }

 static int
@@ -208,6 +258,8 @@
 {
   uint8_t * start = buff;
   uint8_t * end = buff + buff_size;
+  *data_size = 0;
+
   static uint8_t buf[BUFFER_SIZE];
   static uint8_t * bufptr = buf;
   static uint8_t * bufpos = buf + HEADER_SIZE;
@@ -218,8 +270,8 @@
   int bit_rate;
   int len;
   dts_state_t *state = avctx->priv_data;
-
-  *data_size = 0;
+  int finished;
+  finished = 0;

   while (1)
     {
@@ -247,14 +299,15 @@
                   continue;
                 }
               bufpos = buf + length;
+              finished += length;
             }
           else
             {
               level_t level;
               sample_t bias;
               int i;
-
-              flags = 2; /* ???????????? */
+
+//              flags = 2; /* ????????????  */ force
2 CH dts code removed,
libdts now has correct bias in new libdts.a
               level = CONVERT_LEVEL;
               bias = CONVERT_BIAS;

@@ -280,7 +333,10 @@
                 }
               bufptr = buf;
               bufpos = buf + HEADER_SIZE;
-              continue;
+              if (finished < 8192 )
+               continue;
+              else
+                return finished;
             error:
               av_log (NULL, AV_LOG_ERROR, "error\n");
               bufptr = buf;


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




More information about the MPlayer-dev-eng mailing list