diff options
Diffstat (limited to 'ebml/src')
-rw-r--r-- | ebml/src/bin/experiment.rs | 13 | ||||
-rw-r--r-- | ebml/src/matroska.rs | 282 | ||||
-rw-r--r-- | ebml/src/mod.rs | 48 | ||||
-rw-r--r-- | ebml/src/read.rs | 96 | ||||
-rw-r--r-- | ebml/src/write.rs | 36 |
5 files changed, 475 insertions, 0 deletions
diff --git a/ebml/src/bin/experiment.rs b/ebml/src/bin/experiment.rs new file mode 100644 index 0000000..7d8cede --- /dev/null +++ b/ebml/src/bin/experiment.rs @@ -0,0 +1,13 @@ +use std::fs::File; + +use jellyremuxer::format::matroska::read::EbmlReader; + +fn main() { + env_logger::init_from_env("LOG"); + let f = File::open(std::env::args().skip(1).next().unwrap()).unwrap(); + let mut r = EbmlReader::new(f); + + loop { + println!("{:?}", r.read_tag().unwrap()); + } +} diff --git a/ebml/src/matroska.rs b/ebml/src/matroska.rs new file mode 100644 index 0000000..f53a1e8 --- /dev/null +++ b/ebml/src/matroska.rs @@ -0,0 +1,282 @@ + + + +define_ebml! { + global Crc32[0xbf]: Binary, + global Void[0xec]: Binary, + + Ebml[0x1a45dfa3] { + EbmlVersion[0x4286]: u64, + EbmlReadVersion[0x42f7]: u64, + EbmlMaxIdLength[0x42f2]: u64, + EbmlMaxSizeLength[0x42f3]: u64, + DocType[0x4282]: Utf8, + DocTypeVersion[0x4287]: u64, + DocTypeReadVersion[0x4285]: u64, + DocTypeExtension[0x4281]: { + DocTypeExtensionName[0x4283]: Utf8, + DocTypeExtensionVersion[0x4284]: u64, + }, + }, +} +// #[id=0x18538067] Segment(Master), +// #[id=0x1941A469] Segment/Attachments(Master), +// #[id=0x61A7] Segment/Attachments/AttachedFile(Master), +// #[id=0x465C] Segment/Attachments/AttachedFile/FileData(Vec<u8>), +// #[id=0x467E] Segment/Attachments/AttachedFile/FileDescription(Utf8), +// #[id=0x4660] Segment/Attachments/AttachedFile/FileMimeType(Utf8), +// #[id=0x466E] Segment/Attachments/AttachedFile/FileName(Utf8), +// #[id=0x4675] Segment/Attachments/AttachedFile/FileReferral(Vec<u8>), +// #[id=0x46AE] Segment/Attachments/AttachedFile/FileUID(u64), +// #[id=0x4662] Segment/Attachments/AttachedFile/FileUsedEndTime(u64), +// #[id=0x4661] Segment/Attachments/AttachedFile/FileUsedStartTime(u64), + +// #[id=0x1043A770] Segment/Chapters(Master), +// #[id=0x45B9] Segment/Chapters/EditionEntry(Master), +// #[id=0xB6] Segment/Chapters/EditionEntry/ChapterAtom(Master), +// #[id=0x6944] Segment/Chapters/EditionEntry/ChapterAtom/ChapProcess(Master), +// #[id=0x6955] Segment/Chapters/EditionEntry/ChapterAtom/ChapProcess/ChapProcessCodecID(u64), +// #[id=0x6911] Segment/Chapters/EditionEntry/ChapterAtom/ChapProcess/ChapProcessCommand(Master), +// #[id=0x6933] Segment/Chapters/EditionEntry/ChapterAtom/ChapProcess/ChapProcessCommand/ChapProcessData(Vec<u8>), +// #[id=0x6922] Segment/Chapters/EditionEntry/ChapterAtom/ChapProcess/ChapProcessCommand/ChapProcessTime(u64), +// #[id=0x450D] Segment/Chapters/EditionEntry/ChapterAtom/ChapProcess/ChapProcessPrivate(Vec<u8>), +// #[id=0x80] Segment/Chapters/EditionEntry/ChapterAtom/ChapterDisplay(Master), +// #[id=0x437E] Segment/Chapters/EditionEntry/ChapterAtom/ChapterDisplay/ChapCountry(Utf8), +// #[id=0x437C] Segment/Chapters/EditionEntry/ChapterAtom/ChapterDisplay/ChapLanguage(Utf8), +// #[id=0x437D] Segment/Chapters/EditionEntry/ChapterAtom/ChapterDisplay/ChapLanguageIETF(Utf8), +// #[id=0x85] Segment/Chapters/EditionEntry/ChapterAtom/ChapterDisplay/ChapString(Utf8), +// #[id=0x4598] Segment/Chapters/EditionEntry/ChapterAtom/ChapterFlagEnabled(u64), +// #[id=0x98] Segment/Chapters/EditionEntry/ChapterAtom/ChapterFlagHidden(u64), +// #[id=0x63C3] Segment/Chapters/EditionEntry/ChapterAtom/ChapterPhysicalEquiv(u64), +// #[id=0x6EBC] Segment/Chapters/EditionEntry/ChapterAtom/ChapterSegmentEditionUID(u64), +// #[id=0x6E67] Segment/Chapters/EditionEntry/ChapterAtom/ChapterSegmentUID(Vec<u8>), +// #[id=0x5654] Segment/Chapters/EditionEntry/ChapterAtom/ChapterStringUID(Utf8), +// #[id=0x92] Segment/Chapters/EditionEntry/ChapterAtom/ChapterTimeEnd(u64), +// #[id=0x91] Segment/Chapters/EditionEntry/ChapterAtom/ChapterTimeStart(u64), +// #[id=0x8F] Segment/Chapters/EditionEntry/ChapterAtom/ChapterTrack(Master), +// #[id=0x89] Segment/Chapters/EditionEntry/ChapterAtom/ChapterTrack/ChapterTrackUID(u64), +// #[id=0x73C4] Segment/Chapters/EditionEntry/ChapterAtom/ChapterUID(u64), +// #[id=0x45DB] Segment/Chapters/EditionEntry/EditionFlagDefault(u64), +// #[id=0x45BD] Segment/Chapters/EditionEntry/EditionFlagHidden(u64), +// #[id=0x45DD] Segment/Chapters/EditionEntry/EditionFlagOrdered(u64), +// #[id=0x45BC] Segment/Chapters/EditionEntry/EditionUID(u64), + +// #[id=0x1F43B675] Segment/Cluster(Master), +// #[id=0xA0] Segment/Cluster/BlockGroup(Master), +// #[id=0xA1] Segment/Cluster/BlockGroup/Block(Vec<u8>), +// #[id=0x75A1] Segment/Cluster/BlockGroup/BlockAdditions(Master), +// #[id=0xA6] Segment/Cluster/BlockGroup/BlockAdditions/BlockMore(Master), +// #[id=0xEE] Segment/Cluster/BlockGroup/BlockAdditions/BlockMore/BlockAddID(u64), +// #[id=0xA5] Segment/Cluster/BlockGroup/BlockAdditions/BlockMore/BlockAdditional(Vec<u8>), +// #[id=0x9B] Segment/Cluster/BlockGroup/BlockDuration(u64), +// #[id=0xA2] Segment/Cluster/BlockGroup/BlockVirtual(Vec<u8>), +// #[id=0xA4] Segment/Cluster/BlockGroup/CodecState(Vec<u8>), +// #[id=0x75A2] Segment/Cluster/BlockGroup/DiscardPadding(Integer), +// #[id=0xFB] Segment/Cluster/BlockGroup/ReferenceBlock(Integer), +// #[id=0xC8] Segment/Cluster/BlockGroup/ReferenceFrame(Master), +// #[id=0xC9] Segment/Cluster/BlockGroup/ReferenceFrame/ReferenceOffset(u64), +// #[id=0xCA] Segment/Cluster/BlockGroup/ReferenceFrame/ReferenceTimestamp(u64), +// #[id=0xFA] Segment/Cluster/BlockGroup/ReferencePriority(u64), +// #[id=0xFD] Segment/Cluster/BlockGroup/ReferenceVirtual(Integer), +// #[id=0x8E] Segment/Cluster/BlockGroup/Slices(Master), +// #[id=0xE8] Segment/Cluster/BlockGroup/Slices/TimeSlice(Master), +// #[id=0xCB] Segment/Cluster/BlockGroup/Slices/TimeSlice/BlockAdditionID(u64), +// #[id=0xCE] Segment/Cluster/BlockGroup/Slices/TimeSlice/Delay(u64), +// #[id=0xCD] Segment/Cluster/BlockGroup/Slices/TimeSlice/FrameNumber(u64), +// #[id=0xCC] Segment/Cluster/BlockGroup/Slices/TimeSlice/LaceNumber(u64), +// #[id=0xCF] Segment/Cluster/BlockGroup/Slices/TimeSlice/SliceDuration(u64), +// #[id=0xAF] Segment/Cluster/EncryptedBlock(Vec<u8>), +// #[id=0xA7] Segment/Cluster/Position(u64), +// #[id=0xAB] Segment/Cluster/PrevSize(u64), +// #[id=0x5854] Segment/Cluster/SilentTracks(Master), +// #[id=0x58D7] Segment/Cluster/SilentTracks/SilentTrackNumber(u64), +// #[id=0xA3] Segment/Cluster/SimpleBlock(Vec<u8>), +// #[id=0xE7] Segment/Cluster/Timestamp(u64), + +// #[id=0x1C53BB6B] Segment/Cues(Master), +// #[id=0xBB] Segment/Cues/CuePoint(Master), +// #[id=0xB3] Segment/Cues/CuePoint/CueTime(u64), +// #[id=0xB7] Segment/Cues/CuePoint/CueTrackPositions(Master), +// #[id=0x5378] Segment/Cues/CuePoint/CueTrackPositions/CueBlockNumber(u64), +// #[id=0xF1] Segment/Cues/CuePoint/CueTrackPositions/CueClusterPosition(u64), +// #[id=0xEA] Segment/Cues/CuePoint/CueTrackPositions/CueCodecState(u64), +// #[id=0xB2] Segment/Cues/CuePoint/CueTrackPositions/CueDuration(u64), +// #[id=0xDB] Segment/Cues/CuePoint/CueTrackPositions/CueReference(Master), +// #[id=0x97] Segment/Cues/CuePoint/CueTrackPositions/CueReference/CueRefCluster(u64), +// #[id=0xEB] Segment/Cues/CuePoint/CueTrackPositions/CueReference/CueRefCodecState(u64), +// #[id=0x535F] Segment/Cues/CuePoint/CueTrackPositions/CueReference/CueRefNumber(u64), +// #[id=0x96] Segment/Cues/CuePoint/CueTrackPositions/CueReference/CueRefTime(u64), +// #[id=0xF0] Segment/Cues/CuePoint/CueTrackPositions/CueRelativePosition(u64), +// #[id=0xF7] Segment/Cues/CuePoint/CueTrackPositions/CueTrack(u64), + +// #[id=0x1549A966] Segment/Info(Master), +// #[id=0x6924] Segment/Info/ChapterTranslate(Master), +// #[id=0x69BF] Segment/Info/ChapterTranslate/ChapterTranslateCodec(u64), +// #[id=0x69FC] Segment/Info/ChapterTranslate/ChapterTranslateEditionUID(u64), +// #[id=0x69A5] Segment/Info/ChapterTranslate/ChapterTranslateID(Vec<u8>), +// #[id=0x4461] Segment/Info/DateUTC(Integer), +// #[id=0x4489] Segment/Info/Duration(Float), +// #[id=0x4D80] Segment/Info/MuxingApp(Utf8), +// #[id=0x3E83BB] Segment/Info/NextFilename(Utf8), +// #[id=0x3EB923] Segment/Info/NextUID(Vec<u8>), +// #[id=0x3C83AB] Segment/Info/PrevFilename(Utf8), +// #[id=0x3CB923] Segment/Info/PrevUID(Vec<u8>), +// #[id=0x4444] Segment/Info/SegmentFamily(Vec<u8>), +// #[id=0x7384] Segment/Info/SegmentFilename(Utf8), +// #[id=0x73A4] Segment/Info/SegmentUID(Vec<u8>), +// #[id=0x2AD7B1] Segment/Info/TimestampScale(u64), +// #[id=0x7BA9] Segment/Info/Title(Utf8), +// #[id=0x5741] Segment/Info/WritingApp(Utf8), + +// #[id=0x114D9B74] Segment/SeekHead(Master), +// #[id=0x4DBB] Segment/SeekHead/Seek(Master), +// #[id=0x53AB] Segment/SeekHead/Seek/SeekID(Vec<u8>), +// #[id=0x53AC] Segment/SeekHead/Seek/SeekPosition(u64), + +// #[id=0x1254C367] Segment/Tags(Master), +// #[id=0x7373] Segment/Tags/Tag(Master), +// #[id=0x67C8] Segment/Tags/Tag/SimpleTag(Master), +// #[id=0x4485] Segment/Tags/Tag/SimpleTag/TagBinary(Vec<u8>), +// #[id=0x4484] Segment/Tags/Tag/SimpleTag/TagDefault(u64), +// #[id=0x44B4] Segment/Tags/Tag/SimpleTag/TagDefaultBogus(u64), +// #[id=0x447A] Segment/Tags/Tag/SimpleTag/TagLanguage(Utf8), +// #[id=0x447B] Segment/Tags/Tag/SimpleTag/TagLanguageIETF(Utf8), +// #[id=0x45A3] Segment/Tags/Tag/SimpleTag/TagName(Utf8), +// #[id=0x4487] Segment/Tags/Tag/SimpleTag/TagString(Utf8), +// #[id=0x63C0] Segment/Tags/Tag/Targets(Master), +// #[id=0x63C6] Segment/Tags/Tag/Targets/TagAttachmentUID(u64), +// #[id=0x63C4] Segment/Tags/Tag/Targets/TagChapterUID(u64), +// #[id=0x63C9] Segment/Tags/Tag/Targets/TagEditionUID(u64), +// #[id=0x63C5] Segment/Tags/Tag/Targets/TagTrackUID(u64), +// #[id=0x63CA] Segment/Tags/Tag/Targets/TargetType(Utf8), +// #[id=0x68CA] Segment/Tags/Tag/Targets/TargetTypeValue(u64), + +// #[id=0x1654AE6B] Segment/Tracks(Master), +// #[id=0xAE] Segment/Tracks/TrackEntry(Master), +// #[id=0x7446] Segment/Tracks/TrackEntry/AttachmentLink(u64), +// #[id=0xE1] Segment/Tracks/TrackEntry/Audio(Master), +// #[id=0x6264] Segment/Tracks/TrackEntry/Audio/BitDepth(u64), +// #[id=0x7D7B] Segment/Tracks/TrackEntry/Audio/ChannelPositions(Vec<u8>), +// #[id=0x9F] Segment/Tracks/TrackEntry/Audio/Channels(u64), +// #[id=0x78B5] Segment/Tracks/TrackEntry/Audio/OutputSamplingFrequency(Float), +// #[id=0xB5] Segment/Tracks/TrackEntry/Audio/SamplingFrequency(Float), +// #[id=0x41E4] Segment/Tracks/TrackEntry/BlockAdditionMapping(Master), +// #[id=0x41ED] Segment/Tracks/TrackEntry/BlockAdditionMapping/BlockAddIDExtraData(Vec<u8>), +// #[id=0x41A4] Segment/Tracks/TrackEntry/BlockAdditionMapping/BlockAddIDName(Utf8), +// #[id=0x41E7] Segment/Tracks/TrackEntry/BlockAdditionMapping/BlockAddIDType(u64), +// #[id=0x41F0] Segment/Tracks/TrackEntry/BlockAdditionMapping/BlockAddIDValue(u64), +// #[id=0xAA] Segment/Tracks/TrackEntry/CodecDecodeAll(u64), +// #[id=0x56AA] Segment/Tracks/TrackEntry/CodecDelay(u64), +// #[id=0x26B240] Segment/Tracks/TrackEntry/CodecDownloadURL(Utf8), +// #[id=0x86] Segment/Tracks/TrackEntry/CodecID(Utf8), +// #[id=0x3B4040] Segment/Tracks/TrackEntry/CodecInfoURL(Utf8), +// #[id=0x258688] Segment/Tracks/TrackEntry/CodecName(Utf8), +// #[id=0x63A2] Segment/Tracks/TrackEntry/CodecPrivate(Vec<u8>), +// #[id=0x3A9697] Segment/Tracks/TrackEntry/CodecSettings(Utf8), +// #[id=0x6D80] Segment/Tracks/TrackEntry/ContentEncodings(Master), +// #[id=0x6240] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding(Master), +// #[id=0x5034] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentCompression(Master), +// #[id=0x4254] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentCompression/ContentCompAlgo(u64), +// #[id=0x4255] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentCompression/ContentCompSettings(Vec<u8>), +// #[id=0x5031] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncodingOrder(u64), +// #[id=0x5032] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncodingScope(u64), +// #[id=0x5033] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncodingType(u64), +// #[id=0x5035] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption(Master), +// #[id=0x47E7] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption/ContentEncAESSettings(Master), +// #[id=0x47E8] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption/ContentEncAESSettings/AESSettingsCipherMode(u64), +// #[id=0x47E1] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption/ContentEncAlgo(u64), +// #[id=0x47E2] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption/ContentEncKeyID(Vec<u8>), +// #[id=0x47E5] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption/ContentSigAlgo(u64), +// #[id=0x47E6] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption/ContentSigHashAlgo(u64), +// #[id=0x47E4] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption/ContentSigKeyID(Vec<u8>), +// #[id=0x47E3] Segment/Tracks/TrackEntry/ContentEncodings/ContentEncoding/ContentEncryption/ContentSignature(Vec<u8>), +// #[id=0x234E7A] Segment/Tracks/TrackEntry/DefaultDecodedFieldDuration(u64), +// #[id=0x23E383] Segment/Tracks/TrackEntry/DefaultDuration(u64), +// #[id=0x55AF] Segment/Tracks/TrackEntry/FlagCommentary(u64), +// #[id=0x88] Segment/Tracks/TrackEntry/FlagDefault(u64), +// #[id=0xB9] Segment/Tracks/TrackEntry/FlagEnabled(u64), +// #[id=0x55AA] Segment/Tracks/TrackEntry/FlagForced(u64), +// #[id=0x55AB] Segment/Tracks/TrackEntry/FlagHearingImpaired(u64), +// #[id=0x9C] Segment/Tracks/TrackEntry/FlagLacing(u64), +// #[id=0x55AE] Segment/Tracks/TrackEntry/FlagOriginal(u64), +// #[id=0x55AD] Segment/Tracks/TrackEntry/FlagTextDescriptions(u64), +// #[id=0x55AC] Segment/Tracks/TrackEntry/FlagVisualImpaired(u64), +// #[id=0x22B59C] Segment/Tracks/TrackEntry/Language(Utf8), +// #[id=0x22B59D] Segment/Tracks/TrackEntry/LanguageIETF(Utf8), +// #[id=0x55EE] Segment/Tracks/TrackEntry/MaxBlockAdditionID(u64), +// #[id=0x6DF8] Segment/Tracks/TrackEntry/MaxCache(u64), +// #[id=0x6DE7] Segment/Tracks/TrackEntry/MinCache(u64), +// #[id=0x536E] Segment/Tracks/TrackEntry/Name(Utf8), +// #[id=0x56BB] Segment/Tracks/TrackEntry/SeekPreRoll(u64), +// #[id=0xD7] Segment/Tracks/TrackEntry/TrackNumber(u64), +// #[id=0x537F] Segment/Tracks/TrackEntry/TrackOffset(Integer), +// #[id=0xE2] Segment/Tracks/TrackEntry/TrackOperation(Master), +// #[id=0xE3] Segment/Tracks/TrackEntry/TrackOperation/TrackCombinePlanes(Master), +// #[id=0xE4] Segment/Tracks/TrackEntry/TrackOperation/TrackCombinePlanes/TrackPlane(Master), +// #[id=0xE6] Segment/Tracks/TrackEntry/TrackOperation/TrackCombinePlanes/TrackPlane/TrackPlaneType(u64), +// #[id=0xE5] Segment/Tracks/TrackEntry/TrackOperation/TrackCombinePlanes/TrackPlane/TrackPlaneUID(u64), +// #[id=0xE9] Segment/Tracks/TrackEntry/TrackOperation/TrackJoinBlocks(Master), +// #[id=0xED] Segment/Tracks/TrackEntry/TrackOperation/TrackJoinBlocks/TrackJoinUID(u64), +// #[id=0x6FAB] Segment/Tracks/TrackEntry/TrackOverlay(u64), +// #[id=0x23314F] Segment/Tracks/TrackEntry/TrackTimestampScale(Float), +// #[id=0x6624] Segment/Tracks/TrackEntry/TrackTranslate(Master), +// #[id=0x66BF] Segment/Tracks/TrackEntry/TrackTranslate/TrackTranslateCodec(u64), +// #[id=0x66FC] Segment/Tracks/TrackEntry/TrackTranslate/TrackTranslateEditionUID(u64), +// #[id=0x66A5] Segment/Tracks/TrackEntry/TrackTranslate/TrackTranslateTrackID(Vec<u8>), +// #[id=0x83] Segment/Tracks/TrackEntry/TrackType(u64), +// #[id=0x73C5] Segment/Tracks/TrackEntry/TrackUID(u64), +// #[id=0xC4] Segment/Tracks/TrackEntry/TrickMasterTrackSegmentUID(Vec<u8>), +// #[id=0xC7] Segment/Tracks/TrackEntry/TrickMasterTrackUID(u64), +// #[id=0xC6] Segment/Tracks/TrackEntry/TrickTrackFlag(u64), +// #[id=0xC1] Segment/Tracks/TrackEntry/TrickTrackSegmentUID(Vec<u8>), +// #[id=0xC0] Segment/Tracks/TrackEntry/TrickTrackUID(u64), +// #[id=0xE0] Segment/Tracks/TrackEntry/Video(Master), +// #[id=0x53C0] Segment/Tracks/TrackEntry/Video/AlphaMode(u64), +// #[id=0x54B3] Segment/Tracks/TrackEntry/Video/AspectRatioType(u64), +// #[id=0x55B0] Segment/Tracks/TrackEntry/Video/Colour(Master), +// #[id=0x55B2] Segment/Tracks/TrackEntry/Video/Colour/BitsPerChannel(u64), +// #[id=0x55B5] Segment/Tracks/TrackEntry/Video/Colour/CbSubsamplingHorz(u64), +// #[id=0x55B6] Segment/Tracks/TrackEntry/Video/Colour/CbSubsamplingVert(u64), +// #[id=0x55B7] Segment/Tracks/TrackEntry/Video/Colour/ChromaSitingHorz(u64), +// #[id=0x55B8] Segment/Tracks/TrackEntry/Video/Colour/ChromaSitingVert(u64), +// #[id=0x55B3] Segment/Tracks/TrackEntry/Video/Colour/ChromaSubsamplingHorz(u64), +// #[id=0x55B4] Segment/Tracks/TrackEntry/Video/Colour/ChromaSubsamplingVert(u64), +// #[id=0x55D0] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata(Master), +// #[id=0x55D9] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/LuminanceMax(Float), +// #[id=0x55DA] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/LuminanceMin(Float), +// #[id=0x55D5] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/PrimaryBChromaticityX(Float), +// #[id=0x55D6] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/PrimaryBChromaticityY(Float), +// #[id=0x55D3] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/PrimaryGChromaticityX(Float), +// #[id=0x55D4] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/PrimaryGChromaticityY(Float), +// #[id=0x55D1] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/PrimaryRChromaticityX(Float), +// #[id=0x55D2] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/PrimaryRChromaticityY(Float), +// #[id=0x55D7] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/WhitePointChromaticityX(Float), +// #[id=0x55D8] Segment/Tracks/TrackEntry/Video/Colour/MasteringMetadata/WhitePointChromaticityY(Float), +// #[id=0x55B1] Segment/Tracks/TrackEntry/Video/Colour/MatrixCoefficients(u64), +// #[id=0x55BC] Segment/Tracks/TrackEntry/Video/Colour/MaxCLL(u64), +// #[id=0x55BD] Segment/Tracks/TrackEntry/Video/Colour/MaxFALL(u64), +// #[id=0x55BB] Segment/Tracks/TrackEntry/Video/Colour/Primaries(u64), +// #[id=0x55B9] Segment/Tracks/TrackEntry/Video/Colour/Range(u64), +// #[id=0x55BA] Segment/Tracks/TrackEntry/Video/Colour/TransferCharacteristics(u64), +// #[id=0x54BA] Segment/Tracks/TrackEntry/Video/DisplayHeight(u64), +// #[id=0x54B2] Segment/Tracks/TrackEntry/Video/DisplayUnit(u64), +// #[id=0x54B0] Segment/Tracks/TrackEntry/Video/DisplayWidth(u64), +// #[id=0x9D] Segment/Tracks/TrackEntry/Video/FieldOrder(u64), +// #[id=0x9A] Segment/Tracks/TrackEntry/Video/FlagInterlaced(u64), +// #[id=0x2383E3] Segment/Tracks/TrackEntry/Video/FrameRate(Float), +// #[id=0x2FB523] Segment/Tracks/TrackEntry/Video/GammaValue(Float), +// #[id=0x53B9] Segment/Tracks/TrackEntry/Video/OldStereoMode(u64), +// #[id=0x54AA] Segment/Tracks/TrackEntry/Video/PixelCropBottom(u64), +// #[id=0x54CC] Segment/Tracks/TrackEntry/Video/PixelCropLeft(u64), +// #[id=0x54DD] Segment/Tracks/TrackEntry/Video/PixelCropRight(u64), +// #[id=0x54BB] Segment/Tracks/TrackEntry/Video/PixelCropTop(u64), +// #[id=0xBA] Segment/Tracks/TrackEntry/Video/PixelHeight(u64), +// #[id=0xB0] Segment/Tracks/TrackEntry/Video/PixelWidth(u64), +// #[id=0x7670] Segment/Tracks/TrackEntry/Video/Projection(Master), +// #[id=0x7674] Segment/Tracks/TrackEntry/Video/Projection/ProjectionPosePitch(Float), +// #[id=0x7675] Segment/Tracks/TrackEntry/Video/Projection/ProjectionPoseRoll(Float), +// #[id=0x7673] Segment/Tracks/TrackEntry/Video/Projection/ProjectionPoseYaw(Float), +// #[id=0x7672] Segment/Tracks/TrackEntry/Video/Projection/ProjectionPrivate(Vec<u8>), +// #[id=0x7671] Segment/Tracks/TrackEntry/Video/Projection/ProjectionType(u64), +// #[id=0x53B8] Segment/Tracks/TrackEntry/Video/StereoMode(u64), +// #[id=0x2EB524] Segment/Tracks/TrackEntry/Video/UncompressedFourCC(Vec<u8>) diff --git a/ebml/src/mod.rs b/ebml/src/mod.rs new file mode 100644 index 0000000..5da6809 --- /dev/null +++ b/ebml/src/mod.rs @@ -0,0 +1,48 @@ +use crate::format::matroska::read::EbmlSize; + +use self::read::EbmlReader; +use anyhow::{bail, Result}; +use log::debug; + +pub mod matroska; +pub mod read; + +#[derive(Debug, Clone)] +pub enum Master { + Start, + End, +} + +#[derive(Debug, Clone)] +pub enum MatroskaTag { + Ebml(Master), + EbmlVersion(u64), + EbmlReadVersion(u64), + EbmlMaxIdLength(u64), + EbmlMaxSizeLength(u64), + DocType(String), + DocTypeVersion(u64), + DocTypeReadVersion(u64), + DocTypeExtension(Master), +} + +impl EbmlReader { + pub fn read_tag(&mut self) -> Result<MatroskaTag> { + let id = self.read_tag_id()?; + let size = EbmlSize::from_vint(self.read_vint_len()?); + debug!("tag id={id:x}, size={size:?}"); + Ok(match id { + 0x1a45dfa3 => MatroskaTag::Ebml(Master::Start), + 0x4286 => MatroskaTag::EbmlVersion(self.read_vint()?), + 0x42f7 => MatroskaTag::EbmlReadVersion(self.read_vint()?), + 0x42f2 => MatroskaTag::EbmlMaxIdLength(self.read_vint()?), + 0x42f3 => MatroskaTag::EbmlMaxSizeLength(self.read_vint()?), + 0x4282 => MatroskaTag::DocType(self.read_utf8(size)?), + 0x4287 => MatroskaTag::DocTypeVersion(self.read_vint()?), + 0x4285 => MatroskaTag::DocTypeReadVersion(self.read_vint()?), + 0x4281 => MatroskaTag::DocTypeExtension(Master::Start), + + _ => bail!("thats not a tag we know..."), + }) + } +} diff --git a/ebml/src/read.rs b/ebml/src/read.rs new file mode 100644 index 0000000..0ffb24c --- /dev/null +++ b/ebml/src/read.rs @@ -0,0 +1,96 @@ +use std::io::{Read, Seek}; + +use anyhow::{bail, Result}; +use log::debug; +use webm_iterable::matroska_spec::MatroskaSpec; + +use crate::format::matroska::{Master, MatroskaTag}; + +trait ReadAndSeek: Read + Seek {} +impl<T: Read + Seek> ReadAndSeek for T {} + +pub struct EbmlReader { + inner: Box<dyn ReadAndSeek>, + pub position: usize, +} + +pub trait EbmlRead: Sized { + fn read(r: &mut EbmlReader) -> Result<Self>; +} + +impl EbmlReader { + pub fn new<T: Seek + Read + 'static>(inner: T) -> Self { + Self { + inner: Box::new(inner), + position: 0, + } + } + + pub fn read_byte(&mut self) -> Result<u8> { + let mut b = [0u8]; + self.inner.read_exact(&mut b)?; + self.position += 1; + Ok(b[0]) + } + pub fn read_buf(&mut self, size: impl Into<usize>) -> Result<Vec<u8>> { + let size = size.into(); + let mut b = vec![0u8; size]; + self.inner.read_exact(&mut b)?; + self.position += size; + Ok(b) + } + pub fn read_vint_len(&mut self) -> Result<(u64, usize)> { + let s = self.read_byte()?; + let len = s.leading_zeros() + 1; + let mut value = s as u64; + value -= 1 << (8 - len); + for _ in 0..(len - 1) { + value <<= 8; + value += self.read_byte()? as u64; + } + Ok((value, len as usize)) + } + pub fn read_vint(&mut self) -> Result<u64> { + Ok(self.read_vint_len()?.0) + } + pub fn read_utf8(&mut self, size: impl Into<usize>) -> Result<String> { + let b = self.read_buf(size)?; + Ok(String::from_utf8(b)?) + } + + pub fn read_tag_id(&mut self) -> Result<u64> { + let (value, len) = self.read_vint_len()?; + Ok(value + (1 << (7 * len))) + } +} + +#[derive(Debug, Clone, Copy)] +pub enum EbmlSize { + Exact(usize), + Unknown, +} +impl EbmlSize { + #[rustfmt::skip] + pub fn from_vint((value, len): (u64, usize)) -> EbmlSize { + match len { + 1 => if value == ((1 << (7)) - 1) { return Self::Unknown; }, + 2 => if value == ((1 << (7 * 2)) - 1) { return Self::Unknown; }, + 3 => if value == ((1 << (7 * 3)) - 1) { return Self::Unknown; }, + 4 => if value == ((1 << (7 * 4)) - 1) { return Self::Unknown; }, + 5 => if value == ((1 << (7 * 5)) - 1) { return Self::Unknown; }, + 6 => if value == ((1 << (7 * 6)) - 1) { return Self::Unknown; }, + 7 => if value == ((1 << (7 * 7)) - 1) { return Self::Unknown; }, + 8 => if value == ((1 << (7 * 8)) - 1) { return Self::Unknown; }, + _ => {}, + } + Self::Exact(len) + } +} +impl Into<usize> for EbmlSize { + fn into(self) -> usize { + match self { + EbmlSize::Exact(s) => s, + EbmlSize::Unknown => panic!("unknown size, where it should have been known"), + } + } +} diff --git a/ebml/src/write.rs b/ebml/src/write.rs new file mode 100644 index 0000000..b294d44 --- /dev/null +++ b/ebml/src/write.rs @@ -0,0 +1,36 @@ +use anyhow::{bail, Result}; +use std::io::Write; + +pub struct EbmlWriter<T> { + inner: T, + position: usize, +} + +impl<T: Write> EbmlWriter<T> { + pub fn new(inner: T, position: usize) -> Self { + Self { inner, position } + } + + pub fn write(&mut self, data: &[u8]) -> Result<()> { + self.inner.write_all(data)?; + self.position += data.len(); + Ok(()) + } + + pub fn write_vint(&mut self, i: u64) -> Result<()> { + if i > (1 << 56) - 1 { + bail!("vint does not fit"); + } + let mut len = 1; + while len <= 8 { + if i < (1 << ((7 * len) - 1)) { + break; + } + len += 1; + } + let mut bytes = i.to_be_bytes(); + bytes[0] |= 1 << (8 - len); + self.write(&bytes) + } +} + |