dts.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:25k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * dts.c: parse DTS audio sync info and packetize the stream
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2009 the VideoLAN team
  5.  * $Id: 9b4ac47f8d2a92ecf1fe9c414570e584a99bfa5a $
  6.  *
  7.  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
  8.  *          Gildas Bazin <gbazin@netcourrier.com>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include <vlc_codec.h>
  33. #include <vlc_aout.h>
  34. #include <vlc_block_helper.h>
  35. #include <vlc_bits.h>
  36. /*****************************************************************************
  37.  * Module descriptor
  38.  *****************************************************************************/
  39. static int  OpenDecoder   ( vlc_object_t * );
  40. static int  OpenPacketizer( vlc_object_t * );
  41. static void CloseCommon   ( vlc_object_t * );
  42. vlc_module_begin ()
  43.     set_description( N_("DTS parser") )
  44.     set_capability( "decoder", 100 )
  45.     set_callbacks( OpenDecoder, CloseCommon )
  46.     add_submodule ()
  47.     set_description( N_("DTS audio packetizer") )
  48.     set_capability( "packetizer", 10 )
  49.     set_callbacks( OpenPacketizer, CloseCommon )
  50. vlc_module_end ()
  51. /*****************************************************************************
  52.  * decoder_sys_t : decoder descriptor
  53.  *****************************************************************************/
  54. struct decoder_sys_t
  55. {
  56.     /* Module mode */
  57.     bool b_packetizer;
  58.     /*
  59.      * Input properties
  60.      */
  61.     int i_state;
  62.     block_bytestream_t bytestream;
  63.     /*
  64.      * Common properties
  65.      */
  66.     audio_date_t   end_date;
  67.     mtime_t i_pts;
  68.     bool         b_dts_hd;  /* Is the current frame a DTS HD one */
  69.     unsigned int i_bit_rate;
  70.     unsigned int i_frame_size;
  71.     unsigned int i_frame_length;
  72.     unsigned int i_rate;
  73.     unsigned int i_channels;
  74.     unsigned int i_channels_conf;
  75. };
  76. enum {
  77.     STATE_NOSYNC,
  78.     STATE_SYNC,
  79.     STATE_HEADER,
  80.     STATE_NEXT_SYNC,
  81.     STATE_GET_DATA,
  82.     STATE_SEND_DATA
  83. };
  84. #define DTS_HEADER_SIZE 14
  85. /****************************************************************************
  86.  * Local prototypes
  87.  ****************************************************************************/
  88. static int OpenCommon( vlc_object_t *, bool b_packetizer );
  89. static void *DecodeBlock( decoder_t *, block_t ** );
  90. static inline int SyncCode( const uint8_t * );
  91. static int  SyncInfo( const uint8_t *, bool *, unsigned int *, unsigned int *,
  92.                       unsigned int *, unsigned int *, unsigned int * );
  93. static uint8_t       *GetOutBuffer ( decoder_t *, void ** );
  94. static aout_buffer_t *GetAoutBuffer( decoder_t * );
  95. static block_t       *GetSoutBuffer( decoder_t * );
  96. /*****************************************************************************
  97.  * OpenDecoder: probe the decoder
  98.  *****************************************************************************/
  99. static int OpenDecoder( vlc_object_t *p_this )
  100. {
  101.     /* HACK: Don't use this codec if we don't have an dts audio filter */
  102.     if( !module_exists( "dtstofloat32" ) )
  103.         return VLC_EGENERIC;
  104.     return OpenCommon( p_this, false );
  105. }
  106. /*****************************************************************************
  107.  * OpenPacketizer: probe the packetizer
  108.  *****************************************************************************/
  109. static int OpenPacketizer( vlc_object_t *p_this )
  110. {
  111.     return OpenCommon( p_this, true );
  112. }
  113. /*****************************************************************************
  114.  * OpenCommon:
  115.  *****************************************************************************/
  116. static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
  117. {
  118.     decoder_t *p_dec = (decoder_t*)p_this;
  119.     decoder_sys_t *p_sys;
  120.     if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s',' ') &&
  121.         p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s','b') )
  122.     {
  123.         return VLC_EGENERIC;
  124.     }
  125.     /* Allocate the memory needed to store the decoder's structure */
  126.     if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
  127.         return VLC_ENOMEM;
  128.     /* Misc init */
  129.     p_sys->b_packetizer = b_packetizer;
  130.     p_sys->i_state = STATE_NOSYNC;
  131.     aout_DateSet( &p_sys->end_date, 0 );
  132.     p_sys->b_dts_hd = false;
  133.     p_sys->bytestream = block_BytestreamInit();
  134.     /* Set output properties */
  135.     p_dec->fmt_out.i_cat = AUDIO_ES;
  136.     p_dec->fmt_out.i_codec = VLC_FOURCC('d','t','s',' ');
  137.     p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
  138.     /* Set callback */
  139.     p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
  140.         DecodeBlock;
  141.     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
  142.         DecodeBlock;
  143.     return VLC_SUCCESS;
  144. }
  145. /****************************************************************************
  146.  * DecodeBlock: the whole thing
  147.  ****************************************************************************/
  148. static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
  149. {
  150.     decoder_sys_t *p_sys = p_dec->p_sys;
  151.     uint8_t p_header[DTS_HEADER_SIZE];
  152.     uint8_t *p_buf;
  153.     void *p_out_buffer;
  154.     if( !pp_block || !*pp_block )
  155.         return NULL;
  156.     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
  157.     {
  158.         if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
  159.         {
  160.             p_sys->i_state = STATE_NOSYNC;
  161.             block_BytestreamEmpty( &p_sys->bytestream );
  162.         }
  163.         aout_DateSet( &p_sys->end_date, 0 );
  164.         block_Release( *pp_block );
  165.         return NULL;
  166.     }
  167.     if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
  168.     {
  169.         /* We've just started the stream, wait for the first PTS. */
  170.         block_Release( *pp_block );
  171.         return NULL;
  172.     }
  173.     block_BytestreamPush( &p_sys->bytestream, *pp_block );
  174.     while( 1 )
  175.     {
  176.         switch( p_sys->i_state )
  177.         {
  178.         case STATE_NOSYNC:
  179.             /* Look for sync code - should be 0x7ffe8001 */
  180.             while( block_PeekBytes( &p_sys->bytestream, p_header, 6 )
  181.                    == VLC_SUCCESS )
  182.             {
  183.                 if( SyncCode( p_header ) == VLC_SUCCESS )
  184.                 {
  185.                     p_sys->i_state = STATE_SYNC;
  186.                     break;
  187.                 }
  188.                 block_SkipByte( &p_sys->bytestream );
  189.             }
  190.             if( p_sys->i_state != STATE_SYNC )
  191.             {
  192.                 block_BytestreamFlush( &p_sys->bytestream );
  193.                 /* Need more data */
  194.                 return NULL;
  195.             }
  196.         case STATE_SYNC:
  197.             /* New frame, set the Presentation Time Stamp */
  198.             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
  199.             if( p_sys->i_pts != 0 &&
  200.                 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
  201.             {
  202.                 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
  203.             }
  204.             p_sys->i_state = STATE_HEADER;
  205.         case STATE_HEADER:
  206.             /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
  207.             if( block_PeekBytes( &p_sys->bytestream, p_header,
  208.                                  DTS_HEADER_SIZE ) != VLC_SUCCESS )
  209.             {
  210.                 /* Need more data */
  211.                 return NULL;
  212.             }
  213.             /* Check if frame is valid and get frame info */
  214.             p_sys->i_frame_size = SyncInfo( p_header,
  215.                                             &p_sys->b_dts_hd,
  216.                                             &p_sys->i_channels,
  217.                                             &p_sys->i_channels_conf,
  218.                                             &p_sys->i_rate,
  219.                                             &p_sys->i_bit_rate,
  220.                                             &p_sys->i_frame_length );
  221.             if( !p_sys->i_frame_size )
  222.             {
  223.                 msg_Dbg( p_dec, "emulated sync word" );
  224.                 block_SkipByte( &p_sys->bytestream );
  225.                 p_sys->i_state = STATE_NOSYNC;
  226.                 break;
  227.             }
  228.             p_sys->i_state = STATE_NEXT_SYNC;
  229.         case STATE_NEXT_SYNC:
  230.             /* TODO: If pp_block == NULL, flush the buffer without checking the
  231.              * next sync word */
  232.             /* Check if next expected frame contains the sync word */
  233.             if( block_PeekOffsetBytes( &p_sys->bytestream,
  234.                                        p_sys->i_frame_size, p_header, 6 )
  235.                 != VLC_SUCCESS )
  236.             {
  237.                 /* Need more data */
  238.                 return NULL;
  239.             }
  240.             if( SyncCode( p_header ) != VLC_SUCCESS )
  241.             {
  242.                 msg_Dbg( p_dec, "emulated sync word "
  243.                          "(no sync on following frame): %2.2x%2.2x%2.2x%2.2x",
  244.                          (int)p_header[0], (int)p_header[1],
  245.                          (int)p_header[2], (int)p_header[3] );
  246.                 p_sys->i_state = STATE_NOSYNC;
  247.                 block_SkipByte( &p_sys->bytestream );
  248.                 break;
  249.             }
  250.             p_sys->i_state = STATE_SEND_DATA;
  251.             break;
  252.         case STATE_GET_DATA:
  253.             /* Make sure we have enough data.
  254.              * (Not useful if we went through NEXT_SYNC) */
  255.             if( block_WaitBytes( &p_sys->bytestream,
  256.                                  p_sys->i_frame_size ) != VLC_SUCCESS )
  257.             {
  258.                 /* Need more data */
  259.                 return NULL;
  260.             }
  261.             p_sys->i_state = STATE_SEND_DATA;
  262.         case STATE_SEND_DATA:
  263.             if( p_sys->b_dts_hd  )
  264.             {
  265.                 /* Ignore DTS-HD */
  266.                 block_SkipBytes( &p_sys->bytestream, p_sys->i_frame_size );
  267.                 p_sys->i_state = STATE_NOSYNC;
  268.                 break;
  269.             }
  270.             if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
  271.             {
  272.                 //p_dec->b_error = true;
  273.                 return NULL;
  274.             }
  275.             /* Copy the whole frame into the buffer. When we reach this point
  276.              * we already know we have enough data available. */
  277.             block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
  278.             /* Make sure we don't reuse the same pts twice */
  279.             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
  280.                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
  281.             p_sys->i_state = STATE_NOSYNC;
  282.             /* So p_block doesn't get re-added several times */
  283.             *pp_block = block_BytestreamPop( &p_sys->bytestream );
  284.             return p_out_buffer;
  285.         }
  286.     }
  287.     return NULL;
  288. }
  289. /*****************************************************************************
  290.  * CloseCommon: clean up the decoder
  291.  *****************************************************************************/
  292. static void CloseCommon( vlc_object_t *p_this )
  293. {
  294.     decoder_t *p_dec = (decoder_t*)p_this;
  295.     decoder_sys_t *p_sys = p_dec->p_sys;
  296.     block_BytestreamRelease( &p_sys->bytestream );
  297.     free( p_sys );
  298. }
  299. /*****************************************************************************
  300.  * GetOutBuffer:
  301.  *****************************************************************************/
  302. static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
  303. {
  304.     decoder_sys_t *p_sys = p_dec->p_sys;
  305.     uint8_t *p_buf;
  306.     if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
  307.     {
  308.         msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
  309.                   p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
  310.         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
  311.         aout_DateSet( &p_sys->end_date, p_sys->i_pts );
  312.     }
  313.     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
  314.     p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
  315.     /* Hack for DTS S/PDIF filter which needs to pad the DTS frames */
  316.     p_dec->fmt_out.audio.i_bytes_per_frame =
  317.         __MAX( p_sys->i_frame_size, p_sys->i_frame_length * 4 );
  318.     p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
  319.     p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
  320.     p_dec->fmt_out.audio.i_physical_channels =
  321.         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
  322.     p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
  323.     if( p_sys->b_packetizer )
  324.     {
  325.         block_t *p_sout_buffer = GetSoutBuffer( p_dec );
  326.         p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
  327.         *pp_out_buffer = p_sout_buffer;
  328.     }
  329.     else
  330.     {
  331.         aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
  332.         p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
  333.         *pp_out_buffer = p_aout_buffer;
  334.     }
  335.     return p_buf;
  336. }
  337. /*****************************************************************************
  338.  * GetAoutBuffer:
  339.  *****************************************************************************/
  340. static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
  341. {
  342.     decoder_sys_t *p_sys = p_dec->p_sys;
  343.     aout_buffer_t *p_buf;
  344.     /* Hack for DTS S/PDIF filter which needs to send 3 frames at a time
  345.      * (plus a few header bytes) */
  346.     p_buf = decoder_NewAudioBuffer( p_dec, p_sys->i_frame_length * 4 );
  347.     if( p_buf == NULL ) return NULL;
  348.     p_buf->i_nb_samples = p_sys->i_frame_length;
  349.     p_buf->i_nb_bytes = p_sys->i_frame_size;
  350.     p_buf->start_date = aout_DateGet( &p_sys->end_date );
  351.     p_buf->end_date =
  352.         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length );
  353.     return p_buf;
  354. }
  355. /*****************************************************************************
  356.  * GetSoutBuffer:
  357.  *****************************************************************************/
  358. static block_t *GetSoutBuffer( decoder_t *p_dec )
  359. {
  360.     decoder_sys_t *p_sys = p_dec->p_sys;
  361.     block_t *p_block;
  362.     p_block = block_New( p_dec, p_sys->i_frame_size );
  363.     if( p_block == NULL ) return NULL;
  364.     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
  365.     p_block->i_length = aout_DateIncrement( &p_sys->end_date,
  366.         p_sys->i_frame_length ) - p_block->i_pts;
  367.     return p_block;
  368. }
  369. /*****************************************************************************
  370.  * SyncInfo: parse DTS sync info
  371.  *****************************************************************************/
  372. static const unsigned int ppi_dts_samplerate[] =
  373. {
  374.     0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
  375.     12000, 24000, 48000, 96000, 192000
  376. };
  377. static const unsigned int ppi_dts_bitrate[] =
  378. {
  379.     32000, 56000, 64000, 96000, 112000, 128000,
  380.     192000, 224000, 256000, 320000, 384000,
  381.     448000, 512000, 576000, 640000, 768000,
  382.     896000, 1024000, 1152000, 1280000, 1344000,
  383.     1408000, 1411200, 1472000, 1536000, 1920000,
  384.     2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
  385. };
  386. static int SyncInfo16be( const uint8_t *p_buf,
  387.                          unsigned int *pi_audio_mode,
  388.                          unsigned int *pi_sample_rate,
  389.                          unsigned int *pi_bit_rate,
  390.                          unsigned int *pi_frame_length )
  391. {
  392.     unsigned int i_frame_size;
  393.     unsigned int i_lfe;
  394.     *pi_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
  395.     i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
  396.                    (p_buf[7] >> 4);
  397.     *pi_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
  398.     *pi_sample_rate = (p_buf[8] >> 2) & 0x0f;
  399.     *pi_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
  400.     i_lfe = (p_buf[10] >> 1) & 0x03;
  401.     if( i_lfe ) *pi_audio_mode |= 0x10000;
  402.     return i_frame_size + 1;
  403. }
  404. static void BufLeToBe( uint8_t *p_out, const uint8_t *p_in, int i_in )
  405. {
  406.     int i;
  407.     for( i = 0; i < i_in/2; i++  )
  408.     {
  409.         p_out[i*2] = p_in[i*2+1];
  410.         p_out[i*2+1] = p_in[i*2];
  411.     }
  412. }
  413. static int Buf14To16( uint8_t *p_out, const uint8_t *p_in, int i_in, int i_le )
  414. {
  415.     unsigned char tmp, cur = 0;
  416.     int bits_in, bits_out = 0;
  417.     int i, i_out = 0;
  418.     for( i = 0; i < i_in; i++  )
  419.     {
  420.         if( i%2 )
  421.         {
  422.             tmp = p_in[i-i_le];
  423.             bits_in = 8;
  424.         }
  425.         else
  426.         {
  427.             tmp = p_in[i+i_le] & 0x3F;
  428.             bits_in = 8 - 2;
  429.         }
  430.         if( bits_out < 8 )
  431.         {
  432.             int need = __MIN( 8 - bits_out, bits_in );
  433.             cur <<= need;
  434.             cur |= ( tmp >> (bits_in - need) );
  435.             tmp <<= (8 - bits_in + need);
  436.             tmp >>= (8 - bits_in + need);
  437.             bits_in -= need;
  438.             bits_out += need;
  439.         }
  440.         if( bits_out == 8 )
  441.         {
  442.             p_out[i_out] = cur;
  443.             cur = 0;
  444.             bits_out = 0;
  445.             i_out++;
  446.         }
  447.         bits_out += bits_in;
  448.         cur <<= bits_in;
  449.         cur |= tmp;
  450.     }
  451.     return i_out;
  452. }
  453. static inline int SyncCode( const uint8_t *p_buf )
  454. {
  455.     /* 14 bits, little endian version of the bitstream */
  456.     if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
  457.         p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
  458.         (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
  459.     {
  460.         return VLC_SUCCESS;
  461.     }
  462.     /* 14 bits, big endian version of the bitstream */
  463.     else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
  464.              p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
  465.              p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
  466.     {
  467.         return VLC_SUCCESS;
  468.     }
  469.     /* 16 bits, big endian version of the bitstream */
  470.     else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
  471.              p_buf[2] == 0x80 && p_buf[3] == 0x01 )
  472.     {
  473.         return VLC_SUCCESS;
  474.     }
  475.     /* 16 bits, little endian version of the bitstream */
  476.     else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
  477.              p_buf[2] == 0x01 && p_buf[3] == 0x80 )
  478.     {
  479.         return VLC_SUCCESS;
  480.     }
  481.     /* DTS-HD */
  482.     else if( p_buf[0] == 0x64 && p_buf[1] ==  0x58 &&
  483.              p_buf[2] == 0x20 && p_buf[3] ==  0x25 )
  484.     {
  485.         return VLC_SUCCESS;
  486.     }
  487.     return VLC_EGENERIC;
  488. }
  489. static int SyncInfo( const uint8_t *p_buf,
  490.                      bool *pb_dts_hd,
  491.                      unsigned int *pi_channels,
  492.                      unsigned int *pi_channels_conf,
  493.                      unsigned int *pi_sample_rate,
  494.                      unsigned int *pi_bit_rate,
  495.                      unsigned int *pi_frame_length )
  496. {
  497.     unsigned int i_audio_mode;
  498.     unsigned int i_frame_size;
  499.     /* 14 bits, little endian version of the bitstream */
  500.     if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
  501.         p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
  502.         (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
  503.     {
  504.         uint8_t conv_buf[DTS_HEADER_SIZE];
  505.         Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 1 );
  506.         i_frame_size = SyncInfo16be( conv_buf, &i_audio_mode, pi_sample_rate,
  507.                                      pi_bit_rate, pi_frame_length );
  508.         i_frame_size = i_frame_size * 8 / 14 * 2;
  509.     }
  510.     /* 14 bits, big endian version of the bitstream */
  511.     else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
  512.              p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
  513.              p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
  514.     {
  515.         uint8_t conv_buf[DTS_HEADER_SIZE];
  516.         Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 0 );
  517.         i_frame_size = SyncInfo16be( conv_buf, &i_audio_mode, pi_sample_rate,
  518.                                      pi_bit_rate, pi_frame_length );
  519.         i_frame_size = i_frame_size * 8 / 14 * 2;
  520.     }
  521.     /* 16 bits, big endian version of the bitstream */
  522.     else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
  523.              p_buf[2] == 0x80 && p_buf[3] == 0x01 )
  524.     {
  525.         i_frame_size = SyncInfo16be( p_buf, &i_audio_mode, pi_sample_rate,
  526.                                      pi_bit_rate, pi_frame_length );
  527.     }
  528.     /* 16 bits, little endian version of the bitstream */
  529.     else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
  530.              p_buf[2] == 0x01 && p_buf[3] == 0x80 )
  531.     {
  532.         uint8_t conv_buf[DTS_HEADER_SIZE];
  533.         BufLeToBe( conv_buf, p_buf, DTS_HEADER_SIZE );
  534.         i_frame_size = SyncInfo16be( p_buf, &i_audio_mode, pi_sample_rate,
  535.                                      pi_bit_rate, pi_frame_length );
  536.     }
  537.     /* DTS-HD */
  538.     else if( p_buf[0] == 0x64 && p_buf[1] ==  0x58 &&
  539.              p_buf[2] == 0x20 && p_buf[3] ==  0x25 )
  540.     {
  541.         int i_dts_hd_size;
  542.         bs_t s;
  543.         bs_init( &s, &p_buf[4], DTS_HEADER_SIZE - 4 );
  544.         bs_skip( &s, 8 + 2 );
  545.         if( bs_read1( &s ) )
  546.         {
  547.             bs_skip( &s, 12 );
  548.             i_dts_hd_size = bs_read( &s, 20 ) + 1;
  549.         }
  550.         else
  551.         {
  552.             bs_skip( &s, 8 );
  553.             i_dts_hd_size = bs_read( &s, 16 ) + 1;
  554.         }
  555.         //uint16_t s0 = bs_read( &s, 16 );
  556.         //uint16_t s1 = bs_read( &s, 16 );
  557.         //fprintf( stderr, "DTS HD=%d : %x %xn", i_dts_hd_size, s0, s1 );
  558.         *pb_dts_hd = true;
  559.         /* As we ignore the stream, do not modify those variables:
  560.         *pi_channels = ;
  561.         *pi_channels_conf = ;
  562.         *pi_sample_rate = ;
  563.         *pi_bit_rate = ;
  564.         *pi_frame_length = ;
  565.         */
  566.         return i_dts_hd_size;
  567.     }
  568.     *pb_dts_hd = false;
  569.     switch( i_audio_mode & 0xFFFF )
  570.     {
  571.         case 0x0:
  572.             /* Mono */
  573.             *pi_channels_conf = AOUT_CHAN_CENTER;
  574.             break;
  575.         case 0x1:
  576.             /* Dual-mono = stereo + dual-mono */
  577.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  578.                            AOUT_CHAN_DUALMONO;
  579.             break;
  580.         case 0x2:
  581.         case 0x3:
  582.         case 0x4:
  583.             /* Stereo */
  584.             *pi_channels = 2;
  585.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
  586.             break;
  587.         case 0x5:
  588.             /* 3F */
  589.             *pi_channels = 3;
  590.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  591.                                 AOUT_CHAN_CENTER;
  592.             break;
  593.         case 0x6:
  594.             /* 2F/1R */
  595.             *pi_channels = 3;
  596.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  597.                                 AOUT_CHAN_REARCENTER;
  598.             break;
  599.         case 0x7:
  600.             /* 3F/1R */
  601.             *pi_channels = 4;
  602.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  603.                                 AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER;
  604.             break;
  605.         case 0x8:
  606.             /* 2F2R */
  607.             *pi_channels = 4;
  608.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  609.                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
  610.             break;
  611.         case 0x9:
  612.             /* 3F2R */
  613.             *pi_channels = 5;
  614.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  615.                                 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
  616.                                 AOUT_CHAN_REARRIGHT;
  617.             break;
  618.         case 0xA:
  619.         case 0xB:
  620.             /* 2F2M2R */
  621.             *pi_channels = 6;
  622.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  623.                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
  624.                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
  625.             break;
  626.         case 0xC:
  627.             /* 3F2M2R */
  628.             *pi_channels = 7;
  629.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  630.                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
  631.                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
  632.                                 AOUT_CHAN_REARRIGHT;
  633.             break;
  634.         case 0xD:
  635.         case 0xE:
  636.             /* 3F2M2R/LFE */
  637.             *pi_channels = 8;
  638.             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
  639.                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
  640.                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
  641.                                 AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
  642.             break;
  643.         default:
  644.             if( i_audio_mode <= 63 )
  645.             {
  646.                 /* User defined */
  647.                 *pi_channels = 0;
  648.                 *pi_channels_conf = 0;
  649.             }
  650.             else return 0;
  651.             break;
  652.     }
  653.     if( i_audio_mode & 0x10000 )
  654.     {
  655.         (*pi_channels)++;
  656.         *pi_channels_conf |= AOUT_CHAN_LFE;
  657.     }
  658.     if( *pi_sample_rate >= sizeof( ppi_dts_samplerate ) /
  659.                            sizeof( ppi_dts_samplerate[0] ) )
  660.     {
  661.         return 0;
  662.     }
  663.     *pi_sample_rate = ppi_dts_samplerate[ *pi_sample_rate ];
  664.     if( !*pi_sample_rate ) return 0;
  665.     if( *pi_bit_rate >= sizeof( ppi_dts_bitrate ) /
  666.                         sizeof( ppi_dts_bitrate[0] ) )
  667.     {
  668.         return 0;
  669.     }
  670.     *pi_bit_rate = ppi_dts_bitrate[ *pi_bit_rate ];
  671.     if( !*pi_bit_rate ) return 0;
  672.     *pi_frame_length = (*pi_frame_length + 1) * 32;
  673.     return i_frame_size;
  674. }