private bool TryParseContent(TSPacket packet, out byte[] data) { data = null; if (packet.video_block || packet.audio_block) { cache.Close(); data = cache.ToArray(); cache = new MemoryStream(); return(true); } return(false); }
public ProgramMapTable(TSPacket pkt, byte[] packet) { int section_length = ((packet[pkt.payload_offset + 1] & 0x0F) << 8 | packet[pkt.payload_offset + 2]); if (section_length < 13) { PCRPID = -1; } else { PCRPID = ((packet[pkt.payload_offset + 8] & 0x1F) << 8 | packet[pkt.payload_offset + 9]); } }
public async Task ReadAsync(IContentSink sink, Stream stream, CancellationToken cancel_token) { int streamIndex = -1; long contentPosition = 0; DateTime streamOrigin = DateTime.Now; DateTime latestContentTime = DateTime.Now; byte[] bytes188 = new byte[188]; byte[] latestHead = new byte[0]; byte[] contentData = null; streamIndex = Channel.GenerateStreamID(); streamOrigin = DateTime.Now; sink.OnContentHeader(new Content(streamIndex, TimeSpan.Zero, contentPosition, new byte[] {}, PCPChanPacketContinuation.None)); try { while (!cancel_token.IsCancellationRequested) { bytes188 = await stream.ReadBytesAsync(188, cancel_token).ConfigureAwait(false); TSPacket packet = new TSPacket(bytes188); if (packet.sync_byte != 0x47) { throw new Exception(); } if (packet.payload_unit_start_indicator > 0) { if (packet.PID == patID) { pmtID = packet.PMTID; head = new MemoryStream(); if (!addHead(bytes188)) { throw new Exception(); } continue; } if (packet.PID == pmtID) { var pmt = new ProgramMapTable(packet, bytes188); pcrPID = pmt.PCRPID; if (!addHead(bytes188)) { throw new Exception(); } head.Close(); byte[] newHead = head.ToArray(); if (!Enumerable.SequenceEqual(newHead, latestHead)) { streamIndex = Channel.GenerateStreamID(); contentPosition = 0; sink.OnContentHeader(new Content(streamIndex, DateTime.Now - streamOrigin, contentPosition, newHead, PCPChanPacketContinuation.None)); contentPosition += newHead.Length; latestHead = newHead; } continue; } if (packet.PID == pcrPID && packet.program_clock_reference > 0.0) { if (packet.program_clock_reference < rateCounter.lastPCR) { rateCounter.lastPCR = packet.program_clock_reference; rateCounter.byteCount = 0; recvRate = 0.0; } else if (rateCounter.lastPCR + 10.0 < packet.program_clock_reference) { var bitrate = 8 * rateCounter.byteCount / (packet.program_clock_reference - rateCounter.lastPCR); UpdateRecvRate(sink, bitrate); rateCounter.lastPCR = packet.program_clock_reference; rateCounter.byteCount = 0; } } if ((DateTime.Now - latestContentTime).Milliseconds > 50) { TryParseContent(packet, out contentData); if (contentData != null) { sink.OnContent(new Content(streamIndex, DateTime.Now - streamOrigin, contentPosition, contentData, PCPChanPacketContinuation.None)); contentPosition += contentData.Length; latestContentTime = DateTime.Now; } } } if (!addCache(bytes188)) { throw new Exception(); } rateCounter.byteCount += 188; } } catch (EndOfStreamException) { } catch (Exception) { } }