Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

mpeg_audio.c

00001 /*****************************************************************************
00002  * mpeg_audio.c: parse MPEG audio sync info and packetize the stream
00003  *****************************************************************************
00004  * Copyright (C) 2001-2003 the VideoLAN team
00005  * $Id: mpeg_audio.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Laurent Aimar <[email protected]>
00008  *          Eric Petit <[email protected]>
00009  *          Christophe Massiot <[email protected]>
00010  *          Gildas Bazin <[email protected]>
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License as published by
00014  * the Free Software Foundation; either version 2 of the License, or
00015  * (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License
00023  * along with this program; if not, write to the Free Software
00024  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00025  *****************************************************************************/
00026 
00027 /*****************************************************************************
00028  * Preamble
00029  *****************************************************************************/
00030 #include <vlc/vlc.h>
00031 #include <vlc/decoder.h>
00032 #include <vlc/aout.h>
00033 
00034 #include "vlc_block_helper.h"
00035 
00036 /*****************************************************************************
00037  * decoder_sys_t : decoder descriptor
00038  *****************************************************************************/
00039 struct decoder_sys_t
00040 {
00041     /* Module mode */
00042     vlc_bool_t b_packetizer;
00043 
00044     /*
00045      * Input properties
00046      */
00047     int        i_state;
00048 
00049     block_bytestream_t bytestream;
00050 
00051     /*
00052      * Common properties
00053      */
00054     audio_date_t          end_date;
00055     unsigned int          i_current_layer;
00056 
00057     mtime_t i_pts;
00058 
00059     int i_frame_size, i_free_frame_size;
00060     unsigned int i_channels_conf, i_channels;
00061     unsigned int i_rate, i_max_frame_size, i_frame_length;
00062     unsigned int i_layer, i_bit_rate;
00063 };
00064 
00065 enum {
00066 
00067     STATE_NOSYNC,
00068     STATE_SYNC,
00069     STATE_HEADER,
00070     STATE_NEXT_SYNC,
00071     STATE_GET_DATA,
00072     STATE_SEND_DATA
00073 };
00074 
00075 /* This isn't the place to put mad-specific stuff. However, it makes the
00076  * mad plug-in's life much easier if we put 8 extra bytes at the end of the
00077  * buffer, because that way it doesn't have to copy the aout_buffer_t to a
00078  * bigger buffer. This has no implication on other plug-ins, and we only
00079  * lose 8 bytes per frame. --Meuuh */
00080 #define MAD_BUFFER_GUARD 8
00081 #define MPGA_HEADER_SIZE 4
00082 
00083 /****************************************************************************
00084  * Local prototypes
00085  ****************************************************************************/
00086 static int  OpenDecoder   ( vlc_object_t * );
00087 static int  OpenPacketizer( vlc_object_t * );
00088 static void CloseDecoder  ( vlc_object_t * );
00089 static void *DecodeBlock  ( decoder_t *, block_t ** );
00090 
00091 static uint8_t       *GetOutBuffer ( decoder_t *, void ** );
00092 static aout_buffer_t *GetAoutBuffer( decoder_t * );
00093 static block_t       *GetSoutBuffer( decoder_t * );
00094 
00095 static int SyncInfo( uint32_t i_header, unsigned int * pi_channels,
00096                      unsigned int * pi_channels_conf,
00097                      unsigned int * pi_sample_rate, unsigned int * pi_bit_rate,
00098                      unsigned int * pi_frame_length,
00099                      unsigned int * pi_max_frame_size,
00100                      unsigned int * pi_layer );
00101 
00102 /*****************************************************************************
00103  * Module descriptor
00104  *****************************************************************************/
00105 vlc_module_begin();
00106     set_description( _("MPEG audio layer I/II/III parser") );
00107     set_category( CAT_INPUT );
00108     set_subcategory( SUBCAT_INPUT_ACODEC );
00109 #if defined(SYS_DARWIN) || defined(UNDER_CE)
00110    set_capability( "decoder", 5 );
00111 #else
00112     set_capability( "decoder", 100 );
00113 #endif
00114     set_callbacks( OpenDecoder, CloseDecoder );
00115 
00116     add_submodule();
00117     set_description( _("MPEG audio layer I/II/III packetizer") );
00118     set_capability( "packetizer", 10 );
00119     set_callbacks( OpenPacketizer, CloseDecoder );
00120 vlc_module_end();
00121 
00122 /*****************************************************************************
00123  * OpenDecoder: probe the decoder and return score
00124  *****************************************************************************/
00125 static int OpenDecoder( vlc_object_t *p_this )
00126 {
00127     decoder_t *p_dec = (decoder_t*)p_this;
00128     decoder_sys_t *p_sys;
00129 
00130     if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','a') )
00131     {
00132         return VLC_EGENERIC;
00133     }
00134 
00135     /* HACK: Don't use this codec if we don't have an mpga audio filter */
00136     if( p_dec->i_object_type == VLC_OBJECT_DECODER &&
00137         !config_FindModule( p_this, "mpgatofixed32" ) )
00138     {
00139         return VLC_EGENERIC;
00140     }
00141 
00142     /* Allocate the memory needed to store the decoder's structure */
00143     if( ( p_dec->p_sys = p_sys =
00144           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
00145     {
00146         msg_Err( p_dec, "out of memory" );
00147         return VLC_EGENERIC;
00148     }
00149 
00150     /* Misc init */
00151     p_sys->b_packetizer = VLC_FALSE;
00152     p_sys->i_state = STATE_NOSYNC;
00153     aout_DateSet( &p_sys->end_date, 0 );
00154     p_sys->bytestream = block_BytestreamInit( p_dec );
00155 
00156     /* Set output properties */
00157     p_dec->fmt_out.i_cat = AUDIO_ES;
00158     p_dec->fmt_out.i_codec = VLC_FOURCC('m','p','g','a');
00159     p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
00160 
00161     /* Set callback */
00162     p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
00163         DecodeBlock;
00164     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
00165         DecodeBlock;
00166 
00167     /* Start with the minimum size for a free bitrate frame */
00168     p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
00169 
00170     return VLC_SUCCESS;
00171 }
00172 
00173 static int OpenPacketizer( vlc_object_t *p_this )
00174 {
00175     decoder_t *p_dec = (decoder_t*)p_this;
00176 
00177     int i_ret = OpenDecoder( p_this );
00178 
00179     if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
00180 
00181     return i_ret;
00182 }
00183 
00184 /****************************************************************************
00185  * DecodeBlock: the whole thing
00186  ****************************************************************************
00187  * This function is called just after the thread is launched.
00188  ****************************************************************************/
00189 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
00190 {
00191     decoder_sys_t *p_sys = p_dec->p_sys;
00192     uint8_t p_header[MAD_BUFFER_GUARD];
00193     uint32_t i_header;
00194     uint8_t *p_buf;
00195     void *p_out_buffer;
00196 
00197     if( !pp_block || !*pp_block ) return NULL;
00198 
00199     if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
00200     {
00201         /* We've just started the stream, wait for the first PTS. */
00202         block_Release( *pp_block );
00203         return NULL;
00204     }
00205 
00206     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
00207     {
00208         p_sys->i_state = STATE_NOSYNC;
00209     }
00210 
00211     block_BytestreamPush( &p_sys->bytestream, *pp_block );
00212 
00213     while( 1 )
00214     {
00215         switch( p_sys->i_state )
00216         {
00217 
00218         case STATE_NOSYNC:
00219             while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
00220                    == VLC_SUCCESS )
00221             {
00222                 /* Look for sync word - should be 0xffe */
00223                 if( p_header[0] == 0xff && (p_header[1] & 0xe0) == 0xe0 )
00224                 {
00225                     p_sys->i_state = STATE_SYNC;
00226                     break;
00227                 }
00228                 block_SkipByte( &p_sys->bytestream );
00229             }
00230             if( p_sys->i_state != STATE_SYNC )
00231             {
00232                 block_BytestreamFlush( &p_sys->bytestream );
00233 
00234                 /* Need more data */
00235                 return NULL;
00236             }
00237 
00238         case STATE_SYNC:
00239             /* New frame, set the Presentation Time Stamp */
00240             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
00241             if( p_sys->i_pts != 0 &&
00242                 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
00243             {
00244                 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
00245             }
00246             p_sys->i_state = STATE_HEADER;
00247 
00248         case STATE_HEADER:
00249             /* Get MPGA frame header (MPGA_HEADER_SIZE bytes) */
00250             if( block_PeekBytes( &p_sys->bytestream, p_header,
00251                                  MPGA_HEADER_SIZE ) != VLC_SUCCESS )
00252             {
00253                 /* Need more data */
00254                 return NULL;
00255             }
00256 
00257             /* Build frame header */
00258             i_header = (p_header[0]<<24)|(p_header[1]<<16)|(p_header[2]<<8)
00259                        |p_header[3];
00260 
00261             /* Check if frame is valid and get frame info */
00262             p_sys->i_frame_size = SyncInfo( i_header,
00263                                             &p_sys->i_channels,
00264                                             &p_sys->i_channels_conf,
00265                                             &p_sys->i_rate,
00266                                             &p_sys->i_bit_rate,
00267                                             &p_sys->i_frame_length,
00268                                             &p_sys->i_max_frame_size,
00269                                             &p_sys->i_layer );
00270 
00271             if( p_sys->i_frame_size == -1 )
00272             {
00273                 msg_Dbg( p_dec, "emulated startcode" );
00274                 block_SkipByte( &p_sys->bytestream );
00275                 p_sys->i_state = STATE_NOSYNC;
00276                 break;
00277             }
00278 
00279             if( p_sys->i_bit_rate == 0 )
00280             {
00281                 /* Free birate, but 99% emulated startcode :( */
00282                 if( p_dec->p_sys->i_free_frame_size == MPGA_HEADER_SIZE )
00283                 {
00284                     msg_Dbg( p_dec, "free bitrate mode");
00285                 }
00286                 p_sys->i_frame_size = p_sys->i_free_frame_size;
00287             }
00288 
00289             p_sys->i_state = STATE_NEXT_SYNC;
00290 
00291         case STATE_NEXT_SYNC:
00292             /* TODO: If p_block == NULL, flush the buffer without checking the
00293              * next sync word */
00294 
00295             /* Check if next expected frame contains the sync word */
00296             if( block_PeekOffsetBytes( &p_sys->bytestream,
00297                                        p_sys->i_frame_size, p_header,
00298                                        MAD_BUFFER_GUARD ) != VLC_SUCCESS )
00299             {
00300                 /* Need more data */
00301                 return NULL;
00302             }
00303 
00304             if( p_header[0] == 0xff && (p_header[1] & 0xe0) == 0xe0 )
00305             {
00306                 /* Startcode is fine, let's try the header as an extra check */
00307                 int i_next_frame_size;
00308                 unsigned int i_next_channels, i_next_channels_conf;
00309                 unsigned int i_next_rate, i_next_bit_rate;
00310                 unsigned int i_next_frame_length, i_next_max_frame_size;
00311                 unsigned int i_next_layer;
00312 
00313                 /* Build frame header */
00314                 i_header = (p_header[0]<<24)|(p_header[1]<<16)|(p_header[2]<<8)
00315                            |p_header[3];
00316 
00317                 i_next_frame_size = SyncInfo( i_header,
00318                                               &i_next_channels,
00319                                               &i_next_channels_conf,
00320                                               &i_next_rate,
00321                                               &i_next_bit_rate,
00322                                               &i_next_frame_length,
00323                                               &i_next_max_frame_size,
00324                                               &i_next_layer );
00325 
00326                 /* Free bitrate only */
00327                 if( p_sys->i_bit_rate == 0 && i_next_frame_size == -1 )
00328                 {
00329                     if( (unsigned int)p_sys->i_frame_size >
00330                         p_sys->i_max_frame_size )
00331                     {
00332                         msg_Dbg( p_dec, "frame too big %d > %d "
00333                                  "(emulated startcode ?)", p_sys->i_frame_size,
00334                                  p_sys->i_max_frame_size );
00335                         block_SkipByte( &p_sys->bytestream );
00336                         p_sys->i_state = STATE_NOSYNC;
00337                         p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
00338                         break;
00339                     }
00340 
00341                     p_sys->i_frame_size++;
00342                     break;
00343                 }
00344 
00345                 if( i_next_frame_size == -1 )
00346                 {
00347                     msg_Dbg( p_dec, "emulated startcode on next frame" );
00348                     block_SkipByte( &p_sys->bytestream );
00349                     p_sys->i_state = STATE_NOSYNC;
00350                     break;
00351                 }
00352 
00353                 /* Check info is in sync with previous one */
00354                 if( i_next_channels_conf != p_sys->i_channels_conf ||
00355                     i_next_rate != p_sys->i_rate ||
00356                     i_next_layer != p_sys->i_layer ||
00357                     i_next_frame_length != p_sys->i_frame_length )
00358                 {
00359                     /* Free bitrate only */
00360                     if( p_sys->i_bit_rate == 0 )
00361                     {
00362                         p_sys->i_frame_size++;
00363                         break;
00364                     }
00365 
00366                     msg_Dbg( p_dec, "parameters changed unexpectedly "
00367                              "(emulated startcode ?)" );
00368                     block_SkipByte( &p_sys->bytestream );
00369                     p_sys->i_state = STATE_NOSYNC;
00370                     break;
00371                 }
00372 
00373                 /* Free bitrate only */
00374                 if( p_sys->i_bit_rate == 0 )
00375                 {
00376                     if( i_next_bit_rate != 0 )
00377                     {
00378                         p_sys->i_frame_size++;
00379                         break;
00380                     }
00381                 }
00382 
00383             }
00384             else
00385             {
00386                 /* Free bitrate only */
00387                 if( p_sys->i_bit_rate == 0 )
00388                 {
00389                     if( (unsigned int)p_sys->i_frame_size >
00390                         p_sys->i_max_frame_size )
00391                     {
00392                         msg_Dbg( p_dec, "frame too big %d > %d "
00393                                  "(emulated startcode ?)", p_sys->i_frame_size,
00394                                  p_sys->i_max_frame_size );
00395                         block_SkipByte( &p_sys->bytestream );
00396                         p_sys->i_state = STATE_NOSYNC;
00397                         p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
00398                         break;
00399                     }
00400 
00401                     p_sys->i_frame_size++;
00402                     break;
00403                 }
00404 
00405                 msg_Dbg( p_dec, "emulated startcode "
00406                          "(no startcode on following frame)" );
00407                 p_sys->i_state = STATE_NOSYNC;
00408                 block_SkipByte( &p_sys->bytestream );
00409                 break;
00410             }
00411 
00412             p_sys->i_state = STATE_SEND_DATA;
00413             break;
00414 
00415         case STATE_GET_DATA:
00416             /* Make sure we have enough data.
00417              * (Not useful if we went through NEXT_SYNC) */
00418             if( block_WaitBytes( &p_sys->bytestream,
00419                                  p_sys->i_frame_size ) != VLC_SUCCESS )
00420             {
00421                 /* Need more data */
00422                 return NULL;
00423             }
00424             p_sys->i_state = STATE_SEND_DATA;
00425 
00426         case STATE_SEND_DATA:
00427             if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
00428             {
00429                 //p_dec->b_error = VLC_TRUE;
00430                 return NULL;
00431             }
00432 
00433             /* Free bitrate only */
00434             if( p_sys->i_bit_rate == 0 )
00435             {
00436                 p_sys->i_free_frame_size = p_sys->i_frame_size;
00437             }
00438 
00439             /* Copy the whole frame into the buffer. When we reach this point
00440              * we already know we have enough data available. */
00441             block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
00442 
00443             /* Get beginning of next frame for libmad */
00444             if( !p_sys->b_packetizer )
00445             {
00446                 memcpy( p_buf + p_sys->i_frame_size,
00447                         p_header, MAD_BUFFER_GUARD );
00448             }
00449 
00450             p_sys->i_state = STATE_NOSYNC;
00451 
00452             /* Make sure we don't reuse the same pts twice */
00453             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
00454                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
00455 
00456             /* So p_block doesn't get re-added several times */
00457             *pp_block = block_BytestreamPop( &p_sys->bytestream );
00458 
00459             return p_out_buffer;
00460         }
00461     }
00462 
00463     return NULL;
00464 }
00465 
00466 /*****************************************************************************
00467  * GetOutBuffer:
00468  *****************************************************************************/
00469 static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
00470 {
00471     decoder_sys_t *p_sys = p_dec->p_sys;
00472     uint8_t *p_buf;
00473 
00474     if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
00475     {
00476         msg_Dbg( p_dec, "MPGA channels:%d samplerate:%d bitrate:%d",
00477                   p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
00478 
00479         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
00480         aout_DateSet( &p_sys->end_date, p_sys->i_pts );
00481     }
00482 
00483     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
00484     p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
00485     p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
00486     p_dec->fmt_out.audio.i_bytes_per_frame =
00487         p_sys->i_max_frame_size + MAD_BUFFER_GUARD;
00488 
00489     p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
00490     p_dec->fmt_out.audio.i_physical_channels =
00491         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
00492 
00493     p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate * 1000;
00494 
00495     if( p_sys->b_packetizer )
00496     {
00497         block_t *p_sout_buffer = GetSoutBuffer( p_dec );
00498         p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
00499         *pp_out_buffer = p_sout_buffer;
00500     }
00501     else
00502     {
00503         aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
00504         p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
00505         *pp_out_buffer = p_aout_buffer;
00506     }
00507 
00508     return p_buf;
00509 }
00510 
00511 /*****************************************************************************
00512  * GetAoutBuffer:
00513  *****************************************************************************/
00514 static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
00515 {
00516     decoder_sys_t *p_sys = p_dec->p_sys;
00517     aout_buffer_t *p_buf;
00518 
00519     p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length );
00520     if( p_buf == NULL ) return NULL;
00521 
00522     p_buf->start_date = aout_DateGet( &p_sys->end_date );
00523     p_buf->end_date =
00524         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length );
00525 
00526     /* Hack for libmad filter */
00527     p_buf->i_nb_bytes = p_sys->i_frame_size + MAD_BUFFER_GUARD;
00528 
00529     return p_buf;
00530 }
00531 
00532 /*****************************************************************************
00533  * GetSoutBuffer:
00534  *****************************************************************************/
00535 static block_t *GetSoutBuffer( decoder_t *p_dec )
00536 {
00537     decoder_sys_t *p_sys = p_dec->p_sys;
00538     block_t *p_block;
00539 
00540     p_block = block_New( p_dec, p_sys->i_frame_size );
00541     if( p_block == NULL ) return NULL;
00542 
00543     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
00544 
00545     p_block->i_length =
00546         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) -
00547             p_block->i_pts;
00548 
00549     return p_block;
00550 }
00551 
00552 /*****************************************************************************
00553  * CloseDecoder: clean up the decoder
00554  *****************************************************************************/
00555 static void CloseDecoder( vlc_object_t *p_this )
00556 {
00557     decoder_t *p_dec = (decoder_t *)p_this;
00558     decoder_sys_t *p_sys = p_dec->p_sys;
00559 
00560     block_BytestreamRelease( &p_sys->bytestream );
00561 
00562     free( p_sys );
00563 }
00564 
00565 /*****************************************************************************
00566  * SyncInfo: parse MPEG audio sync info
00567  *****************************************************************************/
00568 static int SyncInfo( uint32_t i_header, unsigned int * pi_channels,
00569                      unsigned int * pi_channels_conf,
00570                      unsigned int * pi_sample_rate, unsigned int * pi_bit_rate,
00571                      unsigned int * pi_frame_length,
00572                      unsigned int * pi_max_frame_size, unsigned int * pi_layer)
00573 {
00574     static const int ppi_bitrate[2][3][16] =
00575     {
00576         {
00577             /* v1 l1 */
00578             { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384,
00579               416, 448, 0},
00580             /* v1 l2 */
00581             { 0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256,
00582               320, 384, 0},
00583             /* v1 l3 */
00584             { 0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224,
00585               256, 320, 0}
00586         },
00587 
00588         {
00589             /* v2 l1 */
00590             { 0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192,
00591               224, 256, 0},
00592             /* v2 l2 */
00593             { 0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128,
00594               144, 160, 0},
00595             /* v2 l3 */
00596             { 0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128,
00597               144, 160, 0}
00598         }
00599     };
00600 
00601     static const int ppi_samplerate[2][4] = /* version 1 then 2 */
00602     {
00603         { 44100, 48000, 32000, 0 },
00604         { 22050, 24000, 16000, 0 }
00605     };
00606 
00607     int i_version, i_mode, i_emphasis;
00608     vlc_bool_t b_padding, b_mpeg_2_5, b_crc;
00609     int i_frame_size = 0;
00610     int i_bitrate_index, i_samplerate_index;
00611     int i_max_bit_rate;
00612 
00613     b_mpeg_2_5  = 1 - ((i_header & 0x100000) >> 20);
00614     i_version   = 1 - ((i_header & 0x80000) >> 19);
00615     *pi_layer   = 4 - ((i_header & 0x60000) >> 17);
00616     b_crc = !((i_header >> 16) & 0x01);
00617     i_bitrate_index = (i_header & 0xf000) >> 12;
00618     i_samplerate_index = (i_header & 0xc00) >> 10;
00619     b_padding   = (i_header & 0x200) >> 9;
00620     /* Extension */
00621     i_mode      = (i_header & 0xc0) >> 6;
00622     /* Modeext, copyright & original */
00623     i_emphasis  = i_header & 0x3;
00624 
00625     if( *pi_layer != 4 &&
00626         i_bitrate_index < 0x0f &&
00627         i_samplerate_index != 0x03 &&
00628         i_emphasis != 0x02 )
00629     {
00630         switch ( i_mode )
00631         {
00632         case 0: /* stereo */
00633         case 1: /* joint stereo */
00634             *pi_channels = 2;
00635             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
00636             break;
00637         case 2: /* dual-mono */
00638             *pi_channels = 2;
00639             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
00640                                 | AOUT_CHAN_DUALMONO;
00641             break;
00642         case 3: /* mono */
00643             *pi_channels = 1;
00644             *pi_channels_conf = AOUT_CHAN_CENTER;
00645             break;
00646         }
00647         *pi_bit_rate = ppi_bitrate[i_version][*pi_layer-1][i_bitrate_index];
00648         i_max_bit_rate = ppi_bitrate[i_version][*pi_layer-1][14];
00649         *pi_sample_rate = ppi_samplerate[i_version][i_samplerate_index];
00650 
00651         if ( b_mpeg_2_5 )
00652         {
00653             *pi_sample_rate >>= 1;
00654         }
00655 
00656         switch( *pi_layer )
00657         {
00658         case 1:
00659             i_frame_size = ( 12000 * *pi_bit_rate / *pi_sample_rate +
00660                            b_padding ) * 4;
00661             *pi_max_frame_size = ( 12000 * i_max_bit_rate /
00662                                  *pi_sample_rate + 1 ) * 4;
00663             *pi_frame_length = 384;
00664             break;
00665 
00666         case 2:
00667             i_frame_size = 144000 * *pi_bit_rate / *pi_sample_rate + b_padding;
00668             *pi_max_frame_size = 144000 * i_max_bit_rate / *pi_sample_rate + 1;
00669             *pi_frame_length = 1152;
00670             break;
00671 
00672         case 3:
00673             i_frame_size = ( i_version ? 72000 : 144000 ) *
00674                            *pi_bit_rate / *pi_sample_rate + b_padding;
00675             *pi_max_frame_size = ( i_version ? 72000 : 144000 ) *
00676                                  i_max_bit_rate / *pi_sample_rate + 1;
00677             *pi_frame_length = i_version ? 576 : 1152;
00678             break;
00679 
00680         default:
00681             break;
00682         }
00683     }
00684     else
00685     {
00686         return -1;
00687     }
00688 
00689     return i_frame_size;
00690 }

Generated on Tue Dec 20 10:14:29 2005 for vlc-0.8.4a by  doxygen 1.4.2