dts.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:23k
源码类别:

多媒体

开发平台:

MultiPlatform

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