Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(611)

Side by Side Diff: remoting/protocol/client_video_dispatcher_unittest.cc

Issue 850983002: Implement video frame acknowledgements in the chromoting protocol. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698