1. 程式人生 > >RM RMVB檔案格式分析

RM RMVB檔案格式分析

1 RM RMVB整體結構

RM檔案格式是標準的標記符檔案格式,RM檔案格式把標記符塊組合成頭塊,資料快,索引塊,這些標記符塊的組合方法如下:

.RMF頭塊

RealMedia File Header(RM 檔案頭)

PROP屬性頭

Properties(屬性頭)

MDPR媒體屬性頭

(可含多個)

Media Properties(媒體屬性頭1

Media Properties(媒體屬性頭2

------(其他媒體屬性頭3—n

CONT內容描述頭

Content Properties(內容描述頭)

DATA資料段

(可含多個)

Data Chunk Header(資料塊頭)

Data Packets(資料包)

------(其他資料包)

Data Chunk Header(資料塊頭)

Data Packets(資料包)

------(其他資料包)

---------(其他資料段)

INDX索引段

(可含多個)

Index Section(索引段)

------(其他索引段)

RM檔案格式是標記符檔案格式,所以塊的先後次序並不確定,只有RM檔案頭必須是檔案的第一個塊。 2 RMF檔案頭      在RM檔案中只有一種RM檔案頭,因為RM檔案頭的內容可能隨著RMF的版本不同而改變,所以頭結構裡面有個版本域來指明有什麼其他的額外域存在。其資料結構如下:

typedef struct RealMedia_File_Header

{

       UINT32 object_id;   // object_id,RM檔案的唯一標識(“.RMF”),所有的RM檔案都以這個標識開頭,用32個二進位制位表示;

       UINT32 size;       // size,RM頭段的大小,用32個二進位制位表示;//上述結構體中五個元素都含有時,為18位元組

       UINT16 object_version;     // object_version,RM檔案頭的版本,決定結構中其他成員的取捨,用16個二進位制位表示;

       if((object_version==0)||(object_version= =1))

       {

             UINT32 file_version;    // file_version,RM檔案的版本,用32個二進位制位表示;

             UINT32 num_headers;    //  num_headers,頭段中RM檔案頭後面的包含的頭的個數,用32個二進位制位表示。

       }

};

注:num_headers具體指那些頭的個數,不明,有檔案該值為7,但僅包含1個PROP,3個MPPR,1個CONT,如果算上.RMF共6個;另外有檔案該值為7,包含有1個PROP,3個MPPR,1個CONT,如果算上.RMF共6個,如果算上INDX(3個)則總數是9個。

如圖1.png

object_id  = 2E  52  4D  46  .RMF        size = 00 00 00 12     18     object_version = 00 01       file_version = 00 00 00 00      num_headers = 00 00 00 07

3 PROP屬性頭

       屬性頭描述了RM檔案的一般媒體屬性,RM系統的元件根據屬性頭進行適當的配置來 處理RM檔案或RM流中資料。在RM檔案中只有一個屬性頭,資料結構如下:

typedef struct Properties_Header

{

       UINT32 object_id; [0-3]                 //   object_id,屬性頭唯一標識 (“PROP”),用32個二進位制位表示;

       UINT32 size;[4-7]                          //   size,屬性頭大小,用32個二進位制位表示;10+40位元組

       UINT16 object_version;[8-9]         // object_version,RM檔案頭版本,決定結構中其他成員的取捨,此結構中此值為零,用16個二進位制位表 示;

       if(object_version==0)

       {

             UINT32 max_bit_rate;[10 - 13]                 //  網路傳輸 時要求的最大位元率,用32個二進位制位表示;

             UINT32 avg_bit_rate;[14 - 17]                  //  網路傳輸 時要求的平均位元率,用32個二進位制位表示;

             UINT32 max_packet_size;[18 - 21]          // 最 大媒體資料包的大小(以位元組計算),用32個二進位制位表示;

             UINT32 avg_packet_size;[22 - 25]           //  平 均媒體資料包的大小(以位元組計算),用32個二進位制位表示;

              UINT32 num_packets;[26 - 29]               //   媒體資料包 個數,用32個二 進位制位表示;

              UINT32 duration;[30 - 33]                       //   媒體檔案應該播放 的時間(以毫秒計算),用32個二進位制位表示;

             UINT32 preroll; [34 - 37]                          //   回放之前的預留毫秒 數,用32個二進 制位表示;

              UINT32 index_offset; [38 - 41]               //  索引頭到檔案開始的偏移,這個值可為零,表明沒有索引段,用32個二進位制位表示;

             UINT32 data_offset; [42 - 45]                    //  資料段到檔案開始的偏移,用32個二進位制位表示(注:在RM檔案中可以有不止一個數據塊頭,這個值只表示第一個資料塊頭到檔案開始的偏移,其他資料塊頭的偏移可以從資料塊頭中next_data_header域得到);

             UINT16 num_streams; [46 - 47]             //  在主頭段中 包含的全部媒體屬性頭(MDPR的個數,用16個二進位制位表示;

             UINT16 flags; [48 - 49]                          //   包含檔案資訊的位掩碼, 用16個二進位制位 表示。具體資訊如表5.1,其它位應設定為零。

       }

};

表1

檔案資訊的位掩碼錶

標誌

描述

0

儲存允許

如果是1,就允許儲存此檔案到磁碟

1

最佳播放

如果是1, 建議使用額外的快取

2

實況

如果是1, 表明媒體流來自實況廣播

圖2 4 MDPR 媒體屬性頭

Media_Properties

{

       UINT32 object_id;[0 - 3]    // object_id:媒體屬性頭唯一標識,為“MDPR” 4

       UINT32 size;[4 - 7]     // size,表明媒體屬性頭的大小; 4

       UINT16 object_version;[8 - 9]   // object_version,媒體屬性頭版本號; 2

       if(object_version==0)

       {

              UINT16 stream_number; [10 - 11]    // stream_number流的標識,表明RM媒體檔案中此媒體屬性頭代表的是哪個資料流(視訊資料流或音訊資料流),在資料段中的每個資料包中都包含有類似的標識以表明資料是屬於哪個媒體流。當版本號為零時此成員才存在; 2

             UINT32 max_bit_rate; [12 - 15]   // max_bit_rate,網路上傳輸此媒體流所要求的最大位元率,當版本號為零時此成員才存在; 4

             UINT32 avg_bit_rate; [16 - 19]   // avg_bit_rate,網路上傳輸此媒體流所要求的平均位元率,當版本號為零時此成員才存在; 4

             UINT32 max_packet_size;[20 - 23]  // max_packet_size,媒體流資料包的最大容量(以位元組計算),當版本號為零時此成員才存在; 4

             UINT32 avg_packet_size;[24 - 27]   // avg_packet_size,媒體流資料包的平均容量(以位元組計算),當版本號為零時此成員才存在;    4

             UINT32 start_time;[28 - 31]   // start_time開始時間(毫秒錶示),用於加到資料包時間標誌上,當版本號為零時此成員才存在; 4

             UINT32 preroll; [32 - 35]    // preroll,和start_time相反的時間尺度(毫秒錶示),用於從資料包時間標誌中減去的值,當版本號為零時此成員才存在; 4

             UINT32 duration; [36 -39]    // duration,流的持續時間,當版本號為零時此成員才存在; 4

             UINT8  stream_name_size;[40 - 40]  //  stream_name_size,流名稱所佔位元組數,當版本號為零時此成員才存在,用8個二進位制位表示; 1

              UINT8 stream_name;[41 - 41]    // stream_name,流的名稱,版本號為零時此成員才存在,大小不定 1

             UINT8 mime_type_size;[42 - 42]    // mime_type_size,表明下個成員(mime_type)所佔的儲存空間,版本號為零時此成員才存在,用8個二進位制位表示; 1

             UINT8[mime_type_size]   mime_type;[43 - 43]

//決定Type_Specific_Data   mime_type,和流相關的MIME形式的型別或子型別字串,版本號為零時此成員才存在,大小不定; 1

             UINT32 type_specific_len;[44 - 47]    // type_specific_len,表明下個成員(pe_specific_data)所佔的儲存空間,版本號為零時此成員才存在,; 4

             UINT8[type_specific_len]   Type_Specific_Data;[48 - 51]     // Type_Specific_Data,一般用來儲存對流進行處理的特殊資料,版本號為零時此成員才存在,大小不定。 4

       }

};

mime_type1audio/x-pn-realaudio

                    2video/x-pn-realvideo

                    3logical-fileinfo

圖4

 5 CONT  內容描述頭

6 DATA資料段(包含多個)

7  INDEX索引