예제 #1
0
        /// <summary>
        /// Parses PMT structure.
        /// </summary>
        /// <param name="program"></param>
        /// <param name="br"></param>
        private void ParsePMT(TSPacket tsPacket, TSProgram program)
        {
            tsPacket.ParsePMTHeader();

            uint streamTypeCode = 0;
            uint elementary_PID = 0;
            uint ES_info_length = 0;
            while (tsPacket.ParseNextPMTStream(ref streamTypeCode, ref elementary_PID, ref ES_info_length))
            {
                // Allocate stream and payload handlers
                if (_streams == null)
                    _streams = new Dictionary<uint, TSStream>();

                TSStream stream;
                bool discontinuity;

                HLSTrace.WriteLineLow("PMT: type {0} pid {1} len {2}", streamTypeCode.ToString("X"), elementary_PID.ToString("X"), ES_info_length.ToString("X"));

                if (_streams.TryGetValue(elementary_PID, out stream))
                {
                    discontinuity = false;
                }
                else
                {
                    if (streamTypeCode == AVC_STREAM_TYPE_CODE)
                    {
                        stream = new TSStream(elementary_PID, TSStream.StreamContetType.Video);

                        if (_videoFormatParser == null)
                            _videoFormatParser = new H264Parser(_videoBuffer, _metadata, _stream.HLSStream );
                        else
                            _videoFormatParser.Flush();

                        _videoFormatParser.Bitrate = _bitrate;

                        stream.Parser = new PESParser(_videoFormatParser);
                    }
                    else if (streamTypeCode == AAC_STREAM_TYPE_CODE || streamTypeCode == DDPLUS_STREAM_TYPE_CODE)
                    {
                        stream = new TSStream(elementary_PID, TSStream.StreamContetType.Audio);

                        bool discardThisStream = false;

                        foreach (KeyValuePair<uint, TSStream> s in _streams)
                        {
                            if (s.Value.StreamType == TSStream.StreamContetType.Audio)
                            {
                                if (s.Key > elementary_PID)
                                {
                                    if (_nullFormatParser == null)
                                        _nullFormatParser = new NullParser(null);

                                    s.Value.Parser = new PESParser(_nullFormatParser);
                                }
                                else
                                {
                                    discardThisStream = true;
                                    break;
                                }
                            }
                        }

                        if (discardThisStream)
                        {
                            if (_nullFormatParser == null)
                                _nullFormatParser = new NullParser(null);

                            stream.Parser = new PESParser(_nullFormatParser);
                            stream.StreamType = TSStream.StreamContetType.Unknown;
                        }
                        else
                        {
                            if (null != _audioFormatParser)
                            {
                                _audioFormatParser.Flush();
                            }
                            if (streamTypeCode == AAC_STREAM_TYPE_CODE)
                                _audioFormatParser = new ADTSParser(_audioBuffer, _stream.HLSStream);
                            else
                                _audioFormatParser = new DDPlusParser(_audioBuffer, _stream.HLSStream);

                            stream.Parser = new PESParser(_audioFormatParser);
                            stream.StreamType = TSStream.StreamContetType.Audio;
                        }
                    }
                    else
                    {
                        stream = new TSStream(elementary_PID, TSStream.StreamContetType.Unknown);
                        HLSTrace.WriteLine("Ignoring unknown stream type {0}", streamTypeCode);
                        if (_nullFormatParser == null)
                            _nullFormatParser = new NullParser(null);
                        stream.Parser = new PESParser(_nullFormatParser);
                    }

                    _streams[elementary_PID] = stream;
                    discontinuity = true;
                }

                program.AddStream(stream);
                stream.Parser.StartSegment(discontinuity);
            }
        }
예제 #2
0
        /// <summary>
        /// Parses a single packet of MPEG-2 Transport Stream. Packet must be exactly 188 bytes long
        /// and must begin with packet signature.
        /// </summary>
        /// <param name="byteBuffer"></param>
        protected void ParsePacket(byte[] byteBuffer)
        {
            TSPacket tsPacket = new TSPacket(byteBuffer);

            if (tsPacket.HasPayload())
            {
                if (tsPacket._pid == 0)
                {
                    if (!_parsedPAT)
                    {
                        _parsedPAT = true;
                        if (_programs == null)
                            _programs = new Dictionary<uint, TSProgram>();

                        tsPacket.ParsePAT(ref _programs);
                    }
                }
                else
                {
                    TSProgram program;
                    if (_programs != null && _programs.TryGetValue(tsPacket._pid, out program))
                    {
                        if (!program.ParsedPMT)
                        {
                            program.ParsedPMT = true;
                            ParsePMT(tsPacket, program);
                        }
                    }
                    else
                    {
                        TSStream stream;
                        if (_streams != null && _streams.TryGetValue(tsPacket._pid, out stream))
                        {
                            if ((tsPacket._transport_error_indicator == 0x01) || tsPacket._discontinuity)
                            {
                                stream.Flush(true);
                                HLSTrace.WriteLine("Flush{0}: TEI {1:X} discontinuity {2:X}", tsPacket._pid, tsPacket._transport_error_indicator, tsPacket._discontinuity);
                            }

                            stream.ParseData(byteBuffer, tsPacket._headerSize, byteBuffer.Length - tsPacket._headerSize, (int)tsPacket._continuity_counter);
                        }
                    }
                }
            }
        }