| 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 |