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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * dts.c : raw DTS stream input module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2001 VideoLAN
  5.  * $Id: dts.c 7231 2004-04-01 23:19:30Z fenrir $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <vlc/vlc.h>
  27. #include <vlc/input.h>
  28. #include <vlc_codec.h>
  29. /*****************************************************************************
  30.  * Module descriptor
  31.  *****************************************************************************/
  32. static int  Open  ( vlc_object_t * );
  33. static void Close ( vlc_object_t * );
  34. vlc_module_begin();
  35.     set_description( _("Raw DTS demuxer") );
  36.     set_capability( "demux2", 155 );
  37.     set_callbacks( Open, Close );
  38.     add_shortcut( "dts" );
  39. vlc_module_end();
  40. /*****************************************************************************
  41.  * Local prototypes
  42.  *****************************************************************************/
  43. static int Demux  ( demux_t * );
  44. static int Control( demux_t *, int, va_list );
  45. struct demux_sys_t
  46. {
  47.     vlc_bool_t  b_start;
  48.     es_out_id_t *p_es;
  49.     /* Packetizer */
  50.     decoder_t *p_packetizer;
  51.     int i_mux_rate;
  52. };
  53. static int CheckSync( uint8_t *p_peek );
  54. #define DTS_PACKET_SIZE 16384
  55. #define DTS_PROBE_SIZE (DTS_PACKET_SIZE * 4)
  56. #define DTS_MAX_HEADER_SIZE 11
  57. /*****************************************************************************
  58.  * Open: initializes ES structures
  59.  *****************************************************************************/
  60. static int Open( vlc_object_t * p_this )
  61. {
  62.     demux_t     *p_demux = (demux_t*)p_this;
  63.     demux_sys_t *p_sys;
  64.     byte_t *     p_peek;
  65.     int          i_peek = 0;
  66.     /* Check if we are dealing with a WAV file */
  67.     if( stream_Peek( p_demux->s, &p_peek, 20 ) == 20 &&
  68.         !strncmp( p_peek, "RIFF", 4 ) && !strncmp( &p_peek[8], "WAVE", 4 ) )
  69.     {
  70.         int i_size;
  71.         /* Find the wave format header */
  72.         i_peek = 20;
  73.         while( strncmp( p_peek + i_peek - 8, "fmt ", 4 ) )
  74.         {
  75.             i_size = GetDWLE( p_peek + i_peek - 4 );
  76.             if( i_size + i_peek > DTS_PROBE_SIZE ) return VLC_EGENERIC;
  77.             i_peek += i_size + 8;
  78.             if( stream_Peek( p_demux->s, &p_peek, i_peek ) != i_peek )
  79.                 return VLC_EGENERIC;
  80.         }
  81.         /* Sanity check the wave format header */
  82.         i_size = GetDWLE( p_peek + i_peek - 4 );
  83.         if( i_size + i_peek > DTS_PROBE_SIZE ) return VLC_EGENERIC;
  84.         i_peek += i_size + 8;
  85.         if( stream_Peek( p_demux->s, &p_peek, i_peek ) != i_peek )
  86.             return VLC_EGENERIC;
  87.         if( GetWLE( p_peek + i_peek - i_size - 8 /* wFormatTag */ ) !=
  88.             1 /* WAVE_FORMAT_PCM */ )
  89.             return VLC_EGENERIC;
  90.         if( GetWLE( p_peek + i_peek - i_size - 6 /* nChannels */ ) != 2 )
  91.             return VLC_EGENERIC;
  92.         if( GetDWLE( p_peek + i_peek - i_size - 4 /* nSamplesPerSec */ ) !=
  93.             44100 )
  94.             return VLC_EGENERIC;
  95.         /* Skip the wave header */
  96.         while( strncmp( p_peek + i_peek - 8, "data", 4 ) )
  97.         {
  98.             i_size = GetDWLE( p_peek + i_peek - 4 );
  99.             if( i_size + i_peek > DTS_PROBE_SIZE ) return VLC_EGENERIC;
  100.             i_peek += i_size + 8;
  101.             if( stream_Peek( p_demux->s, &p_peek, i_peek ) != i_peek )
  102.                 return VLC_EGENERIC;
  103.         }
  104.         /* Some DTS wav files don't begin with a sync code so we do a more
  105.          * extensive search */
  106.         i_size = stream_Peek( p_demux->s, &p_peek, DTS_PROBE_SIZE );
  107.         i_size -= DTS_MAX_HEADER_SIZE;
  108.         while( i_peek < i_size )
  109.         {
  110.             if( CheckSync( p_peek + i_peek ) != VLC_SUCCESS )
  111.                 /* The data is stored in 16 bits words */
  112.                 i_peek += 2;
  113.             else
  114.                 break;
  115.         }
  116.     }
  117.     /* Have a peep at the show. */
  118.     if( stream_Peek( p_demux->s, &p_peek, i_peek + DTS_MAX_HEADER_SIZE * 2 ) <
  119.         i_peek + DTS_MAX_HEADER_SIZE * 2 )
  120.     {
  121.         /* Stream too short */
  122.         msg_Warn( p_demux, "cannot peek()" );
  123.         return VLC_EGENERIC;
  124.     }
  125.     if( CheckSync( p_peek + i_peek ) != VLC_SUCCESS )
  126.     {
  127.         if( strncmp( p_demux->psz_demux, "dts", 3 ) )
  128.         {
  129.             return VLC_EGENERIC;
  130.         }
  131.         /* User forced */
  132.         msg_Err( p_demux, "this doesn't look like a DTS audio stream, "
  133.                  "continuing anyway" );
  134.     }
  135.     p_demux->pf_demux = Demux;
  136.     p_demux->pf_control = Control;
  137.     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
  138.     p_sys->b_start = VLC_TRUE;
  139.     p_sys->i_mux_rate = 0;
  140.     /*
  141.      * Load the DTS packetizer
  142.      */
  143.     p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_DECODER );
  144.     p_sys->p_packetizer->pf_decode_audio = 0;
  145.     p_sys->p_packetizer->pf_decode_video = 0;
  146.     p_sys->p_packetizer->pf_decode_sub = 0;
  147.     p_sys->p_packetizer->pf_packetize = 0;
  148.     /* Initialization of decoder structure */
  149.     es_format_Init( &p_sys->p_packetizer->fmt_in, AUDIO_ES,
  150.                     VLC_FOURCC( 'd', 't', 's', ' ' ) );
  151.     p_sys->p_packetizer->p_module =
  152.         module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );
  153.     if( !p_sys->p_packetizer->p_module )
  154.     {
  155.         msg_Err( p_demux, "cannot find DTS packetizer" );
  156.         return VLC_EGENERIC;
  157.     }
  158.     p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_in );
  159.     return VLC_SUCCESS;
  160. }
  161. /*****************************************************************************
  162.  * Close: frees unused data
  163.  *****************************************************************************/
  164. static void Close( vlc_object_t *p_this )
  165. {
  166.     demux_t     *p_demux = (demux_t*)p_this;
  167.     demux_sys_t *p_sys = p_demux->p_sys;
  168.     /* Unneed module */
  169.     module_Unneed( p_sys->p_packetizer, p_sys->p_packetizer->p_module );
  170.     /* Delete the decoder */
  171.     vlc_object_destroy( p_sys->p_packetizer );
  172.     free( p_sys );
  173. }
  174. /*****************************************************************************
  175.  * Demux: reads and demuxes data packets
  176.  *****************************************************************************
  177.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  178.  *****************************************************************************/
  179. static int Demux( demux_t *p_demux )
  180. {
  181.     demux_sys_t *p_sys = p_demux->p_sys;
  182.     block_t *p_block_in, *p_block_out;
  183.     if( !( p_block_in = stream_Block( p_demux->s, DTS_PACKET_SIZE ) ) )
  184.     {
  185.         return 0;
  186.     }
  187.     if( p_sys->b_start )
  188.         p_block_in->i_pts = p_block_in->i_dts = 1;
  189.     else
  190.         p_block_in->i_pts = p_block_in->i_dts = 0;
  191.     while( (p_block_out = p_sys->p_packetizer->pf_packetize(
  192.                 p_sys->p_packetizer, &p_block_in )) )
  193.     {
  194.         p_sys->b_start = VLC_FALSE;
  195.         while( p_block_out )
  196.         {
  197.             block_t *p_next = p_block_out->p_next;
  198.             /* We assume a constant bitrate */
  199.             if( p_block_out->i_length )
  200.             {
  201.                 p_sys->i_mux_rate =
  202.                     p_block_out->i_buffer * I64C(1000000) / p_block_out->i_length;
  203.             }
  204.             /* set PCR */
  205.             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
  206.             es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
  207.             p_block_out = p_next;
  208.         }
  209.     }
  210.     return 1;
  211. }
  212. /*****************************************************************************
  213.  * Control:
  214.  *****************************************************************************/
  215. static int Control( demux_t *p_demux, int i_query, va_list args )
  216. {
  217.     demux_sys_t *p_sys  = p_demux->p_sys;
  218.     if( i_query == DEMUX_SET_TIME )
  219.         return VLC_EGENERIC;
  220.     else
  221.         return demux2_vaControlHelper( p_demux->s,
  222.                                        0, -1,
  223.                                        8*p_sys->i_mux_rate, 1, i_query, args );
  224. }
  225. /*****************************************************************************
  226.  * CheckSync: Check if buffer starts with a DTS sync code
  227.  *****************************************************************************/
  228. static int CheckSync( uint8_t *p_peek )
  229. {
  230.     /* 14 bits, little endian version of the bitstream */
  231.     if( p_peek[0] == 0xff && p_peek[1] == 0x1f &&
  232.         p_peek[2] == 0x00 && p_peek[3] == 0xe8 &&
  233.         (p_peek[4] & 0xf0) == 0xf0 && p_peek[5] == 0x07 )
  234.     {
  235.         return VLC_SUCCESS;
  236.     }
  237.     /* 14 bits, big endian version of the bitstream */
  238.     else if( p_peek[0] == 0x1f && p_peek[1] == 0xff &&
  239.              p_peek[2] == 0xe8 && p_peek[3] == 0x00 &&
  240.              p_peek[4] == 0x07 && (p_peek[5] & 0xf0) == 0xf0)
  241.     {
  242.         return VLC_SUCCESS;
  243.     }
  244.     /* 16 bits, big endian version of the bitstream */
  245.     else if( p_peek[0] == 0x7f && p_peek[1] == 0xfe &&
  246.              p_peek[2] == 0x80 && p_peek[3] == 0x01 )
  247.     {
  248.         return VLC_SUCCESS;
  249.     }
  250.     /* 16 bits, little endian version of the bitstream */
  251.     else if( p_peek[0] == 0xfe && p_peek[1] == 0x7f &&
  252.              p_peek[2] == 0x01 && p_peek[3] == 0x80 )
  253.     {
  254.         return VLC_SUCCESS;
  255.     }
  256.     return VLC_EGENERIC;
  257. }