Пример #1
0
        protected override unsafe void Loop(CancellationToken token)
        {
            using (var tcpClient = new TcpClient(_configuration.DroneHostname, VideoPort))
                using (NetworkStream stream = tcpClient.GetStream())
                {
                    var    packet     = new VideoPacket();
                    byte[] packetData = null;
                    int    offset     = 0;
                    int    frameStart = 0;
                    int    frameEnd   = 0;
                    var    buffer     = new byte[FrameBufferSize];
                    fixed(byte *pBuffer = &buffer[0])
                    while (token.IsCancellationRequested == false)
                    {
                        offset += stream.Read(buffer, offset, NetworkStreamReadSize);
                        if (packetData == null)
                        {
                            // lookup for a frame start
                            int maxSearchIndex = offset - sizeof(parrot_video_encapsulation_t);
                            for (int i = 0; i < maxSearchIndex; i++)
                            {
                                if (buffer[i] == 'P' &&
                                    buffer[i + 1] == 'a' &&
                                    buffer[i + 2] == 'V' &&
                                    buffer[i + 3] == 'E')
                                {
                                    parrot_video_encapsulation_t pve = *(parrot_video_encapsulation_t *)(pBuffer + i);
                                    packetData = new byte[pve.payload_size];
                                    packet     = new VideoPacket
                                    {
                                        Timestamp   = DateTime.UtcNow.Ticks,
                                        FrameNumber = pve.frame_number,
                                        Width       = pve.display_width,
                                        Height      = pve.display_height,
                                        FrameType   = Convert(pve.frame_type),
                                        Data        = packetData
                                    };
                                    frameStart = i + pve.header_size;
                                    frameEnd   = frameStart + packet.Data.Length;
                                    break;
                                }
                            }
                            if (packetData == null)
                            {
                                // frame is not detected
                                offset -= maxSearchIndex;
                                Array.Copy(buffer, maxSearchIndex, buffer, 0, offset);
                            }
                        }
                        if (packetData != null && offset >= frameEnd)
                        {
                            // frame acquired
                            Array.Copy(buffer, frameStart, packetData, 0, packetData.Length);
                            _videoPacketAcquired(packet);

                            // clean up acquired frame
                            packetData = null;
                            offset    -= frameEnd;
                            Array.Copy(buffer, frameEnd, buffer, 0, offset);
                        }
                        Thread.Sleep(10);
                    }
                }
        }
        /// <summary>
        /// 获取视频数据线程
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        protected override unsafe void Loop(CancellationToken token)
        {
            //创建tcp连接
            using (var tcpClient = new TcpClient(_configuration.DroneHostname, VideoPort))
                //获取网络流
                using (NetworkStream stream = tcpClient.GetStream())
                {
                    var    packet     = new VideoPacket();
                    byte[] packetData = null;
                    int    offset     = 0;
                    int    frameStart = 0;
                    int    frameEnd   = 0;
                    //由缓存大小建立数组
                    var buffer = new byte[FrameBufferSize];
                    //只用指针
                    //防止地址改变
                    fixed(byte *pBuffer = &buffer[0])
                    //循环获取视频数据
                    while (token.IsCancellationRequested == false)
                    {
                        //判断是否可用
                        if (tcpClient.Available == 0)
                        {
                            Thread.Sleep(1);
                            continue;
                        }

                        //从流中读取数据 读入buffer
                        int read = stream.Read(buffer, offset, NetworkStreamReadSize);

                        //无数据继续读取
                        if (read == 0)
                        {
                            continue;
                        }

                        //重新设置读取位置
                        offset += read;
                        if (packetData == null)
                        {
                            // lookup for a frame start
                            //设置数据的最大检索范围。要减去parrot_video_encapsulation_t的大小

                            int maxSearchIndex = offset - sizeof(parrot_video_encapsulation_t);
                            for (int i = 0; i < maxSearchIndex; i++)
                            {
                                if (buffer[i] == 'P' && buffer[i + 1] == 'a' && buffer[i + 2] == 'V' && buffer[i + 3] == 'E')
                                {
                                    parrot_video_encapsulation_t pve = *(parrot_video_encapsulation_t *)(pBuffer + i);
                                    packetData = new byte[pve.payload_size];
                                    packet     = new VideoPacket
                                    {
                                        Timestamp   = DateTime.UtcNow.Ticks,
                                        FrameNumber = pve.frame_number,
                                        Width       = pve.display_width,
                                        Height      = pve.display_height,
                                        FrameType   = VideoFrameTypeConverter.Convert(pve.frame_type),
                                        Data        = packetData
                                    };
                                    frameStart = i + pve.header_size;
                                    frameEnd   = frameStart + packet.Data.Length;
                                    break;
                                }
                            }
                            if (packetData == null)
                            {
                                // frame is not detected
                                offset -= maxSearchIndex;
                                Array.Copy(buffer, maxSearchIndex, buffer, 0, offset);
                            }
                        }
                        if (packetData != null && offset >= frameEnd)
                        {
                            // frame acquired
                            //拷贝视频数据
                            Array.Copy(buffer, frameStart, packetData, 0, packetData.Length);
                            //发送视频获取信息
                            _videoPacketAcquired(packet);

                            // clean up acquired frame
                            packetData = null;
                            offset    -= frameEnd;
                            Array.Copy(buffer, frameEnd, buffer, 0, offset);
                        }
                    }
                }
        }