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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * a52.c: parse A/52 audio sync info and packetize the stream
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2002 VideoLAN
  5.  * $Id: a52.c 8435 2004-08-15 16:09:03Z gbazin $
  6.  *
  7.  * Authors: St閜hane Borel <stef@via.ecp.fr>
  8.  *          Christophe Massiot <massiot@via.ecp.fr>
  9.  *          Gildas Bazin <gbazin@videolan.org>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  24.  *****************************************************************************/
  25. /*****************************************************************************
  26.  * Preamble
  27.  *****************************************************************************/
  28. #include <vlc/vlc.h>
  29. #include <vlc/decoder.h>
  30. #include "vlc_block_helper.h"
  31. #define A52_HEADER_SIZE 7
  32. /*****************************************************************************
  33.  * decoder_sys_t : decoder descriptor
  34.  *****************************************************************************/
  35. struct decoder_sys_t
  36. {
  37.     /* Module mode */
  38.     vlc_bool_t b_packetizer;
  39.     /*
  40.      * Input properties
  41.      */
  42.     int i_state;
  43.     block_bytestream_t bytestream;
  44.     /*
  45.      * Common properties
  46.      */
  47.     audio_date_t   end_date;
  48.     mtime_t i_pts;
  49.     int i_frame_size, i_bit_rate;
  50.     unsigned int i_rate, i_channels, i_channels_conf;
  51. };
  52. enum {
  53.     STATE_NOSYNC,
  54.     STATE_SYNC,
  55.     STATE_HEADER,
  56.     STATE_NEXT_SYNC,
  57.     STATE_GET_DATA,
  58.     STATE_SEND_DATA
  59. };
  60. /****************************************************************************
  61.  * Local prototypes
  62.  ****************************************************************************/
  63. static int  OpenDecoder   ( vlc_object_t * );
  64. static int  OpenPacketizer( vlc_object_t * );
  65. static void CloseDecoder  ( vlc_object_t * );
  66. static void *DecodeBlock  ( decoder_t *, block_t ** );
  67. static int  SyncInfo      ( const byte_t *, int *, int *, int *,int * );
  68. static uint8_t       *GetOutBuffer ( decoder_t *, void ** );
  69. static aout_buffer_t *GetAoutBuffer( decoder_t * );
  70. static block_t       *GetSoutBuffer( decoder_t * );
  71. /*****************************************************************************
  72.  * Module descriptor
  73.  *****************************************************************************/
  74. vlc_module_begin();
  75.     set_description( _("A/52 parser") );
  76.     set_capability( "decoder", 100 );
  77.     set_callbacks( OpenDecoder, CloseDecoder );
  78.     add_submodule();
  79.     set_description( _("A/52 audio packetizer") );
  80.     set_capability( "packetizer", 10 );
  81.     set_callbacks( OpenPacketizer, CloseDecoder );
  82. vlc_module_end();
  83. /*****************************************************************************
  84.  * OpenDecoder: probe the decoder and return score
  85.  *****************************************************************************/
  86. static int OpenDecoder( vlc_object_t *p_this )
  87. {
  88.     decoder_t *p_dec = (decoder_t*)p_this;
  89.     decoder_sys_t *p_sys;
  90.     if( p_dec->fmt_in.i_codec != VLC_FOURCC('a','5','2',' ')
  91.           && p_dec->fmt_in.i_codec != VLC_FOURCC('a','5','2','b') )
  92.     {
  93.         return VLC_EGENERIC;
  94.     }
  95.     /* Allocate the memory needed to store the decoder's structure */
  96.     if( ( p_dec->p_sys = p_sys =
  97.           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
  98.     {
  99.         msg_Err( p_dec, "out of memory" );
  100.         return VLC_EGENERIC;
  101.     }
  102.     /* Misc init */
  103.     p_sys->b_packetizer = VLC_FALSE;
  104.     p_sys->i_state = STATE_NOSYNC;
  105.     aout_DateSet( &p_sys->end_date, 0 );
  106.     p_sys->bytestream = block_BytestreamInit( p_dec );
  107.     /* Set output properties */
  108.     p_dec->fmt_out.i_cat = AUDIO_ES;
  109.     p_dec->fmt_out.i_codec = VLC_FOURCC('a','5','2',' ');
  110.     p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
  111.     /* Set callback */
  112.     p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
  113.         DecodeBlock;
  114.     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
  115.         DecodeBlock;
  116.     return VLC_SUCCESS;
  117. }
  118. static int OpenPacketizer( vlc_object_t *p_this )
  119. {
  120.     decoder_t *p_dec = (decoder_t*)p_this;
  121.     int i_ret = OpenDecoder( p_this );
  122.     if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
  123.     return i_ret;
  124. }
  125. /****************************************************************************
  126.  * DecodeBlock: the whole thing
  127.  ****************************************************************************
  128.  * This function is called just after the thread is launched.
  129.  ****************************************************************************/
  130. static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
  131. {
  132.     decoder_sys_t *p_sys = p_dec->p_sys;
  133.     uint8_t p_header[A52_HEADER_SIZE];
  134.     uint8_t *p_buf;
  135.     void *p_out_buffer;
  136.     if( !pp_block || !*pp_block ) return NULL;
  137.     if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
  138.     {
  139.         /* We've just started the stream, wait for the first PTS. */
  140.         block_Release( *pp_block );
  141.         return NULL;
  142.     }
  143.     if( (*pp_block)->i_flags&BLOCK_FLAG_DISCONTINUITY )
  144.     {
  145.         p_sys->i_state = STATE_NOSYNC;
  146.     }
  147.     block_BytestreamPush( &p_sys->bytestream, *pp_block );
  148.     while( 1 )
  149.     {
  150.         switch( p_sys->i_state )
  151.         {
  152.         case STATE_NOSYNC:
  153.             while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
  154.                    == VLC_SUCCESS )
  155.             {
  156.                 if( p_header[0] == 0x0b && p_header[1] == 0x77 )
  157.                 {
  158.                     p_sys->i_state = STATE_SYNC;
  159.                     break;
  160.                 }
  161.                 block_SkipByte( &p_sys->bytestream );
  162.             }
  163.             if( p_sys->i_state != STATE_SYNC )
  164.             {
  165.                 block_BytestreamFlush( &p_sys->bytestream );
  166.                 /* Need more data */
  167.                 return NULL;
  168.             }
  169.         case STATE_SYNC:
  170.             /* New frame, set the Presentation Time Stamp */
  171.             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
  172.             if( p_sys->i_pts != 0 &&
  173.                 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
  174.             {
  175.                 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
  176.             }
  177.             p_sys->i_state = STATE_HEADER;
  178.         case STATE_HEADER:
  179.             /* Get A/52 frame header (A52_HEADER_SIZE bytes) */
  180.             if( block_PeekBytes( &p_sys->bytestream, p_header,
  181.                                  A52_HEADER_SIZE ) != VLC_SUCCESS )
  182.             {
  183.                 /* Need more data */
  184.                 return NULL;
  185.             }
  186.             /* Check if frame is valid and get frame info */
  187.             p_sys->i_frame_size = SyncInfo( p_header,
  188.                                             &p_sys->i_channels,
  189.                                             &p_sys->i_channels_conf,
  190.                                             &p_sys->i_rate,
  191.                                             &p_sys->i_bit_rate );
  192.             if( !p_sys->i_frame_size )
  193.             {
  194.                 msg_Dbg( p_dec, "emulated sync word" );
  195.                 block_SkipByte( &p_sys->bytestream );
  196.                 p_sys->i_state = STATE_NOSYNC;
  197.                 break;
  198.             }
  199.             p_sys->i_state = STATE_NEXT_SYNC;
  200.         case STATE_NEXT_SYNC:
  201.             /* TODO: If pp_block == NULL, flush the buffer without checking the
  202.              * next sync word */
  203.             /* Check if next expected frame contains the sync word */
  204.             if( block_PeekOffsetBytes( &p_sys->bytestream,
  205.                                        p_sys->i_frame_size, p_header, 2 )
  206.                 != VLC_SUCCESS )
  207.             {
  208.                 /* Need more data */
  209.                 return NULL;
  210.             }
  211.             if( p_sys->b_packetizer &&
  212.                 p_header[0] == 0 && p_header[1] == 0 )
  213.             {
  214.                 /* A52 wav files and audio CD's use stuffing */
  215.                 p_sys->i_state = STATE_GET_DATA;
  216.                 break;
  217.             }
  218.             if( p_header[0] != 0x0b || p_header[1] != 0x77 )
  219.             {
  220.                 msg_Dbg( p_dec, "emulated sync word "
  221.                          "(no sync on following frame)" );
  222.                 p_sys->i_state = STATE_NOSYNC;
  223.                 block_SkipByte( &p_sys->bytestream );
  224.                 break;
  225.             }
  226.             p_sys->i_state = STATE_SEND_DATA;
  227.             break;
  228.         case STATE_GET_DATA:
  229.             /* Make sure we have enough data.
  230.              * (Not useful if we went through NEXT_SYNC) */
  231.             if( block_WaitBytes( &p_sys->bytestream,
  232.                                  p_sys->i_frame_size ) != VLC_SUCCESS )
  233.             {
  234.                 /* Need more data */
  235.                 return NULL;
  236.             }
  237.             p_sys->i_state = STATE_SEND_DATA;
  238.         case STATE_SEND_DATA:
  239.             if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
  240.             {
  241.                 //p_dec->b_error = VLC_TRUE;
  242.                 return NULL;
  243.             }
  244.             /* Copy the whole frame into the buffer. When we reach this point
  245.              * we already know we have enough data available. */
  246.             block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
  247.             /* Make sure we don't reuse the same pts twice */
  248.             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
  249.                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
  250.             /* So p_block doesn't get re-added several times */
  251.             *pp_block = block_BytestreamPop( &p_sys->bytestream );
  252.             p_sys->i_state = STATE_NOSYNC;
  253.             return p_out_buffer;
  254.         }
  255.     }
  256.     return NULL;
  257. }
  258. /*****************************************************************************
  259.  * CloseDecoder: clean up the decoder
  260.  *****************************************************************************/
  261. static void CloseDecoder( vlc_object_t *p_this )
  262. {
  263.     decoder_t *p_dec = (decoder_t*)p_this;
  264.     decoder_sys_t *p_sys = p_dec->p_sys;
  265.     block_BytestreamRelease( &p_sys->bytestream );
  266.     free( p_sys );
  267. }
  268. /*****************************************************************************
  269.  * GetOutBuffer:
  270.  *****************************************************************************/
  271. static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
  272. {
  273.     decoder_sys_t *p_sys = p_dec->p_sys;
  274.     uint8_t *p_buf;
  275.     if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
  276.     {
  277.         msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
  278.                   p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
  279.         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
  280.         aout_DateSet( &p_sys->end_date, p_sys->i_pts );
  281.     }
  282.     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
  283.     p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
  284.     p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
  285.     p_dec->fmt_out.audio.i_frame_length = A52_FRAME_NB;
  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.     p_buf = p_dec->pf_aout_buffer_new( p_dec, A52_FRAME_NB  );
  312.     if( p_buf == NULL ) return NULL;
  313.     p_buf->start_date = aout_DateGet( &p_sys->end_date );
  314.     p_buf->end_date = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
  315.     return p_buf;
  316. }
  317. /*****************************************************************************
  318.  * GetSoutBuffer:
  319.  *****************************************************************************/
  320. static block_t *GetSoutBuffer( decoder_t *p_dec )
  321. {
  322.     decoder_sys_t *p_sys = p_dec->p_sys;
  323.     block_t *p_block;
  324.     p_block = block_New( p_dec, p_sys->i_frame_size );
  325.     if( p_block == NULL ) return NULL;
  326.     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
  327.     p_block->i_length = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ) -
  328.         p_block->i_pts;
  329.     return p_block;
  330. }
  331. /*****************************************************************************
  332.  * SyncInfo: parse A/52 sync info
  333.  *****************************************************************************
  334.  * This code is borrowed from liba52 by Aaron Holtzman & Michel Lespinasse,
  335.  * since we don't want to oblige S/PDIF people to use liba52 just to get
  336.  * their SyncInfo...
  337.  *****************************************************************************/
  338. static int SyncInfo( const byte_t * p_buf,
  339.                      int * pi_channels, int * pi_channels_conf,
  340.                      int * pi_sample_rate, int * pi_bit_rate )
  341. {
  342.     static const uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
  343.     static const int rate[] = { 32,  40,  48,  56,  64,  80,  96, 112,
  344.                                 128, 160, 192, 224, 256, 320, 384, 448,
  345.                                 512, 576, 640 };
  346.     static const uint8_t lfeon[8] = { 0x10, 0x10, 0x04, 0x04,
  347.                                       0x04, 0x01, 0x04, 0x01 };
  348.     int frmsizecod;
  349.     int bitrate;
  350.     int half;
  351.     int acmod;
  352.     if ((p_buf[0] != 0x0b) || (p_buf[1] != 0x77))        /* syncword */
  353.         return 0;
  354.     if (p_buf[5] >= 0x60)                /* bsid >= 12 */
  355.         return 0;
  356.     half = halfrate[p_buf[5] >> 3];
  357.     /* acmod, dsurmod and lfeon */
  358.     acmod = p_buf[6] >> 5;
  359.     if ( (p_buf[6] & 0xf8) == 0x50 )
  360.     {
  361.         /* Dolby surround = stereo + Dolby */
  362.         *pi_channels = 2;
  363.         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
  364.                             | AOUT_CHAN_DOLBYSTEREO;
  365.     }
  366.     else switch ( acmod )
  367.     {
  368.     case 0x0:
  369.         /* Dual-mono = stereo + dual-mono */
  370.         *pi_channels = 2;
  371.         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
  372.                             | AOUT_CHAN_DUALMONO;
  373.         break;
  374.     case 0x1:
  375.         /* Mono */
  376.         *pi_channels = 1;
  377.         *pi_channels_conf = AOUT_CHAN_CENTER;
  378.         break;
  379.     case 0x2:
  380.         /* Stereo */
  381.         *pi_channels = 2;
  382.         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
  383.         break;
  384.     case 0x3:
  385.         /* 3F */
  386.         *pi_channels = 3;
  387.         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
  388.                             | AOUT_CHAN_CENTER;
  389.         break;
  390.     case 0x4:
  391.         /* 2F1R */
  392.         *pi_channels = 3;
  393.         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
  394.                             | AOUT_CHAN_REARCENTER;
  395.         break;
  396.     case 0x5:
  397.         /* 3F1R */
  398.         *pi_channels = 4;
  399.         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
  400.                             | AOUT_CHAN_REARCENTER;
  401.         break;
  402.     case 0x6:
  403.         /* 2F2R */
  404.         *pi_channels = 4;
  405.         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
  406.                             | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
  407.         break;
  408.     case 0x7:
  409.         /* 3F2R */
  410.         *pi_channels = 5;
  411.         *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
  412.                             | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
  413.         break;
  414.     default:
  415.         return 0;
  416.     }
  417.     if ( p_buf[6] & lfeon[acmod] )
  418.     {
  419.         (*pi_channels)++;
  420.         *pi_channels_conf |= AOUT_CHAN_LFE;
  421.     }
  422.     frmsizecod = p_buf[4] & 63;
  423.     if (frmsizecod >= 38)
  424.         return 0;
  425.     bitrate = rate [frmsizecod >> 1];
  426.     *pi_bit_rate = (bitrate * 1000) >> half;
  427.     switch (p_buf[4] & 0xc0) {
  428.     case 0:
  429.         *pi_sample_rate = 48000 >> half;
  430.         return 4 * bitrate;
  431.     case 0x40:
  432.         *pi_sample_rate = 44100 >> half;
  433.         return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
  434.     case 0x80:
  435.         *pi_sample_rate = 32000 >> half;
  436.         return 6 * bitrate;
  437.     default:
  438.         return 0;
  439.     }
  440. }