当前位置: 首页 > 工具软件 > SAF > 使用案例 >

saf文件代码

燕智
2023-12-01

/******************************************************************************
 * SIMPLE ASF PARSER by fanoble (fanoblem@gmail.com)
 * 2005.8.10
 *****************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>

#ifdef  WIN32
#define  FS_FILE   FILE
#define  fs_fopen  fopen
#define  fs_fclose  fclose
#define  fs_fseek  fseek
#define  fs_fread  fread
#define  fs_ftell  ftell
#endif

#define  ASF_DEBUGOUT

#define  GUID_ASF_NONE               (-1)
#define  GUID_ASF_HEADER_OBJECT             0
#define  GUID_ASF_DATA_OBJECT             1
#define  GUID_ASF_SIMPLE_INDEX_OBJECT           2
#define  GUID_ASF_INDEX_OBJECT             3
#define  GUID_ASF_MEDIA_OBJECT_INDEX_OBJECT          4
#define  GUID_ASF_TIMECODE_INDEX_OBJECT           5
#define  GUID_ASF_FILE_PROPERTIES_OBJECT           6
#define  GUID_ASF_STREAM_PROPERTIES_OBJECT          7
#define  GUID_ASF_HEADER_EXTENSION_OBJECT          8
#define  GUID_ASF_CODEC_LIST_OBJECT            9
#define  GUID_ASF_SCRIPT_COMMAND_OBJECT           10
#define  GUID_ASF_MARKER_OBJECT             11
#define  GUID_ASF_BITRATE_MUTUAL_EXCLUSION_OBJECT        12
#define  GUID_ASF_ERROR_CORRECTION_OBJECT          13
#define  GUID_ASF_CONTENT_DESCRIPTION_OBJECT          14
#define  GUID_ASF_EXTENDED_CONTENT_DESCRIPTION_OBJECT       15
#define  GUID_ASF_CONTENT_BRANDING_OBJECT          16
#define  GUID_ASF_STREAM_BITRATE_PROPERTIES_OBJECT        17
#define  GUID_ASF_CONTENT_ENCRYPTION_OBJECT          18
#define  GUID_ASF_EXTENDED_CONTENT_ENCRYPTION_OBJECT        19
#define  GUID_ASF_DIGITAL_SIGNATURE_OBJECT          20
#define  GUID_ASF_PADDING_OBJECT             21
#define  GUID_ASF_EXTENDED_STREAM_PROPERTIES_OBJECT        22
#define  GUID_ASF_ADVANCED_MUTUAL_EXCLUSION_OBJECT        23
#define  GUID_ASF_GROUP_MUTUAL_EXCLUSION_OBJECT         24
#define  GUID_ASF_STREAM_PRIORITIZATION_OBJECT         25
#define  GUID_ASF_BANDWIDTH_SHARING_OBJECT          26
#define  GUID_ASF_LANGUAGE_LIST_OBJECT           27
#define  GUID_ASF_METADATA_OBJECT            28
#define  GUID_ASF_METADATA_LIBRARY_OBJECT          29
#define  GUID_ASF_INDEX_PARAMETERS_OBJECT          30
#define  GUID_ASF_MEDIA_OBJECT_INDEX_PARAMETERS_OBJECT       31
#define  GUID_ASF_TIMECODE_INDEX_PARAMETERS_OBJECT        32
#define  GUID_ASF_COMPATIBILITY_OBJECT           33
#define  GUID_ASF_ADVANCED_CONTENT_ENCRYPTION_OBJECT        34
#define  GUID_ASF_AUDIO_MEDIA             35
#define  GUID_ASF_VIDEO_MEDIA             36
#define  GUID_ASF_COMMAND_MEDIA             37
#define  GUID_ASF_JFIF_MEDIA              38
#define  GUID_ASF_DEGRADABLE_JPEG_MEDIA           39
#define  GUID_ASF_FILE_TRANSFER_MEDIA           40
#define  GUID_ASF_BINARY_MEDIA             41
#define  GUID_ASF_WEB_STREAM_MEDIA_SUBTYPE          42
#define  GUID_ASF_WEB_STREAM_FORMAT            43
#define  GUID_ASF_NO_ERROR_CORRECTION           44
#define  GUID_ASF_AUDIO_SPREAD             45
#define  GUID_ASF_RESERVED_1              46
#define  GUID_ASF_RESERVED_2              47
#define  GUID_ASF_RESERVED_3              48
#define  GUID_ASF_RESERVED_4              49
#define  GUID_ASF_MUTEX_LANGUAGE             50
#define  GUID_ASF_MUTEX_BITRATE             51
#define  GUID_ASF_MUTEX_UNKNOWN             52
#define  GUID_ASF_BANDWIDTH_SHARING_EXCLUSIVE         53
#define  GUID_ASF_BANDWIDTH_SHARING_PARTIAL          54
#define  GUID_ASF_PAYLOAD_EXTENSION_SYSTEM_TIMECODE        55
#define  GUID_ASF_PAYLOAD_EXTENSION_SYSTEM_FILE_NAME        56
#define  GUID_ASF_PAYLOAD_EXTENSION_SYSTEM_CONTENT_TYPE       57
#define  GUID_ASF_PAYLOAD_EXTENSION_SYSTEM_PIXEL_ASPECT_RATIO     58
#define  GUID_ASF_PAYLOAD_EXTENSION_SYSTEM_SAMPLE_DURATION      59
#define  GUID_ASF_PAYLOAD_EXTENSION_SYSTEM_ENCRYPTION_SAMPLE_ID     60
#define  GUID_ASF_CONTENT_ENCRYPTION_SYSTEM_WINDOWS_MEDIA_DRM_NETWORK_DEVICES 61

#pragma  pack(push)
#pragma  pack(1)

typedef struct tagASF_FILE_HEADER_OBJECT
{
 unsigned long SizeLo;
 unsigned long SizeHi;
 unsigned long NumOfObjects;
 unsigned char Reserved1;
 unsigned char Reserved2;
} ASF_FILE_HEADER_OBJECT;

typedef struct tagASF_FILE_PROPERTIES_OBJECT
{
 unsigned long SizeLo;
 unsigned long SizeHi;
 unsigned char FileID[16];
 unsigned long FileSizeLo;
 unsigned long FileSizeHi;
 unsigned long FileDateLo;
 unsigned long FileDateHi;
 unsigned long DataPacketsCountLo;
 unsigned long DataPacketsCountHi;
 unsigned long PlayDurationLo;
 unsigned long PlayDurationHi;
 unsigned long SendDurationLo;
 unsigned long SendDurationHi;
 unsigned long PrerollLo;
 unsigned long PrerollHi;
 unsigned long Flags;
 unsigned long MinDataPacketSize;
 unsigned long MaxDataPacketSize;
 unsigned long MaxBitrate;
} ASF_FILE_PROPERTIES_OBJECT;

#pragma  pack(pop)

static const
unsigned char ASF_GUID_Table [][16] =
{
 { 0x30,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C }, // ASF_Header_Object
 { 0x36,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C }, // ASF_Data_Object
 { 0x90,0x08,0x00,0x33,0xB1,0xE5,0xCF,0x11,0x89,0xF4,0x00,0xA0,0xC9,0x03,0x49,0xCB }, // ASF_Simple_Index_Object
 { 0xD3,0x29,0xE2,0xD6,0xDA,0x35,0xD1,0x11,0x90,0x34,0x00,0xA0,0xC9,0x03,0x49,0xBE }, // ASF_Index_Object
 { 0xF8,0x03,0xB1,0xFE,0xAD,0x12,0x64,0x4C,0x84,0x0F,0x2A,0x1D,0x2F,0x7A,0xD4,0x8C }, // ASF_Media_Object_Index_Object
 { 0xD0,0x3F,0xB7,0x3C,0x4A,0x0C,0x03,0x48,0x95,0x3D,0xED,0xF7,0xB6,0x22,0x8F,0x0C }, // ASF_Timecode_Index_Object
 { 0xA1,0xDC,0xAB,0x8C,0x47,0xA9,0xCF,0x11,0x8E,0xE4,0x00,0xC0,0x0C,0x20,0x53,0x65 }, // ASF_File_Properties_Object
 { 0x91,0x07,0xDC,0xB7,0xB7,0xA9,0xCF,0x11,0x8E,0xE6,0x00,0xC0,0x0C,0x20,0x53,0x65 }, // ASF_Stream_Properties_Object
 { 0xB5,0x03,0xBF,0x5F,0x2E,0xA9,0xCF,0x11,0x8E,0xE3,0x00,0xC0,0x0C,0x20,0x53,0x65 }, // ASF_Header_Extension_Object
 { 0x40,0x52,0xD1,0x86,0x1D,0x31,0xD0,0x11,0xA3,0xA4,0x00,0xA0,0xC9,0x03,0x48,0xF6 }, // ASF_Codec_List_Object
 { 0x30,0x1A,0xFB,0x1E,0x62,0x0B,0xD0,0x11,0xA3,0x9B,0x00,0xA0,0xC9,0x03,0x48,0xF6 }, // ASF_Script_Command_Object
 { 0x01,0xCD,0x87,0xF4,0x51,0xA9,0xCF,0x11,0x8E,0xE6,0x00,0xC0,0x0C,0x20,0x53,0x65 }, // ASF_Marker_Object
 { 0xDC,0x29,0xE2,0xD6,0xDA,0x35,0xD1,0x11,0x90,0x34,0x00,0xA0,0xC9,0x03,0x49,0xBE }, // ASF_Bitrate_Mutual_Exclusion_Object
 { 0x35,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C }, // ASF_Error_Correction_Object
 { 0x33,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C }, // ASF_Content_Description_Object
 { 0x40,0xA4,0xD0,0xD2,0x07,0xE3,0xD2,0x11,0x97,0xF0,0x00,0xA0,0xC9,0x5E,0xA8,0x50 }, // ASF_Extended_Content_Description_Object
 { 0xFA,0xB3,0x11,0x22,0x23,0xBD,0xD2,0x11,0xB4,0xB7,0x00,0xA0,0xC9,0x55,0xFC,0x6E }, // ASF_Content_Branding_Object
 { 0xCE,0x75,0xF8,0x7B,0x8D,0x46,0xD1,0x11,0x8D,0x82,0x00,0x60,0x97,0xC9,0xA2,0xB2 }, // ASF_Stream_Bitrate_Properties_Object
 { 0xFB,0xB3,0x11,0x22,0x23,0xBD,0xD2,0x11,0xB4,0xB7,0x00,0xA0,0xC9,0x55,0xFC,0x6E }, // ASF_Content_Encryption_Object
 { 0x14,0xE6,0x8A,0x29,0x22,0x26,0x17,0x4C,0xB9,0x35,0xDA,0xE0,0x7E,0xE9,0x28,0x9C }, // ASF_Extended_Content_Encryption_Object
 { 0xFC,0xB3,0x11,0x22,0x23,0xBD,0xD2,0x11,0xB4,0xB7,0x00,0xA0,0xC9,0x55,0xFC,0x6E }, // ASF_Digital_Signature_Object
 { 0x74,0xD4,0x06,0x18,0xDF,0xCA,0x09,0x45,0xA4,0xBA,0x9A,0xAB,0xCB,0x96,0xAA,0xE8 }, // ASF_Padding_Object
 { 0xCB,0xA5,0xE6,0x14,0x72,0xC6,0x32,0x43,0x83,0x99,0xA9,0x69,0x52,0x06,0x5B,0x5A }, // ASF_Extended_Stream_Properties_Object
 { 0xCF,0x49,0x86,0xA0,0x75,0x47,0x70,0x46,0x8A,0x16,0x6E,0x35,0x35,0x75,0x66,0xCD }, // ASF_Advanced_Mutual_Exclusion_Object
 { 0x40,0x5A,0x46,0xD1,0x79,0x5A,0x38,0x43,0xB7,0x1B,0xE3,0x6B,0x8F,0xD6,0xC2,0x49 }, // ASF_Group_Mutual_Exclusion_Object
 { 0x5B,0xD1,0xFE,0xD4,0xD3,0x88,0x4F,0x45,0x81,0xF0,0xED,0x5C,0x45,0x99,0x9E,0x24 }, // ASF_Stream_Prioritization_Object
 { 0xE6,0x09,0x96,0xA6,0x7B,0x51,0xD2,0x11,0xB6,0xAF,0x00,0xC0,0x4F,0xD9,0x08,0xE9 }, // ASF_Bandwidth_Sharing_Object
 { 0xA9,0x46,0x43,0x7C,0xE0,0xEF,0xFC,0x4B,0xB2,0x29,0x39,0x3E,0xDE,0x41,0x5C,0x85 }, // ASF_Language_List_Object
 { 0xEA,0xCB,0xF8,0xC5,0xAF,0x5B,0x77,0x48,0x84,0x67,0xAA,0x8C,0x44,0xFA,0x4C,0xCA }, // ASF_Metadata_Object
 { 0x94,0x1C,0x23,0x44,0x98,0x94,0xD1,0x49,0xA1,0x41,0x1D,0x13,0x4E,0x45,0x70,0x54 }, // ASF_Metadata_Library_Object
 { 0xDF,0x29,0xE2,0xD6,0xDA,0x35,0xD1,0x11,0x90,0x34,0x00,0xA0,0xC9,0x03,0x49,0xBE }, // ASF_Index_Parameters_Object
 { 0xAD,0x3B,0x20,0x6B,0x11,0x3F,0xE4,0x48,0xAC,0xA8,0xD7,0x61,0x3D,0xE2,0xCF,0xA7 }, // ASF_Media_Object_Index_Parameters_Object
 { 0x6D,0x49,0x5E,0xF5,0x97,0x97,0x5D,0x4B,0x8C,0x8B,0x60,0x4D,0xFE,0x9B,0xFB,0x24 }, // ASF_Timecode_Index_Parameters_Object
 { 0x30,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C }, // ASF_Compatibility_Object
 { 0x33,0x85,0x05,0x43,0x81,0x69,0xE6,0x49,0x9B,0x74,0xAD,0x12,0xCB,0x86,0xD5,0x8C }, // ASF_Advanced_Content_Encryption_Object
 { 0x40,0x9E,0x69,0xF8,0x4D,0x5B,0xCF,0x11,0xA8,0xFD,0x00,0x80,0x5F,0x5C,0x44,0x2B }, // ASF_Audio_Media
 { 0xC0,0xEF,0x19,0xBC,0x4D,0x5B,0xCF,0x11,0xA8,0xFD,0x00,0x80,0x5F,0x5C,0x44,0x2B }, // ASF_Video_Media
 { 0xC0,0xCF,0xDA,0x59,0xE6,0x59,0xD0,0x11,0xA3,0xAC,0x00,0xA0,0xC9,0x03,0x48,0xF6 }, // ASF_Command_Media
 { 0x00,0xE1,0x1B,0xB6,0x4E,0x5B,0xCF,0x11,0xA8,0xFD,0x00,0x80,0x5F,0x5C,0x44,0x2B }, // ASF_JFIF_Media
 { 0xE0,0x7D,0x90,0x35,0x15,0xE4,0xCF,0x11,0xA9,0x17,0x00,0x80,0x5F,0x5C,0x44,0x2B }, // ASF_Degradable_JPEG_Media
 { 0x2C,0x22,0xBD,0x91,0x1C,0xF2,0x7A,0x49,0x8B,0x6D,0x5A,0xA8,0x6B,0xFC,0x01,0x85 }, // ASF_File_Transfer_Media
 { 0xE2,0x65,0xFB,0x3A,0xEF,0x47,0xF2,0x40,0xAC,0x2C,0x70,0xA9,0x0D,0x71,0xD3,0x43 }, // ASF_Binary_Media
 { 0xD4,0x57,0x62,0x77,0x27,0xC6,0xCB,0x41,0x8F,0x81,0x7A,0xC7,0xFF,0x1C,0x40,0xCC }, // ASF_Web_Stream_Media_Subtype
 { 0x13,0x6B,0x1E,0xDA,0x59,0x83,0x50,0x40,0xB3,0x98,0x38,0x8E,0x96,0x5B,0xF0,0x0C }, // ASF_Web_Stream_Format
 { 0x00,0x57,0xFB,0x20,0x55,0x5B,0xCF,0x11,0xA8,0xFD,0x00,0x80,0x5F,0x5C,0x44,0x2B }, // ASF_No_Error_Correction
 { 0x50,0xCD,0xC3,0xBF,0x8F,0x61,0xCF,0x11,0x8B,0xB2,0x00,0xAA,0x00,0xB4,0xE2,0x20 }, // ASF_Audio_Spread
 { 0x11,0xD2,0xD3,0xAB,0xBA,0xA9,0xCF,0x11,0x8E,0xE6,0x00,0xC0,0x0C,0x20,0x53,0x65 }, // ASF_Reserved_1
 { 0x41,0x52,0xD1,0x86,0x1D,0x31,0xD0,0x11,0xA3,0xA4,0x00,0xA0,0xC9,0x03,0x48,0xF6 }, // ASF_Reserved_2
 { 0xE3,0xCB,0x1A,0x4B,0x0B,0x10,0xD0,0x11,0xA3,0x9B,0x00,0xA0,0xC9,0x03,0x48,0xF6 }, // ASF_Reserved_3
 { 0x20,0xDB,0xFE,0x4C,0xF6,0x75,0xCF,0x11,0x9C,0x0F,0x00,0xA0,0xC9,0x03,0x49,0xCB }, // ASF_Reserved_4
 { 0x00,0x2A,0xE2,0xD6,0xDA,0x35,0xD1,0x11,0x90,0x34,0x00,0xA0,0xC9,0x03,0x49,0xBE }, // ASF_Mutex_Language
 { 0x01,0x2A,0xE2,0xD6,0xDA,0x35,0xD1,0x11,0x90,0x34,0x00,0xA0,0xC9,0x03,0x49,0xBE }, // ASF_Mutex_Bitrate
 { 0x02,0x2A,0xE2,0xD6,0xDA,0x35,0xD1,0x11,0x90,0x34,0x00,0xA0,0xC9,0x03,0x49,0xBE }, // ASF_Mutex_Unknown
 { 0xAA,0x60,0x60,0xAF,0x97,0x51,0xD2,0x11,0xB6,0xAF,0x00,0xC0,0x4F,0xD9,0x08,0xE9 }, // ASF_Bandwidth_Sharing_Exclusive
 { 0xAB,0x60,0x60,0xAF,0x97,0x51,0xD2,0x11,0xB6,0xAF,0x00,0xC0,0x4F,0xD9,0x08,0xE9 }, // ASF_Bandwidth_Sharing_Partial
 { 0xEC,0x95,0x95,0x39,0x67,0x86,0x2D,0x4E,0x8F,0xDB,0x98,0x81,0x4C,0xE7,0x6C,0x1E }, // ASF_Payload_Extension_System_Timecode
 { 0x0E,0xEC,0x65,0xE1,0xED,0x19,0xD7,0x45,0xB4,0xA7,0x25,0xCB,0xD1,0xE2,0x8E,0x9B }, // ASF_Payload_Extension_System_File_Name
 { 0x20,0xDC,0x90,0xD5,0xBC,0x07,0x6C,0x43,0x9C,0xF7,0xF3,0xBB,0xFB,0xF1,0xA4,0xDC }, // ASF_Payload_Extension_System_Content_Type
 { 0x54,0xE5,0x1E,0x1B,0xEA,0xF9,0xC8,0x4B,0x82,0x1A,0x37,0x6B,0x74,0xE4,0xC4,0xB8 }, // ASF_Payload_Extension_System_Pixel_Aspect_Ratio
 { 0x50,0x94,0xBD,0xC6,0x7F,0x86,0x07,0x49,0x83,0xA3,0xC7,0x79,0x21,0xB7,0x33,0xAD }, // ASF_Payload_Extension_System_Sample_Duration
 { 0x4E,0xB8,0x98,0x66,0xFA,0x0A,0x30,0x43,0xAE,0xB2,0x1C,0x0A,0x98,0xD7,0xA4,0x4D }, // ASF_Payload_Extension_System_Encryption_Sample_ID
 { 0xB6,0x9B,0x07,0x7A,0xA4,0xDA,0x12,0x4E,0xA5,0xCA,0x91,0xD3,0x8D,0xC1,0x1A,0x8D }  // ASF_Content_Encryption_System_Windows_Media_DRM_Network_Devices
};

static const
char ASF_GUID_Name[][60] =
{
 "Header_Object",
 "Data_Object",
 "Simple_Index_Object",
 "Index_Object",
 "Media_Object_Index_Object",
 "Timecode_Index_Object",
 "File_Properties_Object",
 "Stream_Properties_Object",
 "Header_Extension_Object",
 "Codec_List_Object",
 "Script_Command_Object",
 "Marker_Object",
 "Bitrate_Mutual_Exclusion_Object",
 "Error_Correction_Object",
 "Content_Description_Object",
 "Extended_Content_Description_Object",
 "Content_Branding_Object",
 "Stream_Bitrate_Properties_Object",
 "Content_Encryption_Object",
 "Extended_Content_Encryption_Object",
 "Digital_Signature_Object",
 "Padding_Object",
 "Extended_Stream_Properties_Object",
 "Advanced_Mutual_Exclusion_Object",
 "Group_Mutual_Exclusion_Object",
 "Stream_Prioritization_Object",
 "Bandwidth_Sharing_Object",
 "Language_List_Object",
 "Metadata_Object",
 "Metadata_Library_Object",
 "Index_Parameters_Object",
 "Media_Object_Index_Parameters_Object",
 "Timecode_Index_Parameters_Object",
 "Compatibility_Object",
 "Advanced_Content_Encryption_Object",
 "Audio_Media",
 "Video_Media",
 "Command_Media",
 "JFIF_Media",
 "Degradable_JPEG_Media",
 "File_Transfer_Media",
 "Binary_Media",
 "Web_Stream_Media_Subtype",
 "Web_Stream_Format",
 "No_Error_Correction",
 "Audio_Spread",
 "Reserved_1",
 "Reserved_2",
 "Reserved_3",
 "Reserved_4",
 "Mutex_Language",
 "Mutex_Bitrate",
 "Mutex_Unknown",
 "Bandwidth_Sharing_Exclusive",
 "Bandwidth_Sharing_Partial",
 "Payload_Extension_System_Timecode",
 "Payload_Extension_System_File_Name",
 "Payload_Extension_System_Content_Type",
 "Payload_Extension_System_Pixel_Aspect_Ratio",
 "Payload_Extension_System_Sample_Duration",
 "Payload_Extension_System_Encryption_Sample_ID",
 "Content_Encryption_System_Windows_Media_DRM_Network_Devices"
};

static int ASF_GetGUID(void);
static int ASF_ParseFile(void);
static int ASF_SkipObject(void);
static int ASF_PraseCodecListObject(void);
static int ASF_PraseDataObject(void);
static int ASF_PraseIndexObject(void);
static int ASF_PraseSimpleIndexObject(void);
static int ASF_PraseExtContentDescObject(void);
static int ASF_PraseStreamPropertiesObject(void);

static FS_FILE*   fp_asf;
static unsigned long asf_file_length;
static unsigned long asf_total_time;
static unsigned long asf_max_bitrate;
static unsigned long asf_packet_count;
static unsigned long asf_packet_size;

#ifdef  ASF_DEBUGOUT
static int    is_show_packet = 0;
#endif  // ASF_DEBUGOUT

int main(int argc, char* argv[])
{
 if (argc < 2)
 {
  printf("Arguments Missing.");
  return 1;
 }

 fp_asf = fs_fopen(argv[1], "rb");
 if (0 == fp_asf)
 {
  printf("Open file error.");
  return 1;
 }

#ifdef  ASF_DEBUGOUT
 if (argc > 2)
  is_show_packet = 1;
#endif  // ASF_DEBUGOUT

 if (0 == ASF_ParseFile())
  printf("Prase file OK.");
 else
  printf("Prase file error.");

 fs_fclose(fp_asf);
 int i;
// scanf("%d",&i);
 return 0;
}

static
int ASF_ParseFile(void)//asf解析文件
{
 ASF_FILE_HEADER_OBJECT  afho;
 ASF_FILE_PROPERTIES_OBJECT afpo;
 size_t      length;
 int       id;

 // get file header object
 if (GUID_ASF_HEADER_OBJECT != ASF_GetGUID())
  return -1;

 length = fs_fread(&afho, 1, sizeof(ASF_FILE_HEADER_OBJECT), fp_asf);
 if (sizeof(ASF_FILE_HEADER_OBJECT) != length)
  return -1;

 // get reserved data, must be 0x02, ignore Reserved1
 if (0x02 != afho.Reserved2)
  return -1;

 // find file properties object
 if (0 == afho.NumOfObjects)
  return -1;

#ifdef  ASF_DEBUGOUT
 printf("\tHeader contains %d objects\n", afho.NumOfObjects);
#endif  // ASF_DEBUGOUT

 do
 {
  id = ASF_GetGUID();
  if (GUID_ASF_NONE == id)
   return -1;

  if (GUID_ASF_FILE_PROPERTIES_OBJECT == id)
   break;

  if (GUID_ASF_EXTENDED_CONTENT_DESCRIPTION_OBJECT == id)
  {
   if (-1 == ASF_PraseExtContentDescObject())
    return -1;
  }
  else if (GUID_ASF_CODEC_LIST_OBJECT == id)
  {
   if (-1 == ASF_PraseCodecListObject())
    return -1;
  }
  else if (GUID_ASF_STREAM_PROPERTIES_OBJECT == id)
  {
   if (-1 == ASF_PraseStreamPropertiesObject())
    return -1;
  }
  else
  {
   if (-1 == ASF_SkipObject())
    return -1;
  }
 } while(--afho.NumOfObjects);

 // file properties object not found
 if (0 == afho.NumOfObjects)
  return -1;

 // get file properties object
 length = fs_fread(&afpo, 1, sizeof(ASF_FILE_PROPERTIES_OBJECT), fp_asf);
 if (sizeof(ASF_FILE_PROPERTIES_OBJECT) != length)
  return -1;

 asf_file_length  = afpo.FileSizeLo;
 asf_total_time   = afpo.PlayDurationLo / 10000; // ms
 asf_total_time  += afpo.PlayDurationHi * 429497L;
 asf_max_bitrate  = afpo.MaxBitrate;
 asf_packet_count = afpo.DataPacketsCountLo;
 asf_packet_size  = afpo.MinDataPacketSize;

#ifdef  ASF_DEBUGOUT
 printf("\tFile length : %d bytes\n", asf_file_length);
 printf("\tTotal time  : %02d:%02d.%03d\n", asf_total_time / 1000 / 60,
   (asf_total_time / 1000) % 60, asf_total_time % 1000);
 printf("\tMax bitrate : %d bps\n", asf_max_bitrate);
 printf("\tPacket count: %d\n", asf_packet_count);
 printf("\tPacket size : %d bytes\n", asf_packet_size);
#endif  // ASF_DEBUGOUT

 // see if this file is seekable
 if (afpo.Flags & 2)
 {
#ifdef  ASF_DEBUGOUT
  printf("\t---Seekable---\n");
#endif  // ASF_DEBUGOUT
 }
 else
 {
#ifdef  ASF_DEBUGOUT
  printf("\t---UnSeekable---\n");
#endif  // ASF_DEBUGOUT
 }

 // remain objects in head
 while(--afho.NumOfObjects)
 {
  id = ASF_GetGUID();
  if (GUID_ASF_NONE == id)
   return -1;

  if (GUID_ASF_CODEC_LIST_OBJECT == id)
  {
   if (-1 == ASF_PraseCodecListObject())
    return -1;
  }
  else if (GUID_ASF_EXTENDED_CONTENT_DESCRIPTION_OBJECT == id)
  {
   if (-1 == ASF_PraseExtContentDescObject())
    return -1;
  }
  else if (GUID_ASF_STREAM_PROPERTIES_OBJECT == id)
  {
   if (-1 == ASF_PraseStreamPropertiesObject())
    return -1;
  }
  else
  {
   if (-1 == ASF_SkipObject())
    return -1;
  }
 }

 // data object & index object (if exist)
 for (;;)
 {
  id = ASF_GetGUID();
  if (GUID_ASF_DATA_OBJECT == id)
  {
   if (-1 == ASF_PraseDataObject())
    return -1;
  }
  else if (GUID_ASF_INDEX_OBJECT == id)
  {
   if (-1 == ASF_PraseIndexObject())
    return -1;
  }
  else if (GUID_ASF_SIMPLE_INDEX_OBJECT == id)
  {
   if (-1 == ASF_PraseSimpleIndexObject())
    return -1;
  }
  else if (GUID_ASF_NONE == id)
  {
   break;
  }
  else
  {
   if (-1 == ASF_SkipObject())
   return -1;
  }
 }

 return 0;
}

static
int ASF_GetGUID(void)
{
 int    i;
 size_t   length;
 unsigned char guid[16];

 length = fs_fread(guid, 1, 16, fp_asf);//oxoo429af0
 if (16 != length)
  return GUID_ASF_NONE;

 for (i = 0; i < sizeof(ASF_GUID_Table) / 16; i++)
 {
  if (0 == memcmp(guid, ASF_GUID_Table + i, 16))
  {
#ifdef  ASF_DEBUGOUT
   long pos = fs_ftell(fp_asf) - 16;
   printf("Found %s at %d (0x%X)\n", ASF_GUID_Name[i], pos, pos);
#endif  // ASF_DEBUGOUT
   return i;
  }
 }

 return GUID_ASF_NONE;
}

static
int ASF_SkipObject(void)
{
 unsigned long length;

 if (4 != fs_fread(&length, 1, 4, fp_asf))
  return -1;

 fs_fseek(fp_asf, length - 16 - 4, SEEK_CUR);

 return 0;
}

static
int ASF_PraseDataObject(void)//asf解析数据项
{
 unsigned char errc;
 unsigned char type;
 unsigned long cur_packet_size;
 unsigned long i;
 unsigned long packet_start;
 unsigned short duration;
 unsigned short dummy16;

 // skip size, file id, packets count area
 fs_fseek(fp_asf, 8 + 16 + 8, SEEK_CUR);

 // get reserved data, must be 0x0101
 fs_fread(&dummy16, 1, 2, fp_asf);
 if (0x0101 != dummy16)
  return -1;

 packet_start = fs_ftell(fp_asf);

 // Data Packets
 for (i = 0; i < asf_packet_count; i++)
 {
  // Error correction data
  if (0 == fs_fread(&errc, 1, 1, fp_asf))
   return -1;

  // error correction present
  if (errc & 0x80)
  {
   // Opaque data or type not supported
   if (errc & 0x70)
   {
#ifdef  ASF_DEBUGOUT
    printf("\t---error correction not supported @ %d---\n", fs_ftell(fp_asf) - 1);
#endif  // ASF_DEBUGOUT
    return -1;

   }

   // skip error correction data
   fs_fseek(fp_asf, errc & 0x0F, SEEK_CUR);
   if (0 == fs_fread(&errc, 1, 1, fp_asf))
    return -1;
  }

  // Packet Length Type
  type = (errc >> 5) & 3;

// debug ...
//  type = 0;

  // skip Property Flags
//  fs_fseek(fp_asf, 1, SEEK_CUR);
  unsigned char PropertyFlags;

  if (0 == fs_fread(&PropertyFlags, 1, 1, fp_asf))
   return -1;

  if (0 == type)
  {
   cur_packet_size = asf_packet_size;
  }
  else
  {
   cur_packet_size = 0;
   if (1 == type)  // BYTE
   {
//    if (1 != fs_fread(&cur_packet_size, 1, 1, fp_asf))
//     return -1;
    fs_fseek(fp_asf, 1, SEEK_CUR);
   }
   else if (2== type) // WORD
   {
//    if (2 != fs_fread(&cur_packet_size, 1, 2, fp_asf))
//     return -1;
    fs_fseek(fp_asf, 2, SEEK_CUR);
   }
   else    // DWORD
   {
//    if (4 != fs_fread(&cur_packet_size, 1, 4, fp_asf))
//     return -1;
    fs_fseek(fp_asf, 4, SEEK_CUR);
   }
  }

  if (0 == cur_packet_size)
   cur_packet_size = asf_packet_size;

  {
   // skip Send Time
   unsigned long skip_bytes = 4;
   int    key_frame;

   // Sequence Type
   type = (errc >> 1) & 3;
   // skip Sequence Length
   if (1 == type)
    skip_bytes += 1;
   else if (2 == type)
    skip_bytes += 2;
   else if (3 == type)
    skip_bytes += 4;
   
   // Padding Length Type
   type = (errc >> 3) & 3;
   // skip Padding Length
   if (1 == type)
    skip_bytes += 1;
   else if (2 == type)
    skip_bytes += 2;
   else if (3 == type)
    skip_bytes += 4;
   
   fs_fseek(fp_asf, skip_bytes, SEEK_CUR);
   // get packet duration
   if (2 != fs_fread(&duration, 1, 2, fp_asf))
    return -1;

   if (1 != fs_fread(&key_frame, 1, 1, fp_asf))
    return -1;
   key_frame &= 0xFF;
//   printf("%02X ", key_frame);

   if ((PropertyFlags >> 4) & 0x03)
   {
    int MediaObjectNumber = 0;
    if (1 == ((PropertyFlags >> 4) & 0x03))
    {
     if (1 != fs_fread(&MediaObjectNumber, 1, 1, fp_asf))
      return -1;
    }

    if (2 == ((PropertyFlags >> 4) & 0x03))
    {
     if (2 != fs_fread(&MediaObjectNumber, 1, 2, fp_asf))
      return -1;
    }

    if (3 == ((PropertyFlags >> 4) & 0x03))
    {
     if (4 != fs_fread(&MediaObjectNumber, 1, 4, fp_asf))
      return -1;
    }

//    printf("MediaObjectNumber = %d\r\n", MediaObjectNumber);
   }

   if ((PropertyFlags >> 2) & 0x03)
   {
    int OffsetToObject = 0;
    if (1 == ((PropertyFlags >> 2) & 0x03))
    {
     if (1 != fs_fread(&OffsetToObject, 1, 1, fp_asf))
      return -1;
    }

    if (2 == ((PropertyFlags >> 2) & 0x03))
    {
     if (2 != fs_fread(&OffsetToObject, 1, 2, fp_asf))
      return -1;
    }

    if (3 == ((PropertyFlags >> 2) & 0x03))
    {
     if (4 != fs_fread(&OffsetToObject, 1, 4, fp_asf))
      return -1;
    }

//    printf("OffsetToObject = %d\r\n", OffsetToObject);
   }

   if (PropertyFlags & 0x03)
   {
    size_t RepDataLen = 0;
    if (1 == (PropertyFlags & 0x03))
    {
     if (1 != fs_fread(&RepDataLen, 1, 1, fp_asf))
      return -1;
    }

    if (2 == (PropertyFlags & 0x03))
    {
     if (2 != fs_fread(&RepDataLen, 1, 2, fp_asf))
      return -1;
    }

    if (3 == (PropertyFlags & 0x03))
    {
     if (4 != fs_fread(&RepDataLen, 1, 4, fp_asf))
      return -1;
    }

//    printf("RepDataLen = %d\r\n", RepDataLen);

    if (RepDataLen)
    {
     unsigned char* rep_data = new unsigned char [RepDataLen];
     if (RepDataLen != fs_fread(rep_data, 1, RepDataLen, fp_asf))
     {
      delete [] rep_data;
      return -1;
     }

//     printf("Size=%d, ", *(DWORD*)rep_data);
//     printf("Time=%d\r\n ", *((DWORD*)rep_data + 1));

     delete [] rep_data;
    }
   }
  }

#ifdef  ASF_DEBUGOUT
  if (is_show_packet)
   printf("\t-Found packet %04d @ %d, length=%d, duration=%dms\n", i, packet_start, cur_packet_size, duration);
#endif  // ASF_DEBUGOUT

  // seek to next packet
  packet_start += cur_packet_size;
  fs_fseek(fp_asf, packet_start, SEEK_SET);
 }

 return 0;
}

static
int ASF_PraseIndexObject(void)
{
 unsigned long  entry_time_interval;
 unsigned short  specifiers_count;
 unsigned long  blocks_count, i;
 unsigned long  index_entry_count, j;
 unsigned long  offset;

 // skip object size
 fs_fseek(fp_asf, 8, SEEK_CUR);

 // get Index Entry Time Interval
 if (4 != fs_fread(&entry_time_interval, 1, 4, fp_asf))
  return -1;

 printf("+++Time Interval:%d+++\n", entry_time_interval);

 // get Index Specifiers Count
 if (2 != fs_fread(&specifiers_count, 1, 2, fp_asf))
  return -1;

 // get Index Blocks Count
 if (4 != fs_fread(&blocks_count, 1, 4, fp_asf))
  return -1;

 // skip Index Specifiers (stream number & index type)
 fs_fseek(fp_asf, specifiers_count * (2 + 2), SEEK_CUR);

 // Index Blocks
 for (i = 0; i < blocks_count; i++)
 {
  if (4 != fs_fread(&index_entry_count, 1, 4, fp_asf))
   return -1;

  // skip block positions (QWORD)
  fs_fseek(fp_asf, specifiers_count * 8, SEEK_CUR);

  // index entries
  for (j = 0; j < index_entry_count; j++)
  {
   // only read the 1st offset
   if (4 != fs_fread(&offset, 1, 4, fp_asf))
    return -1;

   if (is_show_packet)
    printf("+++offset:%d+++\n", offset);

   // skip rest offsets
   if (specifiers_count > 1)
    fs_fseek(fp_asf, (specifiers_count - 1) * 4, SEEK_CUR);
  }
 }

 return 0;
}

static
int ASF_PraseSimpleIndexObject(void)
{
 unsigned long time_interval;
 unsigned long time_interval_lo;
 unsigned long time_interval_hi;
 unsigned long entries_count, i;
 unsigned long packet_num;
 unsigned short packet_cnt;

 // skip object size & file ID (GUID)
 fs_fseek(fp_asf, 8 + 16, SEEK_CUR);

 // get time interval (DWORD)
 if (4 != fs_fread(&time_interval_lo, 1, 4, fp_asf))
  return -1;
 if (4 != fs_fread(&time_interval_hi, 1, 4, fp_asf))
  return -1;

 time_interval  = time_interval_lo / 10000; // ms
 time_interval += time_interval_hi * 429497L;

 printf("+++Time Interval:%d+++\n", time_interval);

 // skip Maximum Packet Count
 fs_fseek(fp_asf, 4, SEEK_CUR);

 if (4 != fs_fread(&entries_count, 1, 4, fp_asf))
  return -1;

 for (i = 0; i < entries_count; i++)
 {
  // associated Data Packet
  if (4 != fs_fread(&packet_num, 1, 4, fp_asf))
   return -1;
  if (2 != fs_fread(&packet_cnt, 1, 2, fp_asf))
   return -1;
  if (is_show_packet)
   printf("+++packet:%d(%d)+++\n", packet_num, packet_cnt);
 }

 return 0;
}

static
int ASF_PraseCodecListObject(void)//
{
 unsigned long entries_count, i;
 unsigned short codec_type;
 unsigned short codec_name_len;
 unsigned short codec_desc_len;
 unsigned short codec_info_len;
 char*   buf_string;

 // skip object size & reserved GUID
 fs_fseek(fp_asf, 8 + 16, SEEK_CUR);

 if (4 != fs_fread(&entries_count, 1, 4, fp_asf))
  return -1;

 // Codec Entries
 for (i = 0; i < entries_count; i++)
 {
  // get codec type
  if (2 != fs_fread(&codec_type, 1, 2, fp_asf))
   return -1;

  if (0x01 == codec_type)
   printf("\t**Video Codec***\n");
  else if (0x02 == codec_type)
   printf("\t**Audio Codec**\n");
  else
   printf("\t**Unknown Codec**\n");

  // get codec name length
  if (2 != fs_fread(&codec_name_len, 1, 2, fp_asf))
   return -1;

  // get codec name
  if (codec_name_len)
  {
   buf_string = (char*)malloc(codec_name_len * 4); // WCHAR & CHAR
   if (codec_name_len != fs_fread(buf_string, 2, codec_name_len, fp_asf))
   {
    free(buf_string);
    return -1;
   }

   WideCharToMultiByte(CP_ACP, 0,
        (const unsigned short*)buf_string, codec_name_len,
        buf_string + codec_name_len * 2, codec_name_len * 2,
        NULL, NULL);

   printf("\t ***%s***\n", buf_string + codec_name_len * 2);

   free(buf_string);
  }

  // get codec description length
  if (2 != fs_fread(&codec_desc_len, 1, 2, fp_asf))
   return -1;

  // get codec description
  if (codec_desc_len)
  {
   buf_string = (char*)malloc(codec_desc_len * 4); // WCHAR & CHAR
   if (codec_desc_len != fs_fread(buf_string, 2, codec_desc_len, fp_asf))
   {
    free(buf_string);
    return -1;
   }

   WideCharToMultiByte(CP_ACP, 0,
        (const unsigned short*)buf_string, codec_desc_len,
        buf_string + codec_desc_len * 2, codec_desc_len * 2,
        NULL, NULL);

   if (*(buf_string + codec_desc_len * 2))
    printf("\t ***%s***\n", buf_string + codec_desc_len * 2);

   free(buf_string);
  }

  // get codec information length
  if (2 != fs_fread(&codec_info_len, 1, 2, fp_asf))
   return -1;

  // skip codec information
  fs_fseek(fp_asf, codec_info_len, SEEK_CUR);
 }

 return 0;
}

// function : see if it's a VBR file.
static
int ASF_PraseExtContentDescObject(void)
{
 unsigned short desc_count, i;
 unsigned short desc_name_len;
 unsigned short desc_value_type;
 unsigned short desc_value_len;
 char*   buf_string;

 // skip object size
 fs_fseek(fp_asf, 8, SEEK_CUR);

 // get Content Descriptors Count
 if (2 != fs_fread(&desc_count, 1, 2, fp_asf))
  return -1;

 // prase each Content Descriptor
 for (i = 0; i < desc_count; i++)
 {
  // get Descriptor Name Length
  if (2 != fs_fread(&desc_name_len, 1, 2, fp_asf))
   return -1;

  // get Descriptor Name
  if (desc_name_len)
  {
   desc_name_len /= 2; // CHAR -> WCHAR
   buf_string = (char*)malloc(desc_name_len * 4); // WCHAR & CHAR
   if (desc_name_len != fs_fread(buf_string, 2, desc_name_len, fp_asf))
   {
    free(buf_string);
    return -1;
   }

   WideCharToMultiByte(CP_ACP, 0,
    (const unsigned short*)buf_string, desc_name_len,
    buf_string + desc_name_len * 2, desc_name_len * 2,
    NULL, NULL);
   
   printf("\t==%s==\n", buf_string + desc_name_len * 2);
   
   free(buf_string);
  }

  // get Descriptor Value Data Type
  if (2 != fs_fread(&desc_value_type, 1, 2, fp_asf))
   return -1;

  // get Descriptor Value Length
  if (2 != fs_fread(&desc_value_len, 1, 2, fp_asf))
   return -1;

  if (0 == desc_value_type)  // unicode string
  {
   // get Descriptor Value
   if (desc_value_len)
   {
    desc_value_len /= 2; // CHAR -> WCHAR
    buf_string = (char*)malloc(desc_value_len * 4); // WCHAR & CHAR
    if (desc_value_len != fs_fread(buf_string, 2, desc_value_len, fp_asf))
    {
     free(buf_string);
     return -1;
    }
    
    WideCharToMultiByte(CP_ACP, 0,
     (const unsigned short*)buf_string, desc_value_len,
     buf_string + desc_value_len * 2, desc_value_len * 2,
     NULL, NULL);
    printf("\t ===%s===\n", buf_string + desc_value_len * 2);
    
    free(buf_string);
   }
  }
  else if (0x02 == desc_value_type) // BOOL
  {
   unsigned long val;
   if (4 != fs_fread(&val, 1, 4, fp_asf))
    return -1;

   if (val) // TRUE
    printf("\t ===True===\n");
   else  // FALSE
    printf("\t ===False===\n");
  }
  else // ignore
  {
   fs_fseek(fp_asf, desc_value_len, SEEK_CUR);
  }
 }

 return 0;
}

static
int ASF_PraseStreamPropertiesObject(void)
{
 unsigned long TypeSpecificDataLength;
 unsigned long ErrorCorrectionDataLength;
 unsigned short Flags;
 int    guid;
 unsigned long size;

 if (4 != fs_fread(&size, 1, 4, fp_asf))
  return -1;

 fs_fseek(fp_asf, 4, SEEK_CUR);

 guid = ASF_GetGUID();
 if (-1 == guid) return -1;

 if (GUID_ASF_AUDIO_MEDIA != guid)
 {
  fs_fseek(fp_asf, size - 16 - 8 - 16, SEEK_CUR);
  return 0;
 }

 // skip Error Correction Type & Time Offset
 fs_fseek(fp_asf, 16 + 8, SEEK_CUR);

 if (4 != fs_fread(&TypeSpecificDataLength, 1, 4, fp_asf))
  return -1;

 if (4 != fs_fread(&ErrorCorrectionDataLength, 1, 4, fp_asf))
  return -1;

 if (2 != fs_fread(&Flags, 1, 2, fp_asf))
  return -1;

 if (Flags & 0x8000)
 {
  printf("\t!!! Encrypted !!!\n");
 }

 // skip Reserved field
 fs_fseek(fp_asf, 4, SEEK_CUR);

 // read TypeSpecificData, assume this is a audio file
// printf("\tTypeSpecData@%d\r\n", fs_ftell(fp_asf) + 4);
 unsigned short id, channel, align, sbit;
 unsigned long sps, bps;

 if (2 != fs_fread(&id, 1, 2, fp_asf))
  return -1;

 if (2 != fs_fread(&channel, 1, 2, fp_asf))
  return -1;

 if (4 != fs_fread(&sps, 1, 4, fp_asf))
  return -1;

 if (4 != fs_fread(&bps, 1, 4, fp_asf))
  return -1;

 if (2 != fs_fread(&align, 1, 2, fp_asf))
  return -1;

 if (2 != fs_fread(&sbit, 1, 2, fp_asf))
  return -1;

 printf("\tCodecID:%04X\r\n",     id);
 printf("\tChannel:%d\r\n",       channel);
 printf("\tSampleRate:%d\r\n",    sps);
 printf("\tBytePerSecond:%d\r\n", bps);
 printf("\tBlockAlign:%d\r\n",    align);
 printf("\tBitsOfSample:%d\r\n",  sbit);

 TypeSpecificDataLength -= 16;

 // skip Error Correction Data
 fs_fseek(fp_asf, TypeSpecificDataLength + ErrorCorrectionDataLength, SEEK_CUR);
 return 0;
}

/******************************************************************************
*                              END OF FILE
******************************************************************************/

// #include "stdio.h"
// int main(int argc, char **argv)
// {
//  printf("%s",argv[0]);
//  printf("%s",argv[1]);
//  //printf("%s",argv[2]);
//  int i;
//  scanf("%d",&i);
// }

 类似资料: