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 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); } } } }
public override PesPacket[] GetNextPesPackets() { // there was a big optimization opportunity here: // this method added to partial packets one byte at a time // the calls to PesPacket.AddData used about 40% of total CPU byte[] inData = new byte[1]; byte[] inData2 = new byte[128]; int bytesRead = 0; int bytesToRead = 0; int bytesToGo = 0; UInt32 marker = 0xffffffff; PesPacket pp = null; PesPacket partial = null; int i = 0; while (tsior.Read(inData, 0, inData.Length) == inData.Length) { marker = marker << 8; marker &= 0xffffff00; marker += inData[0]; if ((marker & 0xffffff00) == 0x00000100) { if ((marker & 0xff) == Constants.PACK_ID) { // pack start code UInt64 header = 0; for (i = 4; i < 10; i++) { if (tsior.Read(inData, 0, inData.Length) != inData.Length) goto done; header <<= 8; header |= inData[0]; } for (i = 10; i < 14; i++) // skip mux rate etc. { if (tsior.Read(inData, 0, inData.Length) != inData.Length) goto done; } Int64 pcr = (Int64)((header & 0x380000000000) >> 13); pcr |= (Int64)((header & 0x3fff8000000) >> 12); pcr |= (Int64)((header & 0x3fff800) >> 11); pcr *= 300; pcr |= (Int64)((header & 0x3fe) >> 1); Int64 delta = pcr - lastPcr; if (delta > Constants.MPEG2TS_CLOCK_RATE / 9) { if (pcrDelegate != null) pcrDelegate(pcr); lastPcr = pcr; } } else if (((marker & 0xff) == Constants.SYS_ID) || ((marker & 0xff) == Constants.MAP_ID) || ((marker & 0xff) == Constants.PAD_ID) || ((marker & 0xff) == Constants.DIR_ID)) { ushort Length = 0; for (i = 4; i < 6; i++) { if (tsior.Read(inData, 0, inData.Length) != inData.Length) goto done; Length <<= 8; Length |= inData[0]; } Length += 6; for (i = 6; i < Length; i++) { if (tsior.Read(inData, 0, inData.Length) != inData.Length) goto done; } } else { byte end = inData[0]; inData[0] = 0; partial = new PesPacket(inData, 0, 1, 0); partial.AddData(inData, 0, 1); inData[0] = 1; partial.AddData(inData, 0, 1); inData[0] = end; partial.AddData(inData, 0, 1); ushort Length = 0; for (i = 4; i < 6; i++) { if (tsior.Read(inData, 0, inData.Length) != inData.Length) goto done; partial.AddData(inData, 0, 1); Length <<= 8; Length |= inData[0]; } Length += 6; // we don't need this byte-by-byte loop here, as we have just gotten the length: /* for (i = 6; i < Length; i++) { if (tsior.Read(inData, 0, inData.Length) != inData.Length) goto done; partial.AddData(inData, 0, 1); } */ bytesToGo = Length - 6; while (bytesToGo > 0) { bytesToRead = (bytesToGo > inData2.Length) ? inData2.Length : bytesToGo; if ((bytesRead = tsior.Read(inData2, 0, bytesToRead)) != bytesToRead) goto done; partial.AddData(inData2, 0, bytesRead); bytesToGo -= bytesRead; } pp = partial; PesHeader ph = partial.GetHeader(); if (partial.BaseId == Constants.PES_PRIVATE1) { if ((partial.ExtendedId & 0xf0) == Constants.PES_PRIVATE_AC3_PLUS || (partial.ExtendedId & 0xf8) == Constants.PES_PRIVATE_AC3) { if (soundFrames.ContainsKey(partial.ExtendedId) == false) soundFrames.Add(partial.ExtendedId, new List<byte>()); byte[] tempd = partial.GetPayload(); for (int j = 4; j < tempd.Length; j++) soundFrames[partial.ExtendedId].Add(tempd[j]); tempd = soundFrames[partial.ExtendedId].ToArray(); int len = 0; ushort mk2 = 0xffff; if (tempd.Length > 2 && tempd[0] == (byte)(Constants.AC3_SYNC >> 8) && tempd[1] == (byte)(Constants.AC3_SYNC & 0xff)) { pp = null; while (tempd.Length > 2 && tempd[0] == (byte)(Constants.AC3_SYNC >> 8) && tempd[1] == (byte)(Constants.AC3_SYNC & 0xff)) { AC3Info ac3 = new AC3Info(tempd, 0); if (ac3.Valid == false || ac3.FrameLength == 0 || tempd.Length < ac3.FrameLength) break; if (pp == null) pp = new PesPacket(partial.GetData(), 0, ph.TotalHeaderLength, partial.ExtendedId); pp.AddData(tempd, 0, ac3.FrameLength); soundFrames[partial.ExtendedId].RemoveRange(0, ac3.FrameLength); tempd = soundFrames[partial.ExtendedId].ToArray(); } if (pp != null) { pp.Complete = true; goto done; } } for (int j = 2; j < tempd.Length; j++) { mk2 <<= 8; mk2 |= tempd[j]; if (mk2 == Constants.AC3_SYNC) { len = j - 1; mk2 = 0xffff; break; } } if (len == 0) len = tempd.Length; soundFrames[partial.ExtendedId].RemoveRange(0, len); pp = new PesPacket(partial.GetData(), 0, ph.TotalHeaderLength, partial.ExtendedId); pp.AddData(tempd, 0, len); pp.Complete = true; } else if ((partial.ExtendedId & 0xf8) == Constants.PES_PRIVATE_AC3_TRUE_HD) { if (soundFrames.ContainsKey(partial.ExtendedId) == false) soundFrames.Add(partial.ExtendedId, new List<byte>()); byte[] tempd = partial.GetPayload(); for (int j = 5; j < tempd.Length; j++) soundFrames[partial.ExtendedId].Add(tempd[j]); tempd = soundFrames[partial.ExtendedId].ToArray(); int len = tempd.Length; /* UInt32 mk2 = 0xffffffff; for (int j = 5; j < tempd.Length; j++) { mk2 <<= 8; mk2 |= tempd[j]; if (mk2 == Constants.MLP_SYNC) { len = j - 3; mk2 = 0xffffffff; } } if (len == 0) { len = tempd.Length; } */ soundFrames[partial.ExtendedId].RemoveRange(0, len); pp = new PesPacket(partial.GetData(), 0, ph.TotalHeaderLength, partial.ExtendedId); pp.AddData(tempd, 0, len); pp.Complete = true; } else if ((partial.ExtendedId & 0xf8) == Constants.PES_PRIVATE_LPCM) { if (soundFrames.ContainsKey(partial.ExtendedId) == false) soundFrames.Add(partial.ExtendedId, new List<byte>()); byte[] tempd = partial.GetPayload(); for (int j = 7; j < tempd.Length; j++) soundFrames[partial.ExtendedId].Add(tempd[j]); tempd = soundFrames[partial.ExtendedId].ToArray(); int len = tempd.Length; /* UInt32 mk2 = 0xffffffff; for (int j = 5; j < tempd.Length; j++) { mk2 <<= 8; mk2 |= tempd[j]; if (mk2 == Constants.MLP_SYNC) { len = j - 3; mk2 = 0xffffffff; } } if (len == 0) { len = tempd.Length; } */ soundFrames[partial.ExtendedId].RemoveRange(0, len); pp = new PesPacket(partial.GetData(), 0, ph.TotalHeaderLength, partial.ExtendedId); pp.AddData(tempd, 0, len); pp.Complete = true; } else if ((partial.ExtendedId & 0xf8) == Constants.PES_PRIVATE_DTS_HD) { if (soundFrames.ContainsKey(partial.ExtendedId) == false) soundFrames.Add(partial.ExtendedId, new List<byte>()); byte[] tempd = partial.GetPayload(); for (int j = 4; j < tempd.Length; j++) soundFrames[partial.ExtendedId].Add(tempd[j]); tempd = soundFrames[partial.ExtendedId].ToArray(); int len = 0; UInt32 mk2 = 0xffffffff; for (int j = 4; j < tempd.Length; j++) { mk2 <<= 8; mk2 |= tempd[j]; if (mk2 == Constants.DTS_SYNC) { len = j - 3; mk2 = 0xffffffff; } } if (len == 0) { DtsInfo dts = new DtsInfo(tempd, 0); if (dts.Valid && (int)dts.FrameSize < tempd.Length && (tempd.Length - (int)dts.FrameSize < 4)) len = (int)dts.FrameSize; else len = tempd.Length; } soundFrames[partial.ExtendedId].RemoveRange(0, len); pp = new PesPacket(partial.GetData(), 0, ph.TotalHeaderLength, partial.ExtendedId); pp.AddData(tempd, 0, len); pp.Complete = true; } else pp.PID = pp.ExtendedId; } else if (pp.BaseId == Constants.PES_PADDING || pp.BaseId == Constants.PES_PRIVATE2) { marker = 0xffffffff; continue; } else if (((pp.BaseId & 0xe0) == Constants.PES_AUDIO_MPEG) || ((pp.BaseId & 0xf0) == Constants.PES_VIDEO)) pp.PID = pp.BaseId; else if (pp.BaseId == Constants.PES_VIDEO_VC1 && ph != null) pp.PID = ph.Extention2; if (ph != null && ph.HasPts) { if (ptsDelegate != null) ptsDelegate(ph.Pts, pp.PID); } goto done; } marker = 0xffffffff; } } done: if (null != pp) { PesPacket[] ppa = new PesPacket[1]; ppa[0] = pp; return ppa; } else return null; }
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); } } } }
protected override void GetInitialValues() { GetTimestamps(); Seek(-1); PatPacket pp = null; PmtPacket pm = null; bool bluray = false; bool validPmt = false; ushort pmtPid = 0; int i = 0; Dictionary<ushort, StreamInfo> streams = new Dictionary<ushort, StreamInfo>(); while (true) { for (i = tsior.Read(tsPack, 0, 1 + stride); (i > 0) && (tsPack[stride] != Constants.SYNC_BYTE); i = tsior.Read(tsPack, stride, 1)) ; // ensure a good sync byte if (i == 0) break; // end of stream i = tsior.Read(tsPack, stride + 1, tsPack.Length - (stride + 1)); if (i < tsPack.Length - (stride + 1)) break; // end of stream ts.SetData(tsPack, stride); if (ts.PID == Constants.PAT_PID) { pp = new PatPacket(ts.GetData()); ProgramInfo[] pi = pp.Programs; if (null != pi && pi.Length == 2) { if ((pi[0].ProgramNumber == 0 && pi[0].ProgramPID == 0x001f && pi[1].ProgramNumber == 1 && pi[1].ProgramPID == 0x0100) || (pi[1].ProgramNumber == 0 && pi[1].ProgramPID == 0x001f && pi[0].ProgramNumber == 1 && pi[0].ProgramPID == 0x0100)) { bluray = true; } } else if (null != pi && pi[0] != null && pi[0].ProgramNumber == 1) pmtPid = pi[0].ProgramPID; } else if (bluray && ts.PID == 0x0100) { if (pm == null) pm = new PmtPacket(ts.GetData()); else if (pm.Complete == false) pm.AddData(ts.Payload, 0, ts.Payload.Length); if (pm.Complete) { sis = pm.ElementaryStreams; dt = pm.DtcpInfo; return; } } else if (ts.PID == pmtPid) { pm = new PmtPacket(ts.GetData()); sis = pm.ElementaryStreams; dt = pm.DtcpInfo; } else if (streams.ContainsKey(ts.PID) == false && ts.HasPesHeader) { byte[] payload = ts.Payload; PesHeader ph = new PesHeader(ts.Payload); PesPacket pes = new PesPacket(payload, 0, payload.Length, ts.PID); if (ph.StreamId == Constants.PES_PRIVATE1) { byte[] audio = pes.GetPayload(); AC3Info ac3 = new AC3Info(audio, 0); DtsInfo dts = new DtsInfo(audio, 0); MlpInfo mlp = new MlpInfo(audio, 0); if (ac3.Valid) { if (ac3.SyntaxType == Ac3SyntaxType.Standard || ac3.SyntaxType == Ac3SyntaxType.Alternative) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_AC3, ts.PID); streams.Add(ts.PID, si); } else if (ac3.SyntaxType == Ac3SyntaxType.Enhanced) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_AC3_PLUS, ts.PID); streams.Add(ts.PID, si); } } else if (dts.Valid) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_DTS_HD, ts.PID); streams.Add(ts.PID, si); } else if (mlp.Valid) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_AC3_TRUE_HD, ts.PID); streams.Add(ts.PID, si); } else if ((pes.ExtendedId & 0xf8) == Constants.PES_PRIVATE_LPCM) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_LPCM, ts.PID); streams.Add(ts.PID, si); } } else if ((ph.StreamId & 0xe0) == Constants.PES_AUDIO_MPEG) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_MPEG2, ts.PID); streams.Add(ts.PID, si); } else if ((ph.StreamId & 0xf0) == Constants.PES_VIDEO) { UInt32 format = pes.ExtendedType; if ((format & 0xffff) == 0x1) { } else if ((format & 0xffffff00) == 0x100) { } H264Info h264 = new H264Info(payload, 0); Mpeg2Info mpg2 = new Mpeg2Info(payload, 0); if (h264.Valid) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.VIDEO_STREAM_H264, ts.PID); streams.Add(ts.PID, si); } else if (mpg2.Valid) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.VIDEO_STREAM_MPEG2, ts.PID); streams.Add(ts.PID, si); } } else if (ph.StreamId == Constants.PES_VIDEO_VC1) { StreamInfo si = new StreamInfo(ElementaryStreamTypes.VIDEO_STREAM_VC1, ts.PID); streams.Add(ts.PID, si); } } if (sis != null) { validPmt = true; foreach (StreamInfo si in sis) { if (streams.ContainsKey(si.ElementaryPID) == false) { validPmt = false; break; } } if (validPmt) return; } if (fs.Position > (Constants.DISK_BUFFER << 1)) break; } sis = new StreamInfo[streams.Values.Count]; streams.Values.CopyTo(sis, 0); }