⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg_audio.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
                    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 + -