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

📄 mpeg4audio.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
    if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )    {        /* We've just started the stream, wait for the first PTS. */        block_Release( *pp_block );        return NULL;    }    if( (*pp_block)->i_flags&BLOCK_FLAG_DISCONTINUITY )    {        p_sys->i_state = STATE_NOSYNC;    }    block_BytestreamPush( &p_sys->bytestream, *pp_block );    while( 1 )    {        switch( p_sys->i_state )        {        case STATE_NOSYNC:            while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )                   == VLC_SUCCESS )            {                /* Look for sync word - should be 0xfff + 2 layer bits */                if( p_header[0] == 0xff && (p_header[1] & 0xf6) == 0xf0 )                {                    p_sys->i_state = STATE_SYNC;                    break;                }                block_SkipByte( &p_sys->bytestream );            }            if( p_sys->i_state != STATE_SYNC )            {                block_BytestreamFlush( &p_sys->bytestream );                /* Need more data */                return NULL;            }        case STATE_SYNC:            /* New frame, set the Presentation Time Stamp */            p_sys->i_pts = p_sys->bytestream.p_block->i_pts;            if( p_sys->i_pts != 0 &&                p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )            {                aout_DateSet( &p_sys->end_date, p_sys->i_pts );            }            p_sys->i_state = STATE_HEADER;            break;        case STATE_HEADER:            /* Get ADTS frame header (ADTS_HEADER_SIZE bytes) */            if( block_PeekBytes( &p_sys->bytestream, p_header,                                 ADTS_HEADER_SIZE ) != VLC_SUCCESS )            {                /* Need more data */                return NULL;            }            /* Check if frame is valid and get frame info */            p_sys->i_frame_size = ADTSSyncInfo( p_dec, p_header,                                                &p_sys->i_channels,                                                &p_sys->i_rate,                                                &p_sys->i_frame_length,                                                &p_sys->i_header_size,                                                &p_sys->i_raw_blocks );            if( p_sys->i_frame_size <= 0 )            {                msg_Dbg( p_dec, "emulated sync word" );                block_SkipByte( &p_sys->bytestream );                p_sys->i_state = STATE_NOSYNC;                break;            }            p_sys->i_state = STATE_NEXT_SYNC;        case STATE_NEXT_SYNC:            /* TODO: If p_block == NULL, flush the buffer without checking the             * next sync word */            /* Check if next expected frame contains the sync word */            if( block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_frame_size                                       + p_sys->i_header_size, p_header, 2 )                != VLC_SUCCESS )            {                /* Need more data */                return NULL;            }            if( p_header[0] != 0xff || (p_header[1] & 0xf6) != 0xf0 )            {                msg_Dbg( p_dec, "emulated sync word "                         "(no sync 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 +                                 p_sys->i_header_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;            }            /* When we reach this point we already know we have enough             * data available. */            /* Skip the ADTS header */            block_SkipBytes( &p_sys->bytestream, p_sys->i_header_size );            /* Copy the whole frame into the buffer */            block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );            /* 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 );            p_sys->i_state = STATE_NOSYNC;            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;    block_t *p_block;    if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )    {        msg_Info( p_dec, "AAC channels: %d samplerate: %d",                  p_sys->i_channels, p_sys->i_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_bytes_per_frame = p_sys->i_frame_size;    p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;#if 0    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;#endif    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;    *pp_out_buffer = p_block;    return p_block->p_buffer;}/***************************************************************************** * ClosePacketizer: clean up the packetizer *****************************************************************************/static void ClosePacketizer( 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_dec->p_sys );}/***************************************************************************** * ADTSSyncInfo: parse MPEG 4 audio ADTS sync info *****************************************************************************/static int ADTSSyncInfo( decoder_t * p_dec, const byte_t * p_buf,                         unsigned int * pi_channels,                         unsigned int * pi_sample_rate,                         unsigned int * pi_frame_length,                         unsigned int * pi_header_size,                         unsigned int * pi_raw_blocks_in_frame ){    int i_id, i_profile, i_sample_rate_idx, i_frame_size;    vlc_bool_t b_crc;    /* Fixed header between frames */    i_id = ( (p_buf[1] >> 3) & 0x01 ) ? 2 : 4;    b_crc = !(p_buf[1] & 0x01);    i_profile = p_buf[2] >> 6;    i_sample_rate_idx = (p_buf[2] >> 2) & 0x0f;    *pi_sample_rate = i_sample_rates[i_sample_rate_idx];    *pi_channels = ((p_buf[2] & 0x01) << 2) | ((p_buf[3] >> 6) & 0x03);    /* Variable header */    i_frame_size = ((p_buf[3] & 0x03) << 11) | (p_buf[4] << 3) |                   ((p_buf[5] >> 5) & 0x7);    *pi_raw_blocks_in_frame = (p_buf[6] & 0x02) + 1;    if( !*pi_sample_rate || !*pi_channels || !i_frame_size )    {        return 0;    }    /* Fixme */    *pi_frame_length = 1024;    /* Build the decoder specific info header */    if( !p_dec->fmt_out.i_extra )    {        p_dec->fmt_out.i_extra = 2;        p_dec->fmt_out.p_extra = malloc( 2 );        ((uint8_t *)p_dec->fmt_out.p_extra)[0] =            (i_profile + 1) << 3 | (i_sample_rate_idx >> 1);        ((uint8_t *)p_dec->fmt_out.p_extra)[1] =            ((i_sample_rate_idx & 0x01) << 7) | (*pi_channels <<3);    }    /* ADTS header length */    *pi_header_size = b_crc ? 9 : 7;    return i_frame_size - *pi_header_size;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -