public Element ToBlockGroup() { MasterElement blockGroupElement = MatroskaDocTypes.BlockGroup.GetInstance(); BinaryElement blockElement = MatroskaDocTypes.Block.GetInstance(); blockElement.Data = createInnerData(); UnsignedIntegerElement durationElement = MatroskaDocTypes.BlockDuration.GetInstance(); durationElement.Value = Duration; blockGroupElement.AddChildElement(blockElement); blockGroupElement.AddChildElement(durationElement); return(blockGroupElement); }
public void AddCue(ulong positionInFile, ulong timecodeOfCluster, List <int> clusterTrackNumber) { Utility.LogDebug($"Adding matoska cue to cues element at postion [{positionInFile}], using timecode [{timecodeOfCluster}], for track numbers [{clusterTrackNumber}]"); UnsignedIntegerElement cueTime = MatroskaDocTypes.CueTime.GetInstance(); cueTime.Value = timecodeOfCluster; MasterElement cuePoint = MatroskaDocTypes.CuePoint.GetInstance(); MasterElement cueTrackPosition = createCueTrackPositions(positionInFile, clusterTrackNumber); cues.AddChildElement(cuePoint); cuePoint.AddChildElement(cueTime); cuePoint.AddChildElement(cueTrackPosition); Utility.LogDebug("Finished adding matroska cue to cues element."); }
private MasterElement createCueTrackPositions(ulong positionInFile, List <int> trackNumbers) { MasterElement cueTrackPosition = MatroskaDocTypes.CueTrackPositions.GetInstance(); foreach (int trackNumber in trackNumbers) { UnsignedIntegerElement cueTrack = MatroskaDocTypes.CueTrack.GetInstance(); cueTrack.Value = (ulong)trackNumber; UnsignedIntegerElement cueClusterPosition = MatroskaDocTypes.CueClusterPosition.GetInstance(); cueClusterPosition.Value = getPositionRelativeToSegmentEbmlElement(positionInFile); cueTrackPosition.AddChildElement(cueTrack); cueTrackPosition.AddChildElement(cueClusterPosition); } return(cueTrackPosition); }
/// <summary> /// Adds elements to the seek index. These should be level 1 objects only. /// If this object has already been written, you must use the update() method /// </summary> /// <param name="stream"></param> /// <param name="filePosition"></param> public void AddIndexedElement(MemoryStream stream, ulong filePosition) { Utility.LogDebug($"Adding indexed element @ {filePosition - referencePosition}"); MasterElement seekEntryElement = MatroskaDocTypes.Seek.GetInstance(); BinaryElement seekEntryIdElement = MatroskaDocTypes.SeekID.GetInstance(); seekEntryIdElement.Data = stream; UnsignedIntegerElement seekEntryPositionElement = MatroskaDocTypes.SeekPosition.GetInstance(); seekEntryPositionElement.Value = filePosition - referencePosition; seekEntryElement.AddChildElement(seekEntryIdElement); seekEntryElement.AddChildElement(seekEntryPositionElement); seekHeadElem.AddChildElement(seekEntryElement); placeHolderElement.Size = BLOCK_RESEVER_SIZE - seekHeadElem.TotalSize; }
public long WriteElement(FileStream writer) { MasterElement segmentInfoElement = MatroskaDocTypes.Info.GetInstance(); StringElement writingAppElement = MatroskaDocTypes.WritingApp.GetInstance(); writingAppElement.Value = "Matroska File Writer v1.0 C#"; StringElement muxingAppElement = MatroskaDocTypes.MuxingApp.GetInstance(); muxingAppElement.Value = ".NET EBML v1.0"; DateElement dateElement = MatroskaDocTypes.DateUTC.GetInstance(); dateElement.Date = SegmentDate; UnsignedIntegerElement timecodeScaleElement = MatroskaDocTypes.TimecodeScale.GetInstance(); timecodeScaleElement.Value = TimecodeScale; segmentInfoElement.AddChildElement(dateElement); segmentInfoElement.AddChildElement(timecodeScaleElement); if (Duration != null) { FloatElement durationElement = MatroskaDocTypes.Duration.GetInstance(); durationElement.Value = (double)Duration; segmentInfoElement.AddChildElement(durationElement); } segmentInfoElement.AddChildElement(writingAppElement); segmentInfoElement.AddChildElement(muxingAppElement); ulong len = segmentInfoElement.WriteElement(writer); VoidElement spacer = new VoidElement((ulong)BLOCK_SIZE - len); spacer.WriteElement(writer); return(1); }
public ulong WriteTracks(FileStream writer) { MasterElement trackElements = MatroskaDocTypes.Tracks.GetInstance(); foreach (var track in tracks) { trackElements.AddChildElement(track.ToElement()); } trackElements.WriteElement(writer); if (BLOCK_SIZE < trackElements.TotalSize) { throw new Exception("BLOCK_SIZE was greater than the track element. Something went wrong."); } new VoidElement(BLOCK_SIZE - trackElements.TotalSize).WriteElement(writer); return(BLOCK_SIZE); }
private void writeEBMLHeader() { MasterElement ebmlHeaderElement = MatroskaDocTypes.EBML.GetInstance(); UnsignedIntegerElement ebmlVersionElement = MatroskaDocTypes.EBMLVersion.GetInstance(); ebmlVersionElement.Value = 1; UnsignedIntegerElement ebmlReadVersionElement = MatroskaDocTypes.EBMLReadVersion.GetInstance(); ebmlReadVersionElement.Value = 1; UnsignedIntegerElement ebmlMaxIdLengthElement = MatroskaDocTypes.EBMLMaxIDLength.GetInstance(); ebmlMaxIdLengthElement.Value = 4; UnsignedIntegerElement ebmlMaxSizeLengthElement = MatroskaDocTypes.EBMLMaxSizeLength.GetInstance(); ebmlMaxSizeLengthElement.Value = 8; StringElement docTypeElement = MatroskaDocTypes.DocType.GetInstance(); docTypeElement.Value = "matroska"; UnsignedIntegerElement docTypeVersionElement = MatroskaDocTypes.DocTypeVersion.GetInstance(); docTypeVersionElement.Value = 3; UnsignedIntegerElement docTypeReadVersionElement = MatroskaDocTypes.DocTypeReadVersion.GetInstance(); docTypeReadVersionElement.Value = 2; ebmlHeaderElement.AddChildElement(ebmlVersionElement); ebmlHeaderElement.AddChildElement(ebmlReadVersionElement); ebmlHeaderElement.AddChildElement(ebmlMaxIdLengthElement); ebmlHeaderElement.AddChildElement(ebmlMaxSizeLengthElement); ebmlHeaderElement.AddChildElement(docTypeElement); ebmlHeaderElement.AddChildElement(docTypeVersionElement); ebmlHeaderElement.AddChildElement(docTypeReadVersionElement); ebmlHeaderElement.WriteElement(Writer); }
public ulong Flush(FileStream writer) { if (frames.Count == 0) { return(0); } try { MasterElement clusterElement = MatroskaDocTypes.Cluster.GetInstance(); UnsignedIntegerElement timecodeElement = MatroskaDocTypes.Timecode.GetInstance(); timecodeElement.Value = ClusterTimecode; clusterElement.AddChildElement(timecodeElement); if (silencedTracks.Count != 0) { MasterElement silentElement = MatroskaDocTypes.SilentTracks.GetInstance(); foreach (ulong silent in silencedTracks) { UnsignedIntegerElement silentTrackElement = MatroskaDocTypes.SilentTrackNumber.GetInstance(); silentTrackElement.Value = silent; silentElement.AddChildElement(silentTrackElement); } clusterElement.AddChildElement(silentElement); } MatroskaSimpleBlock block = null; bool forceNew = true; ulong lastTimecode = 0; int lastTrackNumber = 0; foreach (var frame in frames) { frame.Timecode -= ClusterTimecode; if (forceNew || lastTimecode != frame.Timecode || lastTrackNumber != frame.TrackNumber) { if (block != null) { clusterElement.AddChildElement(block.ToElement()); } block = new MatroskaSimpleBlock(); } lastTimecode = frame.Timecode; lastTrackNumber = frame.TrackNumber; forceNew = true; block.AddFrame(frame); } if (block != null) { clusterElement.AddChildElement(block.ToElement()); } return(clusterElement.WriteElement(writer)); } finally { frames.Clear(); Tracks.Clear(); totalSize = 0; ClusterTimecode = ulong.MaxValue; } }
public Element ToElement() { MasterElement trackEntryElement = MatroskaDocTypes.TrackEntry.GetInstance(); UnsignedIntegerElement trackNumberElement = MatroskaDocTypes.TrackNumber.GetInstance(); trackNumberElement.Value = (ulong)TrackNumber; UnsignedIntegerElement trackUIDElement = MatroskaDocTypes.TrackType.GetInstance(); trackUIDElement.Value = TrackUID; UnsignedIntegerElement trackTypeElement = MatroskaDocTypes.TrackType.GetInstance(); trackTypeElement.Value = (ulong)TrackType; Utility.LogTrace($"Track type set to {TrackType.ToString()}"); UnsignedIntegerElement trackFlagEnabledElement = MatroskaDocTypes.FlagEnabled.GetInstance(); trackFlagEnabledElement.Value = (ulong)(FlagEnabled ? 1 : 0); UnsignedIntegerElement trackFlagDefaultElement = MatroskaDocTypes.FlagDefault.GetInstance(); trackFlagDefaultElement.Value = (ulong)(FlagDefault ? 1 : 0); UnsignedIntegerElement trackFlagForcedElement = MatroskaDocTypes.FlagForced.GetInstance(); trackFlagForcedElement.Value = (ulong)(FlagForced ? 1 : 0); UnsignedIntegerElement trackFlagLacingElement = MatroskaDocTypes.FlagLacing.GetInstance(); trackFlagLacingElement.Value = (ulong)(FlagLacing ? 1 : 0); UnsignedIntegerElement trackMinCacheElement = MatroskaDocTypes.MinCache.GetInstance(); trackMinCacheElement.Value = (ulong)MinCache; UnsignedIntegerElement trackMaxBlockAddIdElement = MatroskaDocTypes.MaxBlockAdditionID.GetInstance(); trackMaxBlockAddIdElement.Value = (ulong)MaxBlockAdditionalId; StringElement trackNameElement = MatroskaDocTypes.Name.GetInstance(); trackNameElement.Value = Name; StringElement trackLangElement = MatroskaDocTypes.Language.GetInstance(); trackLangElement.Value = Language; StringElement trackCodecIdElement = MatroskaDocTypes.CodecID.GetInstance(); trackCodecIdElement.Value = CodecId; trackEntryElement.AddChildElement(trackNumberElement); trackEntryElement.AddChildElement(trackUIDElement); trackEntryElement.AddChildElement(trackTypeElement); trackEntryElement.AddChildElement(trackFlagEnabledElement); trackEntryElement.AddChildElement(trackFlagDefaultElement); trackEntryElement.AddChildElement(trackFlagForcedElement); trackEntryElement.AddChildElement(trackFlagLacingElement); trackEntryElement.AddChildElement(trackMinCacheElement); trackEntryElement.AddChildElement(trackMaxBlockAddIdElement); trackEntryElement.AddChildElement(trackNameElement); trackEntryElement.AddChildElement(trackLangElement); trackEntryElement.AddChildElement(trackCodecIdElement); if (CodecPrivate != null && CodecPrivate.Length != CodecPrivate.Position) { BinaryElement trackCodecPrivateElement = MatroskaDocTypes.CodecPrivate.GetInstance(); trackCodecPrivateElement.Data = CodecPrivate; trackEntryElement.AddChildElement(trackCodecPrivateElement); } UnsignedIntegerElement trackDefaultDurationElement = MatroskaDocTypes.DefaultDuration.GetInstance(); trackDefaultDurationElement.Value = DefaultDuration; UnsignedIntegerElement trackCodecDecodeAllElement = MatroskaDocTypes.CodecDecodeAll.GetInstance(); trackCodecDecodeAllElement.Value = (ulong)(CodecDecodeAll ? 0 : 1); trackEntryElement.AddChildElement(trackDefaultDurationElement); trackEntryElement.AddChildElement(trackCodecDecodeAllElement); if (overlayUIDs.Count != 0) { foreach (ulong overlay in overlayUIDs) { UnsignedIntegerElement trackOverlayElement = MatroskaDocTypes.TrackOverlay.GetInstance(); trackOverlayElement.Value = overlay; trackEntryElement.AddChildElement(trackOverlayElement); } } // Now we add the audio/video dependant sub-elements if (this.TrackType == TrackType.Video) { MasterElement trackVideoElement = MatroskaDocTypes.Video.GetInstance(); UnsignedIntegerElement trackVideoPixelWidthElement = MatroskaDocTypes.PixelWidth.GetInstance(); trackVideoPixelWidthElement.Value = (ulong)this.video.PixelWidth; UnsignedIntegerElement trackVideoPixelHeightElement = MatroskaDocTypes.PixelHeight.GetInstance(); trackVideoPixelHeightElement.Value = (ulong)this.video.PixelHeight; UnsignedIntegerElement trackVideoDisplayWidthElement = MatroskaDocTypes.DisplayWidth.GetInstance(); trackVideoDisplayWidthElement.Value = (ulong)this.video.DisplayWidth; UnsignedIntegerElement trackVideoDisplayHeightElement = MatroskaDocTypes.DisplayHeight.GetInstance(); trackVideoDisplayHeightElement.Value = (ulong)this.video.DisplayHeight; trackVideoElement.AddChildElement(trackVideoPixelWidthElement); trackVideoElement.AddChildElement(trackVideoPixelHeightElement); trackVideoElement.AddChildElement(trackVideoDisplayWidthElement); trackVideoElement.AddChildElement(trackVideoDisplayHeightElement); trackEntryElement.AddChildElement(trackVideoElement); } else if (this.TrackType == TrackType.Audio) { MasterElement trackAudioElement = MatroskaDocTypes.Audio.GetInstance(); UnsignedIntegerElement trackAudioChannelsElement = MatroskaDocTypes.Channels.GetInstance(); trackAudioChannelsElement.Value = (ulong)this.audio.Channels; UnsignedIntegerElement trackAudioBitDepthElement = MatroskaDocTypes.BitDepth.GetInstance(); trackAudioBitDepthElement.Value = this.audio.BitDepth; FloatElement trackAudioSamplingRateElement = MatroskaDocTypes.SamplingFrequency.GetInstance(); trackAudioSamplingRateElement.Value = this.audio.SamplingFrequency; FloatElement trackAudioOutputSamplingFrequencyElement = MatroskaDocTypes.OutputSamplingFrequency.GetInstance(); trackAudioOutputSamplingFrequencyElement.Value = this.audio.OutputSamplingFrequency; trackAudioElement.AddChildElement(trackAudioChannelsElement); trackAudioElement.AddChildElement(trackAudioBitDepthElement); trackAudioElement.AddChildElement(trackAudioSamplingRateElement); trackAudioElement.AddChildElement(trackAudioOutputSamplingFrequencyElement); trackEntryElement.AddChildElement(trackAudioElement); } if (joinUIDs != null) { MasterElement trackOpElement = MatroskaDocTypes.TrackOperation.GetInstance(); MasterElement trackJoinElement = MatroskaDocTypes.TrackJoinBlocks.GetInstance(); foreach (ulong uid in joinUIDs) { UnsignedIntegerElement joinUidElement = MatroskaDocTypes.TrackJoinUID.GetInstance(); joinUidElement.Value = uid; trackJoinElement.AddChildElement(joinUidElement); } trackOpElement.AddChildElement(trackJoinElement); trackEntryElement.AddChildElement(trackOpElement); } return(trackEntryElement); }