/// <summary> /// Handle a control message. /// </summary> /// <param name="packet">The packet containing the control message.</param> /// <param name="messageId">The ID of the control message.</param> /// <returns>True if this ended a frame and requires a flush. An end frame message may be processed without a /// flush.</returns> /// <remarks> /// This method may modify the packet data before it is queued for processing. The primary /// use case is to write the current frame number into and end of frame message. /// </remarks> private bool HandleControlMessage(PacketBuffer packet, ControlMessageID messageId) { bool frameFlush = false; ControlMessage msg = new ControlMessage(); if (!msg.Peek(packet)) { return(frameFlush); } if (messageId == ControlMessageID.EndFrame) { // Replace the end of frame packet with a new one including the current frame number. bool flush = OnEndFrame(msg.Value32); // Overwrite msg.Value64 with the current frame number. int memberOffset = PacketHeader.Size + Marshal.OffsetOf(typeof(ControlMessage), "Value64").ToInt32(); byte[] packetData = packet.Data; byte[] frameNumberBytes = BitConverter.GetBytes(Endian.ToNetwork((ulong)_currentFrame)); Array.Copy(frameNumberBytes, 0, packetData, memberOffset, frameNumberBytes.Length); // Override the flags to include the flush value. if (flush) { memberOffset = PacketHeader.Size + Marshal.OffsetOf(typeof(ControlMessage), "ControlFlags").ToInt32(); uint controlFlags = BitConverter.ToUInt32(packetData, memberOffset); controlFlags = Endian.FromNetwork(controlFlags); // Add the flush flag controlFlags |= (uint)EndFrameFlag.Flush; // Convert back to bytes and copy into the packet buffer. frameNumberBytes = BitConverter.GetBytes(Endian.ToNetwork(controlFlags)); Array.Copy(frameNumberBytes, 0, packetData, memberOffset, frameNumberBytes.Length); } frameFlush = !_catchingUp && flush; } else if (messageId == ControlMessageID.FrameCount) { // Set the frame count. lock (this) { // Only set if current value is less than the read value. This caters for // badly saved files, where the frame count was improperly finalised. if (_totalFrames < msg.Value32) { _totalFrames = msg.Value32; } } } return(frameFlush); }
/// <summary> /// Handle a control message. /// </summary> /// <param name="packet">The packet containing the control message.</param> /// <param name="messageId">The ID of the control message.</param> /// <returns>True if this ended a frame.</returns> /// <remarks> /// This method may modify the packet data before it is queued for processing. The primary /// use case is to write the current frame number into and end of frame message. /// </remarks> private bool HandleControlMessage(PacketBuffer packet, ControlMessageID messageId) { bool endedFrame = false; ControlMessage msg = new ControlMessage(); if (!msg.Peek(packet)) { return(endedFrame); } if (messageId == ControlMessageID.EndFrame) { // Replace the end of frame packet with a new one including the current frame number. // FIXME: modify the target value in the buffer stream instead of replacing the object. OnEndFrame(msg.Value32); // Overwrite msg.Value64 with the current frame number. int value64Offset = PacketHeader.Size + Marshal.OffsetOf(typeof(ControlMessage), "Value64").ToInt32(); byte[] packetData = packet.Data; byte[] frameNumberBytes = BitConverter.GetBytes(Endian.ToNetwork((ulong)_currentFrame)); Array.Copy(frameNumberBytes, 0, packetData, value64Offset, frameNumberBytes.Length); endedFrame = true; } else if (messageId == ControlMessageID.FrameCount) { // Set the frame count. lock (this) { // Only set if current value is less than the read value. This caters for // badly saved files, where the frame count was improperly finalised. if (_totalFrames < msg.Value32) { _totalFrames = msg.Value32; } } } return(endedFrame); }