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 + -
显示快捷键?