libasf.c

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

C
852
字号
            for( i = 0; i < i_len; i++ )            {                codec.psz_name[i] = GetWLE( p_data + 2*i );            }            codec.psz_name[i_len] = '\0';            p_data += 2 * i_len;            /* description */            i_len = GetWLE( p_data ); p_data += 2;            codec.psz_description = calloc( sizeof( char ), i_len + 1);            for( i = 0; i < i_len; i++ )            {                codec.psz_description[i] = GetWLE( p_data + 2*i );            }            codec.psz_description[i_len] = '\0';            p_data += 2 * i_len;            /* opaque information */            codec.i_information_length = GetWLE( p_data ); p_data += 2;            if( codec.i_information_length > 0 )            {                codec.p_information = malloc( codec.i_information_length );                memcpy( codec.p_information, p_data, codec.i_information_length );                p_data += codec.i_information_length;            }            else            {                codec.p_information = NULL;            }#undef  codec        }    }    else    {        p_cl->codec = NULL;    }#ifdef ASF_DEBUG    msg_Dbg( (vlc_object_t*)s,            "read \"codec list object\" reserved_guid:" GUID_FMT " codec_entries_count:%d",            GUID_PRINT( p_cl->i_reserved ),            p_cl->i_codec_entries_count );    for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ )    {#define codec p_cl->codec[i_codec]        msg_Dbg( (vlc_object_t*)s,                 "read \"codec list object\" codec[%d] %s name:\"%s\" description:\"%s\" information_length:%d",                 i_codec,                 ( codec.i_type == ASF_CODEC_TYPE_VIDEO ) ? "video" : ( ( codec.i_type == ASF_CODEC_TYPE_AUDIO ) ? "audio" : "unknown" ),                 codec.psz_name,                 codec.psz_description,                 codec.i_information_length );    }#endif    return VLC_SUCCESS;}static void ASF_FreeObject_codec_list( asf_object_t *p_obj ){    asf_object_codec_list_t *p_cl = (asf_object_codec_list_t*)p_obj;    unsigned int i_codec;    for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ )    {#define codec p_cl->codec[i_codec]        FREE( codec.psz_name );        FREE( codec.psz_description );        FREE( codec.p_information );#undef  codec    }    FREE( p_cl->codec );}/* Microsoft should go to hell. This time the length give number of bytes * and for the some others object, length give char16 count ... */static int ASF_ReadObject_content_description(stream_t *s, asf_object_t *p_obj){    asf_object_content_description_t *p_cd =                                    (asf_object_content_description_t*)p_obj;    int     i_peek;    uint8_t *p_peek, *p_data;    int i_len;    int i_title;    int i_author;    int i_copyright;    int i_description;    int i_rating;#define GETSTRINGW( psz_str, i_size ) \   psz_str = calloc( i_size/2 + 1, sizeof( char ) ); \   for( i_len = 0; i_len < i_size/2; i_len++ ) \   { \       psz_str[i_len] = GetWLE( p_data + 2*i_len ); \   } \   psz_str[i_size/2] = '\0'; \   p_data += i_size;    if( ( i_peek = stream_Peek( s, &p_peek, p_cd->i_object_size ) ) < 34 )    {       return VLC_EGENERIC;    }    p_data = p_peek + 24;    i_title = GetWLE( p_data ); p_data += 2;    i_author= GetWLE( p_data ); p_data += 2;    i_copyright     = GetWLE( p_data ); p_data += 2;    i_description   = GetWLE( p_data ); p_data += 2;    i_rating        = GetWLE( p_data ); p_data += 2;    GETSTRINGW( p_cd->psz_title, i_title );    GETSTRINGW( p_cd->psz_author, i_author );    GETSTRINGW( p_cd->psz_copyright, i_copyright );    GETSTRINGW( p_cd->psz_description, i_description );    GETSTRINGW( p_cd->psz_rating, i_rating );#undef  GETSTRINGW#ifdef ASF_DEBUG    msg_Dbg( (vlc_object_t*)s,             "Read \"content description object\" title:\"%s\" author:\"%s\" copyright:\"%s\" description:\"%s\" rating:\"%s\"",             p_cd->psz_title,             p_cd->psz_author,             p_cd->psz_copyright,             p_cd->psz_description,             p_cd->psz_rating );#endif    return VLC_SUCCESS;}static void ASF_FreeObject_content_description( asf_object_t *p_obj){    asf_object_content_description_t *p_cd =                                    (asf_object_content_description_t*)p_obj;    FREE( p_cd->psz_title );    FREE( p_cd->psz_author );    FREE( p_cd->psz_copyright );    FREE( p_cd->psz_description );    FREE( p_cd->psz_rating );}static struct{    const guid_t  *p_id;    int     i_type;    int     (*ASF_ReadObject_function)( stream_t *, asf_object_t *p_obj );    void    (*ASF_FreeObject_function)( asf_object_t *p_obj );} ASF_Object_Function [] ={    { &asf_object_header_guid,            ASF_OBJECT_TYPE_HEADER,             ASF_ReadObject_Header, ASF_FreeObject_Null },    { &asf_object_data_guid,              ASF_OBJECT_TYPE_DATA,               ASF_ReadObject_Data,   ASF_FreeObject_Null },    { &asf_object_index_guid,             ASF_OBJECT_TYPE_INDEX,              ASF_ReadObject_Index,  ASF_FreeObject_Index },    { &asf_object_file_properties_guid,   ASF_OBJECT_TYPE_FILE_PROPERTIES,    ASF_ReadObject_file_properties,  ASF_FreeObject_Null },    { &asf_object_stream_properties_guid, ASF_OBJECT_TYPE_STREAM_PROPERTIES,  ASF_ReadObject_stream_properties,ASF_FreeObject_stream_properties },    { &asf_object_header_extention_guid,  ASF_OBJECT_TYPE_EXTENTION_HEADER,   ASF_ReadObject_header_extention, ASF_FreeObject_header_extention},    { &asf_object_codec_list_guid,        ASF_OBJECT_TYPE_CODEC_LIST,         ASF_ReadObject_codec_list,       ASF_FreeObject_codec_list },    { &asf_object_marker_guid,            ASF_OBJECT_TYPE_MARKER,             NULL,                  NULL },    { &asf_object_content_description_guid, ASF_OBJECT_TYPE_CONTENT_DESCRIPTION, ASF_ReadObject_content_description, ASF_FreeObject_content_description },    { &asf_object_null_guid,   0,                      NULL,                  NULL }};static int ASF_ReadObject( stream_t *s,                           asf_object_t *p_obj, asf_object_t *p_father ){    int i_result;    int i_index;    if( !p_obj )    {        return( 0 );    }    if( ASF_ReadObjectCommon( s, p_obj ) )    {        msg_Warn( (vlc_object_t*)s, "cannot read one asf object" );        return VLC_EGENERIC;    }    p_obj->common.p_father = p_father;    p_obj->common.p_first = NULL;    p_obj->common.p_next = NULL;    p_obj->common.p_last = NULL;    if( p_obj->common.i_object_size < 24 )    {        msg_Warn( (vlc_object_t*)s, "found a corrupted asf object (size<24)" );        return VLC_EGENERIC;    }    /* find this object */    for( i_index = 0; ; i_index++ )    {        if( ASF_CmpGUID( ASF_Object_Function[i_index].p_id,                     &p_obj->common.i_object_id )||            ASF_CmpGUID( ASF_Object_Function[i_index].p_id,                     &asf_object_null_guid ) )        {            break;        }    }    p_obj->common.i_type = ASF_Object_Function[i_index].i_type;    /* Now load this object */    if( ASF_Object_Function[i_index].ASF_ReadObject_function == NULL )    {        msg_Warn( (vlc_object_t*)s, "unknown asf object (not loaded)" );        i_result = VLC_SUCCESS;    }    else    {        /* XXX ASF_ReadObject_function realloc *pp_obj XXX */        i_result =          (ASF_Object_Function[i_index].ASF_ReadObject_function)( s, p_obj );    }    /* link this object with father */    if( p_father )    {        if( p_father->common.p_first )        {            p_father->common.p_last->common.p_next = p_obj;        }        else        {            p_father->common.p_first = p_obj;        }        p_father->common.p_last = p_obj;    }    return( i_result );}static void ASF_FreeObject( stream_t *s, asf_object_t *p_obj ){    int i_index;    asf_object_t *p_child;    if( !p_obj )    {        return;    }    /* Free all child object */    p_child = p_obj->common.p_first;    while( p_child )    {        asf_object_t *p_next;        p_next = p_child->common.p_next;        ASF_FreeObject( s, p_child );        p_child = p_next;    }    /* find this object */    for( i_index = 0; ; i_index++ )    {        if( ASF_CmpGUID( ASF_Object_Function[i_index].p_id,                     &p_obj->common.i_object_id )||            ASF_CmpGUID( ASF_Object_Function[i_index].p_id,                     &asf_object_null_guid ) )        {            break;        }    }    /* Now free this object */    if( ASF_Object_Function[i_index].ASF_FreeObject_function == NULL )    {        msg_Warn( (vlc_object_t*)s,                  "unknown asf object " GUID_FMT,                  GUID_PRINT( p_obj->common.i_object_id ) );    }    else    {#ifdef ASF_DEBUG        msg_Dbg( (vlc_object_t*)s,                  "free asf object " GUID_FMT,                  GUID_PRINT( p_obj->common.i_object_id ) );#endif        (ASF_Object_Function[i_index].ASF_FreeObject_function)( p_obj );    }    free( p_obj );    return;}/***************************************************************************** * ASF_ReadObjetRoot : parse the entire stream/file *****************************************************************************/asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable ){    asf_object_root_t *p_root = malloc( sizeof( asf_object_root_t ) );    asf_object_t *p_obj;    p_root->i_type = ASF_OBJECT_TYPE_ROOT;    memcpy( &p_root->i_object_id, &asf_object_null_guid, sizeof( guid_t ) );    p_root->i_object_pos = 0;    p_root->i_object_size = stream_Tell( s );    p_root->p_first = NULL;    p_root->p_last  = NULL;    p_root->p_next  = NULL;    p_root->p_hdr   = NULL;    p_root->p_data  = NULL;    p_root->p_fp    = NULL;    p_root->p_index = NULL;    for( ; ; )    {        p_obj  = malloc( sizeof( asf_object_t ) );        if( ASF_ReadObject( s, p_obj, (asf_object_t*)p_root ) )        {            break;        }        switch( p_obj->common.i_type )        {            case( ASF_OBJECT_TYPE_HEADER ):                p_root->p_hdr = (asf_object_header_t*)p_obj;                break;            case( ASF_OBJECT_TYPE_DATA ):                p_root->p_data = (asf_object_data_t*)p_obj;                break;            case( ASF_OBJECT_TYPE_INDEX ):                p_root->p_index = (asf_object_index_t*)p_obj;                break;            default:                msg_Warn( (vlc_object_t*)s, "unknow object found" );                break;        }        if( p_obj->common.i_type == ASF_OBJECT_TYPE_DATA &&            p_obj->common.i_object_size <= 50 )        {            /* probably a dump of broadcasted asf */            break;        }        if( !b_seekable && p_root->p_hdr && p_root->p_data )        {            /* For unseekable stream it's enouth to play */            break;        }        if( ASF_NextObject( s, p_obj ) ) /* Go to the next object */        {            break;        }    }    if( p_root->p_hdr != NULL && p_root->p_data != NULL )    {        p_root->p_fp = ASF_FindObject( p_root->p_hdr,                                       &asf_object_file_properties_guid, 0 );        if( p_root->p_fp )        {            return p_root;        }        msg_Warn( (vlc_object_t*)s, "cannot find file properties object" );    }    /* Invalid file */    ASF_FreeObjectRoot( s, p_root );    return NULL;}void ASF_FreeObjectRoot( stream_t *s, asf_object_root_t *p_root ){    asf_object_t *p_obj;    p_obj = p_root->p_first;    while( p_obj )    {        asf_object_t *p_next;        p_next = p_obj->common.p_next;        ASF_FreeObject( s, p_obj );        p_obj = p_next;    }    free( p_root );}int  __ASF_CountObject( asf_object_t *p_obj, const guid_t *p_guid ){    int i_count;    asf_object_t *p_child;    if( !p_obj )    {        return( 0 );    }    i_count = 0;    p_child = p_obj->common.p_first;    while( p_child )    {        if( ASF_CmpGUID( &p_child->common.i_object_id, p_guid ) )        {            i_count++;        }        p_child = p_child->common.p_next;    }    return( i_count );}void *__ASF_FindObject( asf_object_t *p_obj, const guid_t *p_guid, int i_number ){    asf_object_t *p_child;    p_child = p_obj->common.p_first;    while( p_child )    {        if( ASF_CmpGUID( &p_child->common.i_object_id, p_guid ) )        {            if( i_number == 0 )            {                /* We found it */                return( p_child );            }            i_number--;        }        p_child = p_child->common.p_next;    }    return( NULL );}

⌨️ 快捷键说明

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