private void CreatePsi() { pidMappings = new Dictionary <ushort, ushort>(); Continuities = new Dictionary <ushort, byte>(); ushort currentVideoPid = Constants.DEFAULT_VIDEO_PID; ushort currentAudioPid = Constants.DEFAULT_AUDIO_PID; ushort currentSubPid = Constants.DEFAULT_SUBTITLE_PID; ushort currentPresPid = Constants.DEFAULT_PRESENTATION_GRAPHICS_PID; ushort currentIntPid = Constants.DEFAULT_INTERACTIVE_GRAPHICS_PID; pmtStreams = new List <StreamInfo>(); StreamInfo sitemp = null; foreach (StreamInfo si in StreamsToKeep) { if (pidMappings.ContainsKey(si.ElementaryPID)) { throw new ArgumentException(String.Format("Invalid/Duplicate StreamInfo with pid {0}", si.ElementaryPID)); } switch (si.StreamType) { case ElementaryStreamTypes.AUDIO_STREAM_AC3: case ElementaryStreamTypes.AUDIO_STREAM_AC3_PLUS: pidMappings.Add(si.ElementaryPID, currentAudioPid); if (this.fileType == TsFileType.BLU_RAY) { sitemp = new StreamInfo(si.StreamType, currentAudioPid); } else { sitemp = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_AC3, currentAudioPid); } Continuities.Add(currentAudioPid, 0); currentAudioPid++; break; case ElementaryStreamTypes.AUDIO_STREAM_AC3_TRUE_HD: pidMappings.Add(si.ElementaryPID, currentAudioPid); if (MlpToAc3) { sitemp = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_AC3, currentAudioPid); } else { sitemp = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_AC3_TRUE_HD, currentAudioPid); } Continuities.Add(currentAudioPid, 0); currentAudioPid++; break; case ElementaryStreamTypes.AUDIO_STREAM_DTS_HD: case ElementaryStreamTypes.AUDIO_STREAM_DTS_HD_MASTER_AUDIO: pidMappings.Add(si.ElementaryPID, currentAudioPid); if (MlpToAc3) { sitemp = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_DTS, currentAudioPid); } else { sitemp = new StreamInfo(si.StreamType, currentAudioPid); } Continuities.Add(currentAudioPid, 0); currentAudioPid++; break; case ElementaryStreamTypes.AUDIO_STREAM_DTS: case ElementaryStreamTypes.AUDIO_STREAM_LPCM: case ElementaryStreamTypes.AUDIO_STREAM_MPEG1: case ElementaryStreamTypes.AUDIO_STREAM_MPEG2: pidMappings.Add(si.ElementaryPID, currentAudioPid); sitemp = new StreamInfo(si.StreamType, currentAudioPid); Continuities.Add(currentAudioPid, 0); currentAudioPid++; break; case ElementaryStreamTypes.SUBTITLE_STREAM: pidMappings.Add(si.ElementaryPID, currentSubPid); sitemp = new StreamInfo(si.StreamType, currentSubPid); Continuities.Add(currentSubPid, 0); currentSubPid++; break; case ElementaryStreamTypes.PRESENTATION_GRAPHICS_STREAM: pidMappings.Add(si.ElementaryPID, currentPresPid); sitemp = new StreamInfo(si.StreamType, currentPresPid); Continuities.Add(currentPresPid, 0); currentPresPid++; break; case ElementaryStreamTypes.INTERACTIVE_GRAPHICS_STREAM: pidMappings.Add(si.ElementaryPID, currentIntPid); sitemp = new StreamInfo(si.StreamType, currentIntPid); Continuities.Add(currentIntPid, 0); currentIntPid++; break; case ElementaryStreamTypes.VIDEO_STREAM_H264: case ElementaryStreamTypes.VIDEO_STREAM_MPEG1: case ElementaryStreamTypes.VIDEO_STREAM_MPEG2: case ElementaryStreamTypes.VIDEO_STREAM_VC1: pidMappings.Add(si.ElementaryPID, currentVideoPid); sitemp = new StreamInfo(si.StreamType, currentVideoPid); Continuities.Add(currentVideoPid, 0); currentVideoPid++; if (0 == VideoType) { VideoType = (byte)si.StreamType; } break; } sitemp.ElementaryDescriptors = si.ElementaryDescriptors; sitemp.AspectRatio = si.AspectRatio; sitemp.AudioPresentationType = si.AudioPresentationType; sitemp.FrameRate = si.FrameRate; sitemp.SamplingFrequency = si.SamplingFrequency; sitemp.VideoFormat = si.VideoFormat; pmtStreams.Add(sitemp); } pat = new PatPacket(); ProgramInfo[] pi = new ProgramInfo[2]; pi[0] = new ProgramInfo(0, Constants.SIT_PID); pi[1] = new ProgramInfo(1, Constants.DEFAULT_PMT_PID); pat.Programs = pi; pmt = new PmtPacket(); pmt.PID = Constants.DEFAULT_PMT_PID; pmt.ElementaryStreams = pmtStreams.ToArray(); List <byte> programDescriptors = new List <byte>(); programDescriptors.AddRange(Constants.copy_control_descriptor); programDescriptors.AddRange(Constants.hdmv_registration_descriptor); pmt.ProgramDescriptorsData = programDescriptors.ToArray(); sit = new SitPacket(); buffer.Add(pat); pat.IncrementContinuityCounter(); buffer.Add(pmt); pmt.IncrementContinuityCounter(); buffer.Add(sit); sit.IncrementContinuityCounter(); }
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(); }