private void MuxMlpToTs(PesPacket pp, ElementaryStreamTypes type) { Int64 pts = 0; PesHeader ph = pp.GetHeader(); if (ph.HasPts == false) { if (lastPtsList.ContainsKey(pp.PID)) { pts = lastPtsList[pp.PID]; } } else { pts = ph.Pts; lastPtsList[pp.PID] = pts; } byte[] payload = pp.GetPayload(); /* * int index = 0; * int len = 0; * len = payload.Length - index; */ MuxSingleAc3ToTs(payload, 0, payload.Length, pts, type, pp.PID); }
private PesPacket BuildVc1Pes(Int64 timestamp, byte[] data, ushort pid) { List <byte> pes = new List <byte>(); pes.Add(0x00); pes.Add(0x00); pes.Add(0x01); pes.Add(Constants.PES_VIDEO_VC1); pes.Add(0x00); pes.Add(0x00); pes.Add(0x84); pes.Add(0x81); pes.Add(0x08); pes.Add(0x21); pes.Add(0x00); pes.Add(0x01); pes.Add(0x00); pes.Add(0x01); pes.Add(0x01); pes.Add(0x81); pes.Add(0x55); PesHeader ph = new PesHeader(pes.ToArray()); ph.Pts = timestamp; PesPacket pp = new PesPacket(ph.Data, 0, ph.Data.Length, pid); pp.AddData(data, 0, data.Length); pp.Complete = true; return(pp); }
public BlueMux(string fileName, TsFileType fileType, List <StreamInfo> StreamsToKeep, bool fAsync, bool fProcessAudio, bool fMlpToAc3) { fsw = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None, Constants.DISK_BUFFER, fAsync); this.tsiow = new TsIo(null, fsw, Constants.DISK_BUFFER); this.fileType = fileType; this.StreamsToKeep = StreamsToKeep; this.buffer = new List <TsPacket>(); this.currentPcr = -1; this.lastPcr = -1; this.lastDelta = -1; this.pcrOffset = -1; this.lastPts = -1; this.currentPts = -1; this.ptsDelta = -1; this.ptsOffset = 0; this.ptsCount = -1; this.pcrPacket = null; this.header = new byte[4]; this.supHeader = new byte[10]; this.supHeader[0] = (byte)'P'; this.supHeader[1] = (byte)'G'; this.VideoType = 0; this.lastPacket = null; this.sitCount = 0; this.packetCount = 0; this.epData = new List <EpElement>(); this.pmtStreams = null; this.lastPtsList = new Dictionary <ushort, long>(); this.soundFrames = new Dictionary <ushort, List <byte> >(); this.processAudio = fProcessAudio; this.MlpToAc3 = fMlpToAc3; CreatePsi(); }
// If PesPacket contains valid stream data, store it // in the respective output stream. public override void MuxPacket(PesPacket pp) { foreach (DeMuxStream S in _Streams) { if (pp.PID == S.PID) { byte[] data = pp.GetData(); S.FileStream.Write(data, 0, data.Length); } } }
private void MuxSingleDtsToTs(byte[] payload, int offset, int len, Int64 pts, ElementaryStreamTypes type, ushort pid) { List <byte> pes = new List <byte>(); bool priority = false; pes.Add(0x00); pes.Add(0x00); pes.Add(0x01); if (this.fileType == TsFileType.BLU_RAY) { pes.Add(0xfd); } else { pes.Add(0xbd); } pes.Add(0x00); pes.Add(0x00); pes.Add(0x84); pes.Add(0x81); pes.Add(0x08); pes.Add(0x21); pes.Add(0x00); pes.Add(0x01); pes.Add(0x00); pes.Add(0x01); pes.Add(0x01); pes.Add(0x81); DtsInfo info = new DtsInfo(payload, offset); if (this.MlpToAc3 || (info.Valid && info.FrameSize == len)) { pes.Add(0x71); priority = true; } else { pes.Add(0x72); priority = false; } PesHeader ph = new PesHeader(pes.ToArray()); ph.Pts = pts; PesPacket pp = new PesPacket(ph.Data, 0, ph.Data.Length, pid); pp.AddData(payload, offset, len); pp.Complete = true; MuxPesPacketToTs(pp, priority); }
public override void MuxPacket(PesPacket pp) { // TODO: Fix, just QnD ... bool bKeep = false; foreach (StreamInfo si in _StreamsToKeep) { if (si.ElementaryPID == pp.PID) { bKeep = true; } } if (bKeep) { byte[] data = pp.GetData(); _FileStream.Write(data, 0, data.Length); } }
/* * public UInt32 CurrentPacketNumber * { * get { return packetCount + (UInt32)buffer.Count; } * } * * public EpElement[] EpData * { * get * { * return epData.ToArray(); * } * } * * public StreamInfo[] Psi * { * get { return pmtStreams.ToArray(); } * } */ public override void MuxPacket(PesPacket pp) { if (fileType == TsFileType.TS || fileType == TsFileType.M2TS || fileType == TsFileType.BLU_RAY) { MuxTsPacket(pp); } else if (fileType == TsFileType.SUP_ELEMENTARY && pidMappings.ContainsKey(pp.PID)) { byte[] data = pp.GetData(); PesHeader ph = pp.GetHeader(); if (ph.HasPts) { Int64 Pts = ph.Pts; Int64 Dts = 0; if (ph.HasDts) { Dts = ph.Dts; } supHeader[2] = (byte)((Pts >> 24) & 0xff); supHeader[3] = (byte)((Pts >> 16) & 0xff); supHeader[4] = (byte)((Pts >> 8) & 0xff); supHeader[5] = (byte)(Pts & 0xff); supHeader[6] = (byte)((Dts >> 24) & 0xff); supHeader[7] = (byte)((Dts >> 16) & 0xff); supHeader[8] = (byte)((Dts >> 8) & 0xff); supHeader[9] = (byte)(Dts & 0xff); tsiow.Write(supHeader, 0, supHeader.Length); } tsiow.Write(data, ph.HeaderLength + 9, data.Length - (ph.HeaderLength + 9)); } else if (fileType == TsFileType.PES_ELEMENTARY && pidMappings.ContainsKey(pp.PID)) { byte[] data = pp.GetData(); tsiow.Write(data, 0, data.Length); } else if (fileType == TsFileType.ELEMENTARY && pidMappings.ContainsKey(pp.PID)) { byte[] data = pp.GetData(); PesHeader ph = pp.GetHeader(); tsiow.Write(data, ph.HeaderLength + 9, data.Length - (ph.HeaderLength + 9)); } }
private void MuxTsPacket(PesPacket pp) { if (pidMappings.ContainsKey(pp.PID)) { pp = CheckAndFixDiscontinuities(pp); ElementaryStreamTypes type = GetStreamType(pidMappings[pp.PID]); switch (type) { case ElementaryStreamTypes.AUDIO_STREAM_AC3: case ElementaryStreamTypes.AUDIO_STREAM_AC3_PLUS: if (MlpToAc3 == false || pp.Priority) { MuxAc3ToTs(pp, type); } break; case ElementaryStreamTypes.AUDIO_STREAM_AC3_TRUE_HD: MuxMlpToTs(pp, type); break; case ElementaryStreamTypes.AUDIO_STREAM_DTS: case ElementaryStreamTypes.AUDIO_STREAM_DTS_HD: case ElementaryStreamTypes.AUDIO_STREAM_DTS_HD_MASTER_AUDIO: if (MlpToAc3 = false || pp.Priority) { MuxDtsToTs(pp, type); } break; case ElementaryStreamTypes.AUDIO_STREAM_LPCM: case ElementaryStreamTypes.AUDIO_STREAM_MPEG1: case ElementaryStreamTypes.AUDIO_STREAM_MPEG2: MuxPesPacketToTs(pp, true); break; default: MuxPesPacketToTs(pp, pp.Priority); break; } } }
private void MuxPesPacketToTs(PesPacket pp, bool priority) { byte[] data = new byte[Constants.TS_SIZE]; int j = 0; int i = 0; byte[] pes = pp.GetData(); // take care of the first packet data[0] = Constants.SYNC_BYTE; data[1] = 0x40; // payload start data[2] = 0; if (pes.Length < Constants.TS_PAYLOAD_SIZE) { data[3] = 0x30; // adaptation and payload int stufLength = Constants.TS_PAYLOAD_SIZE - pes.Length - 1; data[4] = (byte)stufLength; i = 5; if (stufLength > 0) { data[i] = 0; i++; stufLength--; } for (; i < (6 + stufLength); i++) { data[i] = 0xff; } for (; i < Constants.TS_SIZE; i++) { data[i] = pes[j]; j++; } } else { data[3] = 0x10; // no adaptation, payload only for (i = 4; i < data.Length; i++) { data[i] = pes[j]; j++; } } TsPacket ts = new TsPacket(); ts.SetData(data, 0); ushort pid = pidMappings[pp.PID]; ts.PID = pid; ts.Priority = priority; ts.ContinuityCounter = Continuities[pid]; ts.IncrementContinuityCounter(); Continuities[pid] = ts.ContinuityCounter; buffer.Add(ts); while (j < ((pes.Length / Constants.TS_PAYLOAD_SIZE) * Constants.TS_PAYLOAD_SIZE)) { // take care of the other packets data[0] = Constants.SYNC_BYTE; data[1] = 0x00; // no payload start data[2] = 0; data[3] = 0x10; // no adaptation, payload only for (i = 4; i < data.Length; i++) { data[i] = pes[j]; j++; } ts = new TsPacket(); ts.SetData(data, 0); ts.PID = pid; ts.Priority = priority; ts.ContinuityCounter = Continuities[pid]; ts.IncrementContinuityCounter(); Continuities[pid] = ts.ContinuityCounter; buffer.Add(ts); } // take care of the last packet if (j < pes.Length) { data[0] = Constants.SYNC_BYTE; data[1] = 0x00; // no payload start data[2] = 0; data[3] = 0x30; // adaptation and payload int stufLength = Constants.TS_PAYLOAD_SIZE - (pes.Length - j) - 1; data[4] = (byte)stufLength; i = 5; if (stufLength > 0) { data[i] = 0; i++; stufLength--; for (; i < (6 + stufLength); i++) { data[i] = 0xff; } } for (; i < Constants.TS_SIZE; i++) { data[i] = pes[j]; j++; } ts = new TsPacket(); ts.SetData(data, 0); ts.PID = pid; ts.Priority = priority; ts.ContinuityCounter = Continuities[pid]; ts.IncrementContinuityCounter(); Continuities[pid] = ts.ContinuityCounter; buffer.Add(ts); } }
private PesPacket CheckAndFixDiscontinuities(PesPacket pp) { // checks for PTS/DTS discontinuities PesHeader ph = pp.GetHeader(); byte[] data = pp.GetData(); int len = ph.TotalHeaderLength; int i = len; UInt32 marker = 0xffffffff; if (Constants.DEFAULT_VIDEO_PID == pidMappings[pp.PID]) { // checks for end of stream headers switch (VideoType) { case (byte)ElementaryStreamTypes.VIDEO_STREAM_VC1: for (; i < data.Length; i++) { marker <<= 8; marker |= data[i]; if (marker == Constants.VC1_END_OF_STREAM) { break; } } if (i < data.Length) { // we have an end of stream marker i -= 3; PesPacket pnew = new PesPacket(data, 0, i, pp.PID); i += 4; pnew.AddData(data, i, data.Length - i); pp = pnew; ph = pp.GetHeader(); data = pp.GetData(); } break; case (byte)ElementaryStreamTypes.VIDEO_STREAM_MPEG2: for (; i < data.Length; i++) { marker <<= 8; marker |= data[i]; if (marker == Constants.MPEG2_SEQ_END) { break; } } if (i < data.Length) { // we have an end of stream marker i -= 3; PesPacket pnew = new PesPacket(data, 0, i, pp.PID); i += 4; pnew.AddData(data, i, data.Length - i); pp = pnew; ph = pp.GetHeader(); data = pp.GetData(); } break; case (byte)ElementaryStreamTypes.VIDEO_STREAM_H264: for (; i < data.Length; i++) { marker <<= 8; marker |= data[i]; if ((marker & 0xffffff9f) == Constants.H264_END_OF_STREAM) { break; } } if (i < data.Length) { // we have an end of stream marker i -= 3; PesPacket pnew = new PesPacket(data, 0, i, pp.PID); i += 4; pnew.AddData(data, i, data.Length - i); pp = pnew; ph = pp.GetHeader(); data = pp.GetData(); } break; } if (ph.HasPts) { lastPts = currentPts; currentPts = ph.Pts; ptsCount = ptsDelta; ptsDelta = currentPts - lastPts; if (lastPts != -1) { if (ptsDelta < (0 - (Constants.PTS_CLOCK_RATE << 2)) || ptsDelta > (Constants.PTS_CLOCK_RATE << 2)) { ptsOffset += (lastPts + ptsCount - currentPts); } } } // build EP Map info marker = 0xffffffff; switch (VideoType) { case (byte)ElementaryStreamTypes.VIDEO_STREAM_VC1: for (i = ph.TotalHeaderLength; i < data.Length; i++) { marker <<= 8; marker |= data[i]; if (marker == Constants.VC1_SEQ_SC && ph.HasPts) { EpElement ep = new EpElement(ph.Pts, this.CurrentPacketNumber); epData.Add(ep); break; } } break; case (byte)ElementaryStreamTypes.VIDEO_STREAM_MPEG2: for (i = ph.TotalHeaderLength; i < data.Length; i++) { marker <<= 8; marker |= data[i]; if (marker == Constants.MPEG2_SEQ_CODE && ph.HasPts) { EpElement ep = new EpElement(ph.Pts, this.CurrentPacketNumber); epData.Add(ep); break; } } break; case (byte)ElementaryStreamTypes.VIDEO_STREAM_H264: for (i = ph.TotalHeaderLength; i < data.Length; i++) { marker <<= 8; marker |= data[i]; if ((marker & 0xffffff9f) == Constants.H264_PREFIX && ph.HasPts) { EpElement ep = new EpElement(ph.Pts, this.CurrentPacketNumber); epData.Add(ep); break; } } break; } } if (ph.HasPts && ptsOffset != 0) { Int64 time = ph.Pts + ptsOffset; if (time < 0) { time += Constants.MAX_PTS_CLOCK; } else if (time > Constants.MAX_PTS_CLOCK) { time -= Constants.MAX_PTS_CLOCK; } ph.Pts = time; for (i = 9; i < 14; i++) { pp[i] = ph[i]; // copy PTS } if (ph.HasDts) { time = ph.Dts + ptsOffset; if (time < 0) { time += Constants.MAX_PTS_CLOCK; } else if (time > Constants.MAX_PTS_CLOCK) { time -= Constants.MAX_PTS_CLOCK; } ph.Dts = time; for (i = 14; i < 19; i++) { pp[i] = ph[i]; // copy DTS } } } lastPacket = pp; return(pp); }
private void MuxSingleAc3ToTs(byte[] payload, int offset, int len, Int64 pts, ElementaryStreamTypes type, ushort pid) { List <byte> pes = new List <byte>(); bool priority = false; pes.Add(0x00); pes.Add(0x00); pes.Add(0x01); if (this.fileType == TsFileType.BLU_RAY) { pes.Add(0xfd); } else { pes.Add(0xbd); } pes.Add(0x00); pes.Add(0x00); pes.Add(0x84); pes.Add(0x81); pes.Add(0x08); pes.Add(0x21); pes.Add(0x00); pes.Add(0x01); pes.Add(0x00); pes.Add(0x01); pes.Add(0x01); pes.Add(0x81); if ((type == ElementaryStreamTypes.AUDIO_STREAM_AC3) || (type == ElementaryStreamTypes.AUDIO_STREAM_AC3_PLUS)) { AC3Info info = new AC3Info(payload, offset); if (this.MlpToAc3 || (info.Valid && info.IndependentStream)) { pes.Add(0x71); priority = true; } else { pes.Add(0x72); priority = false; } } else if (type == ElementaryStreamTypes.AUDIO_STREAM_AC3_TRUE_HD) { if (payload.Length - offset > 1 && payload[offset] == (byte)(Constants.AC3_SYNC >> 8) && payload[offset + 1] == (byte)(Constants.AC3_SYNC & 0xff)) { pes.Add(0x76); priority = true; } else { pes.Add(0x72); priority = false; } } PesHeader ph = new PesHeader(pes.ToArray()); ph.Pts = pts; PesPacket pp = new PesPacket(ph.Data, 0, ph.Data.Length, pid); pp.AddData(payload, offset, len); pp.Complete = true; MuxPesPacketToTs(pp, priority); }
private void MuxDtsToTs(PesPacket pp, ElementaryStreamTypes type) { Int64 pts = 0; PesHeader ph = pp.GetHeader(); if (ph.HasPts == false) { if (lastPtsList.ContainsKey(pp.PID)) { pts = lastPtsList[pp.PID]; } } else { pts = ph.Pts; lastPtsList[pp.PID] = pts; } byte[] payload = pp.GetPayload(); DtsInfo dts = new DtsInfo(payload, 0); if (this.processAudio || (dts.Valid && dts.FrameSize == payload.Length)) { MuxSingleDtsToTs(payload, 0, payload.Length, pts, type, pp.PID); } else { if (soundFrames.ContainsKey(pp.PID) == false) { // skip to the good part. UInt32 mk2 = 0xffffffff; int index = 0; for (index = 0; index < payload.Length; index++) { mk2 <<= 8; mk2 |= payload[index]; if (mk2 == Constants.DTS_SYNC) { break; } } if (index == payload.Length) { MuxSingleDtsToTs(payload, 0, payload.Length, pts, type, pp.PID); } else { index--; List <byte> framelist = new List <byte>(); for (; index < payload.Length; index++) { framelist.Add(payload[index]); } soundFrames.Add(pp.PID, framelist); } } else { soundFrames[pp.PID].AddRange(payload); } if (soundFrames.ContainsKey(pp.PID)) { payload = soundFrames[pp.PID].ToArray(); dts = new DtsInfo(payload, 0); int len = 0; while (dts.Valid && dts.FrameSize > 0 && dts.FrameSize + len <= payload.Length) { len += dts.FrameSize; dts = new DtsInfo(payload, len); } if (len > 0) { MuxSingleDtsToTs(payload, 0, len, pts, type, pp.PID); soundFrames[pp.PID].RemoveRange(0, len); } } } }
private void MuxAc3ToTs(PesPacket pp, ElementaryStreamTypes type) { Int64 pts = 0; PesHeader ph = pp.GetHeader(); if (ph.HasPts == false) { if (lastPtsList.ContainsKey(pp.PID)) { pts = lastPtsList[pp.PID]; } } else { pts = ph.Pts; lastPtsList[pp.PID] = pts; } byte[] payload = pp.GetPayload(); AC3Info ac3 = new AC3Info(payload, 0); if (this.processAudio || (ac3.Valid && ac3.FrameLength == payload.Length)) { MuxSingleAc3ToTs(payload, 0, payload.Length, pts, type, pp.PID); } else { if (soundFrames.ContainsKey(pp.PID) == false) { // skip to the good part. ushort mk2 = 0xffff; int index = 0; for (index = 0; index < payload.Length; index++) { mk2 <<= 8; mk2 |= payload[index]; if (mk2 == Constants.AC3_SYNC) { break; } } if (index == payload.Length) { MuxSingleAc3ToTs(payload, 0, payload.Length, pts, type, pp.PID); } else { index--; List <byte> framelist = new List <byte>(); for (; index < payload.Length; index++) { framelist.Add(payload[index]); } soundFrames.Add(pp.PID, framelist); } } else { soundFrames[pp.PID].AddRange(payload); } if (soundFrames.ContainsKey(pp.PID)) { payload = soundFrames[pp.PID].ToArray(); ac3 = new AC3Info(payload, 0); int len = 0; if (payload.Length > ac3.MaxFrameLength) { // resync ac3 ushort mk2 = 0xffff; int index = 0; for (index = 2; index < payload.Length; index++) { mk2 <<= 8; mk2 |= payload[index]; if (mk2 == Constants.AC3_SYNC) { ac3 = new AC3Info(payload, index - 1); if (ac3.Valid && ac3.FrameLength > 0) { break; } } } if (index == payload.Length) { len = payload.Length; } else { index -= 1; len = index; ac3 = new AC3Info(payload, len); while (ac3.Valid && ac3.FrameLength > 0 && ac3.FrameLength + len <= payload.Length) { len += ac3.FrameLength; ac3 = new AC3Info(payload, len); } } } else { while (ac3.Valid && ac3.FrameLength > 0 && ac3.FrameLength + len <= payload.Length) { len += ac3.FrameLength; ac3 = new AC3Info(payload, len); } } if (len > 0) { MuxSingleAc3ToTs(payload, 0, len, pts, type, pp.PID); soundFrames[pp.PID].RemoveRange(0, len); } } } }
public void StartMuxing(string outPath, BackgroundWorker worker, TsFileType outType, List <ushort> pidsToKeep, TimeSpan ts, TimeSpan te, bool useAsync, bool processAudio, bool MlpToAc3, PesFile input, PesFile secondary, TimeSpan offset, TimeSpan chapterLen) { inFile = input; bw = worker; List <StreamInfo> sis = new List <StreamInfo>(); PesPacket[] ppa = null; PesPacket[] spa = null; BluRayOutput bo = null; Int64 startTrim = inFile.StartPcr + ((Int64)ts.TotalSeconds * (Int64)Constants.MPEG2TS_CLOCK_RATE); if (startTrim > Constants.MAX_MPEG2TS_CLOCK) { startTrim -= Constants.MAX_MPEG2TS_CLOCK; } foreach (StreamInfo si in inFile.StreamInfos) { if (pidsToKeep.Contains(si.ElementaryPID)) { sis.Add(si); } } if (null != secondary && pidsToKeep.Contains(secondary.StreamInfos[0].ElementaryPID)) { sis.Add(secondary.StreamInfos[0]); } switch (outType) { case TsFileType.BLU_RAY: bo = new BluRayOutput(outPath, chapterLen); outFile = new BlueMux(Path.Combine(outPath, @"BDMV\STREAM\00001.m2ts"), outType, sis, useAsync, processAudio, MlpToAc3); break; case TsFileType.MKV: outFile = new MkvMux(outPath, sis, useAsync, processAudio); break; case TsFileType.DEMUX: outFile = new DeMux(outPath, sis, useAsync, processAudio); break; default: outFile = new BlueMux(outPath, outType, sis, useAsync, processAudio, MlpToAc3); break; } if (ts.TotalSeconds == 0) { inFile.Seek(-1); } else { inFile.Seek(startTrim); } if (te.TotalSeconds > 0) { endTrim = inFile.EndPcr - ((Int64)te.TotalSeconds * (Int64)Constants.MPEG2TS_CLOCK_RATE); if (endTrim < 0) { endTrim += Constants.MAX_MPEG2TS_CLOCK; } } inFile.SetPcrDelegate(new PcrChanged(UpdatePcr)); inFile.SetPtsDelegate(new PtsChanged(UpdatePts)); startOffset = startTrim + ((Int64)offset.TotalSeconds * (Int64)Constants.MPEG2TS_CLOCK_RATE); if (startOffset > Constants.MAX_MPEG2TS_CLOCK) { startOffset -= Constants.MAX_MPEG2TS_CLOCK; } for (ppa = inFile.GetNextPesPackets(); ppa != null && ppa.Length > 0 && subtitles == false; ppa = inFile.GetNextPesPackets()) { if (worker.CancellationPending || done) { goto leave_routine; } foreach (PesPacket pp in ppa) { if (null != pp) { outFile.MuxPacket(pp); } else { goto leave_routine; } } } if (subtitles) { if (null != secondary && ppa != null && ppa.Length > 0) { secondary.Seek(-1); spa = secondary.GetNextPesPackets(); PesPacket sp = spa[0]; PesHeader sh = sp.GetHeader(); PesHeader ph = ppa[0].GetHeader(); while (ph == null || ph.HasPts == false) { if (worker.CancellationPending || done) { goto leave_routine; } foreach (PesPacket pp in ppa) { if (null != pp) { outFile.MuxPacket(pp); } } ppa = inFile.GetNextPesPackets(); if (ppa == null || ppa.Length == 0 || ppa[0] == null) { goto leave_routine; } ph = ppa[0].GetHeader(); } Int64 ptsOffset = ph.Pts - sh.Pts; bool clock = true; for (; ppa != null && ppa.Length > 0 && ppa[0] != null; ppa = inFile.GetNextPesPackets()) { foreach (PesPacket pp in ppa) { ph = pp.GetHeader(); if (sh != null && ph != null && ph.HasPts) { if (clock) { Int64 time = sh.Pts + ptsOffset; if (time < 0) { time += Constants.MAX_PTS_CLOCK; } else if (time > Constants.MAX_PTS_CLOCK) { time -= Constants.MAX_PTS_CLOCK; } sh.Pts = time; for (int i = 9; i < 14; i++) { sp[i] = sh[i]; // copy PTS } if (sh.HasDts) { time = sh.Dts + ptsOffset; if (time < 0) { time += Constants.MAX_PTS_CLOCK; } else if (time > Constants.MAX_PTS_CLOCK) { time -= Constants.MAX_PTS_CLOCK; } sh.Dts = time; for (int i = 14; i < 19; i++) { sp[i] = sh[i]; // copy DTS } } clock = false; } Int64 delta = sh.Pts - ph.Pts; if (delta > (0 - Constants.PTS_CLOCK_RATE) && delta < Constants.PTS_CLOCK_RATE) { outFile.MuxPacket(sp); spa = secondary.GetNextPesPackets(); if (spa != null && spa.Length > 0 && spa[0] != null) { sp = spa[0]; sh = sp.GetHeader(); clock = true; } } } outFile.MuxPacket(pp); } } } else { for (; ppa != null && ppa.Length > 0; ppa = inFile.GetNextPesPackets()) { if (worker.CancellationPending || done) { goto leave_routine; } foreach (PesPacket pp in ppa) { if (null != pp) { outFile.MuxPacket(pp); } else { goto leave_routine; } } } } } leave_routine: outFile.Close(); if (outType == TsFileType.BLU_RAY) { bo.Author(outFile.EpData, outFile.Psi, outFile.CurrentPacketNumber); } }
// Called with every used / valid PesPacket from source stream. public abstract void MuxPacket(PesPacket pp);