OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdint.h> | 5 #include <stdint.h> |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/test/simple_test_tick_clock.h" | 11 #include "base/test/simple_test_tick_clock.h" |
12 #include "media/base/video_frame.h" | 12 #include "media/base/video_frame.h" |
13 #include "media/cast/cast_environment.h" | 13 #include "media/cast/cast_environment.h" |
14 #include "media/cast/logging/simple_event_subscriber.h" | 14 #include "media/cast/logging/simple_event_subscriber.h" |
15 #include "media/cast/net/cast_transport_config.h" | 15 #include "media/cast/net/cast_transport_config.h" |
16 #include "media/cast/net/cast_transport_sender_impl.h" | 16 #include "media/cast/net/cast_transport_sender_impl.h" |
17 #include "media/cast/net/pacing/paced_sender.h" | 17 #include "media/cast/net/pacing/paced_sender.h" |
| 18 #include "media/cast/sender/fake_video_encode_accelerator_factory.h" |
18 #include "media/cast/sender/video_frame_factory.h" | 19 #include "media/cast/sender/video_frame_factory.h" |
19 #include "media/cast/sender/video_sender.h" | 20 #include "media/cast/sender/video_sender.h" |
20 #include "media/cast/test/fake_single_thread_task_runner.h" | 21 #include "media/cast/test/fake_single_thread_task_runner.h" |
21 #include "media/cast/test/utility/default_config.h" | 22 #include "media/cast/test/utility/default_config.h" |
22 #include "media/cast/test/utility/video_utility.h" | 23 #include "media/cast/test/utility/video_utility.h" |
23 #include "media/video/fake_video_encode_accelerator.h" | 24 #include "media/video/fake_video_encode_accelerator.h" |
24 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
26 | 27 |
27 namespace media { | 28 namespace media { |
28 namespace cast { | 29 namespace cast { |
29 | 30 |
30 namespace { | 31 namespace { |
31 static const uint8 kPixelValue = 123; | 32 static const uint8 kPixelValue = 123; |
32 static const int kWidth = 320; | 33 static const int kWidth = 320; |
33 static const int kHeight = 240; | 34 static const int kHeight = 240; |
34 | 35 |
35 using testing::_; | 36 using testing::_; |
36 using testing::AtLeast; | 37 using testing::AtLeast; |
37 | 38 |
38 void CreateVideoEncodeAccelerator( | |
39 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | |
40 scoped_ptr<VideoEncodeAccelerator> fake_vea, | |
41 const ReceiveVideoEncodeAcceleratorCallback& callback) { | |
42 callback.Run(task_runner, fake_vea.Pass()); | |
43 } | |
44 | |
45 void CreateSharedMemory( | |
46 size_t size, const ReceiveVideoEncodeMemoryCallback& callback) { | |
47 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory()); | |
48 if (!shm->CreateAndMapAnonymous(size)) { | |
49 NOTREACHED(); | |
50 return; | |
51 } | |
52 callback.Run(shm.Pass()); | |
53 } | |
54 | 39 |
55 void SaveOperationalStatus(OperationalStatus* out_status, | 40 void SaveOperationalStatus(OperationalStatus* out_status, |
56 OperationalStatus in_status) { | 41 OperationalStatus in_status) { |
57 DVLOG(1) << "OperationalStatus transitioning from " << *out_status << " to " | 42 DVLOG(1) << "OperationalStatus transitioning from " << *out_status << " to " |
58 << in_status; | 43 << in_status; |
59 *out_status = in_status; | 44 *out_status = in_status; |
60 } | 45 } |
61 | 46 |
62 class TestPacketSender : public PacketSender { | 47 class TestPacketSender : public PacketSender { |
63 public: | 48 public: |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 protected: | 123 protected: |
139 VideoSenderTest() | 124 VideoSenderTest() |
140 : testing_clock_(new base::SimpleTestTickClock()), | 125 : testing_clock_(new base::SimpleTestTickClock()), |
141 task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)), | 126 task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)), |
142 cast_environment_(new CastEnvironment( | 127 cast_environment_(new CastEnvironment( |
143 scoped_ptr<base::TickClock>(testing_clock_).Pass(), | 128 scoped_ptr<base::TickClock>(testing_clock_).Pass(), |
144 task_runner_, | 129 task_runner_, |
145 task_runner_, | 130 task_runner_, |
146 task_runner_)), | 131 task_runner_)), |
147 operational_status_(STATUS_UNINITIALIZED), | 132 operational_status_(STATUS_UNINITIALIZED), |
148 stored_bitrates_(NULL) { | 133 vea_factory_(task_runner_) { |
149 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); | 134 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); |
| 135 vea_factory_.SetAutoRespond(true); |
150 last_pixel_value_ = kPixelValue; | 136 last_pixel_value_ = kPixelValue; |
151 net::IPEndPoint dummy_endpoint; | 137 net::IPEndPoint dummy_endpoint; |
152 transport_sender_.reset(new CastTransportSenderImpl( | 138 transport_sender_.reset(new CastTransportSenderImpl( |
153 NULL, | 139 NULL, |
154 testing_clock_, | 140 testing_clock_, |
155 dummy_endpoint, | 141 dummy_endpoint, |
156 dummy_endpoint, | 142 dummy_endpoint, |
157 make_scoped_ptr(new base::DictionaryValue), | 143 make_scoped_ptr(new base::DictionaryValue), |
158 base::Bind(&UpdateCastTransportStatus), | 144 base::Bind(&UpdateCastTransportStatus), |
159 BulkRawEventsCallback(), | 145 BulkRawEventsCallback(), |
(...skipping 15 matching lines...) Expand all Loading... |
175 } | 161 } |
176 | 162 |
177 // If |external| is true then external video encoder (VEA) is used. | 163 // If |external| is true then external video encoder (VEA) is used. |
178 // |expect_init_sucess| is true if initialization is expected to succeed. | 164 // |expect_init_sucess| is true if initialization is expected to succeed. |
179 void InitEncoder(bool external, bool expect_init_success) { | 165 void InitEncoder(bool external, bool expect_init_success) { |
180 VideoSenderConfig video_config; | 166 VideoSenderConfig video_config; |
181 video_config.ssrc = 1; | 167 video_config.ssrc = 1; |
182 video_config.receiver_ssrc = 2; | 168 video_config.receiver_ssrc = 2; |
183 video_config.rtp_payload_type = 127; | 169 video_config.rtp_payload_type = 127; |
184 video_config.use_external_encoder = external; | 170 video_config.use_external_encoder = external; |
185 video_config.width = kWidth; | |
186 video_config.height = kHeight; | |
187 video_config.max_bitrate = 5000000; | 171 video_config.max_bitrate = 5000000; |
188 video_config.min_bitrate = 1000000; | 172 video_config.min_bitrate = 1000000; |
189 video_config.start_bitrate = 1000000; | 173 video_config.start_bitrate = 1000000; |
190 video_config.max_qp = 56; | 174 video_config.max_qp = 56; |
191 video_config.min_qp = 0; | 175 video_config.min_qp = 0; |
192 video_config.max_frame_rate = 30; | 176 video_config.max_frame_rate = 30; |
193 video_config.max_number_of_video_buffers_used = 1; | 177 video_config.max_number_of_video_buffers_used = 1; |
194 video_config.codec = CODEC_VIDEO_VP8; | 178 video_config.codec = CODEC_VIDEO_VP8; |
195 | 179 |
196 ASSERT_EQ(operational_status_, STATUS_UNINITIALIZED); | 180 ASSERT_EQ(operational_status_, STATUS_UNINITIALIZED); |
197 | 181 |
198 if (external) { | 182 if (external) { |
199 media::FakeVideoEncodeAccelerator* fake_vea = | 183 vea_factory_.SetInitializationWillSucceed(expect_init_success); |
200 new media::FakeVideoEncodeAccelerator(task_runner_); | 184 video_sender_.reset(new PeerVideoSender( |
201 stored_bitrates_ = &fake_vea->stored_bitrates(); | 185 cast_environment_, |
202 fake_vea->SetWillInitializationSucceed(expect_init_success); | 186 video_config, |
203 scoped_ptr<VideoEncodeAccelerator> fake_vea_owner(fake_vea); | 187 base::Bind(&SaveOperationalStatus, &operational_status_), |
204 video_sender_.reset( | 188 base::Bind( |
205 new PeerVideoSender(cast_environment_, | 189 &FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator, |
206 video_config, | 190 base::Unretained(&vea_factory_)), |
207 base::Bind(&SaveOperationalStatus, | 191 base::Bind(&FakeVideoEncodeAcceleratorFactory::CreateSharedMemory, |
208 &operational_status_), | 192 base::Unretained(&vea_factory_)), |
209 base::Bind(&CreateVideoEncodeAccelerator, | 193 transport_sender_.get())); |
210 task_runner_, | |
211 base::Passed(&fake_vea_owner)), | |
212 base::Bind(&CreateSharedMemory), | |
213 transport_sender_.get())); | |
214 } else { | 194 } else { |
215 video_sender_.reset( | 195 video_sender_.reset(new PeerVideoSender( |
216 new PeerVideoSender(cast_environment_, | 196 cast_environment_, |
217 video_config, | 197 video_config, |
218 base::Bind(&SaveOperationalStatus, | 198 base::Bind(&SaveOperationalStatus, &operational_status_), |
219 &operational_status_), | 199 CreateDefaultVideoEncodeAcceleratorCallback(), |
220 CreateDefaultVideoEncodeAcceleratorCallback(), | 200 CreateDefaultVideoEncodeMemoryCallback(), |
221 CreateDefaultVideoEncodeMemoryCallback(), | 201 transport_sender_.get())); |
222 transport_sender_.get())); | |
223 } | 202 } |
224 task_runner_->RunTasks(); | 203 task_runner_->RunTasks(); |
225 } | 204 } |
226 | 205 |
227 scoped_refptr<media::VideoFrame> GetNewVideoFrame() { | 206 scoped_refptr<media::VideoFrame> GetNewVideoFrame() { |
228 if (first_frame_timestamp_.is_null()) | 207 if (first_frame_timestamp_.is_null()) |
229 first_frame_timestamp_ = testing_clock_->NowTicks(); | 208 first_frame_timestamp_ = testing_clock_->NowTicks(); |
230 gfx::Size size(kWidth, kHeight); | 209 gfx::Size size(kWidth, kHeight); |
231 scoped_refptr<media::VideoFrame> video_frame = | 210 scoped_refptr<media::VideoFrame> video_frame = |
232 media::VideoFrame::CreateFrame( | 211 media::VideoFrame::CreateFrame( |
(...skipping 16 matching lines...) Expand all Loading... |
249 } | 228 } |
250 | 229 |
251 void RunTasks(int during_ms) { | 230 void RunTasks(int during_ms) { |
252 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(during_ms)); | 231 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(during_ms)); |
253 } | 232 } |
254 | 233 |
255 base::SimpleTestTickClock* const testing_clock_; // Owned by CastEnvironment. | 234 base::SimpleTestTickClock* const testing_clock_; // Owned by CastEnvironment. |
256 const scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | 235 const scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; |
257 const scoped_refptr<CastEnvironment> cast_environment_; | 236 const scoped_refptr<CastEnvironment> cast_environment_; |
258 OperationalStatus operational_status_; | 237 OperationalStatus operational_status_; |
| 238 FakeVideoEncodeAcceleratorFactory vea_factory_; |
259 TestPacketSender transport_; | 239 TestPacketSender transport_; |
260 scoped_ptr<CastTransportSenderImpl> transport_sender_; | 240 scoped_ptr<CastTransportSenderImpl> transport_sender_; |
261 scoped_ptr<PeerVideoSender> video_sender_; | 241 scoped_ptr<PeerVideoSender> video_sender_; |
262 const std::vector<uint32>* stored_bitrates_; // Owned by |video_sender_|. | |
263 int last_pixel_value_; | 242 int last_pixel_value_; |
264 base::TimeTicks first_frame_timestamp_; | 243 base::TimeTicks first_frame_timestamp_; |
265 | 244 |
266 DISALLOW_COPY_AND_ASSIGN(VideoSenderTest); | 245 DISALLOW_COPY_AND_ASSIGN(VideoSenderTest); |
267 }; | 246 }; |
268 | 247 |
269 TEST_F(VideoSenderTest, BuiltInEncoder) { | 248 TEST_F(VideoSenderTest, BuiltInEncoder) { |
270 InitEncoder(false, true); | 249 InitEncoder(false, true); |
271 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); | 250 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); |
272 | 251 |
273 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); | 252 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
274 | 253 |
275 const base::TimeTicks reference_time = testing_clock_->NowTicks(); | 254 const base::TimeTicks reference_time = testing_clock_->NowTicks(); |
276 video_sender_->InsertRawVideoFrame(video_frame, reference_time); | 255 video_sender_->InsertRawVideoFrame(video_frame, reference_time); |
277 | 256 |
278 task_runner_->RunTasks(); | 257 task_runner_->RunTasks(); |
279 EXPECT_LE(1, transport_.number_of_rtp_packets()); | 258 EXPECT_LE(1, transport_.number_of_rtp_packets()); |
280 EXPECT_LE(1, transport_.number_of_rtcp_packets()); | 259 EXPECT_LE(1, transport_.number_of_rtcp_packets()); |
281 } | 260 } |
282 | 261 |
283 TEST_F(VideoSenderTest, ExternalEncoder) { | 262 TEST_F(VideoSenderTest, ExternalEncoder) { |
284 InitEncoder(true, true); | 263 InitEncoder(true, true); |
285 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); | 264 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); |
286 | 265 |
| 266 // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED |
| 267 // so that frames will be sent to it. Therefore, no encoder activity should |
| 268 // have occurred at this point. Send a frame to spurn creation of the |
| 269 // underlying ExternalVideoEncoder instance. |
| 270 if (vea_factory_.vea_response_count() == 0) { |
| 271 video_sender_->InsertRawVideoFrame(GetNewVideoFrame(), |
| 272 testing_clock_->NowTicks()); |
| 273 task_runner_->RunTasks(); |
| 274 } |
| 275 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); |
| 276 RunTasks(33); |
| 277 |
| 278 // VideoSender created an encoder for 1280x720 frames, in order to provide the |
| 279 // INITIALIZED status. |
| 280 EXPECT_EQ(1, vea_factory_.vea_response_count()); |
| 281 EXPECT_EQ(3, vea_factory_.shm_response_count()); |
| 282 |
287 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); | 283 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
288 | 284 |
289 const base::TimeTicks reference_time = testing_clock_->NowTicks(); | 285 for (int i = 0; i < 3; ++i) { |
290 video_sender_->InsertRawVideoFrame(video_frame, reference_time); | 286 const base::TimeTicks reference_time = testing_clock_->NowTicks(); |
291 task_runner_->RunTasks(); | 287 video_sender_->InsertRawVideoFrame(video_frame, reference_time); |
292 video_sender_->InsertRawVideoFrame(video_frame, reference_time); | 288 RunTasks(33); |
293 task_runner_->RunTasks(); | 289 // VideoSender re-created the encoder for the 320x240 frames we're |
294 video_sender_->InsertRawVideoFrame(video_frame, reference_time); | 290 // providing. |
295 task_runner_->RunTasks(); | 291 EXPECT_EQ(1, vea_factory_.vea_response_count()); |
| 292 EXPECT_EQ(3, vea_factory_.shm_response_count()); |
| 293 } |
296 | 294 |
297 // Fixed bitrate is used for external encoder. Bitrate is only once | |
298 // to the encoder. | |
299 EXPECT_EQ(1u, stored_bitrates_->size()); | |
300 video_sender_.reset(NULL); | 295 video_sender_.reset(NULL); |
301 task_runner_->RunTasks(); | 296 task_runner_->RunTasks(); |
| 297 EXPECT_EQ(1, vea_factory_.vea_response_count()); |
| 298 EXPECT_EQ(3, vea_factory_.shm_response_count()); |
302 } | 299 } |
303 | 300 |
304 TEST_F(VideoSenderTest, ExternalEncoderInitFails) { | 301 TEST_F(VideoSenderTest, ExternalEncoderInitFails) { |
305 InitEncoder(true, false); | 302 InitEncoder(true, false); |
| 303 |
| 304 // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED |
| 305 // so that frames will be sent to it. Send a frame to spurn creation of the |
| 306 // underlying ExternalVideoEncoder instance, which should result in failure. |
| 307 if (operational_status_ == STATUS_INITIALIZED || |
| 308 operational_status_ == STATUS_CODEC_REINIT_PENDING) { |
| 309 video_sender_->InsertRawVideoFrame(GetNewVideoFrame(), |
| 310 testing_clock_->NowTicks()); |
| 311 task_runner_->RunTasks(); |
| 312 } |
306 EXPECT_EQ(STATUS_CODEC_INIT_FAILED, operational_status_); | 313 EXPECT_EQ(STATUS_CODEC_INIT_FAILED, operational_status_); |
307 | 314 |
308 video_sender_.reset(NULL); | 315 video_sender_.reset(NULL); |
309 task_runner_->RunTasks(); | 316 task_runner_->RunTasks(); |
310 } | 317 } |
311 | 318 |
312 TEST_F(VideoSenderTest, RtcpTimer) { | 319 TEST_F(VideoSenderTest, RtcpTimer) { |
313 InitEncoder(false, true); | 320 InitEncoder(false, true); |
314 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); | 321 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); |
315 | 322 |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 | 569 |
563 TEST_F(VideoSenderTest, CheckVideoFrameFactoryIsNull) { | 570 TEST_F(VideoSenderTest, CheckVideoFrameFactoryIsNull) { |
564 InitEncoder(false, true); | 571 InitEncoder(false, true); |
565 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); | 572 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); |
566 | 573 |
567 EXPECT_EQ(nullptr, video_sender_->CreateVideoFrameFactory().get()); | 574 EXPECT_EQ(nullptr, video_sender_->CreateVideoFrameFactory().get()); |
568 } | 575 } |
569 | 576 |
570 } // namespace cast | 577 } // namespace cast |
571 } // namespace media | 578 } // namespace media |
OLD | NEW |