📄 libasf.c
字号:
p_record->i_stream = ASF_READ2(); i_name = ASF_READ2(); p_record->i_type = ASF_READ2(); i_data = ASF_READ4(); if( !ASF_HAVE( i_name + i_data ) ) break; /* Read name */ p_record->psz_name = ASF_READS( i_name ); /* Read data */ if( p_record->i_type == ASF_METADATA_TYPE_STRING ) { p_record->p_data = ASF_READS( i_data ); p_record->i_data = i_data/2; /* FIXME Is that needed ? */ } else if( p_record->i_type == ASF_METADATA_TYPE_BYTE ) { p_record->p_data = malloc( i_data ); p_record->i_data = i_data; if( p_record->p_data && i_data > 0 ) memcpy( p_record->p_data, p_data, i_data ); p_data += i_data; } else if( p_record->i_type == ASF_METADATA_TYPE_QWORD ) { p_record->i_val = ASF_READ8(); } else if( p_record->i_type == ASF_METADATA_TYPE_DWORD ) { p_record->i_val = ASF_READ4(); } else if( p_record->i_type == ASF_METADATA_TYPE_WORD ) { p_record->i_val = ASF_READ2(); } else if( p_record->i_type == ASF_METADATA_TYPE_BOOL ) { p_record->i_val = ASF_READ2(); } else { /* Unknown */ p_data += i_data; } } p_meta->i_record_entries_count = i;#ifdef ASF_DEBUG msg_Dbg( s, "read \"metadata object\" %d entries", p_meta->i_record_entries_count ); for( j = 0; j < p_meta->i_record_entries_count; j++ ) { asf_metadata_record_t *p_rec = &p_meta->record[j]; if( p_rec->i_type == ASF_METADATA_TYPE_STRING ) msg_Dbg( s, " - %s=%s", p_rec->psz_name, p_rec->p_data ); else if( p_rec->i_type == ASF_METADATA_TYPE_BYTE ) msg_Dbg( s, " - %s (%i bytes)", p_rec->psz_name, p_rec->i_data ); else msg_Dbg( s, " - %s=%"PRId64, p_rec->psz_name, p_rec->i_val ); }#endif return VLC_SUCCESS;}static int ASF_ReadObject_header_extension( stream_t *s, asf_object_t *p_obj ){ asf_object_header_extension_t *p_he = &p_obj->header_extension; int i_peek; const uint8_t *p_peek; if( ( i_peek = stream_Peek( s, &p_peek, p_he->i_object_size ) ) < 46) { return VLC_EGENERIC; } ASF_GetGUID( &p_he->i_reserved1, p_peek + 24 ); p_he->i_reserved2 = GetWLE( p_peek + 40 ); p_he->i_header_extension_size = GetDWLE( p_peek + 42 ); if( p_he->i_header_extension_size ) { if( (unsigned int)(i_peek-46) < p_he->i_header_extension_size ) return VLC_EGENERIC; p_he->p_header_extension_data = malloc( p_he->i_header_extension_size ); if( !p_he->p_header_extension_data ) return VLC_ENOMEM; memcpy( p_he->p_header_extension_data, p_peek + 46, p_he->i_header_extension_size ); } else { p_he->p_header_extension_data = NULL; }#ifdef ASF_DEBUG msg_Dbg( s, "read \"header extension object\" reserved1:" GUID_FMT " reserved2:%d header_extension_size:%d", GUID_PRINT( p_he->i_reserved1 ), p_he->i_reserved2, p_he->i_header_extension_size );#endif if( !p_he->i_header_extension_size ) return VLC_SUCCESS; /* Read the extension objects */ stream_Read( s, NULL, 46 ); for( ; ; ) { asf_object_t *p_obj = malloc( sizeof( asf_object_t ) ); if( !p_obj || ASF_ReadObject( s, p_obj, (asf_object_t*)p_he ) ) { free( p_obj ); break; } if( ASF_NextObject( s, p_obj ) ) /* Go to the next object */ { break; } } return VLC_SUCCESS;}static void ASF_FreeObject_header_extension( asf_object_t *p_obj ){ asf_object_header_extension_t *p_he = &p_obj->header_extension; FREENULL( p_he->p_header_extension_data );}static int ASF_ReadObject_stream_properties( stream_t *s, asf_object_t *p_obj ){ asf_object_stream_properties_t *p_sp = &p_obj->stream_properties; size_t i_peek; const uint8_t *p_peek; if( ( i_peek = stream_Peek( s, &p_peek, p_sp->i_object_size ) ) < 78 ) return VLC_EGENERIC; ASF_GetGUID( &p_sp->i_stream_type, p_peek + 24 ); ASF_GetGUID( &p_sp->i_error_correction_type, p_peek + 40 ); p_sp->i_time_offset = GetQWLE( p_peek + 56 ); p_sp->i_type_specific_data_length = GetDWLE( p_peek + 64 ); p_sp->i_error_correction_data_length = GetDWLE( p_peek + 68 ); p_sp->i_flags = GetWLE( p_peek + 72 ); p_sp->i_stream_number = p_sp->i_flags&0x07f; p_sp->i_reserved = GetDWLE( p_peek + 74 ); i_peek -= 78; if( p_sp->i_type_specific_data_length ) { if( i_peek < p_sp->i_type_specific_data_length ) return VLC_EGENERIC; p_sp->p_type_specific_data = malloc( p_sp->i_type_specific_data_length ); if( !p_sp->p_type_specific_data ) return VLC_ENOMEM; memcpy( p_sp->p_type_specific_data, p_peek + 78, p_sp->i_type_specific_data_length ); i_peek -= p_sp->i_type_specific_data_length; } if( p_sp->i_error_correction_data_length ) { if( i_peek < p_sp->i_error_correction_data_length ) { free( p_sp->p_type_specific_data ); return VLC_EGENERIC; } p_sp->p_error_correction_data = malloc( p_sp->i_error_correction_data_length ); if( !p_sp->p_error_correction_data ) { free( p_sp->p_type_specific_data ); return VLC_ENOMEM; } memcpy( p_sp->p_error_correction_data, p_peek + 78 + p_sp->i_type_specific_data_length, p_sp->i_error_correction_data_length ); }#ifdef ASF_DEBUG msg_Dbg( s, "read \"stream Properties object\" stream_type:" GUID_FMT " error_correction_type:" GUID_FMT " time_offset:%"PRId64 " type_specific_data_length:%d error_correction_data_length:%d" " flags:0x%x stream_number:%d", GUID_PRINT( p_sp->i_stream_type ), GUID_PRINT( p_sp->i_error_correction_type ), p_sp->i_time_offset, p_sp->i_type_specific_data_length, p_sp->i_error_correction_data_length, p_sp->i_flags, p_sp->i_stream_number );#endif return VLC_SUCCESS;}static void ASF_FreeObject_stream_properties( asf_object_t *p_obj ){ asf_object_stream_properties_t *p_sp = &p_obj->stream_properties; FREENULL( p_sp->p_type_specific_data ); FREENULL( p_sp->p_error_correction_data );}static int ASF_ReadObject_codec_list( stream_t *s, asf_object_t *p_obj ){ asf_object_codec_list_t *p_cl = &p_obj->codec_list; int i_peek; const uint8_t *p_peek, *p_data; unsigned int i_codec; if( ( i_peek = stream_Peek( s, &p_peek, p_cl->i_object_size ) ) < 44 ) return VLC_EGENERIC; ASF_GetGUID( &p_cl->i_reserved, p_peek + 24 ); p_cl->i_codec_entries_count = GetWLE( p_peek + 40 ); p_data = p_peek + 44; if( p_cl->i_codec_entries_count > 0 ) { p_cl->codec = calloc( p_cl->i_codec_entries_count, sizeof( asf_codec_entry_t ) ); if( !p_cl->codec ) return VLC_ENOMEM; for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ ) { asf_codec_entry_t *p_codec = &p_cl->codec[i_codec]; if( !ASF_HAVE( 2+2+2 ) ) break; /* */ p_codec->i_type = ASF_READ2(); /* XXX the length here are the number of *unicode* characters and * not of bytes like nearly every elsewhere */ /* codec name */ p_codec->psz_name = ASF_READS( 2*ASF_READ2() ); /* description */ p_codec->psz_description = ASF_READS( 2*ASF_READ2() ); /* opaque information */ p_codec->i_information_length = ASF_READ2(); if( p_codec->i_information_length > 0 && ASF_HAVE( p_codec->i_information_length ) ) { p_codec->p_information = malloc( p_codec->i_information_length ); if( p_codec->p_information ) memcpy( p_codec->p_information, p_data, p_codec->i_information_length ); else p_codec->i_information_length = 0; p_data += p_codec->i_information_length; } } p_cl->i_codec_entries_count = i_codec; }#ifdef ASF_DEBUG msg_Dbg( 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++ ) { const asf_codec_entry_t *p_codec = &p_cl->codec[i_codec]; msg_Dbg( s, " - codec[%d] %s name:\"%s\" " "description:\"%s\" information_length:%d", i_codec, ( p_codec->i_type == ASF_CODEC_TYPE_VIDEO ) ? "video" : ( ( p_codec->i_type == ASF_CODEC_TYPE_AUDIO ) ? "audio" : "unknown" ), p_codec->psz_name, p_codec->psz_description, p_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 = &p_obj->codec_list; unsigned int i_codec; for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ ) { asf_codec_entry_t *p_codec = &p_cl->codec[i_codec]; FREENULL( p_codec->psz_name ); FREENULL( p_codec->psz_description ); FREENULL( p_codec->p_information ); } FREENULL( 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 = &p_obj->content_description; const uint8_t *p_peek, *p_data; int i_peek, i_title, i_artist, i_copyright, i_description, i_rating; vlc_iconv_t cd = (vlc_iconv_t)-1; const char *ib = NULL; char *ob = NULL; size_t i_ibl, i_obl, i_len; if( ( i_peek = stream_Peek( s, &p_peek, p_cd->i_object_size ) ) < 34 ) return VLC_EGENERIC; cd = vlc_iconv_open("UTF-8", "UTF-16LE"); if( cd == (vlc_iconv_t)-1 ) { msg_Err( s, "vlc_iconv_open failed" ); return VLC_EGENERIC; }/* FIXME i_size*3 is the worst case. */#define GETSTRINGW( psz_str, i_size ) do { \ psz_str = calloc( i_size*3+1, sizeof(char) ); \ if( psz_str ) { \ ib = (const char *)p_data; \ ob = psz_str; \ i_ibl = i_size; \ i_obl = i_size*3; \ i_len = vlc_iconv(cd, &ib, &i_ibl, &ob, &i_obl); \ p_data += i_size; \ } } while(0) p_data = p_peek + 24; i_title = ASF_READ2(); i_artist = ASF_READ2(); i_copyright = ASF_READ2(); i_description = ASF_READ2(); i_rating = ASF_READ2(); if( !ASF_HAVE( i_title+i_artist+i_copyright+i_description+i_rating ) ) { vlc_iconv_close( cd ); return VLC_EGENERIC; } GETSTRINGW( p_cd->psz_title, i_title ); GETSTRINGW( p_cd->psz_artist, i_artist ); 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( s, "read \"content description object\" title:\"%s\" artist:\"%s\" copyright:\"%s\" description:\"%s\" rating:\"%s\"", p_cd->psz_title, p_cd->psz_artist, p_cd->psz_copyright, p_cd->psz_description, p_cd->psz_rating );#endif vlc_iconv_close(cd); return VLC_SUCCESS;}static void ASF_FreeObject_content_description( asf_object_t *p_obj){ asf_object_content_description_t *p_cd = &p_obj->content_description; FREENULL( p_cd->psz_title ); FREENULL( p_cd->psz_artist ); FREENULL( p_cd->psz_copyright ); FREENULL( p_cd->psz_description ); FREENULL( p_cd->psz_rating );}/* Language list: */static int ASF_ReadObject_language_list(stream_t *s, asf_object_t *p_obj){ asf_object_language_list_t *p_ll = &p_obj->language_list; const uint8_t *p_peek, *p_data; int i_peek; int i; if( ( i_peek = stream_Peek( s, &p_peek, p_ll->i_object_size ) ) < 26 ) return VLC_EGENERIC; p_data = &p_peek[24]; p_ll->i_language = ASF_READ2(); if( p_ll->i_language > 0 ) { p_ll->ppsz_language = calloc( p_ll->i_language, sizeof( char *) ); if( !p_ll->ppsz_language ) return VLC_ENOMEM; for( i = 0; i < p_ll->i_language; i++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -