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

📄 libmp4.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
static int MP4_ReadLengthDescriptor( uint8_t **pp_peek, int64_t  *i_read ){    unsigned int i_b;    unsigned int i_len = 0;    do    {        i_b = **pp_peek;        (*pp_peek)++;        (*i_read)--;        i_len = ( i_len << 7 ) + ( i_b&0x7f );    } while( i_b&0x80 );    return( i_len );}static void MP4_FreeBox_esds( MP4_Box_t *p_box ){    FREENULL( p_box->data.p_esds->es_descriptor.psz_URL );    if( p_box->data.p_esds->es_descriptor.p_decConfigDescr )    {        FREENULL( p_box->data.p_esds->es_descriptor.p_decConfigDescr->p_decoder_specific_info );        FREENULL( p_box->data.p_esds->es_descriptor.p_decConfigDescr );    }}static int MP4_ReadBox_esds( stream_t *p_stream, MP4_Box_t *p_box ){#define es_descriptor p_box->data.p_esds->es_descriptor    unsigned int i_len;    unsigned int i_flags;    unsigned int i_type;    MP4_READBOX_ENTER( MP4_Box_data_esds_t );    MP4_GETVERSIONFLAGS( p_box->data.p_esds );    MP4_GET1BYTE( i_type );    if( i_type == 0x03 ) /* MP4ESDescrTag */    {        i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );#ifdef MP4_VERBOSE        msg_Dbg( p_stream, "found esds MPEG4ESDescr (%dBytes)",                 i_len );#endif        MP4_GET2BYTES( es_descriptor.i_ES_ID );        MP4_GET1BYTE( i_flags );        es_descriptor.b_stream_dependence = ( (i_flags&0x80) != 0);        es_descriptor.b_url = ( (i_flags&0x40) != 0);        es_descriptor.b_OCRstream = ( (i_flags&0x20) != 0);        es_descriptor.i_stream_priority = i_flags&0x1f;        if( es_descriptor.b_stream_dependence )        {            MP4_GET2BYTES( es_descriptor.i_depend_on_ES_ID );        }        if( es_descriptor.b_url )        {            unsigned int i_len;            MP4_GET1BYTE( i_len );            es_descriptor.psz_URL = malloc( i_len + 1 );            if( es_descriptor.psz_URL )            {                memcpy( es_descriptor.psz_URL, p_peek, i_len );                es_descriptor.psz_URL[i_len] = 0;            }            p_peek += i_len;            i_read -= i_len;        }        else        {            es_descriptor.psz_URL = NULL;        }        if( es_descriptor.b_OCRstream )        {            MP4_GET2BYTES( es_descriptor.i_OCR_ES_ID );        }        MP4_GET1BYTE( i_type ); /* get next type */    }    if( i_type != 0x04)/* MP4DecConfigDescrTag */    {         es_descriptor.p_decConfigDescr = NULL;         MP4_READBOX_EXIT( 1 ); /* rest isn't interesting up to now */    }    i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );#ifdef MP4_VERBOSE        msg_Dbg( p_stream, "found esds MP4DecConfigDescr (%dBytes)",                 i_len );#endif    es_descriptor.p_decConfigDescr =            calloc( 1, sizeof( MP4_descriptor_decoder_config_t ));    if( es_descriptor.p_decConfigDescr == NULL )        MP4_READBOX_EXIT( 0 );    MP4_GET1BYTE( es_descriptor.p_decConfigDescr->i_objectTypeIndication );    MP4_GET1BYTE( i_flags );    es_descriptor.p_decConfigDescr->i_streamType = i_flags >> 2;    es_descriptor.p_decConfigDescr->b_upStream = ( i_flags >> 1 )&0x01;    MP4_GET3BYTES( es_descriptor.p_decConfigDescr->i_buffer_sizeDB );    MP4_GET4BYTES( es_descriptor.p_decConfigDescr->i_max_bitrate );    MP4_GET4BYTES( es_descriptor.p_decConfigDescr->i_avg_bitrate );    MP4_GET1BYTE( i_type );    if( i_type !=  0x05 )/* MP4DecSpecificDescrTag */    {        es_descriptor.p_decConfigDescr->i_decoder_specific_info_len = 0;        es_descriptor.p_decConfigDescr->p_decoder_specific_info  = NULL;        MP4_READBOX_EXIT( 1 );    }    i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );#ifdef MP4_VERBOSE        msg_Dbg( p_stream, "found esds MP4DecSpecificDescr (%dBytes)",                 i_len );#endif    if( i_len > i_read )        MP4_READBOX_EXIT( 0 );    es_descriptor.p_decConfigDescr->i_decoder_specific_info_len = i_len;    es_descriptor.p_decConfigDescr->p_decoder_specific_info = malloc( i_len );    if( es_descriptor.p_decConfigDescr->p_decoder_specific_info == NULL )        MP4_READBOX_EXIT( 0 );    memcpy( es_descriptor.p_decConfigDescr->p_decoder_specific_info,            p_peek, i_len );    MP4_READBOX_EXIT( 1 );#undef es_descriptor}static void MP4_FreeBox_avcC( MP4_Box_t *p_box ){    MP4_Box_data_avcC_t *p_avcC = p_box->data.p_avcC;    int i;    if( p_avcC->i_avcC > 0 ) FREENULL( p_avcC->p_avcC );    if( p_avcC->sps )    {        for( i = 0; i < p_avcC->i_sps; i++ )            FREENULL( p_avcC->sps[i] );    }    if( p_avcC->pps )    {        for( i = 0; i < p_avcC->i_pps; i++ )            FREENULL( p_avcC->pps[i] );    }    if( p_avcC->i_sps > 0 ) FREENULL( p_avcC->sps );    if( p_avcC->i_sps > 0 ) FREENULL( p_avcC->i_sps_length );    if( p_avcC->i_pps > 0 ) FREENULL( p_avcC->pps );    if( p_avcC->i_pps > 0 ) FREENULL( p_avcC->i_pps_length );}static int MP4_ReadBox_avcC( stream_t *p_stream, MP4_Box_t *p_box ){    MP4_Box_data_avcC_t *p_avcC;    int i;    MP4_READBOX_ENTER( MP4_Box_data_avcC_t );    p_avcC = p_box->data.p_avcC;    p_avcC->i_avcC = i_read;    if( p_avcC->i_avcC > 0 )    {        uint8_t * p = p_avcC->p_avcC = malloc( p_avcC->i_avcC );        if( p )            memcpy( p, p_peek, i_read );    }    MP4_GET1BYTE( p_avcC->i_version );    MP4_GET1BYTE( p_avcC->i_profile );    MP4_GET1BYTE( p_avcC->i_profile_compatibility );    MP4_GET1BYTE( p_avcC->i_level );    MP4_GET1BYTE( p_avcC->i_reserved1 );    p_avcC->i_length_size = (p_avcC->i_reserved1&0x03) + 1;    p_avcC->i_reserved1 >>= 2;    MP4_GET1BYTE( p_avcC->i_reserved2 );    p_avcC->i_sps = p_avcC->i_reserved2&0x1f;    p_avcC->i_reserved2 >>= 5;    if( p_avcC->i_sps > 0 )    {        p_avcC->i_sps_length = calloc( p_avcC->i_sps, sizeof( uint16_t ) );        p_avcC->sps = calloc( p_avcC->i_sps, sizeof( uint8_t* ) );        if( !p_avcC->i_sps_length || !p_avcC->sps )            goto error;        for( i = 0; i < p_avcC->i_sps; i++ )        {            MP4_GET2BYTES( p_avcC->i_sps_length[i] );            p_avcC->sps[i] = malloc( p_avcC->i_sps_length[i] );            if( p_avcC->sps[i] )                memcpy( p_avcC->sps[i], p_peek, p_avcC->i_sps_length[i] );            p_peek += p_avcC->i_sps_length[i];            i_read -= p_avcC->i_sps_length[i];        }    }    MP4_GET1BYTE( p_avcC->i_pps );    if( p_avcC->i_pps > 0 )    {        p_avcC->i_pps_length = calloc( p_avcC->i_pps, sizeof( uint16_t ) );        p_avcC->pps = calloc( p_avcC->i_pps, sizeof( uint8_t* ) );        if( !p_avcC->i_pps_length || !p_avcC->pps )            goto error;        for( i = 0; i < p_avcC->i_pps; i++ )        {            MP4_GET2BYTES( p_avcC->i_pps_length[i] );            p_avcC->pps[i] = malloc( p_avcC->i_pps_length[i] );            if( p_avcC->pps[i] )                memcpy( p_avcC->pps[i], p_peek, p_avcC->i_pps_length[i] );            p_peek += p_avcC->i_pps_length[i];            i_read -= p_avcC->i_pps_length[i];        }    }#ifdef MP4_VERBOSE    msg_Dbg( p_stream,             "read box: \"avcC\" version=%d profile=0x%x level=0x%x length size=%d sps=%d pps=%d",             p_avcC->i_version, p_avcC->i_profile, p_avcC->i_level,             p_avcC->i_length_size,             p_avcC->i_sps, p_avcC->i_pps );    for( i = 0; i < p_avcC->i_sps; i++ )    {        msg_Dbg( p_stream, "         - sps[%d] length=%d",                 i, p_avcC->i_sps_length[i] );    }    for( i = 0; i < p_avcC->i_pps; i++ )    {        msg_Dbg( p_stream, "         - pps[%d] length=%d",                 i, p_avcC->i_pps_length[i] );    }#endif    MP4_READBOX_EXIT( 1 );error:    MP4_READBOX_EXIT( 0 );}static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box ){    unsigned int i;    MP4_READBOX_ENTER( MP4_Box_data_sample_soun_t );    p_box->data.p_sample_soun->p_qt_description = NULL;    /* Sanity check needed because the "wave" box does also contain an     * "mp4a" box that we don't understand. */    if( i_read < 28 )    {        i_read -= 30;        MP4_READBOX_EXIT( 1 );    }    for( i = 0; i < 6 ; i++ )    {        MP4_GET1BYTE( p_box->data.p_sample_soun->i_reserved1[i] );    }    MP4_GET2BYTES( p_box->data.p_sample_soun->i_data_reference_index );    /*     * XXX hack -> produce a copy of the nearly complete chunk     */    p_box->data.p_sample_soun->i_qt_description = 0;    p_box->data.p_sample_soun->p_qt_description = NULL;    if( i_read > 0 )    {        p_box->data.p_sample_soun->p_qt_description = malloc( i_read );        if( p_box->data.p_sample_soun->p_qt_description )        {            p_box->data.p_sample_soun->i_qt_description = i_read;            memcpy( p_box->data.p_sample_soun->p_qt_description, p_peek, i_read );        }    }    MP4_GET2BYTES( p_box->data.p_sample_soun->i_qt_version );    MP4_GET2BYTES( p_box->data.p_sample_soun->i_qt_revision_level );    MP4_GET4BYTES( p_box->data.p_sample_soun->i_qt_vendor );    MP4_GET2BYTES( p_box->data.p_sample_soun->i_channelcount );    MP4_GET2BYTES( p_box->data.p_sample_soun->i_samplesize );    MP4_GET2BYTES( p_box->data.p_sample_soun->i_predefined );    MP4_GET2BYTES( p_box->data.p_sample_soun->i_reserved3 );    MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratehi );    MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratelo );    if( p_box->data.p_sample_soun->i_qt_version == 1 && i_read >= 16 )    {        /* SoundDescriptionV1 */        MP4_GET4BYTES( p_box->data.p_sample_soun->i_sample_per_packet );        MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_packet );        MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_frame );        MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_sample );#ifdef MP4_VERBOSE        msg_Dbg( p_stream,                 "read box: \"soun\" qt3+ sample/packet=%d bytes/packet=%d "                 "bytes/frame=%d bytes/sample=%d",                 p_box->data.p_sample_soun->i_sample_per_packet,                 p_box->data.p_sample_soun->i_bytes_per_packet,                 p_box->data.p_sample_soun->i_bytes_per_frame,                 p_box->data.p_sample_soun->i_bytes_per_sample );#endif        stream_Seek( p_stream, p_box->i_pos +                        MP4_BOX_HEADERSIZE( p_box ) + 44 );    }    else if( p_box->data.p_sample_soun->i_qt_version == 2 && i_read >= 36 )    {        /* SoundDescriptionV2 */        double f_sample_rate;        int64_t dummy;        uint32_t i_channel;        MP4_GET4BYTES( p_box->data.p_sample_soun->i_sample_per_packet );        MP4_GET8BYTES( dummy );        memcpy( &f_sample_rate, &dummy, 8 );        msg_Dbg( p_stream, "read box: %f Hz", f_sample_rate );        p_box->data.p_sample_soun->i_sampleratehi = (int)f_sample_rate % 65536;        p_box->data.p_sample_soun->i_sampleratelo = f_sample_rate / 65536;        MP4_GET4BYTES( i_channel );        p_box->data.p_sample_soun->i_channelcount = i_channel;#ifdef MP4_VERBOSE        msg_Dbg( p_stream, "read box: \"soun\" V2" );#endif        stream_Seek( p_stream, p_box->i_pos +                        MP4_BOX_HEADERSIZE( p_box ) + 28 + 36 );    }    else    {        p_box->data.p_sample_soun->i_sample_per_packet = 0;        p_box->data.p_sample_soun->i_bytes_per_packet = 0;        p_box->data.p_sample_soun->i_bytes_per_frame = 0;        p_box->data.p_sample_soun->i_bytes_per_sample = 0;        msg_Dbg( p_stream, "read box: \"soun\" mp4 or qt1/2 (rest=%"PRId64")",                 i_read );        stream_Seek( p_stream, p_box->i_pos +                        MP4_BOX_HEADERSIZE( p_box ) + 28 );    }    if( p_box->i_type == FOURCC_drms )    {        p_box->data.p_sample_soun->p_drms =            drms_alloc( config_GetHomeDir() );        if( p_box->data.p_sample_soun->p_drms == NULL )        {            msg_Err( p_stream, "drms_alloc() failed" );        }    }    if( p_box->i_type == FOURCC_samr || p_box->i_type == FOURCC_sawb )    {        /* Ignore channelcount for AMR (3gpp AMRSpecificBox) */        p_box->data.p_sample_soun->i_channelcount = 1;    }    MP4_ReadBoxContainerRaw( p_stream, p_box ); /* esds/wave/... */#ifdef MP4_VERBOSE    msg_Dbg( p_stream, "read box: \"soun\" in stsd channel %d "             "sample size %d sample rate %f",             p_box->data.p_sample_soun->i_channelcount,             p_box->data.p_sample_soun->i_samplesize,             (float)p_box->data.p_sample_soun->i_sampleratehi +             (float)p_box->data.p_sample_soun->i_sampleratelo / 65536 );#endif    MP4_READBOX_EXIT( 1 );}static void MP4_FreeBox_sample_soun( MP4_Box_t *p_box ){    FREENULL( p_box->data.p_sample_soun->p_qt_description );    if( p_box->i_type == FOURCC_drms )    {        if( p_box->data.p_sample_soun->p_drms )        {            drms_free( p_box->data.p_sample_soun->p_drms );        }    }}int MP4_ReadBox_sample_vide( stream_t *p_stream, MP4_Box_t *p_box ){    unsigned int i;    MP4_READBOX_ENTER( MP4_Box_data_sample_vide_t );    for( i = 0; i < 6 ; i++ )    {        MP4_GET1BYTE( p_box->data.p_sample_vide->i_reserved1[i] );    }    MP4_GET2BYTES( p_box->data.p_sample_vide->i_data_reference_index );    /*     * XXX hack -> produce a copy of the nearly complete chunk     */    if( i_read > 0 )    {        p_box->data.p_sample_vide->p_qt_image_description = malloc( i_read );        if( p_box->data.p_sample_vide->p_qt_image_description == NULL )            MP4_READBOX_EXIT( 0 );        p_box->data.p_sample_vide->i_qt_image_description = i_read;        memcpy( p_box->data.p_sample_vide->p_qt_image_description,                p_peek, i_read );    }    else

⌨️ 快捷键说明

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