Last active
August 29, 2015 14:03
-
-
Save tony0x59/2ecc27cad42986aee163 to your computer and use it in GitHub Desktop.
FLV File format parser for 010 Editor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //----------------------------------- | |
| //--- 010 Editor v5.0.1 Binary Template | |
| // | |
| // File: FLVTemplateEx.bt | |
| // Author: lafei(indep@263.net), Tony(HanningKong@gmail.com) | |
| // Revision: 3.0 | |
| // Purpose: Defines a template for | |
| // parsing FLV files. | |
| // Tony Update: base lafie version, add a lot of data deail info: | |
| // 1. Metadata detail info | |
| // 2. Video detail info | |
| // 3. data verify | |
| //----------------------------------- | |
| // Define structures used in FLV files | |
| typedef struct { | |
| CHAR signature[3]; //"FLV" | |
| UBYTE version; | |
| UBYTE dummy : 5; | |
| UBYTE audio : 1; //1 if audio present | |
| UBYTE dummy2 : 1; | |
| UBYTE video : 1; //1 if video present | |
| DWORD dataoffset; //in abs. file offset 4byte | |
| DWORD zero; //previous tag size | |
| } HEADER; | |
| // Define Metadata info | |
| typedef struct { | |
| } ScriptDataLongString; | |
| /*------ base unit -------*/ | |
| struct ScriptDataString; | |
| struct ScriptDataValue; | |
| typedef struct { | |
| ScriptDataString ObjectName; | |
| ScriptDataValue ObjectData (ObjectName.stringData); | |
| } ScriptDataObject; | |
| typedef struct { | |
| UINT16 stringLength; | |
| CHAR stringData[stringLength]; | |
| } ScriptDataString; | |
| struct ScriptDataValue; | |
| typedef struct { | |
| UINT32 ECMArrayLength; | |
| ScriptDataObject Variables[ECMArrayLength] <optimize=false>; | |
| } ScriptDataECMAArray; | |
| typedef struct { | |
| DOUBLE DateTime; | |
| INT16 LocalDateTimeOffset; | |
| } ScriptDataDate; | |
| local uchar buffer[64]; | |
| typedef struct (char name[]) { | |
| UBYTE type : 8; | |
| Printf("ScriptDataName:%s\n", name); | |
| // Value | |
| switch (type) { | |
| case 0: DOUBLE value <comment="Num">; break; | |
| case 1: UBYTE value <comment="Bool">; break; | |
| case 2: ScriptDataString value <comment="Str">; break; | |
| case 3: | |
| { | |
| local BYTE isEnd; | |
| do { | |
| ScriptDataObject value2 <comment="Obj">; | |
| ReadBytes(buffer, FTell(), 3); | |
| isEnd = buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 9; | |
| } while (!isEnd); | |
| CHAR endFlag[3]; | |
| break; | |
| } | |
| case 7: UINT16 value <comment="Reference">; break; | |
| case 8: ScriptDataECMAArray value <comment="Array">; break; | |
| //case 9: UINT value : 24 <comment="Object end marker">; break; | |
| case 10: | |
| { | |
| UINT32 numberItems; | |
| ScriptDataValue value(name)[numberItems] <comment="Strict array",optimize=false>; | |
| break; | |
| } | |
| case 11: ScriptDataDate value <comment="Date">; break; | |
| case 12: ScriptDataLongString value <comment="Long str">; break; | |
| } | |
| } ScriptDataValue; | |
| typedef struct { | |
| ScriptDataValue name ("FLVTagBody"); | |
| ScriptDataValue value (name.value.stringData); | |
| } ScriptTagBody; | |
| typedef struct { | |
| } EncryptedBody; | |
| typedef struct { | |
| if (1) { | |
| ScriptTagBody tagBody; | |
| } else { | |
| EncryptedBody encBody; | |
| } | |
| CHAR End[3]; | |
| if (End[2] != 9) { | |
| Warning( "End should be 9: %d", End[2]); | |
| return -1; | |
| } | |
| } ScriptData; | |
| /* SPS PPS from ISO/IEC 14496-15 */ | |
| typedef struct { | |
| UINT configurationVersion : 8; | |
| if (configurationVersion != 1) { | |
| Warning( "Value should be %d: %d", configurationVersion, 1); | |
| return -1; | |
| } | |
| UINT AVCProfileIndication : 8; | |
| UINT profile_compatibility : 8; | |
| UINT AVCLevelIndication : 8; | |
| UBYTE : 6; | |
| UBYTE lengthSizeMinusOne : 2; | |
| UBYTE : 3; | |
| UBYTE numOfSequenceParameterSets : 5; | |
| // SPS data | |
| struct { | |
| UINT16 sequenceParameterSetLength; | |
| UBYTE sequenceParameterSetNALUnit[sequenceParameterSetLength]; | |
| } sequenceValue[numOfSequenceParameterSets] <optimize=false>; | |
| // PPS data | |
| UBYTE numOfPictureParameterSets : 8; | |
| struct { | |
| UINT16 pictureParameterSetLength; | |
| UBYTE pictureParameterSetNALUnit[pictureParameterSetLength]; | |
| } pictureValue[numOfPictureParameterSets] <optimize=false>; | |
| } AVDecoderConfigurationRecord; | |
| local UINT taglen; | |
| typedef struct { | |
| UINT reserved : 2; | |
| if (reserved != 0) { | |
| Warning( "reserved should be 0: %d", reserved); | |
| return -1; | |
| } | |
| UINT filter : 1; | |
| UINT type : 5; | |
| UINT datasize : 24; | |
| UINT timestamp : 24; | |
| UINT timestamp_ex : 8; | |
| CHAR streamid[3]; | |
| taglen = datasize - 1; | |
| Printf("tag type:%x length: %x\n", type, taglen); | |
| if(type==8) //audio | |
| { | |
| struct { | |
| UBYTE fmt : 4; | |
| UBYTE sr : 2; | |
| UBYTE bits : 1; | |
| UBYTE channels : 1; | |
| if(fmt==10) { | |
| --taglen; | |
| UBYTE frmtype; | |
| } | |
| UBYTE data[taglen]; | |
| } AudioData; | |
| } | |
| else if(type==9)//video | |
| { | |
| struct { | |
| UBYTE FrameType : 4 <bgcolor=cRed>; | |
| /* | |
| 1: keyframe (for AVC, a seekable frame) | |
| 2: inter frame (for AVC, a non- seekable frame) | |
| 3: disposable inter frame (H.263 only) | |
| 4: generated keyframe (reserved for server use only) | |
| 5: video info/command frame | |
| */ | |
| UBYTE CodecID : 4; | |
| /* | |
| 1: JPEG (currently unused) 2: Sorenson H.263 | |
| 3: Screen video | |
| 4: On2 VP6 | |
| 5: On2 VP6 with alpha channel 6: Screen video version 2 | |
| 7: AVC | |
| */ | |
| if (CodecID == 7) //AVC | |
| { | |
| taglen -= 4; | |
| UINT AVCPacketType : 8; | |
| /* | |
| 0: AVC sequence header | |
| 1: AVC NALU | |
| 2: AVC end of sequence (lower level NALU sequence ender is not required or supported) | |
| */ | |
| UINT CompositionTime : 24; | |
| if (AVCPacketType == 0) { // header | |
| SetBackColor( cGreen ); | |
| local uint64 startPos = FTell(); | |
| AVDecoderConfigurationRecord header; | |
| local uint64 endPos = FTell(); | |
| local uint64 size = endPos - startPos; | |
| if (size != taglen) { | |
| Warning("AVDecoderConfigurationRecord size error: %ld %ld", size, taglen); | |
| if (size < taglen) { | |
| UBYTE paddingData[taglen -size] <bgcolor=cRed>; //error data | |
| } else { | |
| return -1; | |
| } | |
| } | |
| } | |
| else if (AVCPacketType == 1) { // NALU | |
| UINT32 naluLen; | |
| UBYTE : 3; //ignore | |
| UBYTE naluType : 5; | |
| taglen -= 5; | |
| UBYTE data[taglen]; | |
| } | |
| else { | |
| UBYTE data[taglen]; | |
| } | |
| } | |
| SetForeColor( cNone ); | |
| } VideoData; | |
| } | |
| else if(type==18)//script | |
| { | |
| ScriptData scriptData <bgcolor=cLtPurple>; | |
| } | |
| else { | |
| UBYTE data[taglen]; | |
| } | |
| UINT32 lastsize; //last tag size | |
| //for debugging | |
| //Printf("lastsize: %x\n",lastsize); | |
| //Printf("Pos: %x\n",FTell()); | |
| } Tag; | |
| BigEndian(); | |
| SetBackColor( cLtGray ); | |
| HEADER hdr; | |
| // Check for header | |
| if( hdr.signature != "FLV" ) | |
| { | |
| Warning( "File is not a FLV. Template stopped." ); | |
| return -1; | |
| } | |
| if( hdr.version != 1 ) | |
| { | |
| Warning( "Unsupported FLV version. Template stopped." ); | |
| return -1; | |
| } | |
| // Define the bytes of the data | |
| SetBackColor( cNone ); | |
| while( !FEof() ) | |
| { | |
| Tag tag; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment