Exemple #1
0
        public static CitpPacket FromByteArray(byte[] data, IpEndpoint?remoteEndpoint = null)
        {
            CitpPacket packet;

            var layerType = getLayerType(data);

            if (layerType == null)
            {
                var layerTypeArray = new byte[4];
                Buffer.BlockCopy(data, CitpContentTypePosition, layerTypeArray, 0, 4);
                throw new InvalidOperationException(
                          $"Unrecognised CITP content type: {Encoding.UTF8.GetString(layerTypeArray, 0, layerTypeArray.Length)}");
            }

            switch (layerType)
            {
            case CitpLayerType.PeerInformationLayer:
            {
                var messageType = PinfPacket.GetMessageType(data);

                if (messageType == null)
                {
                    var messageTypeArray = new byte[4];
                    Buffer.BlockCopy(data, PinfPacket.CitpMessageTypePosition, messageTypeArray, 0, 4);
                    throw new InvalidOperationException(
                              $"Unrecognised PING message type: {Encoding.UTF8.GetString(messageTypeArray, 0, messageTypeArray.Length)}");
                }

                switch (messageType)
                {
                case PinfMessageType.PeerLocationMessage:
                    packet = new PeerLocationMessagePacket();
                    break;

                case PinfMessageType.PeerNameMessage:
                    packet = new PeerNameMessagePacket();
                    break;

                default:
                    throw new NotImplementedException("Unimplemented PINF message type");
                }

                break;
            }

            case CitpLayerType.MediaServerExtensionsLayer:
            {
                var messageType = MsexPacket.GetMessageType(data);

                if (messageType == null)
                {
                    var messageTypeArray = new byte[4];
                    Buffer.BlockCopy(data, MsexPacket.CitpMessageTypePosition, messageTypeArray, 0, 4);
                    throw new InvalidOperationException(
                              $"Unrecognised MSEX message type: {Encoding.UTF8.GetString(messageTypeArray, 0, messageTypeArray.Length)}");
                }

                switch (messageType)
                {
                case MsexMessageType.ClientInformationMessage:
                    packet = new ClientInformationMessagePacket();
                    break;

                case MsexMessageType.ServerInformationMessage:
                    packet = new ServerInformationMessagePacket();
                    break;

                case MsexMessageType.NegativeAcknowledgeMessage:
                    packet = new NegativeAcknowledgeMessagePacket();
                    break;

                case MsexMessageType.LayerStatusMessage:
                    packet = new LayerStatusMessagePacket();
                    break;

                case MsexMessageType.GetElementLibraryInformationMessage:
                    packet = new GetElementLibraryInformationMessagePacket();
                    break;

                case MsexMessageType.ElementLibraryInformationMessage:
                    packet = new ElementLibraryInformationMessagePacket();
                    break;

                case MsexMessageType.ElementLibraryUpdatedMessage:
                    packet = new ElementLibraryUpdatedMessagePacket();
                    break;

                case MsexMessageType.GetElementInformationMessage:
                    packet = new GetElementInformationMessagePacket();
                    break;

                case MsexMessageType.MediaElementInformationMessage:
                    packet = new MediaElementInformationMessagePacket();
                    break;

                case MsexMessageType.EffectElementInformationMessage:
                    packet = new EffectElementInformationMessagePacket();
                    break;

                case MsexMessageType.GenericElementInformationMessage:
                    packet = new GenericElementInformationMessagePacket();
                    break;

                case MsexMessageType.GetElementLibraryThumbnailMessage:
                    packet = new GetElementLibraryThumbnailMessagePacket();
                    break;

                case MsexMessageType.ElementLibraryThumbnailMessage:
                    packet = new ElementLibraryThumbnailMessagePacket();
                    break;

                case MsexMessageType.GetElementThumbnailMessage:
                    packet = new GetElementThumbnailMessagePacket();
                    break;

                case MsexMessageType.ElementThumbnailMessage:
                    packet = new ElementThumbnailMessagePacket();
                    break;

                case MsexMessageType.GetVideoSourcesMessage:
                    packet = new GetVideoSourcesMessagePacket();
                    break;

                case MsexMessageType.RequestStreamMessage:
                    packet = new RequestStreamMessagePacket();
                    break;

                case MsexMessageType.StreamFrameMessage:
                    packet = new StreamFrameMessagePacket();
                    break;

                default:
                    throw new NotImplementedException("Unimplemented MSEX message type");
                }

                break;
            }

            default:
                throw new NotImplementedException("Unimplemented CITP content type");
            }



            using (var reader = new CitpBinaryReader(new MemoryStream(data)))
                packet.DeserializeFromStream(reader);

            packet.RemoteEndpoint = remoteEndpoint;

            return(packet);
        }
Exemple #2
0
        public async Task ProcessStreamRequestsAsync()
        {
            foreach (var request in _streamRequests.Values.ToList())
            {
                foreach (var formatRequest in request.Formats)
                {
                    if (Math.Abs(request.Fps) < float.Epsilon ||
                        DateTime.Now < formatRequest.LastOutput + TimeSpan.FromSeconds(1.0f / request.Fps))
                    {
                        break;
                    }

                    var imageRequest = new CitpImageRequest(request.FrameWidth, request.FrameHeight, formatRequest.FrameFormat, true,
                                                            formatRequest.FrameFormat == MsexImageFormat.Rgb8 && formatRequest.Version == MsexVersion.Version1_0);

                    var frame = _streamProvider.GetVideoSourceFrame(request.SourceIdentifier, imageRequest);

                    if (frame == null)
                    {
                        break;
                    }

                    var packet = new StreamFrameMessagePacket
                    {
                        Version          = formatRequest.Version,
                        MediaServerUuid  = _streamProvider.Uuid,
                        SourceIdentifier = Convert.ToUInt16(request.SourceIdentifier),
                        FrameFormat      = formatRequest.FrameFormat,
                        FrameWidth       = Convert.ToUInt16(frame.ActualWidth),
                        FrameHeight      = Convert.ToUInt16(frame.ActualHeight)
                    };


                    if (formatRequest.FrameFormat == MsexImageFormat.FragmentedJpeg ||
                        formatRequest.FrameFormat == MsexImageFormat.FragmentedPng)
                    {
                        var fragments = frame.Data.Split(MaximumImageBufferSize);

                        packet.FragmentInfo = new StreamFrameMessagePacket.FragmentPreamble()
                        {
                            FrameIndex    = request.FrameCounter,
                            FragmentCount = (ushort)fragments.Length
                        };

                        if (fragments.Length > ushort.MaxValue)
                        {
                            _log.LogWarning("Cannot send streaming frame, too many image fragments");
                            return;
                        }

                        for (uint i = 0; i < fragments.Length; ++i)
                        {
                            packet.FragmentInfo.FragmentIndex      = (ushort)i;
                            packet.FragmentInfo.FragmentByteOffset = MaximumImageBufferSize * i;
                            packet.FrameBuffer = fragments[i];
                            await _networkService.SendMulticastPacketAsync(packet).ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        if (frame.Data.Length > MaximumImageBufferSize)
                        {
                            _log.LogWarning($"Cannot send streaming frame request '{imageRequest}', image buffer too large");
                            return;
                        }

                        packet.FrameBuffer = frame.Data;
                        await _networkService.SendMulticastPacketAsync(packet).ConfigureAwait(false);
                    }

                    formatRequest.LastOutput = DateTime.Now;
                }

                request.RemoveTimedOutRequests();

                if (request.Formats.Count == 0)
                {
                    _streamRequests.Remove(request.SourceIdentifier);
                }

                ++request.FrameCounter;
            }
        }