ref: a41e6c0c1ed77362a80443d65e8b9541a91793b6
parent: 041e2ada566d991e41dc0f626d1d20582276a6c0
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Dec 15 10:15:06 EST 2020
ebml: move element ids elsewhere, make debugging messages more human readable
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
## Status
-The code looks horrible.
+The code looks horrible(?).
It's not a filesystem yet, but it can extract video streams (as IVF)
and audio streams from MP4 and MKV.
--- a/ebml.c
+++ b/ebml.c
@@ -3,6 +3,7 @@
#include <bio.h>
#include <ctype.h>
#include "common.h"
+#include "elem.h"
enum
{@@ -72,7 +73,7 @@
return -1;
}
if(n == 1 && c == 0){- werrstr("invalid number: %02x at 0x%zx", c, Boffset(f));+ werrstr("invalid number: %02x at %#zx", c, Boffset(f));return -1;
}
v |= c;
@@ -307,7 +308,7 @@
duration = 0;
ts = 0;
for(isebml = 0; left != 0;){- if(id == 0x9b)
+ if(id == EBlockDuration)
te.blockdur *= timestampscale;
if(endtracks > 0 && left < endtracks && trackdump == Nodump){/* early exit */
@@ -317,20 +318,25 @@
off = Boffset(f);
if((n = ebmlel(f, left, &id, &sz)) < 0){- werrstr("invalid ebml: %r at 0x%zx", off);+ werrstr("invalid ebml: %r at %#zx", off);goto err;
}
- if(dflag > 1)
- Bprint(&stderr, "0x%zux\t%zux\t%zd\t%zd\n", off, id, sz, left);
+ if(dflag > 1){+ Element *el;
+ if((el = ebmlid2elem(id)) != nil)
+ Bprint(&stderr, "%#zux\t%s\t%zd\t%zd\n", off, el->name, sz, left);
+ else
+ Bprint(&stderr, "%#zux\t%#llx\t%zd\t%zd\n", off, id, sz, left);
+ }
left -= n;
- if(id == 0x1a45dfa3){ /* EBML comes first */+ if(id == EEBML){ /* EBML comes first */ if(isebml != 0){ werrstr("double EBML?");goto err;
}
isebml++;
- }else if(id == 0x18538067){ /* segment */+ }else if(id == ESegment){left = sz;
if(isebml != 1){ werrstr("invalid ebml");@@ -338,15 +344,15 @@
}
isebml++; /* make sure we don't see more segments */
continue; /* go in */
- }else if(id == 0x1549a966){ /* segment info */+ }else if(id == EInfo){ /* segment info */continue;
- }else if(id == 0x1654ae6b){ /* tracks */+ }else if(id == ETracks){endtracks = left - sz; /* to skip early in case track dump not required */
continue;
- }else if(id == 0x1f43b675){ /* cluster */+ }else if(id == ECluster){if(trackdump != Nodump) /* skip it entirely if no dump required */
continue;
- }else if(id == 0xae){ /* track entry */+ }else if(id == ETrackEntry){ /* track entry */ if(e.tracknum > 0){if(trackdump == Nodump)
trackinfo(&out, &e);
@@ -360,11 +366,11 @@
memset(&e, 0, sizeof(e));
e.timestampscale = timestampscale;
continue;
- }else if(id == 0xe0 || id == 0xe1){ /* video/audio settings */+ }else if(id == EVideo || id == EAudio){continue;
- }else if(id == 0xa0 && trackdump != Nodump){ /* block group */+ }else if(id == EBlockGroup && trackdump != Nodump){continue;
- }else if((id == 0xa3 || id == 0xa1) && trackdump != Nodump){ /* (simple) block */+ }else if((id == ESimpleBlock || id == EBlock) && trackdump != Nodump){if(te.tracknum == -1)
memmove(&te, &e, sizeof(e));
if((n = ebmluint(f, &track, 0)) < 0){@@ -467,59 +473,59 @@
continue;
}
}else{- ebmlgetnumber(0x2ad7b1, timestampscale)
+ ebmlgetnumber(ETimestampScale, timestampscale)
else
- ebmlgetfloat(0xb5, e.audio.samplerate)
+ ebmlgetfloat(ESamplingFrequency, e.audio.samplerate)
else
- ebmlgetnumber(0x9f, e.audio.channels)
+ ebmlgetnumber(EChannels, e.audio.channels)
else
- ebmlgetnumber(0x6264, e.audio.bps)
+ ebmlgetnumber(EBitDepth, e.audio.bps)
else
- ebmlgetnumber(0xd7, e.tracknum)
+ ebmlgetnumber(ETrackNumber, e.tracknum)
else
- ebmlgetnumber(0x83, e.tracktype)
+ ebmlgetnumber(ETrackType, e.tracktype)
else
- ebmlgetstring(0x86, e.codec.name)
+ ebmlgetstring(ECodecID, e.codec.name)
else
- ebmlgetbytes(0x63a2, e.codec.priv)
+ ebmlgetbytes(ECodecPrivate, e.codec.priv)
else
- ebmlgetnumber(0x56aa, e.codec.delay)
+ ebmlgetnumber(ECodecDelay, e.codec.delay)
else
- ebmlgetnumber(0xb0, e.video.width)
+ ebmlgetnumber(EPixelWidth, e.video.width)
else
- ebmlgetnumber(0xba, e.video.height)
+ ebmlgetnumber(EPixelHeight, e.video.height)
else
- ebmlgetnumber(0x54aa, e.video.crop.bottom)
+ ebmlgetnumber(EPixelCropBottom, e.video.crop.bottom)
else
- ebmlgetnumber(0x54bb, e.video.crop.top)
+ ebmlgetnumber(EPixelCropTop, e.video.crop.top)
else
- ebmlgetnumber(0x54cc, e.video.crop.left)
+ ebmlgetnumber(EPixelCropLeft, e.video.crop.left)
else
- ebmlgetnumber(0x54dd, e.video.crop.right)
+ ebmlgetnumber(EPixelCropRight, e.video.crop.right)
else
- ebmlgetnumber(0x54b0, e.video.display.width)
+ ebmlgetnumber(EDisplayWidth, e.video.display.width)
else
- ebmlgetnumber(0x54ba, e.video.display.height)
+ ebmlgetnumber(EDisplayHeight, e.video.display.height)
else
- ebmlgetnumber(0x54b2, e.video.display.unit)
+ ebmlgetnumber(EDisplayUnit, e.video.display.unit)
else
- ebmlgetnumber(0x54b3, e.video.display.aspectmode)
+ ebmlgetnumber(EAspectRatioType, e.video.display.aspectmode)
else
- ebmlgetnumber(0xe7, timestamp)
+ ebmlgetnumber(ETimestamp, timestamp)
else
- ebmlgetnumber(0x23e383, e.perframe)
+ ebmlgetnumber(EDefaultDuration, e.perframe)
else
- ebmlgetnumber(0x56bb, e.seekpreroll)
+ ebmlgetnumber(ESeekPreRoll, e.seekpreroll)
else
- ebmlgetfloat(0x4489, duration)
+ ebmlgetfloat(EDuration, duration)
else
- ebmlgetnumber(0x73c5, e.trackuid)
+ ebmlgetnumber(ETrackUID, e.trackuid)
else
- ebmlgetnumber(0x75a2, te.discardpad)
+ ebmlgetnumber(EDiscardPadding, te.discardpad)
else
- ebmlgetnumber(0x9b, te.blockdur)
+ ebmlgetnumber(EBlockDuration, te.blockdur)
else
- ebmlgetstring(0x22b59c, e.lang)
+ ebmlgetstring(ELanguage, e.lang)
}
if(Bseek(f, sz, 1) < 0)
--- /dev/null
+++ b/elem.c
@@ -1,0 +1,283 @@
+#include <u.h>
+#include <libc.h>
+#include "elem.h"
+
+static Element els[] = {+ {EChapterDisplay, "ChapterDisplay", Emaster},+ {ETrackType, "TrackType", Eunsigned},+ {EChapString, "ChapString", Eunicode},+ {ECodecID, "CodecID", Esigned},+ {EFlagDefault, "FlagDefault", Eunsigned},+ {EChapterTrackUID, "ChapterTrackUID", Eunsigned},+ {ESlices, "Slices", Emaster},+ {EChapterTrack, "ChapterTrack", Emaster},+ {EChapterTimeStart, "ChapterTimeStart", Eunsigned},+ {EChapterTimeEnd, "ChapterTimeEnd", Eunsigned},+ {ECueRefTime, "CueRefTime", Eunsigned},+ {ECueRefCluster, "CueRefCluster", Eunsigned},+ {EChapterFlagHidden, "ChapterFlagHidden", Eunsigned},+ {EFlagInterlaced, "FlagInterlaced", Eunsigned},+ {EBlockDuration, "BlockDuration", Eunsigned},+ {EFlagLacing, "FlagLacing", Eunsigned},+ {EFieldOrder, "FieldOrder", Eunsigned},+ {EChannels, "Channels", Eunsigned},+ {EBlockGroup, "BlockGroup", Emaster},+ {EBlock, "Block", Ebinary},+ {EBlockVirtual, "BlockVirtual", Ebinary},+ {ESimpleBlock, "SimpleBlock", Ebinary},+ {ECodecState, "CodecState", Ebinary},+ {EBlockAdditional, "BlockAdditional", Ebinary},+ {EBlockMore, "BlockMore", Emaster},+ {EPosition, "Position", Eunsigned},+ {ECodecDecodeAll, "CodecDecodeAll", Eunsigned},+ {EPrevSize, "PrevSize", Eunsigned},+ {ETrackEntry, "TrackEntry", Emaster},+ {EEncryptedBlock, "EncryptedBlock", Ebinary},+ {EPixelWidth, "PixelWidth", Eunsigned},+ {ECueDuration, "CueDuration", Eunsigned},+ {ECueTime, "CueTime", Eunsigned},+ {ESamplingFrequency, "SamplingFrequency", Efloat},+ {EChapterAtom, "ChapterAtom", Emaster},+ {ECueTrackPositions, "CueTrackPositions", Emaster},+ {EFlagEnabled, "FlagEnabled", Eunsigned},+ {EPixelHeight, "PixelHeight", Eunsigned},+ {ECuePoint, "CuePoint", Emaster},+ {ECRC32, "CRC-32", Ebinary},+ {EReferenceFrame, "ReferenceFrame", Emaster},+ {EReferenceOffset, "ReferenceOffset", Eunsigned},+ {EReferenceTimestamp, "ReferenceTimestamp", Eunsigned},+ {EBlockAdditionID, "BlockAdditionID", Eunsigned},+ {ELaceNumber, "LaceNumber", Eunsigned},+ {EFrameNumber, "FrameNumber", Eunsigned},+ {EDelay, "Delay", Eunsigned},+ {ESliceDuration, "SliceDuration", Eunsigned},+ {ETrackNumber, "TrackNumber", Eunsigned},+ {ECueReference, "CueReference", Emaster},+ {EVideo, "Video", Emaster},+ {EAudio, "Audio", Emaster},+ {ETrackOperation, "TrackOperation", Emaster},+ {ETrackCombinePlanes, "TrackCombinePlanes", Emaster},+ {ETrackPlane, "TrackPlane", Emaster},+ {ETrackPlaneUID, "TrackPlaneUID", Eunsigned},+ {ETrackPlaneType, "TrackPlaneType", Eunsigned},+ {ETimestamp, "Timestamp", Eunsigned},+ {ETimeSlice, "TimeSlice", Emaster},+ {ETrackJoinBlocks, "TrackJoinBlocks", Emaster},+ {ECueCodecState, "CueCodecState", Eunsigned},+ {ECueRefCodecState, "CueRefCodecState", Eunsigned},+ {EVoid, "Void", Ebinary},+ {ETrackJoinUID, "TrackJoinUID", Eunsigned},+ {EBlockAddID, "BlockAddID", Eunsigned},+ {ECueRelativePosition, "CueRelativePosition", Eunsigned},+ {ECueClusterPosition, "CueClusterPosition", Eunsigned},+ {ECueTrack, "CueTrack", Eunsigned},+ {EReferencePriority, "ReferencePriority", Eunsigned},+ {EReferenceBlock, "ReferenceBlock", Esigned},+ {EReferenceVirtual, "ReferenceVirtual", Esigned},+ {EBlockAddIDName, "BlockAddIDName", Eascii},+ {EBlockAdditionMapping, "BlockAdditionMapping", Emaster},+ {EBlockAddIDType, "BlockAddIDType", Eunsigned},+ {EBlockAddIDExtraData, "BlockAddIDExtraData", Ebinary},+ {EBlockAddIDValue, "BlockAddIDValue", Eunsigned},+ {EContentCompAlgo, "ContentCompAlgo", Eunsigned},+ {EContentCompSettings, "ContentCompSettings", Ebinary},+ {EDocTypeExtension, "DocTypeExtension", Emaster},+ {EDocType, "DocType", Eascii},+ {EDocTypeExtensionName, "DocTypeExtensionName", Eascii},+ {EDocTypeExtensionVersion, "DocTypeExtensionVersion", Eunsigned},+ {EDocTypeReadVersion, "DocTypeReadVersion", Eunsigned},+ {EEBMLVersion, "EBMLVersion", Eunsigned},+ {EDocTypeVersion, "DocTypeVersion", Eunsigned},+ {EEBMLMaxIDLength, "EBMLMaxIDLength", Eunsigned},+ {EEBMLMaxSizeLength, "EBMLMaxSizeLength", Eunsigned},+ {EEBMLReadVersion, "EBMLReadVersion", Eunsigned},+ {EChapLanguage, "ChapLanguage", Eascii},+ {EChapLanguageIETF, "ChapLanguageIETF", Eascii},+ {EChapCountry, "ChapCountry", Eascii},+ {ESegmentFamily, "SegmentFamily", Ebinary},+ {EDateUTC, "DateUTC", Etimestamp},+ {ETagLanguage, "TagLanguage", Eascii},+ {ETagLanguageIETF, "TagLanguageIETF", Eascii},+ {ETagDefault, "TagDefault", Eunsigned},+ {ETagBinary, "TagBinary", Ebinary},+ {ETagString, "TagString", Eunicode},+ {EDuration, "Duration", Efloat},+ {EChapProcessPrivate, "ChapProcessPrivate", Ebinary},+ {EChapterFlagEnabled, "ChapterFlagEnabled", Eunsigned},+ {ETagName, "TagName", Eunicode},+ {EEditionEntry, "EditionEntry", Emaster},+ {EEditionUID, "EditionUID", Eunsigned},+ {EEditionFlagHidden, "EditionFlagHidden", Eunsigned},+ {EEditionFlagDefault, "EditionFlagDefault", Eunsigned},+ {EEditionFlagOrdered, "EditionFlagOrdered", Eunsigned},+ {EFileData, "FileData", Ebinary},+ {EFileMimeType, "FileMimeType", Eascii},+ {EFileUsedStartTime, "FileUsedStartTime", Eunsigned},+ {EFileUsedEndTime, "FileUsedEndTime", Eunsigned},+ {EFileName, "FileName", Eunicode},+ {EFileReferral, "FileReferral", Ebinary},+ {EFileDescription, "FileDescription", Eunicode},+ {EFileUID, "FileUID", Eunsigned},+ {EContentEncAlgo, "ContentEncAlgo", Eunsigned},+ {EContentEncKeyID, "ContentEncKeyID", Ebinary},+ {EContentSignature, "ContentSignature", Ebinary},+ {EContentSigKeyID, "ContentSigKeyID", Ebinary},+ {EContentSigAlgo, "ContentSigAlgo", Eunsigned},+ {EContentSigHashAlgo, "ContentSigHashAlgo", Eunsigned},+ {EContentAESSettings, "ContentAESSettings", Emaster},+ {EAESSettingsCipherMode, "AESSettingsCipherMode", Eunsigned},+ {EMuxingApp, "MuxingApp", Eunicode},+ {ESeek, "Seek", Emaster},+ {EContentEncodingOrder, "ContentEncodingOrder", Eunsigned},+ {EContentEncodingScope, "ContentEncodingScope", Eunsigned},+ {EContentEncodingType, "ContentEncodingType", Eunsigned},+ {EContentCompression, "ContentCompression", Emaster},+ {EContentEncryption, "ContentEncryption", Emaster},+ {ECueRefNumber, "CueRefNumber", Eunsigned},+ {EName, "Name", Eunicode},+ {ECueBlockNumber, "CueBlockNumber", Eunsigned},+ {ETrackOffset, "TrackOffset", Esigned},+ {ESeekID, "SeekID", Ebinary},+ {ESeekPosition, "SeekPosition", Eunsigned},+ {EStereoMode, "StereoMode", Eunsigned},+ {EOldStereoMode, "OldStereoMode", Eunsigned},+ {EAlphaMode, "AlphaMode", Eunsigned},+ {EPixelCropBottom, "PixelCropBottom", Eunsigned},+ {EDisplayWidth, "DisplayWidth", Eunsigned},+ {EDisplayUnit, "DisplayUnit", Eunsigned},+ {EAspectRatioType, "AspectRatioType", Eunsigned},+ {EDisplayHeight, "DisplayHeight", Eunsigned},+ {EPixelCropTop, "PixelCropTop", Eunsigned},+ {EPixelCropLeft, "PixelCropLeft", Eunsigned},+ {EPixelCropRight, "PixelCropRight", Eunsigned},+ {EFlagForced, "FlagForced", Eunsigned},+ {EColour, "Colour", Emaster},+ {EMatrixCoefficients, "MatrixCoefficients", Eunsigned},+ {EBitsPerChannel, "BitsPerChannel", Eunsigned},+ {EChromaSubsamplingHorz, "ChromaSubsamplingHorz", Eunsigned},+ {EChromaSubsamplingVert, "ChromaSubsamplingVert", Eunsigned},+ {ECbSubSamplingHorz, "CbSubSamplingHorz", Eunsigned},+ {ECbSubSamplingVert, "CbSubSamplingVert", Eunsigned},+ {EChromaSitingHorz, "ChromaSitingHorz", Eunsigned},+ {EChromaSitingVert, "ChromaSitingVert", Eunsigned},+ {ERange, "Range", Eunsigned},+ {ETransferCharacteristics, "TransferCharacteristics", Eunsigned},+ {EPrimaries, "Primaries", Eunsigned},+ {EMaxCLL, "MaxCLL", Eunsigned},+ {EMaxFALL, "MaxFALL", Eunsigned},+ {EMasteringMetadata, "MasteringMetadata", Emaster},+ {EPrimaryRChromaticityX, "PrimaryRChromaticityX", Efloat},+ {EPrimaryRChromaticityY, "PrimaryRChromaticityY", Efloat},+ {EPrimaryGChromaticityX, "PrimaryGChromaticityX", Efloat},+ {EPrimaryGChromaticityY, "PrimaryGChromaticityY", Efloat},+ {EPrimaryBChromaticityX, "PrimaryBChromaticityX", Efloat},+ {EPrimaryBChromaticityY, "PrimaryBChromaticityY", Efloat},+ {EWhitePointChromaticityX, "WhitePointChromaticityX", Efloat},+ {EWhitePointChromaticityY, "WhitePointChromaticityY", Efloat},+ {ELuminanceMax, "LuminanceMax", Efloat},+ {ELuminanceMin, "LuminanceMin", Efloat},+ {EMaxBlockAdditionID, "MaxBlockAdditionID", Eunsigned},+ {EChapterStringUID, "ChapterStringUID", Eunicode},+ {ECodecDelay, "CodecDelay", Eunsigned},+ {ESeekPreRoll, "SeekPreRoll", Eunsigned},+ {EWritingApp, "WritingApp", Eunicode},+ {ESilentTracks, "SilentTracks", Emaster},+ {ESilentTrackNumber, "SilentTrackNumber", Eunsigned},+ {EAttachedFile, "AttachedFile", Emaster},+ {EContentEncoding, "ContentEncoding", Emaster},+ {EBitDepth, "BitDepth", Eunsigned},+ {ECodecPrivate, "CodecPrivate", Ebinary},+ {ETargets, "Targets", Emaster},+ {EChapterPhysicalEquiv, "ChapterPhysicalEquiv", Eunsigned},+ {ETagChapterUID, "TagChapterUID", Eunsigned},+ {ETagTrackUID, "TagTrackUID", Eunsigned},+ {ETagAttachmentUID, "TagAttachmentUID", Eunsigned},+ {ETagEditionUID, "TagEditionUID", Eunsigned},+ {ETargetType, "TargetType", Eascii},+ {ETrackTranslate, "TrackTranslate", Emaster},+ {ETrackTranslateTrackID, "TrackTranslateTrackID", Ebinary},+ {ETrackTranslateCodec, "TrackTranslateCodec", Eunsigned},+ {ETrackTranslateEditionUID, "TrackTranslateEditionUID", Eunsigned},+ {ESimpleTag, "SimpleTag", Emaster},+ {ETargetTypeValue, "TargetTypeValue", Eunsigned},+ {EChapProcessCommand, "ChapProcessCommand", Emaster},+ {EChapProcessTime, "ChapProcessTime", Eunsigned},+ {EChapterTranslate, "ChapterTranslate", Emaster},+ {EChapProcessData, "ChapProcessData", Ebinary},+ {EChapProcess, "ChapProcess", Emaster},+ {EChapProcessCodecID, "ChapProcessCodecID", Eunsigned},+ {EChapterTranslateID, "ChapterTranslateID", Ebinary},+ {EChapterTranslateCodec, "ChapterTranslateCodec", Eunsigned},+ {EChapterTranslateEditionUID, "ChapterTranslateEditionUID", Eunsigned},+ {EContentEncodings, "ContentEncodings", Emaster},+ {EMinCache, "MinCache", Eunsigned},+ {EMaxCache, "MaxCache", Eunsigned},+ {EChapterSegmentUID, "ChapterSegmentUID", Ebinary},+ {EChapterSegmentEditionUID, "ChapterSegmentEditionUID", Eunsigned},+ {ETrackOverlay, "TrackOverlay", Eunsigned},+ {ETag, "Tag", Emaster},+ {ESegmentFilename, "SegmentFilename", Eunicode},+ {ESegmentUID, "SegmentUID", Ebinary},+ {EChapterUID, "ChapterUID", Eunsigned},+ {ETrackUID, "TrackUID", Eunsigned},+ {EAttachmentLink, "AttachmentLink", Eunsigned},+ {EBlockAdditions, "BlockAdditions", Emaster},+ {EDiscardPadding, "DiscardPadding", Esigned},+ {EProjection, "Projection", Emaster},+ {EProjectionType, "ProjectionType", Eunsigned},+ {EProjectionPrivate, "ProjectionPrivate", Ebinary},+ {EProjectionPoseYaw, "ProjectionPoseYaw", Efloat},+ {EProjectionPosePitch, "ProjectionPosePitch", Efloat},+ {EProjectionPoseRoll, "ProjectionPoseRoll", Efloat},+ {EOutputSamplingFrequency, "OutputSamplingFrequency", Efloat},+ {ETitle, "Title", Eunicode},+ {EChannelPositions, "ChannelPositions", Ebinary},+ {ELanguage, "Language", Eascii},+ {ELanguageIETF, "LanguageIETF", Esigned},+ {ETrackTimestampScale, "TrackTimestampScale", Efloat},+ {EDefaultDecodedFieldDuration, "DefaultDecodedFieldDuration", Eunsigned},+ {EFrameRate, "FrameRate", Efloat},+ {EDefaultDuration, "DefaultDuration", Eunsigned},+ {ECodecName, "CodecName", Eunicode},+ {ECodecDownloadURL, "CodecDownloadURL", Eascii},+ {ETimestampScale, "TimestampScale", Eunsigned},+ {EColourSpace, "ColourSpace", Ebinary},+ {EGammaValue, "GammaValue", Efloat},+ {ECodecSettings, "CodecSettings", Eunicode},+ {ECodecInfoURL, "CodecInfoURL", Eascii},+ {EPrevFilename, "PrevFilename", Eunicode},+ {EPrevUID, "PrevUID", Ebinary},+ {ENextFilename, "NextFilename", Eunicode},+ {ENextUID, "NextUID", Ebinary},+ {EChapters, "Chapters", Emaster},+ {ESeekHead, "SeekHead", Emaster},+ {ETags, "Tags", Emaster},+ {EInfo, "Info", Emaster},+ {ETracks, "Tracks", Emaster},+ {ESegment, "Segment", Emaster},+ {EAttachments, "Attachments", Emaster},+ {EEBML, "EBML", Emaster},+ {ECues, "Cues", Emaster},+ {ECluster, "Cluster", Emaster},+};
+
+Element *
+ebmlid2elem(vlong id)
+{+ Element *p, *t;
+ int m, n;
+
+ n = nelem(els);
+ t = els;
+ while(n > 1){+ m = n/2;
+ p = t + m;
+ if(id >= p->id) {+ t = p;
+ n = n-m;
+ } else
+ n = m;
+ }
+
+ return id == t->id ? t : nil;
+}
--- /dev/null
+++ b/elem.h
@@ -1,0 +1,279 @@
+typedef struct Element Element;
+
+struct Element {+ vlong id;
+ char *name;
+ int type;
+};
+
+enum {+ /* ebml element value types */
+ Emaster,
+ Ebinary,
+ Efloat,
+ Eunsigned,
+ Esigned,
+ Eunicode,
+ Eascii = Eunicode,
+ Etimestamp,
+
+ /* ids */
+ EChapterDisplay = 0x80,
+ ETrackType = 0x83,
+ EChapString = 0x85,
+ ECodecID = 0x86,
+ EFlagDefault = 0x88,
+ EChapterTrackUID = 0x89,
+ ESlices = 0x8e,
+ EChapterTrack = 0x8f,
+ EChapterTimeStart = 0x91,
+ EChapterTimeEnd = 0x92,
+ ECueRefTime = 0x96,
+ ECueRefCluster = 0x97,
+ EChapterFlagHidden = 0x98,
+ EFlagInterlaced = 0x9a,
+ EBlockDuration = 0x9b,
+ EFlagLacing = 0x9c,
+ EFieldOrder = 0x9d,
+ EChannels = 0x9f,
+ EBlockGroup = 0xa0,
+ EBlock = 0xa1,
+ EBlockVirtual = 0xa2,
+ ESimpleBlock = 0xa3,
+ ECodecState = 0xa4,
+ EBlockAdditional = 0xa5,
+ EBlockMore = 0xa6,
+ EPosition = 0xa7,
+ ECodecDecodeAll = 0xaa,
+ EPrevSize = 0xab,
+ ETrackEntry = 0xae,
+ EEncryptedBlock = 0xaf,
+ EPixelWidth = 0xb0,
+ ECueDuration = 0xb2,
+ ECueTime = 0xb3,
+ ESamplingFrequency = 0xb5,
+ EChapterAtom = 0xb6,
+ ECueTrackPositions = 0xb7,
+ EFlagEnabled = 0xb9,
+ EPixelHeight = 0xba,
+ ECuePoint = 0xbb,
+ ECRC32 = 0xbf,
+ EReferenceFrame = 0xc8,
+ EReferenceOffset = 0xc9,
+ EReferenceTimestamp = 0xca,
+ EBlockAdditionID = 0xcb,
+ ELaceNumber = 0xcc,
+ EFrameNumber = 0xcd,
+ EDelay = 0xce,
+ ESliceDuration = 0xcf,
+ ETrackNumber = 0xd7,
+ ECueReference = 0xdb,
+ EVideo = 0xe0,
+ EAudio = 0xe1,
+ ETrackOperation = 0xe2,
+ ETrackCombinePlanes = 0xe3,
+ ETrackPlane = 0xe4,
+ ETrackPlaneUID = 0xe5,
+ ETrackPlaneType = 0xe6,
+ ETimestamp = 0xe7,
+ ETimeSlice = 0xe8,
+ ETrackJoinBlocks = 0xe9,
+ ECueCodecState = 0xea,
+ ECueRefCodecState = 0xeb,
+ EVoid = 0xec,
+ ETrackJoinUID = 0xed,
+ EBlockAddID = 0xee,
+ ECueRelativePosition = 0xf0,
+ ECueClusterPosition = 0xf1,
+ ECueTrack = 0xf7,
+ EReferencePriority = 0xfa,
+ EReferenceBlock = 0xfb,
+ EReferenceVirtual = 0xfd,
+ EBlockAddIDName = 0x41a4,
+ EBlockAdditionMapping = 0x41e4,
+ EBlockAddIDType = 0x41e7,
+ EBlockAddIDExtraData = 0x41ed,
+ EBlockAddIDValue = 0x41f0,
+ EContentCompAlgo = 0x4254,
+ EContentCompSettings = 0x4255,
+ EDocTypeExtension = 0x4281,
+ EDocType = 0x4282,
+ EDocTypeExtensionName = 0x4283,
+ EDocTypeExtensionVersion = 0x4284,
+ EDocTypeReadVersion = 0x4285,
+ EEBMLVersion = 0x4286,
+ EDocTypeVersion = 0x4287,
+ EEBMLMaxIDLength = 0x42f2,
+ EEBMLMaxSizeLength = 0x42f3,
+ EEBMLReadVersion = 0x42f7,
+ EChapLanguage = 0x437c,
+ EChapLanguageIETF = 0x437d,
+ EChapCountry = 0x437e,
+ ESegmentFamily = 0x4444,
+ EDateUTC = 0x4461,
+ ETagLanguage = 0x447a,
+ ETagLanguageIETF = 0x447b,
+ ETagDefault = 0x4484,
+ ETagBinary = 0x4485,
+ ETagString = 0x4487,
+ EDuration = 0x4489,
+ EChapProcessPrivate = 0x450d,
+ EChapterFlagEnabled = 0x4598,
+ ETagName = 0x45a3,
+ EEditionEntry = 0x45b9,
+ EEditionUID = 0x45bc,
+ EEditionFlagHidden = 0x45bd,
+ EEditionFlagDefault = 0x45db,
+ EEditionFlagOrdered = 0x45dd,
+ EFileData = 0x465c,
+ EFileMimeType = 0x4660,
+ EFileUsedStartTime = 0x4661,
+ EFileUsedEndTime = 0x4662,
+ EFileName = 0x466e,
+ EFileReferral = 0x4675,
+ EFileDescription = 0x467e,
+ EFileUID = 0x46ae,
+ EContentEncAlgo = 0x47e1,
+ EContentEncKeyID = 0x47e2,
+ EContentSignature = 0x47e3,
+ EContentSigKeyID = 0x47e4,
+ EContentSigAlgo = 0x47e5,
+ EContentSigHashAlgo = 0x47e6,
+ EContentAESSettings = 0x47e7,
+ EAESSettingsCipherMode = 0x47e8,
+ EMuxingApp = 0x4d80,
+ ESeek = 0x4dbb,
+ EContentEncodingOrder = 0x5031,
+ EContentEncodingScope = 0x5032,
+ EContentEncodingType = 0x5033,
+ EContentCompression = 0x5034,
+ EContentEncryption = 0x5035,
+ ECueRefNumber = 0x535f,
+ EName = 0x536e,
+ ECueBlockNumber = 0x5378,
+ ETrackOffset = 0x537f,
+ ESeekID = 0x53ab,
+ ESeekPosition = 0x53ac,
+ EStereoMode = 0x53b8,
+ EOldStereoMode = 0x53b9,
+ EAlphaMode = 0x53c0,
+ EPixelCropBottom = 0x54aa,
+ EDisplayWidth = 0x54b0,
+ EDisplayUnit = 0x54b2,
+ EAspectRatioType = 0x54b3,
+ EDisplayHeight = 0x54ba,
+ EPixelCropTop = 0x54bb,
+ EPixelCropLeft = 0x54cc,
+ EPixelCropRight = 0x54dd,
+ EFlagForced = 0x55aa,
+ EColour = 0x55b0,
+ EMatrixCoefficients = 0x55b1,
+ EBitsPerChannel = 0x55b2,
+ EChromaSubsamplingHorz = 0x55b3,
+ EChromaSubsamplingVert = 0x55b4,
+ ECbSubSamplingHorz = 0x55b5,
+ ECbSubSamplingVert = 0x55b6,
+ EChromaSitingHorz = 0x55b7,
+ EChromaSitingVert = 0x55b8,
+ ERange = 0x55b9,
+ ETransferCharacteristics = 0x55ba,
+ EPrimaries = 0x55bb,
+ EMaxCLL = 0x55bc,
+ EMaxFALL = 0x55bd,
+ EMasteringMetadata = 0x55d0,
+ EPrimaryRChromaticityX = 0x55d1,
+ EPrimaryRChromaticityY = 0x55d2,
+ EPrimaryGChromaticityX = 0x55d3,
+ EPrimaryGChromaticityY = 0x55d4,
+ EPrimaryBChromaticityX = 0x55d5,
+ EPrimaryBChromaticityY = 0x55d6,
+ EWhitePointChromaticityX = 0x55d7,
+ EWhitePointChromaticityY = 0x55d8,
+ ELuminanceMax = 0x55d9,
+ ELuminanceMin = 0x55da,
+ EMaxBlockAdditionID = 0x55ee,
+ EChapterStringUID = 0x5654,
+ ECodecDelay = 0x56aa,
+ ESeekPreRoll = 0x56bb,
+ EWritingApp = 0x5741,
+ ESilentTracks = 0x5854,
+ ESilentTrackNumber = 0x58d7,
+ EAttachedFile = 0x61a7,
+ EContentEncoding = 0x6240,
+ EBitDepth = 0x6264,
+ ECodecPrivate = 0x63a2,
+ ETargets = 0x63c0,
+ EChapterPhysicalEquiv = 0x63c3,
+ ETagChapterUID = 0x63c4,
+ ETagTrackUID = 0x63c5,
+ ETagAttachmentUID = 0x63c6,
+ ETagEditionUID = 0x63c9,
+ ETargetType = 0x63ca,
+ ETrackTranslate = 0x6624,
+ ETrackTranslateTrackID = 0x66a5,
+ ETrackTranslateCodec = 0x66bf,
+ ETrackTranslateEditionUID = 0x66fc,
+ ESimpleTag = 0x67c8,
+ ETargetTypeValue = 0x68ca,
+ EChapProcessCommand = 0x6911,
+ EChapProcessTime = 0x6922,
+ EChapterTranslate = 0x6924,
+ EChapProcessData = 0x6933,
+ EChapProcess = 0x6944,
+ EChapProcessCodecID = 0x6955,
+ EChapterTranslateID = 0x69a5,
+ EChapterTranslateCodec = 0x69bf,
+ EChapterTranslateEditionUID = 0x69fc,
+ EContentEncodings = 0x6d80,
+ EMinCache = 0x6de7,
+ EMaxCache = 0x6df8,
+ EChapterSegmentUID = 0x6e67,
+ EChapterSegmentEditionUID = 0x6ebc,
+ ETrackOverlay = 0x6fab,
+ ETag = 0x7373,
+ ESegmentFilename = 0x7384,
+ ESegmentUID = 0x73a4,
+ EChapterUID = 0x73c4,
+ ETrackUID = 0x73c5,
+ EAttachmentLink = 0x7446,
+ EBlockAdditions = 0x75a1,
+ EDiscardPadding = 0x75a2,
+ EProjection = 0x7670,
+ EProjectionType = 0x7671,
+ EProjectionPrivate = 0x7672,
+ EProjectionPoseYaw = 0x7673,
+ EProjectionPosePitch = 0x7674,
+ EProjectionPoseRoll = 0x7675,
+ EOutputSamplingFrequency = 0x78b5,
+ ETitle = 0x7ba9,
+ EChannelPositions = 0x7d7b,
+ ELanguage = 0x22b59c,
+ ELanguageIETF = 0x22b59d,
+ ETrackTimestampScale = 0x23314f,
+ EDefaultDecodedFieldDuration = 0x234e7a,
+ EFrameRate = 0x2383e3,
+ EDefaultDuration = 0x23e383,
+ ECodecName = 0x258688,
+ ECodecDownloadURL = 0x26b240,
+ ETimestampScale = 0x2ad7b1,
+ EColourSpace = 0x2eb524,
+ EGammaValue = 0x2fb523,
+ ECodecSettings = 0x3a9697,
+ ECodecInfoURL = 0x3b4040,
+ EPrevFilename = 0x3c83ab,
+ EPrevUID = 0x3cb923,
+ ENextFilename = 0x3e83bb,
+ ENextUID = 0x3eb923,
+ EChapters = 0x1043a770,
+ ESeekHead = 0x114d9b74,
+ ETags = 0x1254c367,
+ EInfo = 0x1549a966,
+ ETracks = 0x1654ae6b,
+ ESegment = 0x18538067,
+ EAttachments = 0x1941a469,
+ EEBML = 0x1a45dfa3,
+ ECues = 0x1c53bb6b,
+ ECluster = 0x1f43b675,
+};
+
+Element *ebmlid2elem(vlong id);
--- a/mkfile
+++ b/mkfile
@@ -8,6 +8,7 @@
OFILES=\
crc32.$O\
ebml.$O\
+ elem.$O\
iso.$O\
ivf.$O\
main.$O\
--
⑨