Ejemplo n.º 1
0
        protected virtual int FindTSHeadFlag(byte[] data)
        {
            var             ms   = new MemoryStream(data);
            TSProgramManage tsms = new TSProgramManage();
            int             pos  = 0;

            while (pos++ < data.Length)
            {
                var index = ms.Position;
                if (ms.ReadByte() == 0x47)
                {
                    int offset = (int)ms.Position - 1;
                    if (!CheckOffsetIsPacketFlag(data, offset))
                    {
                        continue;
                    }
                    ms.Seek(-1, SeekOrigin.Current);
                    byte[] buf = new byte[188];
                    ms.Read(buf, 0, buf.Length);
                    try {
                        TSPacket pack = new TSPacket()
                        {
                            ProgramManage = tsms
                        };
                        pack.SetBytes(buf);
                        pack.Decode();
                        ms.Seek(-188, SeekOrigin.Current);
                        return((int)ms.Position);

                        break;
                    } catch (Exception e) {
                        return(-1);
                    }
                }
            }
            return(-1);
        }
Ejemplo n.º 2
0
        protected virtual void TSStreamResolveThread()
        {
            byte[] buffer_ts = new byte[188 * 2];   //两个包的空间,这里需要读取两个188字节的ts packet 而不是读取一个的原因是,
            //读取两个,当可以检验前后ts packet标识字段是否为0x47,如果不是则当前位置不是处理ts packet的开头,
            //则需要重新找到ts packet的头
            byte[] part_ts = null;//当检测到当前ts packet错误的时候 part_ts用来保存正确的ts packet中的一部分
            while (_isworking)
            {
                int readSize = 188 * 2 - (part_ts != null ? part_ts.Length : 0);//如果上一次没有残留数据则长度为 2个ts packet 的长度
                if (_ioStream.Length >= readSize)
                {
                    if (part_ts != null)
                    {
                        Array.Copy(part_ts, 0, buffer_ts, 0, part_ts.Length);         //残留数据
                    }
                    _ioStream.Read(buffer_ts, buffer_ts.Length - readSize, readSize); //读取到缓冲区
                    if (buffer_ts[0] != 0x47)
                    {
                        //当前为非 ts packet的头,则找到下一个ts packet的头的偏移
                        int offset = FindTSHeadFlag(buffer_ts);
                        if (offset == -1)//没有找到头则返回起点
                        {
                            continue;
                        }
                        //从2*188字节中减去偏移,再减去一个ts packet的长度得到残余的数据长度
                        part_ts = new byte[buffer_ts.Length - 188 - offset];
                        Array.Copy(buffer_ts, offset + 188, part_ts, 0, part_ts.Length);

                        //新建一个临时的缓冲区,并将完整 的ts数据copy到这个临时缓冲区中
                        var tmp_buffer = new byte[188];
                        Array.Copy(buffer_ts, offset, tmp_buffer, 0, tmp_buffer.Length);
                        try {
                            TSPacket pack = new TSPacket()
                            {
                                ProgramManage = _tsms
                            };
                            pack.SetBytes(tmp_buffer);
                            pack.Decode();
                            if (pack.PacketType == TSPacketType.DATA)
                            {
                                pack.ProgramManage.WriteMediaTSPacket(pack);
                            }
                        } catch (Exception e) {
                            _DebugEx.Trace("TSStreamInput", "解析TS失败 1" + e.ToString());
                        }
                    }
                    else
                    {
                        //当前为 ts packet的头,则找到下一个ts packet的头的偏移
                        try {
                            //判断前后两个ts packet是否开头均正确
                            if (buffer_ts[0] == 0x47 && buffer_ts[188] == 0x47)
                            {
                                //将两个ts packet 分别解析
                                var tmp_buffer = new byte[188];
                                Array.Copy(buffer_ts, 0, tmp_buffer, 0, tmp_buffer.Length);
                                TSPacket pack = new TSPacket()
                                {
                                    ProgramManage = _tsms
                                };
                                pack.SetBytes(tmp_buffer);
                                pack.Decode();
                                if (pack.PacketType == TSPacketType.DATA)
                                {
                                    pack.ProgramManage.WriteMediaTSPacket(pack);
                                }

                                Array.Copy(buffer_ts, 188, tmp_buffer, 0, tmp_buffer.Length);
                                pack = new TSPacket()
                                {
                                    ProgramManage = _tsms
                                };
                                pack.SetBytes(tmp_buffer);
                                pack.Decode();
                                if (pack.PacketType == TSPacketType.DATA)
                                {
                                    pack.ProgramManage.WriteMediaTSPacket(pack);
                                }
                            }
                            else
                            {
                                _DebugEx.Trace("TSStreamInput", "TS Packet HeadFlag Error");
                                throw new Exception("TS Packet HeadFlag Error");
                            }
                        } catch (Exception e) {
                            _DebugEx.Trace("TSStreamInput", "解析TS失败 2" + e.ToString());
                        }
                        part_ts = null;
                    }
                }
                else
                {
                    Thread.Sleep(10);
                }
            }
        }
Ejemplo n.º 3
0
        public static byte[] MediaFrame2TSData(MediaFrame frame, TSProgramManage pm)
        {
            var  msOutput    = new MemoryStream();
            var  pes         = PESPacket.MediaFrame2PES(frame);
            var  pes_buffer  = pes.GetBytes();
            var  msInput     = new MemoryStream(pes_buffer);
            int  PID         = frame.nIsAudio == 1 ? 257 : 258;
            bool isFirstPack = true;

            do
            {
                var            payload_unit_start_indicator = 0;
                var            size         = (int)(msInput.Length - msInput.Position);
                var            max_data_len = 188 - 4;//4B为包头长度
                var            data_len     = 0;
                AdaptationInfo ai           = null;
                if ((isFirstPack || size < max_data_len))
                {
                    if (isFirstPack && (frame.nIsAudio == 0 || true))
                    {
                        max_data_len = 188 - 4 - 8;                                   //5B为包头长度 8B为adaptation长度
                        data_len     = Math.Min(max_data_len, size);
                        var adaptation_field_length = 188 - 4 - data_len - 1;         //1B为adaptation的头,这1B不算在adaptation_field_length中
                        var pcr_bas = (frame.nTimetick - pm.FirstFrameTimeTick) * 90; //这里为什么是*45我也不知道,
                        ai = new AdaptationInfo()
                        {
                            adaptation_field_length = (byte)adaptation_field_length,
                            random_access_indicator = 1,
                            PCR_flag = 1,
                            PCR_base = pcr_bas,
                        };
                        payload_unit_start_indicator = 1;
                    }
                    else
                    {
                        max_data_len = 188 - 4 - 1;//4B为包头长度 8B为adaptation长度
                        if (size < max_data_len)
                        {
                            data_len = Math.Min(max_data_len, size);
                            var adaptation_field_length = 188 - 4 - data_len - 1;
                            ai = new AdaptationInfo();
                            ai.adaptation_field_length = (byte)adaptation_field_length;
                        }
                        else
                        {
                            payload_unit_start_indicator = 0;
                            data_len = size;
                        }
                    }
                }
                else
                {
                    data_len = max_data_len;
                }
                byte[] data = new byte[data_len];
                msInput.Read(data, 0, data.Length);
                TSPacket pack_pat = new TSPacket()
                {
                    sync_byte = 0x47,
                    transport_error_indicator    = 0,
                    payload_unit_start_indicator = (byte)payload_unit_start_indicator,//一帧第一个packet或者这个packet需要fill字节时
                    transport_priority           = 0,
                    PID = (ushort)PID,
                    transport_scrambling_control = 0,
                    adaptation_field_control     = (byte)(ai != null ? 3 : 1),
                    continuity_counter           = pm.GetCounter(PID),
                    AdaptationField = ai,
                    data            = data
                };
                var buf = pack_pat.GetBytes();
                msOutput.Write(buf, 0, buf.Length);
                isFirstPack = false;
            } while (msInput.Position < msInput.Length);
            var result = msOutput.ToArray();

            return(result);
        }
Ejemplo n.º 4
0
        public void WriteMediaTSPacket(TSPacket pack)
        {
            // Console.WriteLine(pack.PID);
            var data         = pack.data;
            var newFrameFlag = data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x1 && (data[3] == 0xE0 || data[3] == 0xC0);

            MediaInfo mi = null;

            lock (_dicMediaFrameCache) {
                if (_dicMediaFrameCache.ContainsKey(pack.PID))
                {
                    mi = _dicMediaFrameCache[pack.PID];
                }
                else
                {
                    if (newFrameFlag)
                    {
                        _dicMediaFrameCache[pack.PID] = mi = new MediaInfo()
                        {
                            PID     = pack.PID,
                            IsVideo = pack.data[3] == 0xE0,
                            IsAudio = pack.data[3] == 0xC0,
                        };
                    }
                }
            }
            if (mi != null)
            {
                if (newFrameFlag)
                {
                    lock (mi.TSPackets) {
                        if ((mi.IsAudio && pack.data[3] != 0xC0) || (mi.IsVideo && pack.data[3] != 0xE0))
                        {
                            lock (_dicMediaFrameCache) {
                                foreach (var item in _dicMediaFrameCache.Values)
                                {
                                    item.Release();
                                }
                                _dicMediaFrameCache.Clear();
                            }
                            return;
                        }

                        var mediaFrame = mi.NextMediaFrame();

                        if (mediaFrame != null && mediaFrame.nSize == mediaFrame.Data.Length)
                        {
                            OnNewMediaFrame(mediaFrame);
                        }

                        mi.TSPackets.Clear();

                        mi.TSPackets.Add(pack);
                    }
                }
                else
                {
                    lock (mi.TSPackets)
                        mi.TSPackets.Add(pack);
                }
            }
        }
Ejemplo n.º 5
0
        public static byte[] GetPMTPATData(bool isOnlyVideo = false)
        {
            if (_pmt_pat_tsdata == null)
            {
                var             msOutput = new MemoryStream();
                TSProgramManage ts_pm    = new TSProgramManage();

                TS_PAT pat      = new TS_PAT();
                var    pat_data = pat.GetBytes();

                TSPacket pack_pat = new TSPacket()
                {
                    sync_byte = 0x47,
                    transport_error_indicator    = 0,
                    payload_unit_start_indicator = 1,
                    transport_priority           = 0,
                    PID = 0,
                    transport_scrambling_control = 0,
                    adaptation_field_control     = 1,
                    continuity_counter           = ts_pm.GetCounter(0),
                    data = pat_data,
                };
                var pack_pat_data = pack_pat.GetBytes();
                var pack_pat_tmp  = new TSPacket()
                {
                    ProgramManage = ts_pm,
                };
                msOutput.Write(pack_pat_data, 0, pack_pat_data.Length);

                //pack_pat_tmp.SetBytes(pack_pat_data);
                //pack_pat_tmp.Decode();


                TS_PMT   pmt      = new TS_PMT();
                var      pmt_data = isOnlyVideo ? pmt.GetVideoBytes() : pmt.GetBytes();
                TSPacket pack_pmt = new TSPacket()
                {
                    sync_byte = 0x47,
                    transport_error_indicator    = 0,
                    payload_unit_start_indicator = 1,
                    transport_priority           = 0,
                    PID = 256,//PMT_PID
                    transport_scrambling_control = 0,
                    adaptation_field_control     = 1,
                    continuity_counter           = ts_pm.GetCounter(256),
                    data = pmt_data,
                };
                var pack_pmt_data = pack_pmt.GetBytes();
                var pack_pmt_tmp  = new TSPacket()
                {
                    ProgramManage = ts_pm,
                };
                msOutput.Write(pack_pmt_data, 0, pack_pmt_data.Length);

                //pack_pmt_tmp.SetBytes(pack_pmt_data);
                //pack_pmt_tmp.Decode();

                var _out = msOutput.ToArray();
                _pmt_pat_tsdata = _out;
            }
            return(_pmt_pat_tsdata);
        }