[vlc-devel] [PATCH 10/17] dts_header: refactor, return values directly exploitable by the caller

Thomas Guillem thomas at gllm.fr
Wed Jul 27 17:27:26 CEST 2016


Reimplemented by reading the ETSI TS 102 114 specs.
---
 modules/codec/dts.c             | 153 +++---------------------
 modules/demux/mkv/mkv.cpp       |  15 ++-
 modules/demux/mpeg/es.c         |  16 +--
 modules/packetizer/dts_header.c | 252 +++++++++++++++++++++++++++++-----------
 modules/packetizer/dts_header.h |  23 ++--
 5 files changed, 221 insertions(+), 238 deletions(-)

diff --git a/modules/codec/dts.c b/modules/codec/dts.c
index 875109c..c70f12a 100644
--- a/modules/codec/dts.c
+++ b/modules/codec/dts.c
@@ -181,7 +181,7 @@ static void Flush( decoder_t *p_dec )
 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    uint8_t p_header[DTS_HEADER_SIZE];
+    uint8_t p_header[VLC_DTS_HEADER_SIZE];
     uint8_t *p_buf;
     block_t *p_out_buffer;
 
@@ -219,7 +219,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
             while( block_PeekBytes( &p_sys->bytestream, p_header, 6 )
                    == VLC_SUCCESS )
             {
-                if( SyncCode( p_header ) == VLC_SUCCESS )
+                if( vlc_dts_header_IsSync( p_header, 6 ) )
                 {
                     p_sys->i_state = STATE_SYNC;
                     break;
@@ -245,9 +245,9 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
             p_sys->i_state = STATE_HEADER;
 
         case STATE_HEADER:
-            /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
+            /* Get DTS frame header (VLC_DTS_HEADER_SIZE bytes) */
             if( block_PeekBytes( &p_sys->bytestream, p_header,
-                                 DTS_HEADER_SIZE ) != VLC_SUCCESS )
+                                 VLC_DTS_HEADER_SIZE ) != VLC_SUCCESS )
             {
                 /* Need more data */
                 return NULL;
@@ -291,7 +291,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
                 break;
             }
 
-            if( SyncCode( p_header ) != VLC_SUCCESS )
+            if( vlc_dts_header_IsSync( p_header, 6 ) )
             {
                 msg_Dbg( p_dec, "emulated sync word "
                          "(no sync on following frame): %2.2x%2.2x%2.2x%2.2x",
@@ -455,21 +455,6 @@ static block_t *GetSoutBuffer( decoder_t *p_dec )
 /*****************************************************************************
  * SyncInfo: parse DTS sync info
  *****************************************************************************/
-static const unsigned int ppi_dts_samplerate[] =
-{
-    0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
-    12000, 24000, 48000, 96000, 192000
-};
-
-static const unsigned int ppi_dts_bitrate[] =
-{
-    32000, 56000, 64000, 96000, 112000, 128000,
-    192000, 224000, 256000, 320000, 384000,
-    448000, 512000, 576000, 640000, 768000,
-    896000, 1024000, 1152000, 1280000, 1344000,
-    1408000, 1411200, 1472000, 1536000, 1920000,
-    2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
-};
 
 static int SyncInfo( const uint8_t *p_buf,
                      bool *pb_dts_hd,
@@ -479,127 +464,17 @@ static int SyncInfo( const uint8_t *p_buf,
                      unsigned int *pi_bit_rate,
                      unsigned int *pi_frame_length )
 {
-    unsigned int i_audio_mode;
-
-    unsigned int i_frame_size = GetSyncInfo( p_buf, pb_dts_hd,
-            pi_sample_rate, pi_bit_rate, pi_frame_length, &i_audio_mode);
-
-    if( *pb_dts_hd == true )
-        return i_frame_size;
-
-    switch( i_audio_mode & 0xFFFF )
-    {
-        case 0x0:
-            /* Mono */
-            *pi_channels = 1;
-            *pi_channels_conf = AOUT_CHAN_CENTER;
-            break;
-        case 0x1:
-            /* Dual-mono = stereo + dual-mono */
-            *pi_channels = 2;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                           AOUT_CHAN_DUALMONO;
-            break;
-        case 0x2:
-        case 0x3:
-        case 0x4:
-            /* Stereo */
-            *pi_channels = 2;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
-            break;
-        case 0x5:
-            /* 3F */
-            *pi_channels = 3;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                                AOUT_CHAN_CENTER;
-            break;
-        case 0x6:
-            /* 2F/1R */
-            *pi_channels = 3;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                                AOUT_CHAN_REARCENTER;
-            break;
-        case 0x7:
-            /* 3F/1R */
-            *pi_channels = 4;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                                AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER;
-            break;
-        case 0x8:
-            /* 2F2R */
-            *pi_channels = 4;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                                AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
-            break;
-        case 0x9:
-            /* 3F2R */
-            *pi_channels = 5;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                                AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
-                                AOUT_CHAN_REARRIGHT;
-            break;
-        case 0xA:
-        case 0xB:
-            /* 2F2M2R */
-            *pi_channels = 6;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                                AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
-                                AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
-            break;
-        case 0xC:
-            /* 3F2M2R */
-            *pi_channels = 7;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                                AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
-                                AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
-                                AOUT_CHAN_REARRIGHT;
-            break;
-        case 0xD:
-        case 0xE:
-            /* 3F2M2R/LFE */
-            *pi_channels = 8;
-            *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
-                                AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
-                                AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
-                                AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
-            break;
-
-        case 0xF:
-        default:
-            if( (i_audio_mode & 0xFFFF) >= 0x10 )
-            {
-                /* User defined */
-                *pi_channels = 0;
-                *pi_channels_conf = 0;
-            }
-            else return 0;
-
-            break;
-    }
-
-    if( *pi_channels && (i_audio_mode & 0x10000) )
-    {
-        (*pi_channels)++;
-        *pi_channels_conf |= AOUT_CHAN_LFE;
-    }
-
-    if( *pi_sample_rate >= sizeof( ppi_dts_samplerate ) /
-                           sizeof( ppi_dts_samplerate[0] ) )
-    {
+    vlc_dts_header_t dts;
+    if( vlc_dts_header_Parse( &dts, p_buf, VLC_DTS_HEADER_SIZE ) != VLC_SUCCESS )
         return 0;
-    }
-    *pi_sample_rate = ppi_dts_samplerate[ *pi_sample_rate ];
-    if( !*pi_sample_rate ) return 0;
 
-    if( *pi_bit_rate >= sizeof( ppi_dts_bitrate ) /
-                        sizeof( ppi_dts_bitrate[0] ) )
-    {
-        return 0;
-    }
-    *pi_bit_rate = ppi_dts_bitrate[ *pi_bit_rate ];
-    if( !*pi_bit_rate ) return 0;
+    *pb_dts_hd = dts.b_dts_hd;
 
-    *pi_frame_length = (*pi_frame_length + 1) * 32;
+    *pi_channels = popcount(dts.i_original_channels & AOUT_CHAN_PHYSMASK);
+    *pi_channels_conf = dts.i_original_channels;
+    *pi_sample_rate = dts.i_rate;
+    *pi_bit_rate = dts.i_bitrate;
+    *pi_frame_length = dts.i_frame_length;
 
-    return i_frame_size;
+    return dts.i_frame_size;
 }
diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp
index ff5b9da..8fb66b6 100644
--- a/modules/demux/mkv/mkv.cpp
+++ b/modules/demux/mkv/mkv.cpp
@@ -620,17 +620,16 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
          }
 
         case VLC_CODEC_DTS:
+        {
             /* Check if packetization is correct and without padding.
              * example: Test_mkv_div3_DTS_1920x1080_1785Kbps_23,97fps.mkv */
-            if( p_block->i_buffer > 6 )
-            {
-                unsigned int a, b, c, d;
-                bool e;
-                int i_frame_size = GetSyncInfo( p_block->p_buffer, &e, &a, &b, &c, &d );
-                if( i_frame_size > 0 )
-                    p_block->i_buffer = __MIN(p_block->i_buffer, (size_t)i_frame_size);
-            }
+            vlc_dts_header_t dts;
+            if( vlc_dts_header_Parse( &dts, p_block->p_buffer, p_block->i_buffer )
+                == VLC_SUCCESS && dts.i_frame_size > 0 )
+                p_block->i_buffer = __MIN(p_block->i_buffer,
+                                          (size_t)dts.i_frame_size);
             break;
+        }
 
          case VLC_CODEC_OPUS:
             mtime_t i_length = i_duration * track. f_timecodescale *
diff --git a/modules/demux/mpeg/es.c b/modules/demux/mpeg/es.c
index 12af7ef..182dd7f 100644
--- a/modules/demux/mpeg/es.c
+++ b/modules/demux/mpeg/es.c
@@ -1025,20 +1025,12 @@ static int A52Init( demux_t *p_demux )
  *****************************************************************************/
 static int DtsCheckSync( const uint8_t *p_peek, int *pi_samples )
 {
-    unsigned int i_sample_rate, i_bit_rate, i_frame_length, i_audio_mode;
-    bool b_dts_hd;
-
     VLC_UNUSED(pi_samples);
 
-    int i_frame_size = GetSyncInfo( p_peek,
-                                    &b_dts_hd,
-                                    &i_sample_rate,
-                                    &i_bit_rate,
-                                    &i_frame_length,
-                                    &i_audio_mode );
-
-    if( i_frame_size != VLC_EGENERIC && i_frame_size <= 8192 )
-        return i_frame_size;
+    vlc_dts_header_t dts;
+    if( vlc_dts_header_Parse( &dts, p_peek, 11 ) == VLC_SUCCESS
+     && dts.i_frame_size > 0 && dts.i_frame_size <= 8192 )
+        return dts.i_frame_size;
     else
         return VLC_EGENERIC;
 }
diff --git a/modules/packetizer/dts_header.c b/modules/packetizer/dts_header.c
index a6fed9a..2baa510 100644
--- a/modules/packetizer/dts_header.c
+++ b/modules/packetizer/dts_header.c
@@ -28,32 +28,24 @@
 
 #include <vlc_common.h>
 #include <vlc_bits.h>
+#include <vlc_aout.h>
 
 #include "dts_header.h"
 
 #include <assert.h>
 
-
-static int SyncInfo16be( const uint8_t *p_buf,
-                         unsigned int *pi_audio_mode,
-                         unsigned int *pi_sample_rate,
-                         unsigned int *pi_bit_rate,
-                         unsigned int *pi_frame_length )
+static void SyncInfo16be( const uint8_t *p_buf, uint8_t *pi_nblks,
+                          uint16_t *pi_fsize, uint8_t *pi_amode,
+                          uint8_t *pi_sfreq, uint8_t *pi_rate, bool *pb_lfe )
 {
-    unsigned int frame_size;
-    unsigned int i_lfe;
-
-    *pi_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
-    frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) | (p_buf[7] >> 4);
-
-    *pi_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
-    *pi_sample_rate = (p_buf[8] >> 2) & 0x0f;
-    *pi_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
+    *pi_nblks = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
+    *pi_fsize = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) | (p_buf[7] >> 4);
 
-    i_lfe = (p_buf[10] >> 1) & 0x03;
-    if( i_lfe ) *pi_audio_mode |= 0x10000;
+    *pi_amode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
+    *pi_sfreq = (p_buf[8] >> 2) & 0x0f;
+    *pi_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
 
-    return frame_size + 1;
+    *pb_lfe = (p_buf[10] >> 1) & 0x03;
 }
 
 static void BufLeToBe( uint8_t *p_out, const uint8_t *p_in, int i_in )
@@ -113,98 +105,218 @@ static int Buf14To16( uint8_t *p_out, const uint8_t *p_in, int i_in, int i_le )
     return i_out;
 }
 
-int SyncCode( const uint8_t *p_buf )
+bool vlc_dts_header_IsSync( const void *p_buffer, size_t i_buffer )
 {
+    if( i_buffer < 6 )
+        return false;
+
+    const uint8_t *p_buf = p_buffer;
     /* 14 bits, little endian version of the bitstream */
     if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
         p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
         (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
-    {
-        return VLC_SUCCESS;
-    }
+        return true;
     /* 14 bits, big endian version of the bitstream */
     else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
              p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
              p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
-    {
-        return VLC_SUCCESS;
-    }
+        return true;
     /* 16 bits, big endian version of the bitstream */
     else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
              p_buf[2] == 0x80 && p_buf[3] == 0x01 )
-    {
-        return VLC_SUCCESS;
-    }
+        return true;
     /* 16 bits, little endian version of the bitstream */
     else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
              p_buf[2] == 0x01 && p_buf[3] == 0x80 )
-    {
-        return VLC_SUCCESS;
-    }
+        return true;
     /* DTS-HD */
     else if( p_buf[0] == 0x64 && p_buf[1] ==  0x58 &&
              p_buf[2] == 0x20 && p_buf[3] ==  0x25 )
+        return true;
+    else
+        return false;
+}
+
+static unsigned int dca_get_samplerate( uint8_t i_sfreq )
+{
+    /* See ETSI TS 102 114, table 5-5 */
+    const unsigned int p_dca_samplerates[16] = {
+        0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
+        12000, 24000, 48000, 96000, 192000
+    };
+
+    if( i_sfreq >= 16 )
+        return 0;
+    return p_dca_samplerates[i_sfreq];
+}
+
+static unsigned int dca_get_bitrate( uint8_t i_rate )
+{
+    /* See ETSI TS 102 114, table 5-7 */
+    const unsigned int p_dca_bitrates[32] = {
+        32000,   56000,   64000,   96000,  112000,
+        128000, 192000,  224000,  256000,  320000,
+        384000, 448000,  512000,  576000,  640000,
+        768000, 896000, 1024000, 1152000, 1280000,
+        1344000, 1408000, 1411200, 1472000, 1536000,
+        1920000, 2048000, 3072000, 3840000,
+        /* FIXME: The following can't be put in a VLC audio_format_t:
+         * 1: open, 2: variable, 3: lossless */
+        0, 0, 0
+    };
+
+    if( i_rate >= 32 )
+        return 0;
+    return p_dca_bitrates[i_rate];
+}
+
+static uint32_t dca_get_channels( uint8_t i_amode, bool b_lfe )
+{
+    /* See ETSI TS 102 114, table 5-4
+     * 00: A
+     * 01: A + B (dual mono)
+     * 02: L + R (stereo)
+     * 03: (L+R) + (L-R) (sum and difference)
+     * 04: LT + RT (left and right total)
+     * 05: C + L + R
+     * 06: L + R + S
+     * 07: C + L + R + S
+     * 08: L + R + SL + SR
+     * 09: C + L + R + SL + SR
+     * 0A: CL + CR + L + R + SL + SR
+     * 0B: C + L + R + LR + RR + OV
+     * 0C: CF + CR + LF + RF + LR + RR
+     * 0D: CL + C + CR + L + R + SL + SR
+     * 0E: CL + CR + L + R + SL1 + SL2 + SR1 + SR2
+     * 0F: CL + C + CR + L + R + SL + S + SR
+     * 10-3F: user defined */
+
+    uint32_t i_original_channels;
+
+    switch( i_amode )
     {
-        return VLC_SUCCESS;
+        case 0x0:
+            i_original_channels = AOUT_CHAN_CENTER;
+            break;
+        case 0x1:
+            i_original_channels = AOUT_CHANS_FRONT | AOUT_CHAN_DUALMONO;
+            break;
+        case 0x2:
+        case 0x3:
+        case 0x4:
+            i_original_channels = AOUT_CHANS_FRONT;
+            break;
+        case 0x5:
+            i_original_channels = AOUT_CHANS_3_0;
+            break;
+        case 0x6:
+            i_original_channels = AOUT_CHANS_FRONT | AOUT_CHAN_REARCENTER;
+            break;
+        case 0x7:
+            i_original_channels = AOUT_CHANS_4_CENTER_REAR;
+            break;
+        case 0x8:
+            i_original_channels = AOUT_CHANS_4_0;
+            break;
+        case 0x9:
+            i_original_channels = AOUT_CHANS_5_0;
+            break;
+        case 0xA:
+        case 0xB:
+            i_original_channels = AOUT_CHANS_6_0;
+            break;
+        case 0xC:
+            i_original_channels = AOUT_CHANS_CENTER | AOUT_CHANS_FRONT
+                                | AOUT_CHANS_REAR;
+            break;
+        case 0xD:
+            i_original_channels = AOUT_CHANS_7_0;
+            break;
+        case 0xE:
+        case 0xF:
+            /* FIXME: AOUT_CHANS_8_0 */
+            i_original_channels = AOUT_CHANS_7_0;
+            break;
+        default:
+            return 0;
     }
+    if (b_lfe)
+        i_original_channels |= AOUT_CHAN_LFE;
 
-    return VLC_EGENERIC;
+    return i_original_channels;
 }
 
-int GetSyncInfo( const uint8_t *p_buf,
-                        bool *pb_dts_hd,
-                        unsigned int *pi_sample_rate,
-                        unsigned int *pi_bit_rate,
-                        unsigned int *pi_frame_length,
-                        unsigned int *pi_audio_mode )
+int vlc_dts_header_Parse( vlc_dts_header_t *p_header,
+                          const void *p_buffer, size_t i_buffer)
 {
+    const uint8_t *p_buf = p_buffer;
     unsigned int i_frame_size;
+    bool b_lfe;
+    uint16_t i_fsize;
+    uint8_t i_nblks, i_rate, i_sfreq, i_amode;
+
+    if( i_buffer < 11 )
+        return VLC_EGENERIC;
 
     /* 14 bits, little endian version of the bitstream */
     if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
         p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
         (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
     {
-        uint8_t conv_buf[DTS_HEADER_SIZE];
-        Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 1 );
-        i_frame_size = SyncInfo16be( conv_buf, pi_audio_mode, pi_sample_rate,
-                                     pi_bit_rate, pi_frame_length );
-        i_frame_size = i_frame_size * 8 / 14 * 2;
+        if( i_buffer < VLC_DTS_HEADER_SIZE )
+            return VLC_EGENERIC;
+
+        uint8_t conv_buf[VLC_DTS_HEADER_SIZE];
+        Buf14To16( conv_buf, p_buf, VLC_DTS_HEADER_SIZE, 1 );
+        SyncInfo16be( conv_buf, &i_nblks, &i_fsize, &i_amode, &i_sfreq,
+                      &i_rate, &b_lfe );
+        i_frame_size = (i_fsize + 1) * 8 / 14 * 2;
     }
     /* 14 bits, big endian version of the bitstream */
     else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
              p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
              p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
     {
-        uint8_t conv_buf[DTS_HEADER_SIZE];
-        Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 0 );
-        i_frame_size = SyncInfo16be( conv_buf, pi_audio_mode, pi_sample_rate,
-                                     pi_bit_rate, pi_frame_length );
-        i_frame_size = i_frame_size * 8 / 14 * 2;
+        if( i_buffer < VLC_DTS_HEADER_SIZE )
+            return VLC_EGENERIC;
+
+        uint8_t conv_buf[VLC_DTS_HEADER_SIZE];
+        Buf14To16( conv_buf, p_buf, VLC_DTS_HEADER_SIZE, 0 );
+        SyncInfo16be( conv_buf, &i_nblks, &i_fsize, &i_amode, &i_sfreq,
+                      &i_rate, &b_lfe );
+        i_frame_size = (i_fsize + 1) * 8 / 14 * 2;
     }
     /* 16 bits, big endian version of the bitstream */
     else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
              p_buf[2] == 0x80 && p_buf[3] == 0x01 )
     {
-        i_frame_size = SyncInfo16be( p_buf, pi_audio_mode, pi_sample_rate,
-                                     pi_bit_rate, pi_frame_length );
+        SyncInfo16be( p_buf, &i_nblks, &i_fsize, &i_amode, &i_sfreq,
+                      &i_rate, &b_lfe );
+        i_frame_size = i_fsize + 1;
     }
     /* 16 bits, little endian version of the bitstream */
     else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
              p_buf[2] == 0x01 && p_buf[3] == 0x80 )
     {
-        uint8_t conv_buf[DTS_HEADER_SIZE];
-        BufLeToBe( conv_buf, p_buf, DTS_HEADER_SIZE );
-        i_frame_size = SyncInfo16be( conv_buf, pi_audio_mode, pi_sample_rate,
-                                     pi_bit_rate, pi_frame_length );
+        if( i_buffer < VLC_DTS_HEADER_SIZE )
+            return VLC_EGENERIC;
+
+        uint8_t conv_buf[VLC_DTS_HEADER_SIZE];
+        BufLeToBe( conv_buf, p_buf, VLC_DTS_HEADER_SIZE );
+        SyncInfo16be( conv_buf, &i_nblks, &i_fsize, &i_amode, &i_sfreq,
+                      &i_rate, &b_lfe );
+        i_frame_size = i_fsize + 1;
     }
     /* DTS-HD */
     else if( p_buf[0] == 0x64 && p_buf[1] ==  0x58 &&
                 p_buf[2] == 0x20 && p_buf[3] ==  0x25 )
     {
+        if( i_buffer < VLC_DTS_HEADER_SIZE )
+            return VLC_EGENERIC;
+
         int i_dts_hd_size;
         bs_t s;
-        bs_init( &s, &p_buf[4], DTS_HEADER_SIZE - 4 );
+        bs_init( &s, &p_buf[4], VLC_DTS_HEADER_SIZE - 4 );
 
         bs_skip( &s, 8 + 2 );
 
@@ -222,22 +334,22 @@ int GetSyncInfo( const uint8_t *p_buf,
         //uint16_t s1 = bs_read( &s, 16 );
         //fprintf( stderr, "DTS HD=%d : %x %x\n", i_dts_hd_size, s0, s1 );
 
-        *pb_dts_hd = true;
-        /* As we ignore the stream, do not modify those variables:
-        *pi_channels = ;
-        *pi_channels_conf = ;
-        *pi_sample_rate = ;
-        *pi_bit_rate = ;
-        *pi_frame_length = ;
-        */
-        return i_dts_hd_size;
+        /* As we ignore the stream, do not modify those variables: */
+        memset(p_header, 0, sizeof(*p_header));
+        p_header->b_dts_hd = true;
+        p_header->i_frame_size = i_dts_hd_size;
+        return VLC_SUCCESS;
     }
     else
-    {
         return VLC_EGENERIC;
-    }
 
-    *pb_dts_hd = false;
-    return i_frame_size;
-}
+    p_header->b_dts_hd = false;
+    p_header->i_rate = dca_get_samplerate( i_sfreq );
+    p_header->i_bitrate = dca_get_bitrate( i_rate );
+    p_header->i_frame_size = i_frame_size;
+    /* See ETSI TS 102 114, table 5-2 */
+    p_header->i_frame_length = (i_nblks + 1) * 32;
+    p_header->i_original_channels = dca_get_channels( i_amode, b_lfe );
 
+    return VLC_SUCCESS;
+}
diff --git a/modules/packetizer/dts_header.h b/modules/packetizer/dts_header.h
index 1429f81..89392b9 100644
--- a/modules/packetizer/dts_header.h
+++ b/modules/packetizer/dts_header.h
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * dts_header.c: parse DTS audio headers info
  *****************************************************************************
- * Copyright (C) 2004-2009 VLC authors and VideoLAN
+ * Copyright (C) 2004-2016 VLC authors and VideoLAN
  * $Id$
  *
  * Authors: Gildas Bazin <gbazin at netcourrier.com>
@@ -22,14 +22,19 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-#define DTS_HEADER_SIZE 14
+#define VLC_DTS_HEADER_SIZE 14
 
-int GetSyncInfo( const uint8_t *p_buf,
-                        bool *pb_dts_hd,
-                        unsigned int *pi_sample_rate,
-                        unsigned int *pi_bit_rate,
-                        unsigned int *pi_frame_length,
-                        unsigned int *pi_audio_mode );
+typedef struct
+{
+    bool            b_dts_hd;
+    unsigned int    i_rate;
+    unsigned int    i_bitrate;
+    unsigned int    i_frame_size;
+    unsigned int    i_frame_length;
+    uint32_t        i_original_channels;
+} vlc_dts_header_t;
 
-int SyncCode( const uint8_t * );
+int     vlc_dts_header_Parse( vlc_dts_header_t *p_header,
+                              const void *p_buffer, size_t i_buffer);
 
+bool    vlc_dts_header_IsSync( const void *p_buffer, size_t i_buffer );
-- 
2.8.1



More information about the vlc-devel mailing list