internal VideoSampleEntry(Mp4Reader reader, ref int bytesLeft) { var ss = reader.readStructure <Structures.VisualSampleEntry>(); bytesLeft -= Marshal.SizeOf <Structures.VisualSampleEntry>(); sizePixels = ss.size; pixelsPerInch = ss.resolution; framesPerSample = ss.frameCount; unsafe { byte *comp = ss.compressorname; compressorName = StringMarshal.copy(comp, 32); } }
VideoDevice(string path, FileHandle file) { this.file = file; sCapability capability = file.read <sCapability>(eControlCode.QUERYCAP); unsafe { driver = StringMarshal.copy(capability.driver, 16); card = StringMarshal.copy(capability.card, 32); busInfo = StringMarshal.copy(capability.bus_info, 32); } deviceCapabilities = capability.capabilities; endpointCapabilities = capability.device_caps; bufferCaps = BufferCapabilities.getBufferCaps(path, this); }
public MP4AudioSampleEntry(Mp4Reader mp4, int bytesLeft) : base(mp4, ref bytesLeft) { Span <byte> bytes = stackalloc byte[bytesLeft]; mp4.read(bytes); int atomSize = BitConverter.ToInt32(bytes).endian(); uint atomTag = BitConverter.ToUInt32(bytes.Slice(4)); switch (atomTag) { case (uint)eAudioBoxType.esds: break; default: throw new NotImplementedException(); } // Skip header, version and flags bytes = bytes.Slice(12); Reader streamReader = new Reader(bytes); if (streamReader.EOF) { throw new ArgumentException($"The `esds` atom is empty"); } // Read tag and size eDescriptorTag tag = streamReader.readTag(); if (eDescriptorTag.ElementaryStream != tag) { throw new ArgumentException($"The `esds` atom is expected to contain an elementary stream descriptor, got { tag } instead"); } int size = streamReader.readSize(); // Create a reader for the content Reader esdReader = streamReader.readSubStream(size); // Read ElementaryStreamDescriptor ElementaryStreamDescriptor esd = esdReader.readStructure <ElementaryStreamDescriptor>(); id = esd.id; flags = esd.flags; priority = esd.priority; if (esd.flags.HasFlag(eDescriptorFlags.DependentStream)) { dependsOn = esdReader.readStructure <ushort>().endian(); } if (esd.flags.HasFlag(eDescriptorFlags.URL)) { byte urlLength = esdReader.readByte(); Span <byte> urlBuffer = stackalloc byte[urlLength]; esdReader.readBytes(urlBuffer); unsafe { fixed(byte *ptr = urlBuffer) url = StringMarshal.copy(ptr, urlLength); } } if (esd.flags.HasFlag(eDescriptorFlags.OCRstream)) { esId = esdReader.readStructure <ushort>().endian(); } while (!esdReader.EOF) { tag = esdReader.readTag(); size = esdReader.readSize(); Reader ss = esdReader.readSubStream(size); switch (tag) { case eDescriptorTag.DecoderConfiguration: decoderConfig = new DecoderConfiguration(ref ss); break; case eDescriptorTag.SyncLayerConfiguration: syncLayerConfig = new SyncLayerConfiguration(ref ss); break; case eDescriptorTag.ProfileLevelIndicationIndex: profileLevelIndicationindex = ss.readByte(); break; case eDescriptorTag.IPIdentificationPointer: case eDescriptorTag.IPMPPointer: case eDescriptorTag.Language: case eDescriptorTag.QoS: case eDescriptorTag.Registration: // Because of the way we implemented readSubStream, this break will skip them gracefully. // TODO: support at least language, likely to be seen in the wild break; default: throw new NotSupportedException(); } } // TODO: the esdReader has EOF, but the outer one, streamReader, might have not. It might contain moar stuff. // You can test for `if( !streamReader.EOF )` here, and parse even moar garbage carefully designed by these ISO/IEC committees and documented in many thousands of pages of these PDFs they sell. }