libmp4.c

来自「VLC媒体播放程序」· C语言 代码 · 共 2,060 行 · 第 1/5 页

C
2,060
字号
    return( MP4_SeekStream( p_stream, p_box->i_size + p_box->i_pos ) ? 0 : 1 );}/***************************************************************************** * For all known box a loader is given, *  XXX: all common struct have to be already read by MP4_ReadBoxCommon *       after called one of theses functions, file position is unknown *       you need to call MP4_GotoBox to go where you want *****************************************************************************/static int MP4_ReadBoxContainerRaw( MP4_Stream_t *p_stream, MP4_Box_t *p_container ){    MP4_Box_t *p_box;    if( MP4_TellStream( p_stream ) + 8 >                 (off_t)(p_container->i_pos + p_container->i_size) )    {        /* there is no box to load */        return( 0 );    }    do    {        if( ( p_box = MP4_ReadBox( p_stream, p_container ) ) == NULL )        {            break;        }        /* chain this box with the father and the other at same level */        if( !p_container->p_first )        {            p_container->p_first = p_box;        }        else        {            p_container->p_last->p_next = p_box;        }        p_container->p_last = p_box;    } while( MP4_NextBox( p_stream, p_box ) == 1 );    return( 1 );}static int MP4_ReadBoxContainer( MP4_Stream_t *p_stream, MP4_Box_t *p_container ){    if( p_container->i_size <= (size_t)MP4_BOX_HEADERSIZE(p_container ) + 8 )    {        /* container is empty, 8 stand for the first header in this box */        return( 1 );    }    /* enter box */    MP4_SeekStream( p_stream, p_container->i_pos + MP4_BOX_HEADERSIZE( p_container ) );    return( MP4_ReadBoxContainerRaw( p_stream, p_container ) );}static void MP4_FreeBox_Common( MP4_Box_t *p_box ){    /* Up to now do nothing */}static int MP4_ReadBoxSkip( MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    /* XXX sometime moov is hiden in a free box */    if( p_box->p_father && p_box->p_father->i_type == VLC_FOURCC( 'r', 'o', 'o', 't' )&&        p_box->i_type == FOURCC_free )    {        uint8_t *p_peek;        int     i_read;        vlc_fourcc_t i_fcc;        i_read  = MP4_PeekStream( p_stream, &p_peek, 44 );        p_peek += MP4_BOX_HEADERSIZE( p_box ) + 4;        i_read -= MP4_BOX_HEADERSIZE( p_box ) + 4;        if( i_read >= 8 )        {            i_fcc = VLC_FOURCC( p_peek[0], p_peek[1], p_peek[2], p_peek[3] );            if( i_fcc == FOURCC_cmov || i_fcc == FOURCC_mvhd )            {                msg_Warn( p_stream->p_input, "detected moov hidden in a free box ..." );                p_box->i_type = FOURCC_foov;                return MP4_ReadBoxContainer( p_stream, p_box );            }        }    }    /* Nothing to do */#ifdef MP4_VERBOSE    msg_Dbg( p_stream->p_input, "skip box: \"%4.4s\"",            (char*)&p_box->i_type );#endif    return( 1 );}static int MP4_ReadBox_ftyp( MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    MP4_READBOX_ENTER( MP4_Box_data_ftyp_t );    MP4_GETFOURCC( p_box->data.p_ftyp->i_major_brand );    MP4_GET4BYTES( p_box->data.p_ftyp->i_minor_version );    if( ( p_box->data.p_ftyp->i_compatible_brands_count = i_read / 4 ) )    {        unsigned int i;        p_box->data.p_ftyp->i_compatible_brands =            calloc( p_box->data.p_ftyp->i_compatible_brands_count, sizeof(uint32_t));        for( i =0; i < p_box->data.p_ftyp->i_compatible_brands_count; i++ )        {            MP4_GETFOURCC( p_box->data.p_ftyp->i_compatible_brands[i] );        }    }    else    {        p_box->data.p_ftyp->i_compatible_brands = NULL;    }    MP4_READBOX_EXIT( 1 );}static void MP4_FreeBox_ftyp( MP4_Box_t *p_box ){    FREE( p_box->data.p_ftyp->i_compatible_brands );}static int MP4_ReadBox_mvhd(  MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    unsigned int i;#ifdef MP4_VERBOSE    char s_creation_time[128];    char s_modification_time[128];    char s_duration[128];#endif    MP4_READBOX_ENTER( MP4_Box_data_mvhd_t );    MP4_GETVERSIONFLAGS( p_box->data.p_mvhd );    if( p_box->data.p_mvhd->i_version )    {        MP4_GET8BYTES( p_box->data.p_mvhd->i_creation_time );        MP4_GET8BYTES( p_box->data.p_mvhd->i_modification_time );        MP4_GET4BYTES( p_box->data.p_mvhd->i_timescale );        MP4_GET8BYTES( p_box->data.p_mvhd->i_duration );    }    else    {        MP4_GET4BYTES( p_box->data.p_mvhd->i_creation_time );        MP4_GET4BYTES( p_box->data.p_mvhd->i_modification_time );        MP4_GET4BYTES( p_box->data.p_mvhd->i_timescale );        MP4_GET4BYTES( p_box->data.p_mvhd->i_duration );    }    MP4_GET4BYTES( p_box->data.p_mvhd->i_rate );    MP4_GET2BYTES( p_box->data.p_mvhd->i_volume );    MP4_GET2BYTES( p_box->data.p_mvhd->i_reserved1 );    for( i = 0; i < 2; i++ )    {        MP4_GET4BYTES( p_box->data.p_mvhd->i_reserved2[i] );    }    for( i = 0; i < 9; i++ )    {        MP4_GET4BYTES( p_box->data.p_mvhd->i_matrix[i] );    }    for( i = 0; i < 6; i++ )    {        MP4_GET4BYTES( p_box->data.p_mvhd->i_predefined[i] );    }    MP4_GET4BYTES( p_box->data.p_mvhd->i_next_track_id );#ifdef MP4_VERBOSE    MP4_ConvertDate2Str( s_creation_time, p_box->data.p_mvhd->i_creation_time );    MP4_ConvertDate2Str( s_modification_time,                         p_box->data.p_mvhd->i_modification_time );    if( p_box->data.p_mvhd->i_rate )    {        MP4_ConvertDate2Str( s_duration,                 p_box->data.p_mvhd->i_duration / p_box->data.p_mvhd->i_rate );    }    else    {        s_duration[0] = 0;    }    msg_Dbg( p_stream->p_input, "read box: \"mvhd\" creation %s modification %s time scale %d duration %s rate %f volume %f next track id %d",                  s_creation_time,                  s_modification_time,                  (uint32_t)p_box->data.p_mvhd->i_timescale,                  s_duration,                  (float)p_box->data.p_mvhd->i_rate / (1<<16 ),                  (float)p_box->data.p_mvhd->i_volume / 256 ,                  (uint32_t)p_box->data.p_mvhd->i_next_track_id );#endif    MP4_READBOX_EXIT( 1 );}static int MP4_ReadBox_tkhd(  MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    unsigned int i;#ifdef MP4_VERBOSE    char s_creation_time[128];    char s_modification_time[128];    char s_duration[128];#endif    MP4_READBOX_ENTER( MP4_Box_data_tkhd_t );    MP4_GETVERSIONFLAGS( p_box->data.p_tkhd );    if( p_box->data.p_tkhd->i_version )    {        MP4_GET8BYTES( p_box->data.p_tkhd->i_creation_time );        MP4_GET8BYTES( p_box->data.p_tkhd->i_modification_time );        MP4_GET4BYTES( p_box->data.p_tkhd->i_track_ID );        MP4_GET4BYTES( p_box->data.p_tkhd->i_reserved );        MP4_GET8BYTES( p_box->data.p_tkhd->i_duration );    }    else    {        MP4_GET4BYTES( p_box->data.p_tkhd->i_creation_time );        MP4_GET4BYTES( p_box->data.p_tkhd->i_modification_time );        MP4_GET4BYTES( p_box->data.p_tkhd->i_track_ID );        MP4_GET4BYTES( p_box->data.p_tkhd->i_reserved );        MP4_GET4BYTES( p_box->data.p_tkhd->i_duration );    }    for( i = 0; i < 2; i++ )    {        MP4_GET4BYTES( p_box->data.p_tkhd->i_reserved2[i] );    }    MP4_GET2BYTES( p_box->data.p_tkhd->i_layer );    MP4_GET2BYTES( p_box->data.p_tkhd->i_predefined );    MP4_GET2BYTES( p_box->data.p_tkhd->i_volume );    MP4_GET2BYTES( p_box->data.p_tkhd->i_reserved3 );    for( i = 0; i < 9; i++ )    {        MP4_GET4BYTES( p_box->data.p_tkhd->i_matrix[i] );    }    MP4_GET4BYTES( p_box->data.p_tkhd->i_width );    MP4_GET4BYTES( p_box->data.p_tkhd->i_height );#ifdef MP4_VERBOSE    MP4_ConvertDate2Str( s_creation_time, p_box->data.p_mvhd->i_creation_time );    MP4_ConvertDate2Str( s_modification_time, p_box->data.p_mvhd->i_modification_time );    MP4_ConvertDate2Str( s_duration, p_box->data.p_mvhd->i_duration );    msg_Dbg( p_stream->p_input, "read box: \"tkhd\" creation %s modification %s duration %s track ID %d layer %d volume %f width %f height %f",                  s_creation_time,                  s_modification_time,                  s_duration,                  p_box->data.p_tkhd->i_track_ID,                  p_box->data.p_tkhd->i_layer,                  (float)p_box->data.p_tkhd->i_volume / 256 ,                  (float)p_box->data.p_tkhd->i_width / 65536,                  (float)p_box->data.p_tkhd->i_height / 65536 );#endif    MP4_READBOX_EXIT( 1 );}static int MP4_ReadBox_mdhd( MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    unsigned int i;    uint16_t i_language;#ifdef MP4_VERBOSE    char s_creation_time[128];    char s_modification_time[128];    char s_duration[128];#endif    MP4_READBOX_ENTER( MP4_Box_data_mdhd_t );    MP4_GETVERSIONFLAGS( p_box->data.p_mdhd );    if( p_box->data.p_mdhd->i_version )    {        MP4_GET8BYTES( p_box->data.p_mdhd->i_creation_time );        MP4_GET8BYTES( p_box->data.p_mdhd->i_modification_time );        MP4_GET4BYTES( p_box->data.p_mdhd->i_timescale );        MP4_GET8BYTES( p_box->data.p_mdhd->i_duration );    }    else    {        MP4_GET4BYTES( p_box->data.p_mdhd->i_creation_time );        MP4_GET4BYTES( p_box->data.p_mdhd->i_modification_time );        MP4_GET4BYTES( p_box->data.p_mdhd->i_timescale );        MP4_GET4BYTES( p_box->data.p_mdhd->i_duration );    }    i_language = GetWBE( p_peek );    for( i = 0; i < 3; i++ )    {        p_box->data.p_mdhd->i_language[i] =                    ( ( i_language >> ( (2-i)*5 ) )&0x1f ) + 0x60;    }    MP4_GET2BYTES( p_box->data.p_mdhd->i_predefined );#ifdef MP4_VERBOSE    MP4_ConvertDate2Str( s_creation_time, p_box->data.p_mdhd->i_creation_time );    MP4_ConvertDate2Str( s_modification_time, p_box->data.p_mdhd->i_modification_time );    MP4_ConvertDate2Str( s_duration, p_box->data.p_mdhd->i_duration );    msg_Dbg( p_stream->p_input, "read box: \"mdhd\" creation %s modification %s time scale %d duration %s language %c%c%c",                  s_creation_time,                  s_modification_time,                  (uint32_t)p_box->data.p_mdhd->i_timescale,                  s_duration,                  p_box->data.p_mdhd->i_language[0],                  p_box->data.p_mdhd->i_language[1],                  p_box->data.p_mdhd->i_language[2] );#endif    MP4_READBOX_EXIT( 1 );}static int MP4_ReadBox_hdlr( MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    MP4_READBOX_ENTER( MP4_Box_data_hdlr_t );    MP4_GETVERSIONFLAGS( p_box->data.p_hdlr );    MP4_GET4BYTES( p_box->data.p_hdlr->i_predefined );    MP4_GETFOURCC( p_box->data.p_hdlr->i_handler_type );    p_box->data.p_hdlr->psz_name = calloc( sizeof( char ), i_read + 1 );    memcpy( p_box->data.p_hdlr->psz_name, p_peek, i_read );#ifdef MP4_VERBOSE    msg_Dbg( p_stream->p_input, "read box: \"hdlr\" hanler type %4.4s name %s",                       (char*)&p_box->data.p_hdlr->i_handler_type,                       p_box->data.p_hdlr->psz_name );#endif    MP4_READBOX_EXIT( 1 );}static void MP4_FreeBox_hdlr( MP4_Box_t *p_box ){    FREE( p_box->data.p_hdlr->psz_name );}static int MP4_ReadBox_vmhd( MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    unsigned int i;    MP4_READBOX_ENTER( MP4_Box_data_vmhd_t );    MP4_GETVERSIONFLAGS( p_box->data.p_vmhd );    MP4_GET2BYTES( p_box->data.p_vmhd->i_graphics_mode );    for( i = 0; i < 3; i++ )    {        MP4_GET2BYTES( p_box->data.p_vmhd->i_opcolor[i] );    }#ifdef MP4_VERBOSE    msg_Dbg( p_stream->p_input, "read box: \"vmhd\" graphics-mode %d opcolor (%d, %d, %d)",                      p_box->data.p_vmhd->i_graphics_mode,                      p_box->data.p_vmhd->i_opcolor[0],                      p_box->data.p_vmhd->i_opcolor[1],                      p_box->data.p_vmhd->i_opcolor[2] );#endif    MP4_READBOX_EXIT( 1 );}static int MP4_ReadBox_smhd( MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    MP4_READBOX_ENTER( MP4_Box_data_smhd_t );    MP4_GETVERSIONFLAGS( p_box->data.p_smhd );    MP4_GET2BYTES( p_box->data.p_smhd->i_balance );    MP4_GET2BYTES( p_box->data.p_smhd->i_reserved );#ifdef MP4_VERBOSE    msg_Dbg( p_stream->p_input, "read box: \"smhd\" balance %f",                      (float)p_box->data.p_smhd->i_balance / 256 );#endif    MP4_READBOX_EXIT( 1 );}static int MP4_ReadBox_hmhd( MP4_Stream_t *p_stream, MP4_Box_t *p_box ){    MP4_READBOX_ENTER( MP4_Box_data_hmhd_t );    MP4_GETVERSIONFLAGS( p_box->data.p_hmhd );    MP4_GET2BYTES( p_box->data.p_hmhd->i_max_PDU_size );    MP4_GET2BYTES( p_box->data.p_hmhd->i_avg_PDU_size );    MP4_GET4BYTES( p_box->data.p_hmhd->i_max_bitrate );    MP4_GET4BYTES( p_box->data.p_hmhd->i_avg_bitrate );    MP4_GET4BYTES( p_box->data.p_hmhd->i_reserved );#ifdef MP4_VERBOSE    msg_Dbg( p_stream->p_input, "read box: \"hmhd\" maxPDU-size %d avgPDU-size %d max-bitrate %d avg-bitrate %d",                      p_box->data.p_hmhd->i_max_PDU_size,                      p_box->data.p_hmhd->i_avg_PDU_size,                      p_box->data.p_hmhd->i_max_bitrate,                      p_box->data.p_hmhd->i_avg_bitrate );#endif    MP4_READBOX_EXIT( 1 );}

⌨️ 快捷键说明

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