/* Copyright (c) MediaArea.net SARL. All Rights Reserved. * * Use of this source code is governed by a BSD-style license that can * be found in the License.html file in the root of the source tree. */ //--------------------------------------------------------------------------- // Pre-compilation #include "MediaInfo/PreComp.h" #ifdef __BORLANDC__ #pragma hdrstop #endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Setup.h" //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #if defined(MEDIAINFO_RM_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include #include #include "MediaInfo/Multiple/File_Rm.h" using namespace ZenLib; //--------------------------------------------------------------------------- namespace MediaInfoLib { // https://common.helixcommunity.org/2003/HCS_SDK_r5/htmfiles/rmff.htm // http://wiki.multimedia.cx/index.php?title=RealMedia //*************************************************************************** // Const //*************************************************************************** //--------------------------------------------------------------------------- namespace Elements { const int32u RMF=0x2E524D46; const int32u CONT=0x434F4E54; const int32u DATA=0x44415441; const int32u INDX=0x494E4458; const int32u MDPR=0x4D445052; const int32u PROP=0x50524F50; const int32u RJMD=0x524A4D44; const int32u RMJE=0x524D4A45; const int32u RMMD=0x524D4D44; const int32u TAG =0x54414700; } //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_Rm::File_Rm() :File__Analyze() { //In FromMKV_StreamType=Stream_Max; } //*************************************************************************** // Buffer - File header //*************************************************************************** //--------------------------------------------------------------------------- bool File_Rm::FileHeader_Begin() { if (IsSub) return true; if (4>Buffer_Size) return false; if (Buffer[0]!=0x2E //".RMF" || Buffer[1]!=0x52 || Buffer[2]!=0x4D || Buffer[3]!=0x46) { Reject(); return false; } return true; } //*************************************************************************** // Buffer //*************************************************************************** //--------------------------------------------------------------------------- void File_Rm::Header_Parse() { //Specific case if (FromMKV_StreamType!=Stream_Max) { //Filling Header_Fill_Code(0, __T("Real Media Header")); Header_Fill_Size(Element_Size); return; } //Parsing int32u Name, Size; Get_C4 (Name, "Name"); if (Name==Elements::RMMD) { Size=8; //Name + Size of the Metadata section (after Version) in bytes. } else if (Name==Elements::RJMD) { Skip_B4( "Version"); Get_B4 (Size, "Size"); Size+=8; //Name + Version + Size of the section (after Version) in bytes. if (Element_Size>=12) Element_Offset-=8; //Is valid, so we must keep Version and size in the stream } else if (Name==Elements::RMJE) { Size=12; } else if ((Name&0xFFFFFF00)==Elements::TAG) { Name=Elements::TAG; Element_Offset-=4; Size=0; } else { Get_B4 (Size, "Size"); } //Filling Header_Fill_Code(Name, Ztring().From_CC4(Name)); Header_Fill_Size(Size); } //--------------------------------------------------------------------------- void File_Rm::Data_Parse() { //Specific case if (FromMKV_StreamType!=Stream_Max) { switch (FromMKV_StreamType) { case Stream_Video : MDPR_realvideo(); break; case Stream_Audio : MDPR_realaudio(); break; default : ; } Finish("RealMedia"); return; } //Parsing DATA_BEGIN ATOM( RMF) ATOM(CONT) LIST_SKIP(DATA) ATOM(INDX) ATOM(MDPR) ATOM(PROP) ATOM(RJMD) ATOM(RMJE) ATOM(RMMD) ATOM(TAG) DATA_END } //*************************************************************************** // Elements //*************************************************************************** #define NAME_VERSION(ELEMENT_NAME) \ Element_Name(ELEMENT_NAME); \ int16u Version; \ { \ Get_B2(Version, "ObjectVersion"); \ } \ #define INTEGRITY_VERSION(_VERSION) \ if (Version>_VERSION) \ { \ Skip_XX(Element_Size-Element_Offset, "Data"); \ return; \ } \ //--------------------------------------------------------------------------- void File_Rm::RMF() { NAME_VERSION("Real Media Format"); INTEGRITY_VERSION(1); //Parsing if (Element_Size==4) Skip_B2( "file_version"); //The version of the RealMedia file. else Skip_B4( "file_version"); //The version of the RealMedia file. Skip_B4( "num_headers"); //The number of headers in the header section that follow the RealMedia File Header. //Filling Accept("RealMedia"); Fill(Stream_General, 0, General_Format, "RealMedia"); } //--------------------------------------------------------------------------- void File_Rm::CONT() { NAME_VERSION("Content"); INTEGRITY_VERSION(0); //Parsing Ztring title, author, copyright, comment; int16u title_len, author_len, copyright_len, comment_len; Get_B2 (title_len, "title_len"); //The length of the title data in bytes. Get_Local(title_len, title, "title"); //An array of ASCII characters that represents the title information for the RealMedia file. Get_B2 (author_len, "author_len"); //The length of the author data in bytes. Get_Local(author_len, author, "author"); //An array of ASCII characters that represents the author information for the RealMedia file. Get_B2 (copyright_len, "copyright_len"); //The length of the copyright data in bytes. Get_Local(copyright_len, copyright, "copyright"); //An array of ASCII characters that represents the copyright information for the RealMedia file. Get_B2 (comment_len, "comment_len"); //The length of the comment data in bytes. Get_Local(comment_len, comment, "comment"); //An array of ASCII characters that represents the comment information for the RealMedia file. //Filling Fill(Stream_General, 0, General_Title, title); Fill(Stream_General, 0, General_Performer, author); Fill(Stream_General, 0, General_Copyright, copyright); Fill(Stream_General, 0, General_Comment, comment); } //--------------------------------------------------------------------------- void File_Rm::DATA() { NAME_VERSION("Data"); //Currently, we stop here, enough info Finish("RealMedia"); return; /* //Parsing int32u num_packets; int16u length; int8u flags; Get_B4 (num_packets, "num_packets"); //Number of packets in the data chunk. Skip_B4( "next_data_header"); //Offset from start of file to the next data chunk. A non-zero value refers to the file offset of the next data chunk. A value of zero means there are no more data chunks in this file. This field is not typically used. for (int32u Pos=0; Pos10) { Pos=num_packets; Element_Info1("(...)"); } Element_End0(); } */ } //--------------------------------------------------------------------------- void File_Rm::INDX() { NAME_VERSION("INDeX"); //Parsing int32u num_indices; Get_B4 (num_indices, "num_indices"); //Number of index records in the index chunk. Skip_B2( "stream_number"); //The stream number for which the index records in this index chunk are associated. Skip_B4( "next_index_header"); //Offset from start of file to the next index chunk. This member enables RealMedia file format readers to find all the index chunks quickly. A value of zero for this member indicates there are no more index headers in this file. for (int32u Pos=0; Pos