OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 "media/remoting/remote_renderer_impl.h" | |
6 | |
7 #include "base/memory/ptr_util.h" | |
8 #include "base/run_loop.h" | |
9 #include "base/threading/thread_task_runner_handle.h" | |
10 #include "media/base/pipeline_status.h" | |
11 #include "media/base/test_helpers.h" | |
12 #include "media/remoting/fake_remoting_controller.h" | |
13 #include "media/remoting/fake_remoting_demuxer_stream_provider.h" | |
14 #include "media/remoting/remoting_renderer_controller.h" | |
15 #include "testing/gmock/include/gmock/gmock.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 using testing::_; | |
19 using testing::Invoke; | |
20 using testing::Return; | |
21 | |
22 namespace media { | |
23 | |
24 namespace { | |
25 | |
26 PipelineMetadata DefaultMetadata() { | |
27 PipelineMetadata data; | |
28 data.has_audio = true; | |
29 data.has_video = true; | |
30 data.video_decoder_config = TestVideoConfig::Normal(); | |
31 return data; | |
32 } | |
33 | |
34 class RendererClientImpl : public RendererClient { | |
35 public: | |
36 RendererClientImpl() { | |
37 ON_CALL(*this, OnStatisticsUpdate(_)) | |
38 .WillByDefault( | |
39 Invoke(this, &RendererClientImpl::DelegateOnStatisticsUpdate)); | |
40 ON_CALL(*this, OnPipelineStatus(_)) | |
41 .WillByDefault( | |
42 Invoke(this, &RendererClientImpl::DelegateOnPipelineStatus)); | |
43 ON_CALL(*this, OnBufferingStateChange(_)) | |
44 .WillByDefault( | |
45 Invoke(this, &RendererClientImpl::DelegateOnBufferingStateChange)); | |
46 ON_CALL(*this, OnVideoNaturalSizeChange(_)) | |
47 .WillByDefault(Invoke( | |
48 this, &RendererClientImpl::DelegateOnVideoNaturalSizeChange)); | |
49 ON_CALL(*this, OnVideoOpacityChange(_)) | |
50 .WillByDefault( | |
51 Invoke(this, &RendererClientImpl::DelegateOnVideoOpacityChange)); | |
52 ON_CALL(*this, OnDurationChange(_)) | |
53 .WillByDefault( | |
54 Invoke(this, &RendererClientImpl::DelegateOnDurationChange)); | |
55 } | |
56 ~RendererClientImpl() {} | |
57 | |
58 // RendererClient implementation. | |
59 void OnError(PipelineStatus status) override {} | |
60 void OnEnded() override {} | |
61 MOCK_METHOD1(OnStatisticsUpdate, void(const PipelineStatistics& stats)); | |
62 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState state)); | |
63 void OnWaitingForDecryptionKey() override {} | |
64 MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size& size)); | |
65 MOCK_METHOD1(OnVideoOpacityChange, void(bool opaque)); | |
66 MOCK_METHOD1(OnDurationChange, void(base::TimeDelta duration)); | |
67 | |
68 void DelegateOnStatisticsUpdate(const PipelineStatistics& stats) { | |
69 stats_ = stats; | |
70 } | |
71 void DelegateOnBufferingStateChange(BufferingState state) { state_ = state; } | |
72 void DelegateOnVideoNaturalSizeChange(const gfx::Size& size) { size_ = size; } | |
73 void DelegateOnVideoOpacityChange(bool opaque) { opaque_ = opaque; } | |
74 void DelegateOnDurationChange(base::TimeDelta duration) { | |
75 duration_ = duration; | |
76 } | |
77 | |
78 MOCK_METHOD1(OnPipelineStatus, void(PipelineStatus status)); | |
79 void DelegateOnPipelineStatus(PipelineStatus status) { | |
80 VLOG(2) << "OnPipelineStatus status:" << status; | |
81 status_ = status; | |
82 } | |
83 MOCK_METHOD0(OnFlushCallback, void()); | |
84 | |
85 PipelineStatus status() const { return status_; } | |
86 PipelineStatistics stats() const { return stats_; } | |
87 BufferingState state() const { return state_; } | |
88 gfx::Size size() const { return size_; } | |
89 bool opaque() const { return opaque_; } | |
90 base::TimeDelta duration() const { return duration_; } | |
91 | |
92 private: | |
93 PipelineStatus status_ = PIPELINE_OK; | |
94 BufferingState state_ = BUFFERING_HAVE_NOTHING; | |
95 gfx::Size size_; | |
96 bool opaque_ = false; | |
97 base::TimeDelta duration_; | |
98 PipelineStatistics stats_; | |
99 | |
100 DISALLOW_COPY_AND_ASSIGN(RendererClientImpl); | |
101 }; | |
102 | |
103 } // namespace | |
104 | |
105 class RemoteRendererImplTest : public testing::Test { | |
106 public: | |
107 RemoteRendererImplTest() | |
108 : receiver_renderer_handle_(10), | |
109 receiver_audio_demuxer_callback_handle_(11), | |
110 receiver_video_demuxer_callback_handle_(12), | |
111 sender_client_handle_(remoting::kInvalidHandle), | |
112 sender_renderer_callback_handle_(remoting::kInvalidHandle), | |
113 sender_audio_demuxer_handle_(remoting::kInvalidHandle), | |
114 sender_video_demuxer_handle_(remoting::kInvalidHandle), | |
115 received_audio_ds_init_cb_(false), | |
116 received_video_ds_init_cb_(false), | |
117 renderer_initialized_(false) {} | |
118 ~RemoteRendererImplTest() override = default; | |
119 | |
120 // Use this function to mimic receiver to handle RPC message for renderer | |
121 // initialization, | |
122 void RpcMessageResponseBot(std::unique_ptr<std::vector<uint8_t>> message) { | |
123 std::unique_ptr<remoting::pb::RpcMessage> rpc( | |
124 new remoting::pb::RpcMessage()); | |
125 ASSERT_TRUE(rpc->ParseFromArray(message->data(), message->size())); | |
126 switch (rpc->proc()) { | |
127 case remoting::pb::RpcMessage::RPC_ACQUIRE_RENDERER: { | |
128 // Issues RPC_ACQUIRE_RENDERER_DONE RPC message. | |
129 std::unique_ptr<remoting::pb::RpcMessage> acquire_done( | |
130 new remoting::pb::RpcMessage()); | |
131 acquire_done->set_handle(rpc->integer_value()); | |
132 acquire_done->set_proc( | |
133 remoting::pb::RpcMessage::RPC_ACQUIRE_RENDERER_DONE); | |
134 acquire_done->set_integer_value(receiver_renderer_handle_); | |
135 remoting_renderer_controller_->GetRpcBroker()->ProcessMessageFromRemote( | |
136 std::move(acquire_done)); | |
137 } break; | |
138 case remoting::pb::RpcMessage::RPC_R_INITIALIZE: { | |
139 EXPECT_EQ(rpc->handle(), receiver_renderer_handle_); | |
140 sender_renderer_callback_handle_ = | |
141 rpc->renderer_initialize_rpc().callback_handle(); | |
142 sender_client_handle_ = rpc->renderer_initialize_rpc().client_handle(); | |
143 sender_audio_demuxer_handle_ = | |
144 rpc->renderer_initialize_rpc().audio_demuxer_handle(); | |
145 sender_video_demuxer_handle_ = | |
146 rpc->renderer_initialize_rpc().video_demuxer_handle(); | |
147 | |
148 // Issues audio RPC_DS_INITIALIZE RPC message. | |
149 if (sender_audio_demuxer_handle_ != remoting::kInvalidHandle) { | |
150 std::unique_ptr<remoting::pb::RpcMessage> ds_init( | |
151 new remoting::pb::RpcMessage()); | |
152 ds_init->set_handle(sender_audio_demuxer_handle_); | |
153 ds_init->set_proc(remoting::pb::RpcMessage::RPC_DS_INITIALIZE); | |
154 ds_init->set_integer_value(receiver_audio_demuxer_callback_handle_); | |
155 remoting_renderer_controller_->GetRpcBroker() | |
156 ->ProcessMessageFromRemote(std::move(ds_init)); | |
157 } | |
158 if (sender_video_demuxer_handle_ != remoting::kInvalidHandle) { | |
159 std::unique_ptr<remoting::pb::RpcMessage> ds_init( | |
160 new remoting::pb::RpcMessage()); | |
161 ds_init->set_handle(sender_video_demuxer_handle_); | |
162 ds_init->set_proc(remoting::pb::RpcMessage::RPC_DS_INITIALIZE); | |
163 ds_init->set_integer_value(receiver_video_demuxer_callback_handle_); | |
164 remoting_renderer_controller_->GetRpcBroker() | |
165 ->ProcessMessageFromRemote(std::move(ds_init)); | |
166 } | |
167 } break; | |
168 case remoting::pb::RpcMessage::RPC_DS_INITIALIZE_CALLBACK: { | |
169 if (rpc->handle() == receiver_audio_demuxer_callback_handle_) | |
170 received_audio_ds_init_cb_ = true; | |
171 if (rpc->handle() == receiver_video_demuxer_callback_handle_) | |
172 received_video_ds_init_cb_ = true; | |
173 | |
174 // Issues RPC_R_INITIALIZE_CALLBACK RPC message when receiving | |
175 // RPC_DS_INITIALIZE_CALLBACK on available streams. | |
176 if (received_audio_ds_init_cb_ == | |
177 (sender_audio_demuxer_handle_ != remoting::kInvalidHandle) && | |
178 received_video_ds_init_cb_ == | |
179 (sender_video_demuxer_handle_ != remoting::kInvalidHandle)) { | |
180 std::unique_ptr<remoting::pb::RpcMessage> init_cb( | |
181 new remoting::pb::RpcMessage()); | |
182 init_cb->set_handle(sender_renderer_callback_handle_); | |
183 init_cb->set_proc( | |
184 remoting::pb::RpcMessage::RPC_R_INITIALIZE_CALLBACK); | |
185 init_cb->set_boolean_value(true); | |
186 remoting_renderer_controller_->GetRpcBroker() | |
187 ->ProcessMessageFromRemote(std::move(init_cb)); | |
188 renderer_initialized_ = true; | |
189 } | |
190 | |
191 } break; | |
192 case remoting::pb::RpcMessage::RPC_R_FLUSHUNTIL: { | |
193 // Issues RPC_R_FLUSHUNTIL_CALLBACK RPC message. | |
194 std::unique_ptr<remoting::pb::RpcMessage> flush_cb( | |
195 new remoting::pb::RpcMessage()); | |
196 flush_cb->set_handle(rpc->renderer_flushuntil_rpc().callback_handle()); | |
197 flush_cb->set_proc(remoting::pb::RpcMessage::RPC_R_FLUSHUNTIL_CALLBACK); | |
198 remoting_renderer_controller_->GetRpcBroker()->ProcessMessageFromRemote( | |
199 std::move(flush_cb)); | |
200 | |
201 } break; | |
202 | |
203 default: | |
204 NOTREACHED(); | |
205 } | |
206 RunPendingTasks(); | |
207 } | |
208 | |
209 // Callback from RpcBroker when sending message to remote sink. | |
210 void OnSendMessageToSink(std::unique_ptr<std::vector<uint8_t>> message) { | |
211 std::unique_ptr<remoting::pb::RpcMessage> rpc( | |
212 new remoting::pb::RpcMessage()); | |
213 ASSERT_TRUE(rpc->ParseFromArray(message->data(), message->size())); | |
214 received_rpc_.push_back(std::move(rpc)); | |
215 } | |
216 | |
217 protected: | |
218 void InitializeRenderer() { | |
219 // Register media::RendererClient implementation. | |
220 render_client_.reset(new RendererClientImpl()); | |
221 demuxer_stream_provider_.reset(new FakeRemotingDemuxerStreamProvider()); | |
222 EXPECT_CALL(*render_client_, OnPipelineStatus(_)).Times(1); | |
223 DCHECK(remote_renderer_impl_); | |
224 // Redirect RPC message for simulate receiver scenario | |
225 remoting_renderer_controller_->GetRpcBroker()->SetMessageCallbackForTesting( | |
226 base::Bind(&RemoteRendererImplTest::RpcMessageResponseBot, | |
227 base::Unretained(this))); | |
228 RunPendingTasks(); | |
229 remote_renderer_impl_->Initialize( | |
230 demuxer_stream_provider_.get(), render_client_.get(), | |
231 base::Bind(&RendererClientImpl::OnPipelineStatus, | |
232 base::Unretained(render_client_.get()))); | |
233 RunPendingTasks(); | |
234 // Redirect RPC message back to save for later check. | |
235 remoting_renderer_controller_->GetRpcBroker()->SetMessageCallbackForTesting( | |
236 base::Bind(&RemoteRendererImplTest::OnSendMessageToSink, | |
237 base::Unretained(this))); | |
238 RunPendingTasks(); | |
239 } | |
240 | |
241 bool IsRendererInitialized() const { | |
242 return remote_renderer_impl_->state_ == RemoteRendererImpl::STATE_PLAYING; | |
243 } | |
244 | |
245 void OnReceivedRpc(std::unique_ptr<remoting::pb::RpcMessage> message) { | |
246 remote_renderer_impl_->OnReceivedRpc(std::move(message)); | |
247 } | |
248 | |
249 void SetUp() override { | |
250 // Creates RemotingRendererController. | |
251 remoting_renderer_controller_ = | |
252 base::MakeUnique<RemotingRendererController>( | |
253 CreateRemotingSourceImpl(false)); | |
254 remoting_renderer_controller_->OnMetadataChanged(DefaultMetadata()); | |
255 | |
256 // Redirect RPC message to RemoteRendererImplTest::OnSendMessageToSink(). | |
257 remoting_renderer_controller_->GetRpcBroker()->SetMessageCallbackForTesting( | |
258 base::Bind(&RemoteRendererImplTest::OnSendMessageToSink, | |
259 base::Unretained(this))); | |
260 | |
261 // Creates RemoteRendererImpl. | |
262 remote_renderer_impl_.reset(new RemoteRendererImpl( | |
263 base::ThreadTaskRunnerHandle::Get(), | |
264 remoting_renderer_controller_->GetWeakPtr(), nullptr)); | |
265 RunPendingTasks(); | |
266 } | |
267 | |
268 RemoteRendererImpl::State state() const { | |
269 return remote_renderer_impl_->state_; | |
270 } | |
271 | |
272 void RunPendingTasks() { base::RunLoop().RunUntilIdle(); } | |
273 | |
274 // Gets first available RpcMessage with specific |proc|. | |
275 const remoting::pb::RpcMessage* PeekRpcMessage(int proc) const { | |
276 for (auto& s : received_rpc_) { | |
277 if (proc == s->proc()) | |
278 return s.get(); | |
279 } | |
280 return nullptr; | |
281 } | |
282 int ReceivedRpcMessageCount() const { return received_rpc_.size(); } | |
283 void ResetReceivedRpcMessage() { received_rpc_.clear(); } | |
284 | |
285 void ValidateCurrentTime(base::TimeDelta current, | |
286 base::TimeDelta current_max) const { | |
287 ASSERT_EQ(remote_renderer_impl_->current_media_time_, current); | |
288 ASSERT_EQ(remote_renderer_impl_->current_max_time_, current_max); | |
289 } | |
290 | |
291 base::MessageLoop message_loop_; | |
292 std::unique_ptr<RemotingRendererController> remoting_renderer_controller_; | |
293 std::unique_ptr<RendererClientImpl> render_client_; | |
294 std::unique_ptr<FakeRemotingDemuxerStreamProvider> demuxer_stream_provider_; | |
295 std::unique_ptr<RemoteRendererImpl> remote_renderer_impl_; | |
296 | |
297 // RPC handles. | |
298 const int receiver_renderer_handle_; | |
299 const int receiver_audio_demuxer_callback_handle_; | |
300 const int receiver_video_demuxer_callback_handle_; | |
301 int sender_client_handle_; | |
302 int sender_renderer_callback_handle_; | |
303 int sender_audio_demuxer_handle_; | |
304 int sender_video_demuxer_handle_; | |
305 | |
306 // flag to indicate if RPC_DS_INITIALIZE_CALLBACK RPC messages are received. | |
307 bool received_audio_ds_init_cb_; | |
308 bool received_video_ds_init_cb_; | |
309 | |
310 // Check if |remote_renderer_impl_| is initialized successfully or not. | |
311 bool renderer_initialized_; | |
312 | |
313 // vector to store received RPC message with proc value | |
314 std::vector<std::unique_ptr<remoting::pb::RpcMessage>> received_rpc_; | |
315 | |
316 private: | |
317 DISALLOW_COPY_AND_ASSIGN(RemoteRendererImplTest); | |
318 }; | |
319 | |
320 TEST_F(RemoteRendererImplTest, Initialize) { | |
321 InitializeRenderer(); | |
322 RunPendingTasks(); | |
323 | |
324 ASSERT_TRUE(IsRendererInitialized()); | |
325 ASSERT_EQ(render_client_->status(), PIPELINE_OK); | |
326 } | |
327 | |
328 TEST_F(RemoteRendererImplTest, Flush) { | |
329 // Initialize Renderer. | |
330 InitializeRenderer(); | |
331 RunPendingTasks(); | |
332 ASSERT_TRUE(IsRendererInitialized()); | |
333 ASSERT_EQ(render_client_->status(), PIPELINE_OK); | |
334 | |
335 // Flush Renderer. | |
336 // Redirect RPC message for simulate receiver scenario | |
337 remoting_renderer_controller_->GetRpcBroker()->SetMessageCallbackForTesting( | |
338 base::Bind(&RemoteRendererImplTest::RpcMessageResponseBot, | |
339 base::Unretained(this))); | |
340 RunPendingTasks(); | |
341 EXPECT_CALL(*render_client_, OnFlushCallback()).Times(1); | |
342 remote_renderer_impl_->Flush( | |
343 base::Bind(&RendererClientImpl::OnFlushCallback, | |
344 base::Unretained(render_client_.get()))); | |
345 RunPendingTasks(); | |
346 } | |
347 | |
348 TEST_F(RemoteRendererImplTest, StartPlayingFrom) { | |
349 // Initialize Renderer | |
350 InitializeRenderer(); | |
351 RunPendingTasks(); | |
352 ASSERT_TRUE(IsRendererInitialized()); | |
353 ASSERT_EQ(render_client_->status(), PIPELINE_OK); | |
354 | |
355 // StartPlaying from | |
356 base::TimeDelta seek = base::TimeDelta::FromMicroseconds(100); | |
357 remote_renderer_impl_->StartPlayingFrom(seek); | |
358 RunPendingTasks(); | |
359 | |
360 // Checks if it sends out RPC message with correct value. | |
361 ASSERT_EQ(1, ReceivedRpcMessageCount()); | |
362 const remoting::pb::RpcMessage* rpc = | |
363 PeekRpcMessage(remoting::pb::RpcMessage::RPC_R_STARTPLAYINGFROM); | |
364 ASSERT_TRUE(rpc); | |
365 ASSERT_EQ(rpc->integer64_value(), 100); | |
366 } | |
367 | |
368 TEST_F(RemoteRendererImplTest, SetVolume) { | |
369 // Initialize Renderer because, as of this writing, the pipeline guarantees it | |
370 // will not call SetVolume() until after the media::Renderer is initialized. | |
371 InitializeRenderer(); | |
372 RunPendingTasks(); | |
373 ASSERT_EQ(0, ReceivedRpcMessageCount()); | |
374 | |
375 // SetVolume() will send remoting::pb::RpcMessage::RPC_R_SETVOLUME RPC. | |
376 remote_renderer_impl_->SetVolume(3.0); | |
377 RunPendingTasks(); | |
378 | |
379 // Checks if it sends out RPC message with correct value. | |
380 ASSERT_EQ(1, ReceivedRpcMessageCount()); | |
381 const remoting::pb::RpcMessage* rpc = | |
382 PeekRpcMessage(remoting::pb::RpcMessage::RPC_R_SETVOLUME); | |
383 ASSERT_TRUE(rpc); | |
384 ASSERT_TRUE(rpc->double_value() == 3.0); | |
385 } | |
386 | |
387 TEST_F(RemoteRendererImplTest, SetPlaybackRate) { | |
388 // Initialize Renderer because, as of this writing, the pipeline guarantees it | |
389 // will not call SetPlaybackRate() until after the media::Renderer is | |
390 // initialized. | |
391 InitializeRenderer(); | |
392 RunPendingTasks(); | |
393 ASSERT_EQ(0, ReceivedRpcMessageCount()); | |
394 | |
395 remoting_renderer_controller_->GetRpcBroker()->SetMessageCallbackForTesting( | |
396 base::Bind(&RemoteRendererImplTest::OnSendMessageToSink, | |
397 base::Unretained(this))); | |
398 remote_renderer_impl_->SetPlaybackRate(2.5); | |
399 RunPendingTasks(); | |
400 ASSERT_EQ(1, ReceivedRpcMessageCount()); | |
401 // Checks if it sends out RPC message with correct value. | |
402 const remoting::pb::RpcMessage* rpc = | |
403 PeekRpcMessage(remoting::pb::RpcMessage::RPC_R_SETPLAYBACKRATE); | |
404 ASSERT_TRUE(rpc); | |
405 ASSERT_TRUE(rpc->double_value() == 2.5); | |
406 } | |
407 | |
408 TEST_F(RemoteRendererImplTest, OnTimeUpdate) { | |
409 // Issues RPC_RC_ONTIMEUPDATE RPC message. | |
410 base::TimeDelta media_time = base::TimeDelta::FromMicroseconds(100); | |
411 base::TimeDelta max_media_time = base::TimeDelta::FromMicroseconds(500); | |
412 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | |
413 rpc->set_handle(5); | |
414 rpc->set_proc(remoting::pb::RpcMessage::RPC_RC_ONTIMEUPDATE); | |
415 auto* time_message = rpc->mutable_rendererclient_ontimeupdate_rpc(); | |
416 time_message->set_time_usec(media_time.InMicroseconds()); | |
417 time_message->set_max_time_usec(max_media_time.InMicroseconds()); | |
418 OnReceivedRpc(std::move(rpc)); | |
419 ValidateCurrentTime(media_time, max_media_time); | |
420 | |
421 // Issues RPC_RC_ONTIMEUPDATE RPC message with invalid time | |
422 base::TimeDelta media_time2 = base::TimeDelta::FromMicroseconds(-100); | |
423 base::TimeDelta max_media_time2 = base::TimeDelta::FromMicroseconds(500); | |
424 std::unique_ptr<remoting::pb::RpcMessage> rpc2( | |
425 new remoting::pb::RpcMessage()); | |
426 rpc2->set_handle(5); | |
427 rpc2->set_proc(remoting::pb::RpcMessage::RPC_RC_ONTIMEUPDATE); | |
428 auto* time_message2 = rpc2->mutable_rendererclient_ontimeupdate_rpc(); | |
429 time_message2->set_time_usec(media_time2.InMicroseconds()); | |
430 time_message2->set_max_time_usec(max_media_time2.InMicroseconds()); | |
431 OnReceivedRpc(std::move(rpc2)); | |
432 // Because of invalid value, the time will not be updated and remain the same. | |
433 ValidateCurrentTime(media_time, max_media_time); | |
434 } | |
435 | |
436 TEST_F(RemoteRendererImplTest, OnBufferingStateChange) { | |
437 InitializeRenderer(); | |
438 // Issues RPC_RC_ONBUFFERINGSTATECHANGE RPC message. | |
439 EXPECT_CALL(*render_client_, | |
440 OnBufferingStateChange(media::BUFFERING_HAVE_NOTHING)) | |
441 .Times(1); | |
442 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | |
443 rpc->set_handle(5); | |
444 rpc->set_proc(remoting::pb::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE); | |
445 auto* buffering_state = | |
446 rpc->mutable_rendererclient_onbufferingstatechange_rpc(); | |
447 buffering_state->set_state( | |
448 remoting::pb::RendererClientOnBufferingStateChange:: | |
449 BUFFERING_HAVE_NOTHING); | |
450 OnReceivedRpc(std::move(rpc)); | |
451 RunPendingTasks(); | |
452 } | |
453 | |
454 TEST_F(RemoteRendererImplTest, OnVideoNaturalSizeChange) { | |
455 InitializeRenderer(); | |
456 // Makes sure initial value of video natural size is not set to | |
457 // gfx::Size(100, 200). | |
458 ASSERT_NE(render_client_->size().width(), 100); | |
459 ASSERT_NE(render_client_->size().height(), 200); | |
460 // Issues RPC_RC_ONVIDEONATURALSIZECHANGE RPC message. | |
461 EXPECT_CALL(*render_client_, OnVideoNaturalSizeChange(gfx::Size(100, 200))) | |
462 .Times(1); | |
463 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | |
464 rpc->set_handle(5); | |
465 rpc->set_proc(remoting::pb::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE); | |
466 auto* size_message = | |
467 rpc->mutable_rendererclient_onvideonatualsizechange_rpc(); | |
468 size_message->set_width(100); | |
469 size_message->set_height(200); | |
470 OnReceivedRpc(std::move(rpc)); | |
471 RunPendingTasks(); | |
472 ASSERT_EQ(render_client_->size().width(), 100); | |
473 ASSERT_EQ(render_client_->size().height(), 200); | |
474 } | |
475 | |
476 TEST_F(RemoteRendererImplTest, OnVideoNaturalSizeChangeWithInvalidValue) { | |
477 InitializeRenderer(); | |
478 // Issues RPC_RC_ONVIDEONATURALSIZECHANGE RPC message. | |
479 EXPECT_CALL(*render_client_, OnVideoNaturalSizeChange(_)).Times(0); | |
480 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | |
481 rpc->set_handle(5); | |
482 rpc->set_proc(remoting::pb::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE); | |
483 auto* size_message = | |
484 rpc->mutable_rendererclient_onvideonatualsizechange_rpc(); | |
485 size_message->set_width(-100); | |
486 size_message->set_height(0); | |
487 OnReceivedRpc(std::move(rpc)); | |
488 RunPendingTasks(); | |
489 } | |
490 | |
491 TEST_F(RemoteRendererImplTest, OnVideoOpacityChange) { | |
492 InitializeRenderer(); | |
493 ASSERT_FALSE(render_client_->opaque()); | |
494 // Issues RPC_RC_ONVIDEOOPACITYCHANGE RPC message. | |
495 EXPECT_CALL(*render_client_, OnVideoOpacityChange(true)).Times(1); | |
496 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | |
497 rpc->set_handle(5); | |
498 rpc->set_proc(remoting::pb::RpcMessage::RPC_RC_ONVIDEOOPACITYCHANGE); | |
499 rpc->set_boolean_value(true); | |
500 OnReceivedRpc(std::move(rpc)); | |
501 RunPendingTasks(); | |
502 ASSERT_TRUE(render_client_->opaque()); | |
503 } | |
504 | |
505 TEST_F(RemoteRendererImplTest, OnStatisticsUpdate) { | |
506 InitializeRenderer(); | |
507 ASSERT_NE(render_client_->stats().audio_bytes_decoded, 1234U); | |
508 ASSERT_NE(render_client_->stats().video_bytes_decoded, 2345U); | |
509 ASSERT_NE(render_client_->stats().video_frames_decoded, 3456U); | |
510 ASSERT_NE(render_client_->stats().video_frames_dropped, 4567U); | |
511 ASSERT_NE(render_client_->stats().audio_memory_usage, 5678); | |
512 ASSERT_NE(render_client_->stats().video_memory_usage, 6789); | |
513 // Issues RPC_RC_ONSTATISTICSUPDATE RPC message. | |
514 EXPECT_CALL(*render_client_, OnStatisticsUpdate(_)).Times(1); | |
515 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | |
516 rpc->set_handle(5); | |
517 rpc->set_proc(remoting::pb::RpcMessage::RPC_RC_ONSTATISTICSUPDATE); | |
518 auto* message = rpc->mutable_rendererclient_onstatisticsupdate_rpc(); | |
519 message->set_audio_bytes_decoded(1234U); | |
520 message->set_video_bytes_decoded(2345U); | |
521 message->set_video_frames_decoded(3456U); | |
522 message->set_video_frames_dropped(4567U); | |
523 message->set_audio_memory_usage(5678); | |
524 message->set_video_memory_usage(6789); | |
525 OnReceivedRpc(std::move(rpc)); | |
526 RunPendingTasks(); | |
527 ASSERT_EQ(render_client_->stats().audio_bytes_decoded, 1234U); | |
528 ASSERT_EQ(render_client_->stats().video_bytes_decoded, 2345U); | |
529 ASSERT_EQ(render_client_->stats().video_frames_decoded, 3456U); | |
530 ASSERT_EQ(render_client_->stats().video_frames_dropped, 4567U); | |
531 ASSERT_EQ(render_client_->stats().audio_memory_usage, 5678); | |
532 ASSERT_EQ(render_client_->stats().video_memory_usage, 6789); | |
533 } | |
534 | |
535 TEST_F(RemoteRendererImplTest, OnDurationChange) { | |
536 InitializeRenderer(); | |
537 ASSERT_NE(render_client_->duration(), | |
538 base::TimeDelta::FromMicroseconds(1234)); | |
539 // Issues RPC_RC_ONDURATIONCHANGE RPC message. | |
540 EXPECT_CALL(*render_client_, | |
541 OnDurationChange(base::TimeDelta::FromMicroseconds(1234))) | |
542 .Times(1); | |
543 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | |
544 rpc->set_handle(5); | |
545 rpc->set_proc(remoting::pb::RpcMessage::RPC_RC_ONDURATIONCHANGE); | |
546 rpc->set_integer64_value(1234); | |
547 OnReceivedRpc(std::move(rpc)); | |
548 RunPendingTasks(); | |
549 ASSERT_EQ(render_client_->duration(), | |
550 base::TimeDelta::FromMicroseconds(1234)); | |
551 } | |
552 | |
553 TEST_F(RemoteRendererImplTest, OnDurationChangeWithInvalidValue) { | |
554 InitializeRenderer(); | |
555 // Issues RPC_RC_ONDURATIONCHANGE RPC message. | |
556 EXPECT_CALL(*render_client_, OnDurationChange(_)).Times(0); | |
557 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | |
558 rpc->set_handle(5); | |
559 rpc->set_proc(remoting::pb::RpcMessage::RPC_RC_ONDURATIONCHANGE); | |
560 rpc->set_integer64_value(-345); | |
561 OnReceivedRpc(std::move(rpc)); | |
562 RunPendingTasks(); | |
563 } | |
564 | |
565 // TODO(xjz): Tests for detecting PACING_TOO_SLOWLY and FRAME_DROP_RATE_HIGH. | |
566 | |
567 } // namespace media | |
OLD | NEW |