[MPlayer-dev-eng] DTS software decoder [patch]

wei jiang wj2b at virginia.edu
Thu Oct 14 00:47:23 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;




More information about the MPlayer-dev-eng mailing list