Ejemplo n.º 1
0
        private void uncompressFrame(int senderId, byte[] messageData)
        {
            byte frameId          = messageData[1];
            byte referenceFrameId = messageData[2];

            // send video frame reception notification
            using (NetworkPacket packet = new NetworkPacket(2)) {
                packet.Write((byte)ReservedMessageType.VideoFrameAck);
                packet.Write((int)senderId);
                packet.Write((byte)frameId);
                // use a timeout equal to 10 times the capture period (15 times per second)
                try {
                    server.SendTo(senderId, packet, 10 * 1000 / 15, SendFlags.NoComplete | SendFlags.Coalesce | SendFlags.PriorityHigh);
                } catch (Microsoft.DirectX.DirectPlay.InvalidPlayerException) { }
            }

            // uncompress video frame
            InboundVideoFrameHistory history;

            if (!inboundVideoFrameHistories.TryGetValue(senderId, out history))
            {
                history = new InboundVideoFrameHistory();
                inboundVideoFrameHistories.Add(senderId, history);
            }
            byte[] frame = new byte[64 * 64 * 3];
            if (senderId == hostingPlayerId)
            {
                // no compression needed
                Array.Copy(messageData, 3, frame, 0, frame.Length);
            }
            else
            {
                unsafe
                {
                    fixed(byte *framePtr = frame)
                    {
                        fixed(byte *dataPtr = messageData)
                        {
                            if (frameId == referenceFrameId)
                            {
                                // no reference frame
                                videoCodec.Decode((IntPtr)(dataPtr + 3), (IntPtr)framePtr);
                            }
                            else
                            {
                                // reference frame
                                fixed(byte *referenceFramePtr = history.GetFrameData(referenceFrameId))
                                {
                                    videoCodec.Decode((IntPtr)referenceFramePtr, (IntPtr)(dataPtr + 3), (IntPtr)framePtr);
                                }
                            }
                        }
                    }
                }
            }
            if (referenceFrameId != frameId)
            {
                history.ClearHistoryUntilThisFrame(referenceFrameId);
            }
            history.AddFrame(frameId, frame);

            // make one compress job for each other player
            foreach (int playerId in server.Players)
            {
                if (playerId != senderId && playerId != serverId)
                {
                    compressJobs.AddFirst(new CompressJob(senderId, playerId, frame));
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>Get all pending messages received.</summary>
        /// <returns>An array of NetworkMessage instances.</returns>
        public NetworkMessage[] RetrieveNetworkMessages()
        {
            NetworkMessage[] shallowCopy;
            lock (networkMessages) {
                shallowCopy = networkMessages.ToArray();
                networkMessages.Clear();
            }
            for (int i = shallowCopy.Length - 1; i >= 0; --i)
            {
                NetworkMessage message = shallowCopy[i];
                if (message.Type == (byte)ReservedMessageType.VideoFrameReceived && message.Data != null)
                {
                    byte frameId = message.Data[5];

                    // send video frame reception notification
                    if (status == NetworkStatus.Connected)
                    {
                        using (NetworkPacket packet = new NetworkPacket(6)) {
                            packet.Write((byte)ReservedMessageType.VideoFrameAck);
                            packet.Write((int)message.SenderId);
                            packet.Write((byte)frameId);
                            // use a timeout equal to 10 times the capture period (15 times per second)
                            client.Send(packet, 10 * 1000 / 15, SendFlags.NoComplete | SendFlags.Coalesce | SendFlags.PriorityHigh);
                        }
                    }

                    // ignore earlier frames from same sender
                    for (int j = 0; j < i; ++j)
                    {
                        NetworkMessage earlierMessage = shallowCopy[j];
                        if (earlierMessage.Type == (byte)ReservedMessageType.VideoFrameReceived && earlierMessage.SenderId == message.SenderId)
                        {
                            shallowCopy[j] = new NetworkMessage(earlierMessage.SenderId, earlierMessage.Type, null);
                        }
                    }
                }
            }
            for (int i = 0; i < shallowCopy.Length; ++i)
            {
                NetworkMessage message = shallowCopy[i];
                if (message.Type == (byte)ReservedMessageType.VideoFrameReceived && message.Data != null)
                {
                    byte frameId          = message.Data[5];
                    byte referenceFrameId = message.Data[6];

                    InboundVideoFrameHistory history;
                    if (!inboundVideoFrameHistories.TryGetValue(message.SenderId, out history))
                    {
                        history = new InboundVideoFrameHistory();
                        inboundVideoFrameHistories.Add(message.SenderId, history);
                    }
                    byte[] frame = new byte[64 * 64 * 3];
                    if (serverIsOnSameComputer)
                    {
                        // no compression
                        Array.Copy(message.Data, 7, frame, 0, frame.Length);
                    }
                    else
                    {
                        // uncompress video frame
                        unsafe
                        {
                            fixed(byte *framePtr = frame)
                            {
                                fixed(byte *dataPtr = message.Data)
                                {
                                    if (frameId == referenceFrameId)
                                    {
                                        // no reference frame
                                        videoCodec.Decode((IntPtr)(dataPtr + 7), (IntPtr)framePtr);
                                    }
                                    else
                                    {
                                        // reference frame
                                        fixed(byte *referenceFramePtr = history.GetFrameData(referenceFrameId))
                                        {
                                            videoCodec.Decode((IntPtr)referenceFramePtr, (IntPtr)(dataPtr + 7), (IntPtr)framePtr);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (referenceFrameId != frameId)
                    {
                        history.ClearHistoryUntilThisFrame(referenceFrameId);
                    }
                    history.AddFrame(frameId, frame);
                    shallowCopy[i] = new NetworkMessage(message.SenderId, message.Type, frame);
                }
            }
            return(shallowCopy);
        }