static TrackMetadata parseTrack(Mp4Reader reader, uint timescale) { TrackHeader header = default; MediaInfo info = default; EditListBox editList = null; foreach (eBoxType boxType in reader.readChildren()) { switch (boxType) { case eBoxType.tkhd: header = new TrackHeader(reader, timescale); break; case eBoxType.mdia: info = new MediaInfo(reader); break; case eBoxType.edts: editList = EditListBox.load(reader); break; default: reader.skipCurrentBox(); break; } } iEditList el = Mpeg4EditList.create(editList, timescale, info.timeScale); return(new TrackMetadata(header, info, el)); }
public Metadata(Mp4Reader reader) { reader.moveToBox(eBoxType.moov); Debug.Assert(1 == reader.level); movieHeader = default; List <TrackMetadata> list = new List <TrackMetadata>(); foreach (eBoxType boxType in reader.readChildren()) { switch (boxType) { case eBoxType.mvhd: movieHeader = new MovieHeader(reader); break; case eBoxType.trak: list.Add(parseTrack(reader, movieHeader.timescale)); break; default: // e.g. udta, for optional user data. reader.skipCurrentBox(); break; } } tracks = list.ToArray(); }
internal SampleTable(Mp4Reader reader) { Debug.Assert(reader.currentBox == eBoxType.stbl); entries = null; timeToSample = null; sampleToChunk = null; sampleSize = null; chunkOffset = null; compositionToSample = null; syncSampleTable = null; foreach (eBoxType boxType in reader.readChildren()) { switch (boxType) { case eBoxType.stsd: entries = parseSampleTable(reader); break; case eBoxType.stts: timeToSample = TimingTables.readTimeToSample(reader); break; case eBoxType.ctts: compositionToSample = CompositionTimeDeltas.read(reader); break; case eBoxType.stsc: sampleToChunk = TimingTables.readSampleToChunk(reader); break; case eBoxType.stsz: sampleSize = TimingTables.readSampleSize(reader); break; case eBoxType.stz2: sampleSize = TimingTables.readSampleSizeCompact(reader); break; case eBoxType.stco: chunkOffset = TimingTables.readOffsets32(reader); break; case eBoxType.co64: chunkOffset = TimingTables.readOffsets64(reader); break; case eBoxType.stss: syncSampleTable = TimingTables.readSyncSample(reader); break; default: reader.skipCurrentBox(); break; } } }
internal VideoInformation(Mp4Reader reader) { foreach (eBoxType boxType in reader.readChildren()) { switch (boxType) { default: // dinf is useless but mandatory in the spec. // vmhd is useless, as well. reader.skipCurrentBox(); break; case eBoxType.stbl: sampleTable = new SampleTable(reader); break; } } }
internal AudioInformation(Mp4Reader reader) { foreach (eBoxType boxType in reader.readChildren()) { switch (boxType) { case eBoxType.smhd: balance = readHeader(reader); break; default: // dinf is useless but mandatory in the spec reader.skipCurrentBox(); break; case eBoxType.stbl: sampleTable = new SampleTable(reader); break; } } }
internal MediaInfo(Mp4Reader reader) { creationTime = modificationTime = default; duration = default; culture = null; mediaHandler = default; mediaInformation = null; timeScale = 0; foreach (eBoxType boxType in reader.readChildren()) { switch (boxType) { case eBoxType.mdhd: readInfoHeader(reader, out creationTime, out modificationTime, out duration, out culture, out timeScale); break; case eBoxType.hdlr: mediaHandler = new MediaHandler(reader); break; case eBoxType.minf: switch (mediaHandler.mediaHandler) { case eMediaHandler.vide: case eMediaHandler.auxv: mediaInformation = new VideoInformation(reader); break; case eMediaHandler.soun: mediaInformation = new AudioInformation(reader); break; } break; } } }