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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * mpga.c : MPEG-I/II Audio input module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2004 VideoLAN
  5.  * $Id: mpga.c 9061 2004-10-26 13:03:03Z gbazin $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *          Gildas Bazin <gbazin@videolan.org>
  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 <stdlib.h>                                      /* malloc(), free() */
  28. #include <vlc/vlc.h>
  29. #include <vlc/input.h>
  30. #include "vlc_codec.h"
  31. #include "vlc_meta.h"
  32. #define MPGA_PACKET_SIZE 4096
  33. /*****************************************************************************
  34.  * Module descriptor
  35.  *****************************************************************************/
  36. static int  Open ( vlc_object_t * );
  37. static void Close( vlc_object_t * );
  38. vlc_module_begin();
  39.     set_description( _("MPEG-I/II audio demuxer" ) );
  40.     set_capability( "demux2", 100 );
  41.     set_callbacks( Open, Close );
  42.     add_shortcut( "mpga" );
  43.     add_shortcut( "mp3" );
  44. vlc_module_end();
  45. /*****************************************************************************
  46.  * Local prototypes
  47.  *****************************************************************************/
  48. static int Demux  ( demux_t * );
  49. static int Control( demux_t *, int, va_list );
  50. struct demux_sys_t
  51. {
  52.     es_out_id_t *p_es;
  53.     vlc_meta_t  *meta;
  54.     vlc_bool_t  b_start;
  55.     decoder_t   *p_packetizer;
  56.     mtime_t     i_pts;
  57.     mtime_t     i_time_offset;
  58.     int         i_bitrate_avg;  /* extracted from Xing header */
  59.     int i_xing_frames;
  60.     int i_xing_bytes;
  61.     int i_xing_bitrate_avg;
  62.     int i_xing_frame_samples;
  63. };
  64. static int HeaderCheck( uint32_t h )
  65. {
  66.     if( ((( h >> 21 )&0x07FF) != 0x07FF )   /* header sync */
  67.         || (((h >> 17)&0x03) == 0 )         /* valid layer ?*/
  68.         || (((h >> 12)&0x0F) == 0x0F )
  69.         || (((h >> 12)&0x0F) == 0x00 )      /* valid bitrate ? */
  70.         || (((h >> 10) & 0x03) == 0x03 )    /* valide sampling freq ? */
  71.         || ((h & 0x03) == 0x02 ))           /* valid emphasis ? */
  72.     {
  73.         return VLC_FALSE;
  74.     }
  75.     return VLC_TRUE;
  76. }
  77. #define MPGA_VERSION( h )   ( 1 - (((h)>>19)&0x01) )
  78. #define MPGA_LAYER( h )     ( 3 - (((h)>>17)&0x03) )
  79. #define MPGA_MODE(h)        (((h)>> 6)&0x03)
  80. static int mpga_frame_samples( uint32_t h )
  81. {
  82.     switch( MPGA_LAYER(h) )
  83.     {
  84.         case 0:
  85.             return 384;
  86.         case 1:
  87.             return 1152;
  88.         case 2:
  89.             return MPGA_VERSION(h) ? 576 : 1152;
  90.         default:
  91.             return 0;
  92.     }
  93. }
  94. /*****************************************************************************
  95.  * Open: initializes demux structures
  96.  *****************************************************************************/
  97. static int Open( vlc_object_t * p_this )
  98. {
  99.     demux_t     *p_demux = (demux_t*)p_this;
  100.     demux_sys_t *p_sys;
  101.     vlc_bool_t  b_forced = VLC_FALSE;
  102.     uint32_t     header;
  103.     uint8_t     *p_peek;
  104.     module_t    *p_id3;
  105.     vlc_meta_t  *p_meta = NULL;
  106.     if( p_demux->psz_path )
  107.     {
  108.         int  i_len = strlen( p_demux->psz_path );
  109.         if( i_len > 4 && !strcasecmp( &p_demux->psz_path[i_len - 4], ".mp3" ) )
  110.         {
  111.             b_forced = VLC_TRUE;
  112.         }
  113.     }
  114.     /* Skip/parse possible id3 header */
  115.     if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) )
  116.     {
  117.         p_meta = (vlc_meta_t *)p_demux->p_private;
  118.         p_demux->p_private = NULL;
  119.         module_Unneed( p_demux, p_id3 );
  120.     }
  121.     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
  122.     {
  123.         msg_Err( p_demux, "cannot peek" );
  124.         if( p_meta ) vlc_meta_Delete( p_meta );
  125.         return VLC_EGENERIC;
  126.     }
  127.     if( !HeaderCheck( header = GetDWBE( p_peek ) ) )
  128.     {
  129.         vlc_bool_t b_ok = VLC_FALSE;
  130.         int i_peek;
  131.         if( !p_demux->b_force && !b_forced )
  132.         {
  133.             if( p_meta ) vlc_meta_Delete( p_meta );
  134.             return VLC_EGENERIC;
  135.         }
  136.         i_peek = stream_Peek( p_demux->s, &p_peek, 8096 );
  137.         while( i_peek > 4 )
  138.         {
  139.             if( HeaderCheck( header = GetDWBE( p_peek ) ) )
  140.             {
  141.                 b_ok = VLC_TRUE;
  142.                 break;
  143.             }
  144.             p_peek += 1;
  145.             i_peek -= 1;
  146.         }
  147.         if( !b_ok && !p_demux->b_force )
  148.         {
  149.             msg_Warn( p_demux, "mpga module discarded" );
  150.             if( p_meta ) vlc_meta_Delete( p_meta );
  151.             return VLC_EGENERIC;
  152.         }
  153.     }
  154.     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
  155.     memset( p_sys, 0, sizeof( demux_sys_t ) );
  156.     p_sys->p_es = 0;
  157.     p_sys->p_packetizer = 0;
  158.     p_sys->b_start = VLC_TRUE;
  159.     p_sys->meta = p_meta;
  160.     p_demux->pf_demux   = Demux;
  161.     p_demux->pf_control = Control;
  162.     /*
  163.      * Load the mpeg audio packetizer
  164.      */
  165.     p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
  166.     p_sys->p_packetizer->pf_decode_audio = NULL;
  167.     p_sys->p_packetizer->pf_decode_video = NULL;
  168.     p_sys->p_packetizer->pf_decode_sub = NULL;
  169.     p_sys->p_packetizer->pf_packetize = NULL;
  170.     es_format_Init( &p_sys->p_packetizer->fmt_in, AUDIO_ES,
  171.                     VLC_FOURCC( 'm', 'p', 'g', 'a' ) );
  172.     es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 );
  173.     p_sys->p_packetizer->p_module =
  174.         module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );
  175.     if( p_sys->p_packetizer->p_module == NULL )
  176.     {
  177.         msg_Err( p_demux, "cannot find mpga packetizer" );
  178.         Close( VLC_OBJECT(p_demux ) );
  179.         return VLC_EGENERIC;
  180.     }
  181.     /* Xing header */
  182.     if( HeaderCheck( header ) )
  183.     {
  184.         int i_xing, i_skip;
  185.         uint8_t *p_xing;
  186.         if( ( i_xing = stream_Peek( p_demux->s, &p_xing, 1024 ) ) < 21 )
  187.             return VLC_SUCCESS; /* No header */
  188.         if( MPGA_VERSION( header ) == 0 )
  189.         {
  190.             i_skip = MPGA_MODE( header ) != 3 ? 36 : 21;
  191.         }
  192.         else
  193.         {
  194.             i_skip = MPGA_MODE( header ) != 3 ? 21 : 13;
  195.         }
  196.         if( i_skip + 8 < i_xing && !strncmp( &p_xing[i_skip], "Xing", 4 ) )
  197.         {
  198.             unsigned int i_flags = GetDWBE( &p_xing[i_skip+4] );
  199.             p_xing += i_skip + 8;
  200.             i_xing -= i_skip + 8;
  201.             i_skip = 0;
  202.             if( i_flags&0x01 && i_skip + 4 <= i_xing )   /* XING_FRAMES */
  203.             {
  204.                 p_sys->i_xing_frames = GetDWBE( &p_xing[i_skip] );
  205.                 i_skip += 4;
  206.             }
  207.             if( i_flags&0x02 && i_skip + 4 <= i_xing )   /* XING_BYTES */
  208.             {
  209.                 p_sys->i_xing_bytes = GetDWBE( &p_xing[i_skip] );
  210.                 i_skip += 4;
  211.             }
  212.             if( i_flags&0x04 )   /* XING_TOC */
  213.             {
  214.                 i_skip += 100;
  215.             }
  216.             // FIXME: doesn't return the right bitrage average, at least
  217.             // with some MP3's
  218.             if( i_flags&0x08 && i_skip + 4 <= i_xing )   /* XING_VBR */
  219.             {
  220.                 p_sys->i_xing_bitrate_avg = GetDWBE( &p_xing[i_skip] );
  221.                 msg_Dbg( p_demux, "xing vbr value present (%d)",
  222.                          p_sys->i_xing_bitrate_avg );
  223.             }
  224.             if( p_sys->i_xing_frames > 0 && p_sys->i_xing_bytes > 0 )
  225.             {
  226.                 p_sys->i_xing_frame_samples = mpga_frame_samples( header );
  227.                 msg_Dbg( p_demux, "xing frames&bytes value present "
  228.                          "(%d bytes, %d frames, %d samples/frame)",
  229.                          p_sys->i_xing_bytes, p_sys->i_xing_frames,
  230.                          p_sys->i_xing_frame_samples );
  231.             }
  232.         }
  233.     }
  234.     return VLC_SUCCESS;
  235. }
  236. /*****************************************************************************
  237.  * Demux: reads and demuxes data packets
  238.  *****************************************************************************
  239.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  240.  *****************************************************************************/
  241. static int Demux( demux_t *p_demux )
  242. {
  243.     demux_sys_t *p_sys = p_demux->p_sys;
  244.     block_t *p_block_in, *p_block_out;
  245.     if( ( p_block_in = stream_Block( p_demux->s, MPGA_PACKET_SIZE ) ) == NULL )
  246.     {
  247.         return 0;
  248.     }
  249.     p_block_in->i_pts = p_block_in->i_dts = p_sys->b_start ? 1 : 0;
  250.     p_sys->b_start = VLC_FALSE;
  251.     while( (p_block_out = p_sys->p_packetizer->pf_packetize(
  252.                                           p_sys->p_packetizer, &p_block_in )) )
  253.     {
  254.         while( p_block_out )
  255.         {
  256.             block_t *p_next = p_block_out->p_next;
  257.             if( p_sys->p_es == NULL )
  258.             {
  259.                 p_sys->p_packetizer->fmt_out.b_packetized = VLC_TRUE;
  260.                 p_sys->p_es = es_out_Add( p_demux->out,
  261.                                           &p_sys->p_packetizer->fmt_out);
  262.                 p_sys->i_bitrate_avg = p_sys->p_packetizer->fmt_out.i_bitrate;
  263.                 if( p_sys->i_xing_bytes && p_sys->i_xing_frames &&
  264.                     p_sys->i_xing_frame_samples )
  265.                 {
  266.                     p_sys->i_bitrate_avg = p_sys->i_xing_bytes * I64C(8) *
  267.                         p_sys->p_packetizer->fmt_out.audio.i_rate /
  268.                         p_sys->i_xing_frames / p_sys->i_xing_frame_samples;
  269.                 }
  270.             }
  271.             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
  272.             p_block_out->p_next = NULL;
  273.             p_sys->i_pts = p_block_out->i_pts;
  274.             es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
  275.             p_block_out = p_next;
  276.         }
  277.     }
  278.     return 1;
  279. }
  280. /*****************************************************************************
  281.  * Close: frees unused data
  282.  *****************************************************************************/
  283. static void Close( vlc_object_t * p_this )
  284. {
  285.     demux_t     *p_demux = (demux_t*)p_this;
  286.     demux_sys_t *p_sys = p_demux->p_sys;
  287.     if( p_sys->meta ) vlc_meta_Delete( p_sys->meta );
  288.     if( p_sys->p_packetizer && p_sys->p_packetizer->p_module )
  289.         module_Unneed( p_sys->p_packetizer, p_sys->p_packetizer->p_module );
  290.     if( p_sys->p_packetizer )
  291.         vlc_object_destroy( p_sys->p_packetizer );
  292.     free( p_sys );
  293. }
  294. /*****************************************************************************
  295.  * Control:
  296.  *****************************************************************************/
  297. static int Control( demux_t *p_demux, int i_query, va_list args )
  298. {
  299.     demux_sys_t *p_sys  = p_demux->p_sys;
  300.     int64_t *pi64;
  301.     vlc_meta_t **pp_meta;
  302.     int i_ret;
  303.     switch( i_query )
  304.     {
  305.         case DEMUX_GET_META:
  306.             pp_meta = (vlc_meta_t **)va_arg( args, vlc_meta_t** );
  307.             if( p_sys->meta ) *pp_meta = vlc_meta_Duplicate( p_sys->meta );
  308.             else *pp_meta = NULL;
  309.             return VLC_SUCCESS;
  310.         case DEMUX_GET_TIME:
  311.             pi64 = (int64_t*)va_arg( args, int64_t * );
  312.             *pi64 = p_sys->i_pts + p_sys->i_time_offset;
  313.             return VLC_SUCCESS;
  314.         case DEMUX_SET_TIME:
  315.             /* FIXME TODO: implement a high precision seek (with mp3 parsing)
  316.              * needed for multi-input */
  317.         default:
  318.             i_ret = demux2_vaControlHelper( p_demux->s, 0, -1,
  319.                                             p_sys->i_bitrate_avg, 1, i_query,
  320.                                             args );
  321.             if( !i_ret && p_sys->i_bitrate_avg > 0 &&
  322.                 (i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME) )
  323.             {
  324.                 int64_t i_time = I64C(8000000) * stream_Tell(p_demux->s) /
  325.                     p_sys->i_bitrate_avg;
  326.                 /* Fix time_offset */
  327.                 if( i_time >= 0 ) p_sys->i_time_offset = i_time - p_sys->i_pts;
  328.             }
  329.             return i_ret;
  330.     }
  331. }