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
00029 #include <vlc/vlc.h>
00030 #include <vlc/decoder.h>
00031
00032 #include "vlc_block_helper.h"
00033
00034 #define A52_HEADER_SIZE 7
00035
00036
00037
00038
00039 struct decoder_sys_t
00040 {
00041
00042 vlc_bool_t b_packetizer;
00043
00044
00045
00046
00047 int i_state;
00048
00049 block_bytestream_t bytestream;
00050
00051
00052
00053
00054 audio_date_t end_date;
00055
00056 mtime_t i_pts;
00057 int i_frame_size, i_bit_rate;
00058 unsigned int i_rate, i_channels, i_channels_conf;
00059
00060 };
00061
00062 enum {
00063
00064 STATE_NOSYNC,
00065 STATE_SYNC,
00066 STATE_HEADER,
00067 STATE_NEXT_SYNC,
00068 STATE_GET_DATA,
00069 STATE_SEND_DATA
00070 };
00071
00072
00073
00074
00075 static int OpenDecoder ( vlc_object_t * );
00076 static int OpenPacketizer( vlc_object_t * );
00077 static void CloseDecoder ( vlc_object_t * );
00078 static void *DecodeBlock ( decoder_t *, block_t ** );
00079
00080 static int SyncInfo ( const byte_t *, unsigned int *, unsigned int *,
00081 unsigned int *, int * );
00082
00083 static uint8_t *GetOutBuffer ( decoder_t *, void ** );
00084 static aout_buffer_t *GetAoutBuffer( decoder_t * );
00085 static block_t *GetSoutBuffer( decoder_t * );
00086
00087
00088
00089
00090 vlc_module_begin();
00091 set_description( _("A/52 parser") );
00092 set_capability( "decoder", 100 );
00093 set_callbacks( OpenDecoder, CloseDecoder );
00094 set_category( CAT_INPUT );
00095 set_subcategory( SUBCAT_INPUT_ACODEC );
00096
00097 add_submodule();
00098 set_description( _("A/52 audio packetizer") );
00099 set_capability( "packetizer", 10 );
00100 set_callbacks( OpenPacketizer, CloseDecoder );
00101 vlc_module_end();
00102
00103
00104
00105
00106 static int OpenDecoder( vlc_object_t *p_this )
00107 {
00108 decoder_t *p_dec = (decoder_t*)p_this;
00109 decoder_sys_t *p_sys;
00110
00111 if( p_dec->fmt_in.i_codec != VLC_FOURCC('a','5','2',' ')
00112 && p_dec->fmt_in.i_codec != VLC_FOURCC('a','5','2','b') )
00113 {
00114 return VLC_EGENERIC;
00115 }
00116
00117
00118 if( ( p_dec->p_sys = p_sys =
00119 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
00120 {
00121 msg_Err( p_dec, "out of memory" );
00122 return VLC_EGENERIC;
00123 }
00124
00125
00126 p_sys->b_packetizer = VLC_FALSE;
00127 p_sys->i_state = STATE_NOSYNC;
00128 aout_DateSet( &p_sys->end_date, 0 );
00129
00130 p_sys->bytestream = block_BytestreamInit( p_dec );
00131
00132
00133 p_dec->fmt_out.i_cat = AUDIO_ES;
00134 p_dec->fmt_out.i_codec = VLC_FOURCC('a','5','2',' ');
00135 p_dec->fmt_out.audio.i_rate = 0;
00136
00137
00138 p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
00139 DecodeBlock;
00140 p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
00141 DecodeBlock;
00142
00143 return VLC_SUCCESS;
00144 }
00145
00146 static int OpenPacketizer( vlc_object_t *p_this )
00147 {
00148 decoder_t *p_dec = (decoder_t*)p_this;
00149
00150 int i_ret = OpenDecoder( p_this );
00151
00152 if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
00153
00154 return i_ret;
00155 }
00156
00157
00158
00159
00160
00161
00162 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
00163 {
00164 decoder_sys_t *p_sys = p_dec->p_sys;
00165 uint8_t p_header[A52_HEADER_SIZE];
00166 uint8_t *p_buf;
00167 void *p_out_buffer;
00168
00169 if( !pp_block || !*pp_block ) return NULL;
00170
00171 if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
00172 {
00173
00174 block_Release( *pp_block );
00175 return NULL;
00176 }
00177
00178 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
00179 {
00180 p_sys->i_state = STATE_NOSYNC;
00181 }
00182
00183 block_BytestreamPush( &p_sys->bytestream, *pp_block );
00184
00185 while( 1 )
00186 {
00187 switch( p_sys->i_state )
00188 {
00189 case STATE_NOSYNC:
00190 while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
00191 == VLC_SUCCESS )
00192 {
00193 if( p_header[0] == 0x0b && p_header[1] == 0x77 )
00194 {
00195 p_sys->i_state = STATE_SYNC;
00196 break;
00197 }
00198 block_SkipByte( &p_sys->bytestream );
00199 }
00200 if( p_sys->i_state != STATE_SYNC )
00201 {
00202 block_BytestreamFlush( &p_sys->bytestream );
00203
00204
00205 return NULL;
00206 }
00207
00208 case STATE_SYNC:
00209
00210 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
00211 if( p_sys->i_pts != 0 &&
00212 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
00213 {
00214 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
00215 }
00216 p_sys->i_state = STATE_HEADER;
00217
00218 case STATE_HEADER:
00219
00220 if( block_PeekBytes( &p_sys->bytestream, p_header,
00221 A52_HEADER_SIZE ) != VLC_SUCCESS )
00222 {
00223
00224 return NULL;
00225 }
00226
00227
00228 p_sys->i_frame_size = SyncInfo( p_header,
00229 &p_sys->i_channels,
00230 &p_sys->i_channels_conf,
00231 &p_sys->i_rate,
00232 &p_sys->i_bit_rate );
00233 if( !p_sys->i_frame_size )
00234 {
00235 msg_Dbg( p_dec, "emulated sync word" );
00236 block_SkipByte( &p_sys->bytestream );
00237 p_sys->i_state = STATE_NOSYNC;
00238 break;
00239 }
00240 p_sys->i_state = STATE_NEXT_SYNC;
00241
00242 case STATE_NEXT_SYNC:
00243
00244
00245
00246
00247 if( block_PeekOffsetBytes( &p_sys->bytestream,
00248 p_sys->i_frame_size, p_header, 2 )
00249 != VLC_SUCCESS )
00250 {
00251
00252 return NULL;
00253 }
00254
00255 if( p_sys->b_packetizer &&
00256 p_header[0] == 0 && p_header[1] == 0 )
00257 {
00258
00259 p_sys->i_state = STATE_GET_DATA;
00260 break;
00261 }
00262
00263 if( p_header[0] != 0x0b || p_header[1] != 0x77 )
00264 {
00265 msg_Dbg( p_dec, "emulated sync word "
00266 "(no sync on following frame)" );
00267 p_sys->i_state = STATE_NOSYNC;
00268 block_SkipByte( &p_sys->bytestream );
00269 break;
00270 }
00271 p_sys->i_state = STATE_SEND_DATA;
00272 break;
00273
00274 case STATE_GET_DATA:
00275
00276
00277 if( block_WaitBytes( &p_sys->bytestream,
00278 p_sys->i_frame_size ) != VLC_SUCCESS )
00279 {
00280
00281 return NULL;
00282 }
00283 p_sys->i_state = STATE_SEND_DATA;
00284
00285 case STATE_SEND_DATA:
00286 if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
00287 {
00288
00289 return NULL;
00290 }
00291
00292
00293
00294 block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
00295
00296
00297 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
00298 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
00299
00300
00301 *pp_block = block_BytestreamPop( &p_sys->bytestream );
00302
00303 p_sys->i_state = STATE_NOSYNC;
00304
00305 return p_out_buffer;
00306 }
00307 }
00308
00309 return NULL;
00310 }
00311
00312
00313
00314
00315 static void CloseDecoder( vlc_object_t *p_this )
00316 {
00317 decoder_t *p_dec = (decoder_t*)p_this;
00318 decoder_sys_t *p_sys = p_dec->p_sys;
00319
00320 block_BytestreamRelease( &p_sys->bytestream );
00321
00322 free( p_sys );
00323 }
00324
00325
00326
00327
00328 static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
00329 {
00330 decoder_sys_t *p_sys = p_dec->p_sys;
00331 uint8_t *p_buf;
00332
00333 if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
00334 {
00335 msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
00336 p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
00337
00338 aout_DateInit( &p_sys->end_date, p_sys->i_rate );
00339 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
00340 }
00341
00342 p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
00343 p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
00344 p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
00345 p_dec->fmt_out.audio.i_frame_length = A52_FRAME_NB;
00346
00347 p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
00348 p_dec->fmt_out.audio.i_physical_channels =
00349 p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
00350
00351 p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
00352
00353 if( p_sys->b_packetizer )
00354 {
00355 block_t *p_sout_buffer = GetSoutBuffer( p_dec );
00356 p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
00357 *pp_out_buffer = p_sout_buffer;
00358 }
00359 else
00360 {
00361 aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
00362 p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
00363 *pp_out_buffer = p_aout_buffer;
00364 }
00365
00366 return p_buf;
00367 }
00368
00369
00370
00371
00372 static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
00373 {
00374 decoder_sys_t *p_sys = p_dec->p_sys;
00375 aout_buffer_t *p_buf;
00376
00377 p_buf = p_dec->pf_aout_buffer_new( p_dec, A52_FRAME_NB );
00378 if( p_buf == NULL ) return NULL;
00379
00380 p_buf->start_date = aout_DateGet( &p_sys->end_date );
00381 p_buf->end_date = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
00382
00383 return p_buf;
00384 }
00385
00386
00387
00388
00389 static block_t *GetSoutBuffer( decoder_t *p_dec )
00390 {
00391 decoder_sys_t *p_sys = p_dec->p_sys;
00392 block_t *p_block;
00393
00394 p_block = block_New( p_dec, p_sys->i_frame_size );
00395 if( p_block == NULL ) return NULL;
00396
00397 p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
00398
00399 p_block->i_length = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ) -
00400 p_block->i_pts;
00401
00402 return p_block;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412 static int SyncInfo( const byte_t * p_buf,
00413 unsigned int * pi_channels,
00414 unsigned int * pi_channels_conf,
00415 unsigned int * pi_sample_rate, int * pi_bit_rate )
00416 {
00417 static const uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
00418 static const int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
00419 128, 160, 192, 224, 256, 320, 384, 448,
00420 512, 576, 640 };
00421 static const uint8_t lfeon[8] = { 0x10, 0x10, 0x04, 0x04,
00422 0x04, 0x01, 0x04, 0x01 };
00423 int frmsizecod;
00424 int bitrate;
00425 int half;
00426 int acmod;
00427
00428 if ((p_buf[0] != 0x0b) || (p_buf[1] != 0x77))
00429 return 0;
00430
00431 if (p_buf[5] >= 0x60)
00432 return 0;
00433 half = halfrate[p_buf[5] >> 3];
00434
00435
00436 acmod = p_buf[6] >> 5;
00437 if ( (p_buf[6] & 0xf8) == 0x50 )
00438 {
00439
00440 *pi_channels = 2;
00441 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
00442 | AOUT_CHAN_DOLBYSTEREO;
00443 }
00444 else switch ( acmod )
00445 {
00446 case 0x0:
00447
00448 *pi_channels = 2;
00449 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
00450 | AOUT_CHAN_DUALMONO;
00451 break;
00452 case 0x1:
00453
00454 *pi_channels = 1;
00455 *pi_channels_conf = AOUT_CHAN_CENTER;
00456 break;
00457 case 0x2:
00458
00459 *pi_channels = 2;
00460 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
00461 break;
00462 case 0x3:
00463
00464 *pi_channels = 3;
00465 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
00466 | AOUT_CHAN_CENTER;
00467 break;
00468 case 0x4:
00469
00470 *pi_channels = 3;
00471 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
00472 | AOUT_CHAN_REARCENTER;
00473 break;
00474 case 0x5:
00475
00476 *pi_channels = 4;
00477 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
00478 | AOUT_CHAN_REARCENTER;
00479 break;
00480 case 0x6:
00481
00482 *pi_channels = 4;
00483 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
00484 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
00485 break;
00486 case 0x7:
00487
00488 *pi_channels = 5;
00489 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
00490 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
00491 break;
00492 default:
00493 return 0;
00494 }
00495
00496 if ( p_buf[6] & lfeon[acmod] )
00497 {
00498 (*pi_channels)++;
00499 *pi_channels_conf |= AOUT_CHAN_LFE;
00500 }
00501
00502 frmsizecod = p_buf[4] & 63;
00503 if (frmsizecod >= 38)
00504 return 0;
00505 bitrate = rate [frmsizecod >> 1];
00506 *pi_bit_rate = (bitrate * 1000) >> half;
00507
00508 switch (p_buf[4] & 0xc0) {
00509 case 0:
00510 *pi_sample_rate = 48000 >> half;
00511 return 4 * bitrate;
00512 case 0x40:
00513 *pi_sample_rate = 44100 >> half;
00514 return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
00515 case 0x80:
00516 *pi_sample_rate = 32000 >> half;
00517 return 6 * bitrate;
00518 default:
00519 return 0;
00520 }
00521 }