00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdlib.h>
00029
00030 #include <vlc/vlc.h>
00031 #include <vlc/input.h>
00032 #include "vlc_codec.h"
00033 #include "vlc_meta.h"
00034
00035 #define MPGA_PACKET_SIZE 1024
00036
00037
00038
00039
00040 static int Open ( vlc_object_t * );
00041 static void Close( vlc_object_t * );
00042
00043 vlc_module_begin();
00044 set_category( CAT_INPUT );
00045 set_subcategory( SUBCAT_INPUT_DEMUX );
00046 set_description( _("MPEG-I/II audio demuxer" ) );
00047 set_capability( "demux2", 100 );
00048 set_callbacks( Open, Close );
00049 add_shortcut( "mpga" );
00050 add_shortcut( "mp3" );
00051 vlc_module_end();
00052
00053
00054
00055
00056 static int Demux ( demux_t * );
00057 static int Control( demux_t *, int, va_list );
00058
00059 struct demux_sys_t
00060 {
00061 es_out_id_t *p_es;
00062 vlc_meta_t *meta;
00063
00064 vlc_bool_t b_start;
00065 decoder_t *p_packetizer;
00066
00067 mtime_t i_pts;
00068 mtime_t i_time_offset;
00069 int i_bitrate_avg;
00070
00071 int i_xing_frames;
00072 int i_xing_bytes;
00073 int i_xing_bitrate_avg;
00074 int i_xing_frame_samples;
00075 block_t *p_block_in, *p_block_out;
00076 };
00077
00078 static int HeaderCheck( uint32_t h )
00079 {
00080 if( ((( h >> 21 )&0x07FF) != 0x07FF )
00081 || (((h >> 17)&0x03) == 0 )
00082 || (((h >> 12)&0x0F) == 0x0F )
00083 || (((h >> 12)&0x0F) == 0x00 )
00084 || (((h >> 10) & 0x03) == 0x03 )
00085 || ((h & 0x03) == 0x02 ))
00086 {
00087 return VLC_FALSE;
00088 }
00089 return VLC_TRUE;
00090 }
00091
00092 #define MPGA_VERSION( h ) ( 1 - (((h)>>19)&0x01) )
00093 #define MPGA_LAYER( h ) ( 3 - (((h)>>17)&0x03) )
00094 #define MPGA_MODE(h) (((h)>> 6)&0x03)
00095
00096 static int mpga_frame_samples( uint32_t h )
00097 {
00098 switch( MPGA_LAYER(h) )
00099 {
00100 case 0:
00101 return 384;
00102 case 1:
00103 return 1152;
00104 case 2:
00105 return MPGA_VERSION(h) ? 576 : 1152;
00106 default:
00107 return 0;
00108 }
00109 }
00110
00111
00112
00113
00114 static int Open( vlc_object_t * p_this )
00115 {
00116 demux_t *p_demux = (demux_t*)p_this;
00117 demux_sys_t *p_sys;
00118 vlc_bool_t b_forced = VLC_FALSE;
00119
00120 uint32_t header;
00121 uint8_t *p_peek;
00122 module_t *p_id3;
00123 block_t *p_block_in, *p_block_out;
00124
00125 if( p_demux->psz_path )
00126 {
00127 int i_len = strlen( p_demux->psz_path );
00128 if( i_len > 4 && !strcasecmp( &p_demux->psz_path[i_len - 4], ".mp3" ) )
00129 {
00130 b_forced = VLC_TRUE;
00131 }
00132 }
00133
00134 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
00135
00136 if( !HeaderCheck( header = GetDWBE( p_peek ) ) )
00137 {
00138 vlc_bool_t b_ok = VLC_FALSE;
00139 int i_peek;
00140
00141 if( !p_demux->b_force && !b_forced ) return VLC_EGENERIC;
00142
00143 i_peek = stream_Peek( p_demux->s, &p_peek, 8096 );
00144 while( i_peek > 4 )
00145 {
00146 if( HeaderCheck( header = GetDWBE( p_peek ) ) )
00147 {
00148 b_ok = VLC_TRUE;
00149 break;
00150 }
00151 p_peek += 1;
00152 i_peek -= 1;
00153 }
00154 if( !b_ok && !p_demux->b_force ) return VLC_EGENERIC;
00155 }
00156
00157 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
00158 memset( p_sys, 0, sizeof( demux_sys_t ) );
00159 p_sys->p_es = 0;
00160 p_sys->p_packetizer = 0;
00161 p_sys->b_start = VLC_TRUE;
00162 p_sys->meta = 0;
00163 p_demux->pf_demux = Demux;
00164 p_demux->pf_control = Control;
00165
00166
00167
00168
00169 p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
00170 p_sys->p_packetizer->pf_decode_audio = NULL;
00171 p_sys->p_packetizer->pf_decode_video = NULL;
00172 p_sys->p_packetizer->pf_decode_sub = NULL;
00173 p_sys->p_packetizer->pf_packetize = NULL;
00174 es_format_Init( &p_sys->p_packetizer->fmt_in, AUDIO_ES,
00175 VLC_FOURCC( 'm', 'p', 'g', 'a' ) );
00176 es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 );
00177 p_sys->p_packetizer->p_module =
00178 module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );
00179
00180 if( p_sys->p_packetizer->p_module == NULL )
00181 {
00182 msg_Err( p_demux, "cannot find mpga packetizer" );
00183 Close( VLC_OBJECT(p_demux ) );
00184 return VLC_EGENERIC;
00185 }
00186
00187
00188 if( HeaderCheck( header ) )
00189 {
00190 int i_xing, i_skip;
00191 uint8_t *p_xing;
00192
00193 if( ( i_xing = stream_Peek( p_demux->s, &p_xing, 1024 ) ) < 21 )
00194 return VLC_SUCCESS;
00195
00196 if( MPGA_VERSION( header ) == 0 )
00197 {
00198 i_skip = MPGA_MODE( header ) != 3 ? 36 : 21;
00199 }
00200 else
00201 {
00202 i_skip = MPGA_MODE( header ) != 3 ? 21 : 13;
00203 }
00204
00205 if( i_skip + 8 < i_xing && !strncmp( (char *)&p_xing[i_skip], "Xing", 4 ) )
00206 {
00207 unsigned int i_flags = GetDWBE( &p_xing[i_skip+4] );
00208
00209 p_xing += i_skip + 8;
00210 i_xing -= i_skip + 8;
00211
00212 i_skip = 0;
00213 if( i_flags&0x01 && i_skip + 4 <= i_xing )
00214 {
00215 p_sys->i_xing_frames = GetDWBE( &p_xing[i_skip] );
00216 i_skip += 4;
00217 }
00218 if( i_flags&0x02 && i_skip + 4 <= i_xing )
00219 {
00220 p_sys->i_xing_bytes = GetDWBE( &p_xing[i_skip] );
00221 i_skip += 4;
00222 }
00223 if( i_flags&0x04 )
00224 {
00225 i_skip += 100;
00226 }
00227
00228
00229
00230 if( i_flags&0x08 && i_skip + 4 <= i_xing )
00231 {
00232 p_sys->i_xing_bitrate_avg = GetDWBE( &p_xing[i_skip] );
00233 msg_Dbg( p_demux, "xing vbr value present (%d)",
00234 p_sys->i_xing_bitrate_avg );
00235 }
00236
00237 if( p_sys->i_xing_frames > 0 && p_sys->i_xing_bytes > 0 )
00238 {
00239 p_sys->i_xing_frame_samples = mpga_frame_samples( header );
00240 msg_Dbg( p_demux, "xing frames&bytes value present "
00241 "(%d bytes, %d frames, %d samples/frame)",
00242 p_sys->i_xing_bytes, p_sys->i_xing_frames,
00243 p_sys->i_xing_frame_samples );
00244 }
00245 }
00246 }
00247
00248 if( ( p_block_in = stream_Block( p_demux->s, MPGA_PACKET_SIZE ) ) == NULL )
00249 {
00250 return VLC_EGENERIC;
00251 }
00252 p_block_in->i_pts = p_block_in->i_dts = 1;
00253 p_block_out = p_sys->p_packetizer->pf_packetize(
00254 p_sys->p_packetizer, &p_block_in );
00255
00256 p_sys->p_packetizer->fmt_out.b_packetized = VLC_TRUE;
00257 p_sys->p_es = es_out_Add( p_demux->out,
00258 &p_sys->p_packetizer->fmt_out);
00259 p_sys->i_bitrate_avg = p_sys->p_packetizer->fmt_out.i_bitrate;
00260
00261 if( p_sys->i_xing_bytes && p_sys->i_xing_frames &&
00262 p_sys->i_xing_frame_samples )
00263 {
00264 p_sys->i_bitrate_avg = p_sys->i_xing_bytes * I64C(8) *
00265 p_sys->p_packetizer->fmt_out.audio.i_rate /
00266 p_sys->i_xing_frames / p_sys->i_xing_frame_samples;
00267 }
00268
00269 p_sys->p_block_in = p_block_in;
00270 p_sys->p_block_out = p_block_out;
00271
00272
00273 if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) )
00274 {
00275 p_sys->meta = (vlc_meta_t *)p_demux->p_private;
00276 p_demux->p_private = NULL;
00277 module_Unneed( p_demux, p_id3 );
00278 }
00279
00280 return VLC_SUCCESS;
00281 }
00282
00283
00284
00285
00286
00287
00288 static int Demux( demux_t *p_demux )
00289 {
00290 demux_sys_t *p_sys = p_demux->p_sys;
00291 block_t *p_block_in, *p_block_out;
00292 if( p_sys->b_start )
00293 {
00294 p_sys->b_start = VLC_FALSE;
00295 p_block_in = p_sys->p_block_in;
00296 p_block_out = p_sys->p_block_out;
00297 }
00298 else
00299 {
00300 if( ( p_block_in = stream_Block( p_demux->s, MPGA_PACKET_SIZE ) )
00301 == NULL )
00302 {
00303 return 0;
00304 }
00305 p_block_in->i_pts = p_block_in->i_dts = 0;
00306 p_block_out = p_sys->p_packetizer->pf_packetize(
00307 p_sys->p_packetizer, &p_block_in );
00308 }
00309
00310
00311 while( p_block_out )
00312 {
00313 while( p_block_out )
00314 {
00315 block_t *p_next = p_block_out->p_next;
00316
00317 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
00318
00319 p_block_out->p_next = NULL;
00320 p_sys->i_pts = p_block_out->i_pts;
00321 es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
00322
00323 p_block_out = p_next;
00324 }
00325 p_block_out = p_sys->p_packetizer->pf_packetize(
00326 p_sys->p_packetizer, &p_block_in );
00327 }
00328 return 1;
00329 }
00330
00331
00332
00333
00334 static void Close( vlc_object_t * p_this )
00335 {
00336 demux_t *p_demux = (demux_t*)p_this;
00337 demux_sys_t *p_sys = p_demux->p_sys;
00338
00339 if( p_sys->meta ) vlc_meta_Delete( p_sys->meta );
00340
00341 if( p_sys->p_packetizer && p_sys->p_packetizer->p_module )
00342 module_Unneed( p_sys->p_packetizer, p_sys->p_packetizer->p_module );
00343 if( p_sys->p_packetizer )
00344 vlc_object_destroy( p_sys->p_packetizer );
00345
00346 free( p_sys );
00347 }
00348
00349
00350
00351
00352 static int Control( demux_t *p_demux, int i_query, va_list args )
00353 {
00354 demux_sys_t *p_sys = p_demux->p_sys;
00355 int64_t *pi64;
00356 vlc_meta_t **pp_meta;
00357 int i_ret;
00358
00359 switch( i_query )
00360 {
00361 case DEMUX_GET_META:
00362 pp_meta = (vlc_meta_t **)va_arg( args, vlc_meta_t** );
00363 if( p_sys->meta ) *pp_meta = vlc_meta_Duplicate( p_sys->meta );
00364 else *pp_meta = NULL;
00365 return VLC_SUCCESS;
00366
00367 case DEMUX_GET_TIME:
00368 pi64 = (int64_t*)va_arg( args, int64_t * );
00369 *pi64 = p_sys->i_pts + p_sys->i_time_offset;
00370 return VLC_SUCCESS;
00371
00372 case DEMUX_SET_TIME:
00373
00374
00375
00376 default:
00377 i_ret = demux2_vaControlHelper( p_demux->s, 0, -1,
00378 p_sys->i_bitrate_avg, 1, i_query,
00379 args );
00380 if( !i_ret && p_sys->i_bitrate_avg > 0 &&
00381 (i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME) )
00382 {
00383 int64_t i_time = I64C(8000000) * stream_Tell(p_demux->s) /
00384 p_sys->i_bitrate_avg;
00385
00386
00387 if( i_time >= 0 ) p_sys->i_time_offset = i_time - p_sys->i_pts;
00388 }
00389 return i_ret;
00390 }
00391 }