public override void AtomCreated(BaseAtom atom) { switch (atom.Type) { case SMHD: _atomSMHD = (AtomSMHD)atom; return; case DINF: _atomDINF = (AtomDINF)atom; return; case STBL: _atomSTBL = (AtomSTBL)atom; return; case VMHD: _atomVMHD = (AtomVMHD)atom; return; case HDLR: _atomHDLR = (AtomHdlr)atom; return; } }
public override void AtomCreated(BaseAtom atom) { switch (atom.Type) { case TKHD: _atomTkhd = (AtomTKHD)atom; break; case MDIA: _atomMdia = (AtomMDIA)atom; break; case HDLR: _atomHdlr = (AtomHdlr)atom; break; case MINF: _atomMinf = (AtomMINF)atom; break; case DINF: _atomDinf = (AtomDINF)atom; break; case STBL: _atomStbl = (AtomSTBL)atom; break; case UDTA: _atomUdta = (AtomUDTA)atom; break; case META: _atomMeta = (AtomMETA)atom; break; } }
private void CreateSubs(ITrack track, AtomSTBL stbl) { if (track.SubsampleInformationBox != null) { stbl.AddAtom(track.SubsampleInformationBox); } }
private void CreateStss(ITrack track, AtomSTBL stbl) { if (track.SyncSamples?.Count() > 0) { AtomSTSS stss = new AtomSTSS(track.SyncSamples); stbl.AddAtom(stss); } }
private void CreateSdtp(ITrack track, AtomSTBL stbl) { if (track.SampleDependencies?.Count() > 0) { AtomSDTP sdtp = new AtomSDTP(track.SampleDependencies); stbl.AddAtom(sdtp); } }
private void CreateStsz(ITrack track, AtomSTBL stbl) { AtomSTSZ stsz = new AtomSTSZ { Entries = Track2SampleSizes[track] }; stbl.AddAtom(stsz); }
private void CreateCtts(ITrack track, AtomSTBL stbl) { List <AtomCTTS.Entry> compositionTimeToSampleEntries = track.CompositionTimeEntries; if (compositionTimeToSampleEntries?.Count > 0) { AtomCTTS ctts = new AtomCTTS(compositionTimeToSampleEntries); stbl.AddAtom(ctts); } }
public override void AtomCreated(BaseAtom atom) { switch (atom.Type) { case MDHD: _atomMDHD = (AtomMdhd) atom; return; case HDLR: _atomHDLR = (AtomHdlr) atom; return; case MINF: _atomMINF = (AtomMINF) atom; return; case DINF: _atomDINF = (AtomDINF) atom; return; case STBL: _atomSTBL = (AtomSTBL) atom; return; } }
private void CreateStsc(ITrack track, Dictionary <ITrack, int[]> chunks, AtomSTBL stbl) { var tracksChunkSizes = chunks[track]; var stsc = new AtomSTSC(new List <AtomSTSC.Entry>()); var lastChunkSize = long.MinValue; // to be sure the first chunks hasn't got the same size for (var i = 0; i < tracksChunkSizes.Length; i++) { // The sample description index references the sample description box // that describes the samples of this chunk. My Tracks cannot have more // than one sample description box. Therefore 1 is always right // the first chunk has the number '1' if (lastChunkSize != tracksChunkSizes[i]) { stsc.Entries.Add(new AtomSTSC.Entry() { FirstChunk = (uint)(i + 1), SamplesPerChunk = (uint)tracksChunkSizes[i], SampleDescriptionIndex = 1 }); lastChunkSize = tracksChunkSizes[i]; } } stbl.AddAtom(stsc); }
private void CreateStts(ITrack track, AtomSTBL stbl) { AtomSTTS.Entry lastEntry = null; AtomSTTS stts = new AtomSTTS(); var entries = stts.SttsEntries; foreach (var delta in track.SampleDurations) { if (lastEntry != null && lastEntry.Delta == delta) { lastEntry.Count++; } else { lastEntry = new AtomSTTS.Entry { Count = 1, Delta = delta }; entries.Add(lastEntry); } } stbl.AddAtom(stts); }
public BaseAtom ReadAtom(IBoxContainer parentAtom) { BaseAtom atom = null; uint type = 0; var currentPos = MediaFile.Position; long size = MediaFile.Br.ReadUInt32(); if (size == 0) { atom = new AtomNULL(this, type, size, currentPos) { Parent = parentAtom }; return(atom); } type = MediaFile.Br.ReadUInt32(); if (size == 1) { size = MediaFile.Br.ReadInt64(); if (size == 0) { atom = new AtomNULL(this, type, size, currentPos) { Parent = parentAtom }; return(atom); } } switch (type) { case FTYP: atom = new AtomFTYP(this, size, currentPos); break; case MOOV: atom = new AtomMOOV(this, type, size, currentPos); break; case MOOF: atom = new AtomMOOF(this, type, size, currentPos); break; case MVEX: atom = new AtomMVEX(this, type, size, currentPos); break; case MVHD: atom = new AtomMVHD(this, type, size, currentPos); break; case MFHD: atom = new AtomMFHD(this, type, size, currentPos); break; case TRAK: atom = new AtomTRAK(this, type, size, currentPos); break; case TRAF: atom = new AtomTRAF(this, type, size, currentPos); break; case TREX: atom = new AtomTREX(this, type, size, currentPos); break; case TRUN: atom = new AtomTRUN(this, type, size, currentPos); break; case TKHD: atom = new AtomTKHD(this, type, size, currentPos); break; case TFHD: atom = new AtomTFHD(this, type, size, currentPos); break; case MDIA: atom = new AtomMDIA(this, type, size, currentPos); break; case MDHD: atom = new AtomMdhd(this, type, size, currentPos); break; case HDLR: atom = new AtomHdlr(this, type, size, currentPos); break; case MINF: atom = new AtomMINF(this, type, size, currentPos); break; case SMHD: atom = new AtomSMHD(this, type, size, currentPos); break; case DINF: atom = new AtomDINF(this, type, size, currentPos); break; case STBL: atom = new AtomSTBL(this, type, size, currentPos); break; case VMHD: atom = new AtomVMHD(this, type, size, currentPos); break; case DREF: atom = new AtomDREF(this, type, size, currentPos); break; case STSD: atom = new AtomSTSD(this, type, size, currentPos); break; case STTS: atom = new AtomSTTS(this, type, size, currentPos); break; case STSC: atom = new AtomSTSC(this, type, size, currentPos); break; case STSZ: atom = new AtomSTSZ(this, type, size, currentPos); break; case STCO: atom = new AtomSTCO(this, type, size, currentPos); break; case CTTS: atom = new AtomCTTS(this, type, size, currentPos); break; case STSS: atom = new AtomSTSS(this, type, size, currentPos); break; case URL: atom = new AtomURL(this, type, size, currentPos); break; case MP4A: atom = new AtomMP4A(this, type, size, currentPos); break; case AVC1: atom = new AtomAVC1(this, type, size, currentPos); break; case ESDS: atom = new AtomESDS(this, type, size, currentPos); break; case AVCC: atom = new AtomAVCC(this, type, size, currentPos); break; case UDTA: atom = new AtomUDTA(this, type, size, currentPos); break; case WAVE: atom = new AtomWAVE(this, type, size, currentPos); break; case META: atom = new AtomMETA(this, type, size, currentPos); break; case NULL: atom = new AtomNULL(this, type, size, currentPos); break; case ILST: atom = new AtomILST(this, type, size, currentPos); break; case DATA: atom = new AtomDATA(this, type, size, currentPos); break; case CO64: atom = new AtomCO64(this, type, size, currentPos); break; case _COM: case NAME: case COVR: case AART: case _WRT: case _GRP: case _LYR: case _NAM: case _ART1: case _ART2: case _PRT: case _TOO: case _DAY: case _CMT: case _CPY: case _DES: case _ALB: case TRKN: case CPIL: case PGAP: case TMPO: case GNRE: case DISK: case _GEN: case DESC: case TVSH: case TVEN: case TVSN: case TVES: atom = new AtomMetaField(this, type, size, currentPos); break; default: { atom = new IgnoredAtom(this, type, size, currentPos); break; } } atom.Parent = parentAtom; atom.Read(); if (currentPos + atom.Size != MediaFile.Position) { FATAL("atom start:{0};Atom Size:{1};currentPostion:{2}", currentPos, atom.Size, MediaFile.Position); } return(atom); }
private void CreateStsd(ITrack track, AtomSTBL stbl) => stbl.AddAtom(track.SampleDescriptionBox);
private void CreateStco(ITrack targetTrack, Movie movie, Dictionary <ITrack, int[]> chunks, AtomSTBL stbl) { if (ChunkOffsetBoxes[targetTrack] == null) { // The ChunkOffsetBox we create here is just a stub // since we haven't created the whole structure we can't tell where the // first chunk starts (mdat box). So I just let the chunk offset // start at zero and I will add the mdat offset later. uint offset = 0; // all tracks have the same number of chunks //LOG.logDebug("Calculating chunk offsets for track_" + targetTrack.getTrackMetaData().getTrackId()); List <ITrack> tracks = new List <ITrack>(chunks.Keys); tracks.Sort(new ChunksComparer()); Dictionary <ITrack, int> trackToChunk = new Dictionary <ITrack, int>(); Dictionary <ITrack, int> trackToSample = new Dictionary <ITrack, int>(); Dictionary <ITrack, double> trackToTime = new Dictionary <ITrack, double>(); foreach (ITrack track in tracks) { trackToChunk.Add(track, 0); trackToSample.Add(track, 0); trackToTime.Add(track, 0.0); ChunkOffsetBoxes.Add(track, new AtomSTCO()); } while (true) { ITrack nextChunksTrack = null; foreach (ITrack track in tracks) { // This always chooses the least progressed track if ((nextChunksTrack == null || trackToTime[track] < trackToTime[nextChunksTrack]) && // either first OR track's next chunk's starttime is smaller than nextTrack's next chunks starttime // AND their need to be chunks left! (trackToChunk[track] < chunks[track].Length)) { nextChunksTrack = track; } } if (nextChunksTrack == null) { break; // no next } // found the next one AtomSTCO chunkOffsetBox = ChunkOffsetBoxes[nextChunksTrack]; chunkOffsetBox.Entries.Add(offset); int nextChunksIndex = trackToChunk[nextChunksTrack]; int numberOfSampleInNextChunk = chunks[nextChunksTrack][nextChunksIndex]; int startSample = trackToSample[nextChunksTrack]; double time = trackToTime[nextChunksTrack]; var durs = nextChunksTrack.SampleDurations; for (int j = startSample; j < startSample + numberOfSampleInNextChunk; j++) { offset += (uint)Track2SampleSizes[nextChunksTrack][j]; time += (double)durs[j] / nextChunksTrack.TrackMetaData.Timescale; } trackToChunk.Add(nextChunksTrack, nextChunksIndex + 1); trackToSample.Add(nextChunksTrack, startSample + numberOfSampleInNextChunk); trackToTime.Add(nextChunksTrack, time); } } stbl.AddAtom(ChunkOffsetBoxes[targetTrack]); }
private BaseAtom CreateStbl(ITrack track, Movie movie, Dictionary <ITrack, int[]> chunks) { AtomSTBL stbl = new AtomSTBL(); CreateStsd(track, stbl); CreateStts(track, stbl); CreateCtts(track, stbl); CreateStss(track, stbl); CreateSdtp(track, stbl); CreateStsc(track, chunks, stbl); CreateStsz(track, stbl); CreateStco(track, movie, chunks, stbl); Dictionary <string, List <IGroupEntry> > groupEntryFamilies = new Dictionary <string, List <IGroupEntry> >(); foreach (var sg in track.SampleGroups) { var type = sg.Key.Type; var groupEntries = groupEntryFamilies[type]; if (groupEntries == null) { groupEntries = new List <IGroupEntry>(); groupEntryFamilies.Add(type, groupEntries); } groupEntries.Add(sg.Key); } foreach (var sg in groupEntryFamilies) { var sgdb = new AtomSGPD(); var type = sg.Key; sgdb.GroupEntries = sg.Value; var sbgp = new AtomSBGP { GroupingType = type }; AtomSBGP.Entry last = null; for (int i = 0; i < track.Samples.Count; i++) { var index = 0; for (int j = 0; j < sg.Value.Count; j++) { var sampleNums = track.SampleGroups[sg.Value[j]]; if (sampleNums.Contains(i)) { index = j + 1; } } if (last == null || last.GroupDescriptionIndex != index) { last = new AtomSBGP.Entry(1, index); sbgp.Entries.Add(last); } else { last.SampleCount++; } } stbl.AddAtom(sgdb); stbl.AddAtom(sbgp); } //if (track is CencEncryptedTrack) { // createCencBoxes((CencEncryptedTrack)track, stbl, chunks[track]); //} CreateSubs(track, stbl); return(stbl); }