public byte[] SerializeAsEbml() { byte[] data = Serialize(); byte[] elementLengthCoded = EbmlHelper.MakeEbmlUInt(data.Length); byte[] element = new byte[EbmlElementIDs.ReSampleTrack.Length + elementLengthCoded.Length + data.Length]; using (BinaryWriter bw = new BinaryWriter(new MemoryStream(element))) { bw.Write(EbmlElementIDs.ReSampleTrack); bw.Write(elementLengthCoded); bw.Write(data); } return(element); }
public static void CreateSRS(SortedList <int, TrackData> tracks, FileData file, FileInfo inFile, FileInfo srsFile, bool bigFile) { using (FileStream fsOut = srsFile.Create()) using (EbmlReader rdr = new EbmlReader(inFile.FullName, EbmlReadMode.MKV)) { while (rdr.Read()) { fsOut.Write(rdr.Element.RawHeader, 0, rdr.Element.RawHeader.Length); switch (rdr.ElementType) { case EbmlElementType.Segment: // in store mode, create and write our custom ebml element as the first child of the segment byte[] fileElement = file.SerializeAsEbml(); int elementSize = fileElement.Length; byte[][] trackElements = new byte[tracks.Count][]; for (int i = 0; i < tracks.Count; i++) { if (bigFile) { tracks.Values[i].Flags |= TrackData.TrackDataFlags.BigFile; } trackElements[i] = tracks.Values[i].SerializeAsEbml(); elementSize += trackElements[i].Length; } byte[] elementSizeCoded = EbmlHelper.MakeEbmlUInt(elementSize); byte[] element = new byte[EbmlElementIDs.ReSample.Length + elementSizeCoded.Length + elementSize]; fsOut.Write(EbmlElementIDs.ReSample, 0, EbmlElementIDs.ReSample.Length); fsOut.Write(elementSizeCoded, 0, elementSizeCoded.Length); fsOut.Write(fileElement, 0, fileElement.Length); foreach (byte[] trackElement in trackElements) { fsOut.Write(trackElement, 0, trackElement.Length); } rdr.MoveToChild(); break; case EbmlElementType.Cluster: case EbmlElementType.BlockGroup: case EbmlElementType.AttachmentList: case EbmlElementType.Attachment: // these elements have no useful info of their own, but we want to step into them to examine their children rdr.MoveToChild(); break; case EbmlElementType.AttachedFileData: // eliminate the data from any attachments rdr.SkipContents(); break; case EbmlElementType.Block: // copy block header, but eliminate any frame data fsOut.Write(rdr.Block.RawBlockHeader, 0, rdr.Block.RawBlockHeader.Length); rdr.SkipContents(); break; default: // anything not caught above is considered metadata, so we copy it as is byte[] buff = rdr.ReadContents(); fsOut.Write(buff, 0, buff.Length); break; } } } }