OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "remoting/protocol/client_video_dispatcher.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/memory/scoped_vector.h" |
| 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" |
| 11 #include "remoting/base/constants.h" |
| 12 #include "remoting/proto/video.pb.h" |
| 13 #include "remoting/protocol/fake_session.h" |
| 14 #include "remoting/protocol/fake_stream_socket.h" |
| 15 #include "remoting/protocol/message_serialization.h" |
| 16 #include "remoting/protocol/video_stub.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 |
| 19 namespace remoting { |
| 20 namespace protocol { |
| 21 |
| 22 class ClientVideoDispatcherTest : public testing::Test, |
| 23 public VideoStub, |
| 24 public ChannelDispatcherBase::EventHandler { |
| 25 public: |
| 26 ClientVideoDispatcherTest() |
| 27 : initialized_(false), |
| 28 dispatcher_(this), |
| 29 parser_(base::Bind(&ClientVideoDispatcherTest::OnVideoAck, |
| 30 base::Unretained(this)), |
| 31 &reader_) { |
| 32 } |
| 33 |
| 34 void InitializeWithProtocolVersion(int version) { |
| 35 dispatcher_.Init(&session_, |
| 36 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, version, |
| 37 ChannelConfig::CODEC_UNDEFINED), |
| 38 this); |
| 39 base::RunLoop().RunUntilIdle(); |
| 40 DCHECK(initialized_); |
| 41 host_socket_.PairWith( |
| 42 session_.fake_channel_factory().GetFakeChannel(kVideoChannelName)); |
| 43 reader_.StartReading(&host_socket_); |
| 44 writer_.Init(&host_socket_, BufferedSocketWriter::WriteFailedCallback()); |
| 45 } |
| 46 |
| 47 // VideoStub interface. |
| 48 void ProcessVideoPacket(scoped_ptr<VideoPacket> video_packet, |
| 49 const ProgressCallback& progress_callback) { |
| 50 video_packets_.push_back(video_packet.release()); |
| 51 packet_progress_callbacks_.push_back(progress_callback); |
| 52 } |
| 53 |
| 54 // ChannelDispatcherBase::EventHandler interface. |
| 55 void OnChannelInitialized(ChannelDispatcherBase* channel_dispatcher) { |
| 56 initialized_ = true; |
| 57 } |
| 58 void OnChannelError(ChannelDispatcherBase* channel_dispatcher, |
| 59 ErrorCode error) { |
| 60 // Don't expect channel creation to fail. |
| 61 FAIL(); |
| 62 } |
| 63 |
| 64 protected: |
| 65 void OnVideoAck(scoped_ptr<VideoAck> ack, const base::Closure& done) { |
| 66 ack_messages_.push_back(ack.release()); |
| 67 done.Run(); |
| 68 } |
| 69 |
| 70 base::MessageLoop message_loop_; |
| 71 |
| 72 // Set to true in OnChannelInitialized(). |
| 73 bool initialized_; |
| 74 |
| 75 // Client side. |
| 76 ClientVideoDispatcher dispatcher_; |
| 77 FakeSession session_; |
| 78 |
| 79 // Host side. |
| 80 FakeStreamSocket host_socket_; |
| 81 MessageReader reader_; |
| 82 ProtobufMessageParser<VideoAck> parser_; |
| 83 BufferedSocketWriter writer_; |
| 84 |
| 85 ScopedVector<VideoPacket> video_packets_; |
| 86 std::vector<ProgressCallback> packet_progress_callbacks_; |
| 87 |
| 88 ScopedVector<VideoAck> ack_messages_; |
| 89 }; |
| 90 |
| 91 // Verify that the client can receive video packets and acks are not sent for |
| 92 // older versions of the protocol. |
| 93 TEST_F(ClientVideoDispatcherTest, WithoutAcks) { |
| 94 int kTestFrameId = 3; |
| 95 |
| 96 InitializeWithProtocolVersion(kVideoStreamVersionNoAck); |
| 97 |
| 98 VideoPacket packet; |
| 99 packet.set_data(std::string()); |
| 100 packet.set_frame_id(kTestFrameId); |
| 101 |
| 102 // Send a VideoPacket and verify that the client receives it. |
| 103 writer_.Write(SerializeAndFrameMessage(packet), base::Closure()); |
| 104 base::RunLoop().RunUntilIdle(); |
| 105 EXPECT_EQ(1U, video_packets_.size()); |
| 106 |
| 107 packet_progress_callbacks_.front().Run(VideoStub::PacketProgress::DONE); |
| 108 base::RunLoop().RunUntilIdle(); |
| 109 |
| 110 // Ack should never be sent for this version of the protocol. |
| 111 EXPECT_TRUE(ack_messages_.empty()); |
| 112 } |
| 113 |
| 114 // Verifies that the dispatcher sends Ack message with correct rendering delay. |
| 115 TEST_F(ClientVideoDispatcherTest, WithAcks) { |
| 116 int kTestFrameId = 3; |
| 117 |
| 118 InitializeWithProtocolVersion(kVideoStreamVersion); |
| 119 |
| 120 VideoPacket packet; |
| 121 packet.set_data(std::string()); |
| 122 packet.set_frame_id(kTestFrameId); |
| 123 |
| 124 // Send a VideoPacket and verify that the client receives it. |
| 125 base::TimeTicks write_started_time = base::TimeTicks::Now(); |
| 126 writer_.Write(SerializeAndFrameMessage(packet), base::Closure()); |
| 127 base::RunLoop().RunUntilIdle(); |
| 128 EXPECT_EQ(1U, video_packets_.size()); |
| 129 |
| 130 // Ack should only be sent after the packet is processed. |
| 131 EXPECT_TRUE(ack_messages_.empty()); |
| 132 |
| 133 // Simulate frame render delay. |
| 134 base::TimeTicks render_started_time = base::TimeTicks::Now(); |
| 135 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); |
| 136 base::TimeDelta render_delay_min = |
| 137 base::TimeTicks::Now() - render_started_time; |
| 138 |
| 139 //Fake completion of video packet decoding, to trigger the Ack. |
| 140 packet_progress_callbacks_.front().Run(VideoStub::PacketProgress::DONE); |
| 141 base::TimeDelta render_delay_max = |
| 142 base::TimeTicks::Now() - write_started_time; |
| 143 |
| 144 base::RunLoop().RunUntilIdle(); |
| 145 ASSERT_EQ(1U, ack_messages_.size()); |
| 146 EXPECT_EQ(kTestFrameId, ack_messages_[0]->frame_id()); |
| 147 |
| 148 // Verify that rendering latency is reported correctly. |
| 149 base::TimeDelta render_delay = |
| 150 base::TimeDelta::FromMicroseconds(ack_messages_[0]->rendering_delay_us()); |
| 151 EXPECT_TRUE(render_delay >= render_delay_min); |
| 152 EXPECT_TRUE(render_delay <= render_delay_max); |
| 153 } |
| 154 |
| 155 // Verifies that the dispatcher reports correct read delay in the messages it |
| 156 // receives. |
| 157 TEST_F(ClientVideoDispatcherTest, ReadDelay) { |
| 158 int kTestFrameId = 3; |
| 159 |
| 160 InitializeWithProtocolVersion(kVideoStreamVersion); |
| 161 |
| 162 VideoPacket packet; |
| 163 packet.set_data(std::string()); |
| 164 packet.set_frame_id(kTestFrameId); |
| 165 |
| 166 // Generate buffers for two video frames. |
| 167 scoped_refptr<net::IOBufferWithSize> packet_buffer_1 = |
| 168 SerializeAndFrameMessage(packet); |
| 169 packet.set_frame_id(kTestFrameId + 1); |
| 170 scoped_refptr<net::IOBufferWithSize> packet_buffer_2 = |
| 171 SerializeAndFrameMessage(packet); |
| 172 packet.set_frame_id(kTestFrameId + 2); |
| 173 scoped_refptr<net::IOBufferWithSize> packet_buffer_3 = |
| 174 SerializeAndFrameMessage(packet); |
| 175 |
| 176 base::TimeTicks send_started_time = base::TimeTicks::Now(); |
| 177 |
| 178 // First send all data for the first frame and the first byte for the second |
| 179 // frame in a single network packet. |
| 180 scoped_refptr<net::IOBufferWithSize> buffer = |
| 181 new net::IOBufferWithSize(packet_buffer_1->size() + 1); |
| 182 memcpy(buffer->data(), packet_buffer_1->data(), packet_buffer_1->size()); |
| 183 memcpy(buffer->data() + packet_buffer_1->size(), packet_buffer_2->data(), 1); |
| 184 writer_.Write(buffer, base::Closure()); |
| 185 base::RunLoop().RunUntilIdle(); |
| 186 |
| 187 // Verify that the packet was received. |
| 188 EXPECT_EQ(1U, video_packets_.size()); |
| 189 video_packets_.clear(); |
| 190 packet_progress_callbacks_.front().Run(VideoStub::PacketProgress::DONE); |
| 191 packet_progress_callbacks_.clear(); |
| 192 base::RunLoop().RunUntilIdle(); |
| 193 |
| 194 // Verify that the Ack message for the first video frame has time_to_receive |
| 195 // field set to 0, because the whole frame was received in one message. |
| 196 ASSERT_EQ(1U, ack_messages_.size()); |
| 197 EXPECT_EQ(kTestFrameId, ack_messages_[0]->frame_id()); |
| 198 EXPECT_EQ(0, ack_messages_[0]->time_to_receive_us()); |
| 199 ack_messages_.clear(); |
| 200 |
| 201 // Simulate networking latency while receiving the second frame. |
| 202 base::TimeTicks network_delay_started_time = base::TimeTicks::Now(); |
| 203 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); |
| 204 base::TimeDelta time_to_receive_min = |
| 205 base::TimeTicks::Now() - network_delay_started_time; |
| 206 |
| 207 // Send the remainder of the second frame. |
| 208 buffer = new net::IOBufferWithSize(packet_buffer_2->size() - 1 + |
| 209 packet_buffer_3->size()); |
| 210 memcpy(buffer->data(), packet_buffer_2->data() + 1, |
| 211 packet_buffer_2->size() - 1); |
| 212 memcpy(buffer->data() + packet_buffer_2->size() - 1, packet_buffer_3->data(), |
| 213 packet_buffer_3->size()); |
| 214 writer_.Write(buffer, base::Closure()); |
| 215 base::RunLoop().RunUntilIdle(); |
| 216 |
| 217 base::TimeDelta time_to_receive_max = |
| 218 base::TimeTicks::Now() - send_started_time; |
| 219 |
| 220 // Verify that the last 2 packets were received. |
| 221 EXPECT_EQ(2U, video_packets_.size()); |
| 222 packet_progress_callbacks_[0].Run(VideoStub::PacketProgress::DONE); |
| 223 packet_progress_callbacks_[1].Run(VideoStub::PacketProgress::DONE); |
| 224 base::RunLoop().RunUntilIdle(); |
| 225 |
| 226 // Verify that we've received 2 Ack for the last 2 frames. |
| 227 ASSERT_EQ(2U, ack_messages_.size()); |
| 228 EXPECT_EQ(kTestFrameId + 1, ack_messages_[0]->frame_id()); |
| 229 |
| 230 // Verify that the dispatcher set correct time_to_receive value. |
| 231 base::TimeDelta time_to_receive = |
| 232 base::TimeDelta::FromMicroseconds(ack_messages_[0]->time_to_receive_us()); |
| 233 EXPECT_TRUE(time_to_receive >= time_to_receive_min); |
| 234 EXPECT_TRUE(time_to_receive <= time_to_receive_max); |
| 235 |
| 236 EXPECT_EQ(kTestFrameId + 2, ack_messages_[1]->frame_id()); |
| 237 EXPECT_EQ(0, ack_messages_[1]->time_to_receive_us()); |
| 238 } |
| 239 |
| 240 } // namespace protocol |
| 241 } // namespace remoting |
OLD | NEW |