📄 mpeg_audio.c
字号:
break; } /* Check info is in sync with previous one */ if( i_next_channels_conf != p_sys->i_channels_conf || i_next_rate != p_sys->i_rate || i_next_layer != p_sys->i_layer || i_next_frame_length != p_sys->i_frame_length ) { /* Free bitrate only */ if( p_sys->i_bit_rate == 0 ) { p_sys->i_frame_size++; break; } msg_Dbg( p_dec, "parameters changed unexpectedly " "(emulated startcode ?)" ); block_SkipByte( &p_sys->bytestream ); p_sys->i_state = STATE_NOSYNC; break; } /* Free bitrate only */ if( p_sys->i_bit_rate == 0 ) { if( i_next_bit_rate != 0 ) { p_sys->i_frame_size++; break; } } } else { /* Free bitrate only */ if( p_sys->i_bit_rate == 0 ) { if( (unsigned int)p_sys->i_frame_size > p_sys->i_max_frame_size ) { msg_Dbg( p_dec, "frame too big %d > %d " "(emulated startcode ?)", p_sys->i_frame_size, p_sys->i_max_frame_size ); block_SkipByte( &p_sys->bytestream ); p_sys->i_state = STATE_NOSYNC; p_sys->i_free_frame_size = MPGA_HEADER_SIZE; break; } p_sys->i_frame_size++; break; } msg_Dbg( p_dec, "emulated startcode " "(no startcode on following frame)" ); p_sys->i_state = STATE_NOSYNC; block_SkipByte( &p_sys->bytestream ); break; } p_sys->i_state = STATE_SEND_DATA; break; case STATE_GET_DATA: /* Make sure we have enough data. * (Not useful if we went through NEXT_SYNC) */ if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size ) != VLC_SUCCESS ) { /* Need more data */ return NULL; } p_sys->i_state = STATE_SEND_DATA; case STATE_SEND_DATA: if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) ) { //p_dec->b_error = VLC_TRUE; return NULL; } /* Free bitrate only */ if( p_sys->i_bit_rate == 0 ) { p_sys->i_free_frame_size = p_sys->i_frame_size; } /* Copy the whole frame into the buffer. When we reach this point * we already know we have enough data available. */ block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size ); /* Get beginning of next frame for libmad */ if( !p_sys->b_packetizer ) { memcpy( p_buf + p_sys->i_frame_size, p_header, MAD_BUFFER_GUARD ); } p_sys->i_state = STATE_NOSYNC; /* Make sure we don't reuse the same pts twice */ if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts ) p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0; /* So p_block doesn't get re-added several times */ *pp_block = block_BytestreamPop( &p_sys->bytestream ); return p_out_buffer; } } return NULL;}/***************************************************************************** * GetOutBuffer: *****************************************************************************/static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer ){ decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *p_buf; if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate ) { msg_Dbg( p_dec, "MPGA channels:%d samplerate:%d bitrate:%d", p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate ); aout_DateInit( &p_sys->end_date, p_sys->i_rate ); aout_DateSet( &p_sys->end_date, p_sys->i_pts ); } p_dec->fmt_out.audio.i_rate = p_sys->i_rate; p_dec->fmt_out.audio.i_channels = p_sys->i_channels; p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length; p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_max_frame_size + MAD_BUFFER_GUARD; p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf; p_dec->fmt_out.audio.i_physical_channels = p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK; p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate * 1000; if( p_sys->b_packetizer ) { block_t *p_sout_buffer = GetSoutBuffer( p_dec ); p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL; *pp_out_buffer = p_sout_buffer; } else { aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec ); p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL; *pp_out_buffer = p_aout_buffer; } return p_buf;}/***************************************************************************** * GetAoutBuffer: *****************************************************************************/static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec ){ decoder_sys_t *p_sys = p_dec->p_sys; aout_buffer_t *p_buf; p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length ); if( p_buf == NULL ) return NULL; p_buf->start_date = aout_DateGet( &p_sys->end_date ); p_buf->end_date = aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ); /* Hack for libmad filter */ p_buf->i_nb_bytes = p_sys->i_frame_size + MAD_BUFFER_GUARD; return p_buf;}/***************************************************************************** * GetSoutBuffer: *****************************************************************************/static block_t *GetSoutBuffer( decoder_t *p_dec ){ decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_block; p_block = block_New( p_dec, p_sys->i_frame_size ); if( p_block == NULL ) return NULL; p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date ); p_block->i_length = aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts; return p_block;}/***************************************************************************** * CloseDecoder: clean up the decoder *****************************************************************************/static void CloseDecoder( vlc_object_t *p_this ){ decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys = p_dec->p_sys; block_BytestreamRelease( &p_sys->bytestream ); free( p_sys );}/***************************************************************************** * SyncInfo: parse MPEG audio sync info *****************************************************************************/static int SyncInfo( uint32_t i_header, unsigned int * pi_channels, unsigned int * pi_channels_conf, unsigned int * pi_sample_rate, unsigned int * pi_bit_rate, unsigned int * pi_frame_length, unsigned int * pi_max_frame_size, unsigned int * pi_layer){ static const int ppi_bitrate[2][3][16] = { { /* v1 l1 */ { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0}, /* v1 l2 */ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}, /* v1 l3 */ { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0} }, { /* v2 l1 */ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0}, /* v2 l2 */ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, /* v2 l3 */ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0} } }; static const int ppi_samplerate[2][4] = /* version 1 then 2 */ { { 44100, 48000, 32000, 0 }, { 22050, 24000, 16000, 0 } }; int i_version, i_mode, i_emphasis; vlc_bool_t b_padding, b_mpeg_2_5, b_crc; int i_frame_size = 0; int i_bitrate_index, i_samplerate_index; int i_max_bit_rate; b_mpeg_2_5 = 1 - ((i_header & 0x100000) >> 20); i_version = 1 - ((i_header & 0x80000) >> 19); *pi_layer = 4 - ((i_header & 0x60000) >> 17); b_crc = !((i_header >> 16) & 0x01); i_bitrate_index = (i_header & 0xf000) >> 12; i_samplerate_index = (i_header & 0xc00) >> 10; b_padding = (i_header & 0x200) >> 9; /* Extension */ i_mode = (i_header & 0xc0) >> 6; /* Modeext, copyright & original */ i_emphasis = i_header & 0x3; if( *pi_layer != 4 && i_bitrate_index < 0x0f && i_samplerate_index != 0x03 && i_emphasis != 0x02 ) { switch ( i_mode ) { case 0: /* stereo */ case 1: /* joint stereo */ *pi_channels = 2; *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; break; case 2: /* dual-mono */ *pi_channels = 2; *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_DUALMONO; break; case 3: /* mono */ *pi_channels = 1; *pi_channels_conf = AOUT_CHAN_CENTER; break; } *pi_bit_rate = ppi_bitrate[i_version][*pi_layer-1][i_bitrate_index]; i_max_bit_rate = ppi_bitrate[i_version][*pi_layer-1][14]; *pi_sample_rate = ppi_samplerate[i_version][i_samplerate_index]; if ( b_mpeg_2_5 ) { *pi_sample_rate >>= 1; } switch( *pi_layer ) { case 1: i_frame_size = ( 12000 * *pi_bit_rate / *pi_sample_rate + b_padding ) * 4; *pi_max_frame_size = ( 12000 * i_max_bit_rate / *pi_sample_rate + 1 ) * 4; *pi_frame_length = 384; break; case 2: i_frame_size = 144000 * *pi_bit_rate / *pi_sample_rate + b_padding; *pi_max_frame_size = 144000 * i_max_bit_rate / *pi_sample_rate + 1; *pi_frame_length = 1152; break; case 3: i_frame_size = ( i_version ? 72000 : 144000 ) * *pi_bit_rate / *pi_sample_rate + b_padding; *pi_max_frame_size = ( i_version ? 72000 : 144000 ) * i_max_bit_rate / *pi_sample_rate + 1; *pi_frame_length = i_version ? 576 : 1152; break; default: break; } } else { return -1; } return i_frame_size;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -