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

Side by Side Diff: media/cast/sender/video_encoder_unittest.cc

Issue 906403006: [Cast] Size-Adaptable platform video encoders. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed hubbe's comments. 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
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 <vector> 5 #include <vector>
6 #include <utility>
6 7
7 #include "base/bind.h" 8 #include "base/bind.h"
8 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
10 #include "media/base/video_frame.h" 11 #include "media/base/video_frame.h"
11 #include "media/cast/cast_defines.h" 12 #include "media/cast/cast_defines.h"
12 #include "media/cast/cast_environment.h" 13 #include "media/cast/cast_environment.h"
13 #include "media/cast/sender/video_encoder_impl.h" 14 #include "media/cast/sender/fake_video_encode_accelerator_factory.h"
15 #include "media/cast/sender/video_frame_factory.h"
16 #include "media/cast/sender/video_encoder.h"
14 #include "media/cast/test/fake_single_thread_task_runner.h" 17 #include "media/cast/test/fake_single_thread_task_runner.h"
15 #include "media/cast/test/utility/default_config.h" 18 #include "media/cast/test/utility/default_config.h"
16 #include "media/cast/test/utility/video_utility.h" 19 #include "media/cast/test/utility/video_utility.h"
17 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
18 21
22 #if defined(OS_MACOSX)
23 #include "media/cast/sender/h264_vt_encoder.h"
24 #endif
25
19 namespace media { 26 namespace media {
20 namespace cast { 27 namespace cast {
21 28
22 class VideoEncoderImplTest : public ::testing::TestWithParam<Codec> { 29 class VideoEncoderTest
30 : public ::testing::TestWithParam<std::pair<Codec, bool>> {
23 protected: 31 protected:
24 VideoEncoderImplTest() 32 VideoEncoderTest()
25 : testing_clock_(new base::SimpleTestTickClock()), 33 : testing_clock_(new base::SimpleTestTickClock()),
26 task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)), 34 task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)),
27 cast_environment_(new CastEnvironment( 35 cast_environment_(new CastEnvironment(
28 scoped_ptr<base::TickClock>(testing_clock_).Pass(), 36 scoped_ptr<base::TickClock>(testing_clock_).Pass(),
29 task_runner_, 37 task_runner_,
30 task_runner_, 38 task_runner_,
31 task_runner_)), 39 task_runner_)),
32 video_config_(GetDefaultVideoSenderConfig()), 40 video_config_(GetDefaultVideoSenderConfig()),
33 operational_status_(STATUS_UNINITIALIZED), 41 operational_status_(STATUS_UNINITIALIZED),
34 count_frames_delivered_(0) { 42 count_frames_delivered_(0) {
35 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); 43 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
36 first_frame_time_ = testing_clock_->NowTicks(); 44 first_frame_time_ = testing_clock_->NowTicks();
37 } 45 }
38 46
39 ~VideoEncoderImplTest() override {} 47 ~VideoEncoderTest() override {}
40 48
41 void SetUp() override { 49 void SetUp() override {
42 video_config_.codec = GetParam(); 50 video_config_.codec = GetParam().first;
51 video_config_.use_external_encoder = GetParam().second;
52
53 if (video_config_.use_external_encoder)
54 vea_factory_.reset(new FakeVideoEncodeAcceleratorFactory(task_runner_));
43 } 55 }
44 56
45 void TearDown() override { 57 void TearDown() override {
46 video_encoder_.reset(); 58 video_encoder_.reset();
47 task_runner_->RunTasks(); 59 RunTasksAndAdvanceClock();
48 } 60 }
49 61
50 void CreateEncoder(bool three_buffer_mode) { 62 void CreateEncoder(bool three_buffer_mode) {
51 ASSERT_EQ(STATUS_UNINITIALIZED, operational_status_); 63 ASSERT_EQ(STATUS_UNINITIALIZED, operational_status_);
52 video_config_.max_number_of_video_buffers_used = 64 video_config_.max_number_of_video_buffers_used =
53 (three_buffer_mode ? 3 : 1); 65 (three_buffer_mode ? 3 : 1);
54 video_encoder_.reset(new VideoEncoderImpl( 66 video_encoder_ = VideoEncoder::Create(
55 cast_environment_, 67 cast_environment_,
56 video_config_, 68 video_config_,
57 base::Bind(&VideoEncoderImplTest::OnOperationalStatusChange, 69 base::Bind(&VideoEncoderTest::OnOperationalStatusChange,
58 base::Unretained(this)))); 70 base::Unretained(this)),
59 task_runner_->RunTasks(); 71 base::Bind(
60 ASSERT_EQ(STATUS_INITIALIZED, operational_status_); 72 &FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator,
73 base::Unretained(vea_factory_.get())),
74 base::Bind(&FakeVideoEncodeAcceleratorFactory::CreateSharedMemory,
75 base::Unretained(vea_factory_.get()))).Pass();
76 RunTasksAndAdvanceClock();
77 if (is_encoder_present())
78 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
79 }
80
81 bool is_encoder_present() const {
82 return !!video_encoder_;
83 }
84
85 bool is_testing_software_vp8_encoder() const {
86 return video_config_.codec == CODEC_VIDEO_VP8 &&
87 !video_config_.use_external_encoder;
88 }
89
90 bool is_testing_video_toolbox_encoder() const {
91 return
92 #if defined(OS_MACOSX)
93 (!video_config_.use_external_encoder &&
94 H264VideoToolboxEncoder::IsSupported(video_config_)) ||
95 #endif
96 false;
97 }
98
99 bool is_testing_platform_encoder() const {
100 return video_config_.use_external_encoder ||
101 is_testing_video_toolbox_encoder();
61 } 102 }
62 103
63 VideoEncoder* video_encoder() const { 104 VideoEncoder* video_encoder() const {
64 return video_encoder_.get(); 105 return video_encoder_.get();
65 } 106 }
66 107
67 void AdvanceClock() { 108 void DestroyEncoder() {
68 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33)); 109 video_encoder_.reset();
69 } 110 }
70 111
71 base::TimeTicks Now() const { 112 base::TimeTicks Now() const {
72 return testing_clock_->NowTicks(); 113 return testing_clock_->NowTicks();
73 } 114 }
74 115
75 void RunTasks() const { 116 void RunTasksAndAdvanceClock() const {
76 return task_runner_->RunTasks(); 117 const base::TimeDelta frame_duration = base::TimeDelta::FromMicroseconds(
118 1000000.0 / video_config_.max_frame_rate);
119 #if defined(OS_MACOSX)
120 if (is_testing_video_toolbox_encoder()) {
121 // The H264VideoToolboxEncoder (on MAC_OSX and IOS) is not a faked
122 // implementation in these tests, and performs its encoding asynchronously
123 // on an unknown set of threads. Therefore, sleep the current thread for
124 // the real amount of time to avoid excessively spinning the CPU while
125 // waiting for something to happen.
126 base::PlatformThread::Sleep(frame_duration);
127 }
128 #endif
129 task_runner_->RunTasks();
130 testing_clock_->Advance(frame_duration);
77 } 131 }
78 132
79 int count_frames_delivered() const { 133 int count_frames_delivered() const {
80 return count_frames_delivered_; 134 return count_frames_delivered_;
81 } 135 }
82 136
83 // Return a callback that, when run, expects the EncodedFrame to have the 137 void WaitForAllFramesToBeDelivered(int total_expected) const {
84 // given properties. 138 video_encoder_->EmitFrames();
85 VideoEncoder::FrameEncodedCallback CreateFrameDeliverCallback( 139 while (count_frames_delivered_ < total_expected)
86 uint32 expected_frame_id, 140 RunTasksAndAdvanceClock();
87 uint32 expected_last_referenced_frame_id,
88 uint32 expected_rtp_timestamp,
89 const base::TimeTicks& expected_reference_time) {
90 return base::Bind(&VideoEncoderImplTest::DeliverEncodedVideoFrame,
91 base::Unretained(this),
92 expected_frame_id,
93 expected_last_referenced_frame_id,
94 expected_rtp_timestamp,
95 expected_reference_time);
96 } 141 }
97 142
98 // Creates a new VideoFrame of the given |size|, filled with a test pattern. 143 // Creates a new VideoFrame of the given |size|, filled with a test pattern.
99 scoped_refptr<media::VideoFrame> CreateTestVideoFrame( 144 // When available, it attempts to use the VideoFrameFactory provided by the
100 const gfx::Size& size) const { 145 // encoder.
101 const scoped_refptr<media::VideoFrame> frame = 146 scoped_refptr<media::VideoFrame> CreateTestVideoFrame(const gfx::Size& size) {
102 media::VideoFrame::CreateFrame( 147 const base::TimeDelta timestamp =
103 VideoFrame::I420, size, gfx::Rect(size), size, 148 testing_clock_->NowTicks() - first_frame_time_;
104 testing_clock_->NowTicks() - first_frame_time_); 149 scoped_refptr<media::VideoFrame> frame;
150 if (video_frame_factory_)
151 frame = video_frame_factory_->MaybeCreateFrame(size, timestamp);
152 if (!frame) {
153 frame = media::VideoFrame::CreateFrame(
154 VideoFrame::I420, size, gfx::Rect(size), size, timestamp);
155 }
105 PopulateVideoFrame(frame.get(), 123); 156 PopulateVideoFrame(frame.get(), 123);
106 return frame; 157 return frame;
107 } 158 }
108 159
160 // Requests encoding the |video_frame| and has the resulting frame delivered
161 // via a callback that checks for expected results. Returns false if the
162 // encoder rejected the request.
163 bool EncodeAndCheckDelivery(
164 const scoped_refptr<media::VideoFrame>& video_frame,
165 uint32 frame_id,
166 uint32 reference_frame_id) {
167 return video_encoder_->EncodeVideoFrame(
168 video_frame,
169 Now(),
170 base::Bind(&VideoEncoderTest::DeliverEncodedVideoFrame,
171 base::Unretained(this),
172 frame_id,
173 reference_frame_id,
174 TimeDeltaToRtpDelta(video_frame->timestamp(),
175 kVideoFrequency),
176 Now()));
177 }
178
179 // If the implementation of |video_encoder_| is ExternalVideoEncoder, check
180 // that the VEA factory has responded (by running the callbacks) a specific
181 // number of times. Otherwise, check that the VEA factory is inactive.
182 void ExpectVEAResponsesForExternalVideoEncoder(
183 int vea_response_count,
184 int shm_response_count) const {
185 if (!vea_factory_)
186 return;
187 EXPECT_EQ(vea_response_count, vea_factory_->vea_response_count());
188 EXPECT_EQ(shm_response_count, vea_factory_->shm_response_count());
189 }
190
191 void SetVEAFactoryAutoRespond(bool auto_respond) {
192 if (vea_factory_)
193 vea_factory_->SetAutoRespond(auto_respond);
194 }
195
109 private: 196 private:
110 void OnOperationalStatusChange(OperationalStatus status) { 197 void OnOperationalStatusChange(OperationalStatus status) {
198 DVLOG(1) << "OnOperationalStatusChange: from " << operational_status_
199 << " to " << status;
111 operational_status_ = status; 200 operational_status_ = status;
201
202 EXPECT_TRUE(operational_status_ == STATUS_CODEC_REINIT_PENDING ||
203 operational_status_ == STATUS_INITIALIZED);
204
205 // Create the VideoFrameFactory the first time status changes to
206 // STATUS_INITIALIZED.
207 if (operational_status_ == STATUS_INITIALIZED && !video_frame_factory_)
208 video_frame_factory_ = video_encoder_->CreateVideoFrameFactory().Pass();
112 } 209 }
113 210
114 // Checks that |encoded_frame| matches expected values. This is the method 211 // Checks that |encoded_frame| matches expected values. This is the method
115 // bound in the callback returned from CreateFrameDeliverCallback(). 212 // bound in the callback returned from EncodeAndCheckDelivery().
116 void DeliverEncodedVideoFrame( 213 void DeliverEncodedVideoFrame(
117 uint32 expected_frame_id, 214 uint32 expected_frame_id,
118 uint32 expected_last_referenced_frame_id, 215 uint32 expected_last_referenced_frame_id,
119 uint32 expected_rtp_timestamp, 216 uint32 expected_rtp_timestamp,
120 const base::TimeTicks& expected_reference_time, 217 const base::TimeTicks& expected_reference_time,
121 scoped_ptr<EncodedFrame> encoded_frame) { 218 scoped_ptr<EncodedFrame> encoded_frame) {
122 if (expected_frame_id != expected_last_referenced_frame_id) { 219 EXPECT_TRUE(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
123 EXPECT_EQ(EncodedFrame::DEPENDENT, encoded_frame->dependency); 220
124 } else if (video_config_.max_number_of_video_buffers_used == 1) {
125 EXPECT_EQ(EncodedFrame::KEY, encoded_frame->dependency);
126 }
127 EXPECT_EQ(expected_frame_id, encoded_frame->frame_id); 221 EXPECT_EQ(expected_frame_id, encoded_frame->frame_id);
128 EXPECT_EQ(expected_last_referenced_frame_id,
129 encoded_frame->referenced_frame_id)
130 << "frame id: " << expected_frame_id;
131 EXPECT_EQ(expected_rtp_timestamp, encoded_frame->rtp_timestamp); 222 EXPECT_EQ(expected_rtp_timestamp, encoded_frame->rtp_timestamp);
132 EXPECT_EQ(expected_reference_time, encoded_frame->reference_time); 223 EXPECT_EQ(expected_reference_time, encoded_frame->reference_time);
133 EXPECT_FALSE(encoded_frame->data.empty()); 224
225 // The platform encoders are "black boxes" and may choose to vend key frames
226 // and/or empty data at any time. The software encoders, however, should
227 // strictly adhere to expected behavior.
228 if (is_testing_platform_encoder()) {
229 const bool expected_key_frame =
230 expected_frame_id == expected_last_referenced_frame_id;
231 const bool have_key_frame =
232 encoded_frame->dependency == EncodedFrame::KEY;
233 EXPECT_EQ(have_key_frame,
234 encoded_frame->frame_id == encoded_frame->referenced_frame_id);
235 LOG_IF(WARNING, expected_key_frame != have_key_frame)
236 << "Platform encoder chose to emit a "
237 << (have_key_frame ? "key" : "delta")
238 << " frame instead of the expected kind @ frame_id="
239 << encoded_frame->frame_id;
240 LOG_IF(WARNING, encoded_frame->data.empty())
241 << "Platform encoder returned an empty frame @ frame_id="
242 << encoded_frame->frame_id;
243 } else {
244 if (expected_frame_id != expected_last_referenced_frame_id) {
245 EXPECT_EQ(EncodedFrame::DEPENDENT, encoded_frame->dependency);
246 } else if (video_config_.max_number_of_video_buffers_used == 1) {
247 EXPECT_EQ(EncodedFrame::KEY, encoded_frame->dependency);
248 }
249 EXPECT_EQ(expected_last_referenced_frame_id,
250 encoded_frame->referenced_frame_id);
251 EXPECT_FALSE(encoded_frame->data.empty());
252 }
253
134 ++count_frames_delivered_; 254 ++count_frames_delivered_;
135 } 255 }
136 256
137 base::SimpleTestTickClock* const testing_clock_; // Owned by CastEnvironment. 257 base::SimpleTestTickClock* const testing_clock_; // Owned by CastEnvironment.
138 const scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; 258 const scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
139 const scoped_refptr<CastEnvironment> cast_environment_; 259 const scoped_refptr<CastEnvironment> cast_environment_;
140 VideoSenderConfig video_config_; 260 VideoSenderConfig video_config_;
261 scoped_ptr<FakeVideoEncodeAcceleratorFactory> vea_factory_;
141 base::TimeTicks first_frame_time_; 262 base::TimeTicks first_frame_time_;
142 OperationalStatus operational_status_; 263 OperationalStatus operational_status_;
143 scoped_ptr<VideoEncoder> video_encoder_; 264 scoped_ptr<VideoEncoder> video_encoder_;
265 scoped_ptr<VideoFrameFactory> video_frame_factory_;
144 266
145 int count_frames_delivered_; 267 int count_frames_delivered_;
146 268
147 DISALLOW_COPY_AND_ASSIGN(VideoEncoderImplTest); 269 DISALLOW_COPY_AND_ASSIGN(VideoEncoderTest);
148 }; 270 };
149 271
150 // A simple test to encode ten frames of video, expecting to see one key frame 272 // A simple test to encode ten frames of video, expecting to see one key frame
151 // followed by nine delta frames. 273 // followed by nine delta frames.
152 TEST_P(VideoEncoderImplTest, GeneratesKeyFrameThenOnlyDeltaFrames) { 274 TEST_P(VideoEncoderTest, GeneratesKeyFrameThenOnlyDeltaFrames) {
153 CreateEncoder(false); 275 CreateEncoder(false);
276 SetVEAFactoryAutoRespond(true);
154 277
155 EXPECT_EQ(0, count_frames_delivered()); 278 EXPECT_EQ(0, count_frames_delivered());
279 ExpectVEAResponsesForExternalVideoEncoder(0, 0);
156 280
157 scoped_refptr<media::VideoFrame> video_frame = 281 uint32 frame_id = 0;
158 CreateTestVideoFrame(gfx::Size(1280, 720)); 282 uint32 reference_frame_id = 0;
159 EXPECT_TRUE(video_encoder()->EncodeVideoFrame( 283 const gfx::Size frame_size(1280, 720);
160 video_frame,
161 Now(),
162 CreateFrameDeliverCallback(
163 0, 0, TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency),
164 Now())));
165 RunTasks();
166 284
167 for (uint32 frame_id = 1; frame_id < 10; ++frame_id) { 285 // For the platform encoders, the first one or more frames is dropped while
168 AdvanceClock(); 286 // the encoder initializes. Then, for all encoders, expect one key frame is
169 video_frame = CreateTestVideoFrame(gfx::Size(1280, 720)); 287 // delivered.
170 EXPECT_TRUE(video_encoder()->EncodeVideoFrame( 288 bool accepted_first_frame = false;
171 video_frame, 289 do {
172 Now(), 290 accepted_first_frame = EncodeAndCheckDelivery(
173 CreateFrameDeliverCallback( 291 CreateTestVideoFrame(frame_size), frame_id, reference_frame_id);
174 frame_id, frame_id - 1, 292 if (!is_testing_platform_encoder())
175 TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency), 293 EXPECT_TRUE(accepted_first_frame);
176 Now()))); 294 RunTasksAndAdvanceClock();
177 RunTasks(); 295 } while (!accepted_first_frame);
296 ExpectVEAResponsesForExternalVideoEncoder(1, 3);
297
298 // Expect the remaining frames are encoded as delta frames.
299 for (++frame_id; frame_id < 10; ++frame_id, ++reference_frame_id) {
300 EXPECT_TRUE(EncodeAndCheckDelivery(CreateTestVideoFrame(frame_size),
301 frame_id,
302 reference_frame_id));
303 RunTasksAndAdvanceClock();
178 } 304 }
179 305
180 EXPECT_EQ(10, count_frames_delivered()); 306 WaitForAllFramesToBeDelivered(10);
307 ExpectVEAResponsesForExternalVideoEncoder(1, 3);
181 } 308 }
182 309
183 // Tests basic frame dependency rules when using the VP8 encoder in multi-buffer 310 // Tests basic frame dependency rules when using the VP8 encoder in multi-buffer
184 // mode. 311 // mode.
185 TEST_P(VideoEncoderImplTest, 312 TEST_P(VideoEncoderTest, FramesDoNotDependOnUnackedFramesInMultiBufferMode) {
186 FramesDoNotDependOnUnackedFramesInMultiBufferMode) { 313 if (!is_testing_software_vp8_encoder())
187 if (GetParam() != CODEC_VIDEO_VP8) 314 return; // Only test multibuffer mode for the software VP8 encoder.
188 return; // Only test multibuffer mode for the VP8 encoder.
189 CreateEncoder(true); 315 CreateEncoder(true);
190 316
191 EXPECT_EQ(0, count_frames_delivered()); 317 EXPECT_EQ(0, count_frames_delivered());
192 318
193 scoped_refptr<media::VideoFrame> video_frame = 319 const gfx::Size frame_size(1280, 720);
194 CreateTestVideoFrame(gfx::Size(1280, 720)); 320 EXPECT_TRUE(EncodeAndCheckDelivery(CreateTestVideoFrame(frame_size), 0, 0));
195 EXPECT_TRUE(video_encoder()->EncodeVideoFrame( 321 RunTasksAndAdvanceClock();
196 video_frame,
197 Now(),
198 CreateFrameDeliverCallback(
199 0, 0, TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency),
200 Now())));
201 RunTasks();
202 322
203 AdvanceClock();
204 video_encoder()->LatestFrameIdToReference(0); 323 video_encoder()->LatestFrameIdToReference(0);
205 video_frame = CreateTestVideoFrame(gfx::Size(1280, 720)); 324 EXPECT_TRUE(EncodeAndCheckDelivery(CreateTestVideoFrame(frame_size), 1, 0));
206 EXPECT_TRUE(video_encoder()->EncodeVideoFrame( 325 RunTasksAndAdvanceClock();
207 video_frame,
208 Now(),
209 CreateFrameDeliverCallback(
210 1, 0, TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency),
211 Now())));
212 RunTasks();
213 326
214 AdvanceClock();
215 video_encoder()->LatestFrameIdToReference(1); 327 video_encoder()->LatestFrameIdToReference(1);
216 video_frame = CreateTestVideoFrame(gfx::Size(1280, 720)); 328 EXPECT_TRUE(EncodeAndCheckDelivery(CreateTestVideoFrame(frame_size), 2, 1));
217 EXPECT_TRUE(video_encoder()->EncodeVideoFrame( 329 RunTasksAndAdvanceClock();
218 video_frame,
219 Now(),
220 CreateFrameDeliverCallback(
221 2, 1, TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency),
222 Now())));
223 RunTasks();
224 330
225 video_encoder()->LatestFrameIdToReference(2); 331 video_encoder()->LatestFrameIdToReference(2);
226 332
227 for (uint32 frame_id = 3; frame_id < 10; ++frame_id) { 333 for (uint32 frame_id = 3; frame_id < 10; ++frame_id) {
228 AdvanceClock(); 334 EXPECT_TRUE(EncodeAndCheckDelivery(
229 video_frame = CreateTestVideoFrame(gfx::Size(1280, 720)); 335 CreateTestVideoFrame(frame_size), frame_id, 2));
230 EXPECT_TRUE(video_encoder()->EncodeVideoFrame( 336 RunTasksAndAdvanceClock();
231 video_frame,
232 Now(),
233 CreateFrameDeliverCallback(
234 frame_id, 2,
235 TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency),
236 Now())));
237 RunTasks();
238 } 337 }
239 338
240 EXPECT_EQ(10, count_frames_delivered()); 339 EXPECT_EQ(10, count_frames_delivered());
241 } 340 }
242 341
243 // Tests that the encoder continues to output EncodedFrames as the frame size 342 // Tests that the encoder continues to output EncodedFrames as the frame size
244 // changes. See media/cast/receiver/video_decoder_unittest.cc for a complete 343 // changes. See media/cast/receiver/video_decoder_unittest.cc for a complete
245 // encode/decode cycle of varied frame sizes that actually checks the frame 344 // encode/decode cycle of varied frame sizes that actually checks the frame
246 // content. 345 // content.
247 TEST_P(VideoEncoderImplTest, EncodesVariedFrameSizes) { 346 TEST_P(VideoEncoderTest, EncodesVariedFrameSizes) {
248 CreateEncoder(false); 347 CreateEncoder(false);
249 ASSERT_TRUE(video_encoder()->CanEncodeVariedFrameSizes()); 348 SetVEAFactoryAutoRespond(true);
250 349
251 EXPECT_EQ(0, count_frames_delivered()); 350 EXPECT_EQ(0, count_frames_delivered());
351 ExpectVEAResponsesForExternalVideoEncoder(0, 0);
252 352
253 std::vector<gfx::Size> frame_sizes; 353 std::vector<gfx::Size> frame_sizes;
254 frame_sizes.push_back(gfx::Size(1280, 720)); 354 frame_sizes.push_back(gfx::Size(1280, 720));
255 frame_sizes.push_back(gfx::Size(640, 360)); // Shrink both dimensions. 355 frame_sizes.push_back(gfx::Size(640, 360)); // Shrink both dimensions.
256 frame_sizes.push_back(gfx::Size(300, 200)); // Shrink both dimensions again. 356 frame_sizes.push_back(gfx::Size(300, 200)); // Shrink both dimensions again.
257 frame_sizes.push_back(gfx::Size(200, 300)); // Same area. 357 frame_sizes.push_back(gfx::Size(200, 300)); // Same area.
258 frame_sizes.push_back(gfx::Size(600, 400)); // Grow both dimensions. 358 frame_sizes.push_back(gfx::Size(600, 400)); // Grow both dimensions.
259 frame_sizes.push_back(gfx::Size(638, 400)); // Shrink only one dimension. 359 frame_sizes.push_back(gfx::Size(638, 400)); // Shrink only one dimension.
260 frame_sizes.push_back(gfx::Size(638, 398)); // Shrink the other dimension. 360 frame_sizes.push_back(gfx::Size(638, 398)); // Shrink the other dimension.
261 frame_sizes.push_back(gfx::Size(320, 180)); // Shrink both dimensions again. 361 frame_sizes.push_back(gfx::Size(320, 180)); // Shrink both dimensions again.
262 frame_sizes.push_back(gfx::Size(322, 180)); // Grow only one dimension. 362 frame_sizes.push_back(gfx::Size(322, 180)); // Grow only one dimension.
263 frame_sizes.push_back(gfx::Size(322, 182)); // Grow the other dimension. 363 frame_sizes.push_back(gfx::Size(322, 182)); // Grow the other dimension.
264 frame_sizes.push_back(gfx::Size(1920, 1080)); // Grow both dimensions again. 364 frame_sizes.push_back(gfx::Size(1920, 1080)); // Grow both dimensions again.
265 365
266 uint32 frame_id = 0; 366 uint32 frame_id = 0;
267 367
268 // Encode one frame at each size. Expect nothing but key frames to come out. 368 // Encode one frame at each size. For the platform encoders, expect no frames
369 // to be delivered since each frame size change will sprun re-initialization
370 // of the underlying encoder. Otherwise, expect all key frames to come out.
269 for (const auto& frame_size : frame_sizes) { 371 for (const auto& frame_size : frame_sizes) {
270 AdvanceClock(); 372 EXPECT_EQ(!is_testing_platform_encoder(),
271 const scoped_refptr<media::VideoFrame> video_frame = 373 EncodeAndCheckDelivery(CreateTestVideoFrame(frame_size),
272 CreateTestVideoFrame(frame_size); 374 frame_id,
273 EXPECT_TRUE(video_encoder()->EncodeVideoFrame( 375 frame_id));
274 video_frame, 376 RunTasksAndAdvanceClock();
275 Now(), 377 if (!is_testing_platform_encoder())
276 CreateFrameDeliverCallback( 378 ++frame_id;
277 frame_id,
278 frame_id,
279 TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency),
280 Now())));
281 RunTasks();
282 ++frame_id;
283 } 379 }
284 380
285 // Encode 10 frames at each size. Expect one key frame followed by nine delta 381 // Encode 10+ frames at each size. For the platform decoders, expect the
286 // frames for each frame size. 382 // first one or more frames are dropped while the encoder re-inits. Then, for
383 // all encoders, expect one key frame followed by all delta frames.
287 for (const auto& frame_size : frame_sizes) { 384 for (const auto& frame_size : frame_sizes) {
288 for (int i = 0; i < 10; ++i) { 385 bool accepted_first_frame = false;
289 AdvanceClock(); 386 do {
290 const scoped_refptr<media::VideoFrame> video_frame = 387 accepted_first_frame = EncodeAndCheckDelivery(
291 CreateTestVideoFrame(frame_size); 388 CreateTestVideoFrame(frame_size), frame_id, frame_id);
292 EXPECT_TRUE(video_encoder()->EncodeVideoFrame( 389 if (!is_testing_platform_encoder())
293 video_frame, 390 EXPECT_TRUE(accepted_first_frame);
294 Now(), 391 RunTasksAndAdvanceClock();
295 CreateFrameDeliverCallback( 392 } while (!accepted_first_frame);
296 frame_id, 393 ++frame_id;
297 i == 0 ? frame_id : frame_id - 1, 394 for (int i = 1; i < 10; ++i, ++frame_id) {
298 TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency), 395 EXPECT_TRUE(EncodeAndCheckDelivery(CreateTestVideoFrame(frame_size),
299 Now()))); 396 frame_id,
300 RunTasks(); 397 frame_id - 1));
301 ++frame_id; 398 RunTasksAndAdvanceClock();
302 } 399 }
303 } 400 }
304 401
305 EXPECT_EQ(static_cast<int>(frame_id), count_frames_delivered()); 402 WaitForAllFramesToBeDelivered(10 * frame_sizes.size());
403 ExpectVEAResponsesForExternalVideoEncoder(
404 2 * frame_sizes.size(), 6 * frame_sizes.size());
306 } 405 }
307 406
308 INSTANTIATE_TEST_CASE_P(, 407 // Verify that everything goes well even if ExternalVideoEncoder is destroyed
309 VideoEncoderImplTest, 408 // before it has a chance to receive the VEA creation callback. For all other
310 ::testing::Values(CODEC_VIDEO_FAKE, CODEC_VIDEO_VP8)); 409 // encoders, this tests that the encoder can be safely destroyed before the task
410 // is run that delivers the first EncodedFrame.
411 TEST_P(VideoEncoderTest, CanBeDestroyedBeforeVEAIsCreated) {
412 CreateEncoder(false);
413
414 // Send a frame to spawn creation of the ExternalVideoEncoder instance.
415 EncodeAndCheckDelivery(CreateTestVideoFrame(gfx::Size(1280, 720)), 0, 0);
416
417 // Destroy the encoder, and confirm the VEA Factory did not respond yet.
418 DestroyEncoder();
419 ExpectVEAResponsesForExternalVideoEncoder(0, 0);
420
421 // Allow the VEA Factory to respond by running the creation callback. When
422 // the task runs, it will be a no-op since the weak pointers to the
423 // ExternalVideoEncoder were invalidated.
424 SetVEAFactoryAutoRespond(true);
425 RunTasksAndAdvanceClock();
426 ExpectVEAResponsesForExternalVideoEncoder(1, 0);
427 }
428
429 namespace {
430 std::vector<std::pair<Codec, bool>> DetermineEncodersToTest() {
431 std::vector<std::pair<Codec, bool>> values;
432 // Fake encoder.
433 values.push_back(std::make_pair(CODEC_VIDEO_FAKE, false));
434 // Software VP8 encoder.
435 values.push_back(std::make_pair(CODEC_VIDEO_VP8, false));
436 // Hardware-accelerated encoder (faked).
437 values.push_back(std::make_pair(CODEC_VIDEO_VP8, true));
438 #if defined(OS_MACOSX)
439 // VideoToolbox encoder (when VideoToolbox is present).
440 VideoSenderConfig video_config = GetDefaultVideoSenderConfig();
441 video_config.use_external_encoder = false;
442 video_config.codec = CODEC_VIDEO_H264;
443 if (H264VideoToolboxEncoder::IsSupported(video_config))
444 values.push_back(std::make_pair(CODEC_VIDEO_H264, false));
445 #endif
446 return values;
447 }
448 } // namespace
449
450 INSTANTIATE_TEST_CASE_P(
451 , VideoEncoderTest, ::testing::ValuesIn(DetermineEncodersToTest()));
311 452
312 } // namespace cast 453 } // namespace cast
313 } // namespace media 454 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/sender/video_encoder_impl_unittest.cc ('k') | media/cast/sender/video_frame_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698