예제 #1
0
 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);
 }
예제 #2
0
            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]);
                }
            }
예제 #3
0
        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)
            { }
        }