public override void PcrChanged(Int64 pcr) { lastPcr = currentPcr; currentPcr = pcr; Int64 newPcr = -1; if (lastPcr == -1) { pcrOffset = currentPcr - Constants.MPEG2TS_CLOCK_RATE; newPcr = currentPcr - pcrOffset; if (newPcr < 0) newPcr += Constants.MAX_MPEG2TS_CLOCK; if (newPcr >= Constants.MAX_MPEG2TS_CLOCK) newPcr -= Constants.MAX_MPEG2TS_CLOCK; pcrPacket = new PcrPacket(newPcr,0,Constants.DEFAULT_PCR_PID); PcrPacket pp = new PcrPacket(newPcr, pcrPacket.ContinuityCounter, Constants.DEFAULT_PCR_PID); buffer.Add(pp); return; } Int64 delta = currentPcr - lastPcr; if (delta < 0) delta += Constants.MAX_MPEG2TS_CLOCK; if (delta > Constants.MPEG2TS_CLOCK_RATE) { // discontinuity - adjust offset Int64 predictedPcr = lastPcr + (buffer.Count * lastDelta); if (predictedPcr >= Constants.MAX_MPEG2TS_CLOCK) predictedPcr -= Constants.MAX_MPEG2TS_CLOCK; pcrOffset += currentPcr - predictedPcr; pcrPacket.IncrementContinuityCounter(); PcrPacket pp = new PcrPacket(newPcr, pcrPacket.ContinuityCounter, Constants.DEFAULT_PCR_PID); buffer.Add(pp); return; } newPcr = currentPcr - pcrOffset; if (newPcr < 0) newPcr += Constants.MAX_MPEG2TS_CLOCK; if (newPcr >= Constants.MAX_MPEG2TS_CLOCK) newPcr -= Constants.MAX_MPEG2TS_CLOCK; pat.IncrementContinuityCounter(); buffer.Add(new PatPacket(pat.GetData())); pmt.IncrementContinuityCounter(); buffer.Add(new PmtPacket(pmt.GetData())); sitCount += 1; sitCount %= 10; if (sitCount == 0) { // one SIT for every 10 PMT/PAT sit.IncrementContinuityCounter(); buffer.Add(new SitPacket(sit.GetData())); } pcrPacket.IncrementContinuityCounter(); PcrPacket p = new PcrPacket(newPcr, pcrPacket.ContinuityCounter, Constants.DEFAULT_PCR_PID); buffer.Add(p); lastDelta = delta / buffer.Count; Int64 stamp = lastPcr % Constants.MAX_BLURAY_CLOCK; for (int i = 0; i < buffer.Count; i++) { stamp += lastDelta; stamp %= Constants.MAX_BLURAY_CLOCK; header[0] = (byte)((stamp >> 24) & 0x3f); header[1] = (byte)((stamp >> 16) & 0xff); header[2] = (byte)((stamp >> 8) & 0xff); header[3] = (byte)(stamp & 0xff); if (fileType == TsFileType.M2TS || fileType == TsFileType.BLU_RAY) { tsiow.Write(header, 0, 4); tsiow.Write(buffer[i].GetData(), 0, Constants.TS_SIZE); } else if (fileType == TsFileType.TS) { tsiow.Write(buffer[i].GetData(), 0, Constants.TS_SIZE); } } packetCount += (UInt32)buffer.Count; buffer.Clear(); }
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(); }