1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/filters/fake_video_decoder.h"
10 #include "base/functional/bind.h"
11 #include "base/functional/callback_helpers.h"
12 #include "base/run_loop.h"
13 #include "base/test/task_environment.h"
14 #include "media/base/decoder_buffer.h"
15 #include "media/base/mock_filters.h"
16 #include "media/base/test_helpers.h"
17 #include "media/base/video_frame.h"
18 #include "testing/gtest/include/gtest/gtest.h"
22 static const int kTotalBuffers = 12;
23 static const int kDurationMs = 30;
25 struct FakeVideoDecoderTestParams {
26 FakeVideoDecoderTestParams(int decoding_delay, int max_decode_requests)
27 : decoding_delay(decoding_delay),
28 max_decode_requests(max_decode_requests) {}
30 int max_decode_requests;
33 class FakeVideoDecoderTest
34 : public testing::Test,
35 public testing::WithParamInterface<FakeVideoDecoderTestParams> {
37 FakeVideoDecoderTest()
38 : decoder_(std::make_unique<FakeVideoDecoder>(
40 GetParam().decoding_delay,
41 GetParam().max_decode_requests,
42 base::BindRepeating(&FakeVideoDecoderTest::OnBytesDecoded,
43 base::Unretained(this)))),
44 num_input_buffers_(0),
45 num_decoded_frames_(0),
46 num_bytes_decoded_(0),
47 total_bytes_in_buffers_(0),
48 last_decode_status_(DecoderStatus::Codes::kOk),
49 pending_decode_requests_(0),
50 is_reset_pending_(false) {}
52 FakeVideoDecoderTest(const FakeVideoDecoderTest&) = delete;
53 FakeVideoDecoderTest& operator=(const FakeVideoDecoderTest&) = delete;
55 virtual ~FakeVideoDecoderTest() {
59 void InitializeWithConfigAndExpectResult(const VideoDecoderConfig& config,
61 decoder_->Initialize(config, false, nullptr,
63 [](bool success, DecoderStatus status) {
64 EXPECT_EQ(status.is_ok(), success);
67 base::BindRepeating(&FakeVideoDecoderTest::FrameReady,
68 base::Unretained(this)),
69 base::NullCallback());
70 base::RunLoop().RunUntilIdle();
71 current_config_ = config;
75 InitializeWithConfigAndExpectResult(TestVideoConfig::Normal(), true);
78 void EnterPendingInitState() {
79 decoder_->HoldNextInit();
84 decoder_->SatisfyInit();
85 base::RunLoop().RunUntilIdle();
88 // Callback for VideoDecoder::Decode().
89 void DecodeDone(DecoderStatus status) {
90 DCHECK_GT(pending_decode_requests_, 0);
91 --pending_decode_requests_;
92 last_decode_status_ = std::move(status);
95 void FrameReady(scoped_refptr<VideoFrame> frame) {
96 DCHECK(!frame->metadata().end_of_stream);
97 last_decoded_frame_ = std::move(frame);
98 num_decoded_frames_++;
101 void OnBytesDecoded(int count) {
102 num_bytes_decoded_ += count;
105 enum CallbackResult {
112 void ExpectReadResult(CallbackResult result) {
115 EXPECT_GT(pending_decode_requests_, 0);
118 EXPECT_EQ(0, pending_decode_requests_);
119 ASSERT_TRUE(last_decode_status_.is_ok());
120 ASSERT_TRUE(last_decoded_frame_.get());
122 case NOT_ENOUGH_DATA:
123 EXPECT_EQ(0, pending_decode_requests_);
124 ASSERT_TRUE(last_decode_status_.is_ok());
125 ASSERT_FALSE(last_decoded_frame_.get());
128 EXPECT_EQ(0, pending_decode_requests_);
129 ASSERT_EQ(DecoderStatus::Codes::kAborted, last_decode_status_.code());
130 EXPECT_FALSE(last_decoded_frame_.get());
136 scoped_refptr<DecoderBuffer> buffer;
138 if (num_input_buffers_ < kTotalBuffers) {
139 buffer = CreateFakeVideoBufferForTest(
140 current_config_, base::Milliseconds(kDurationMs * num_input_buffers_),
141 base::Milliseconds(kDurationMs));
142 total_bytes_in_buffers_ += buffer->data_size();
144 buffer = DecoderBuffer::CreateEOSBuffer();
147 ++num_input_buffers_;
148 ++pending_decode_requests_;
150 decoder_->Decode(buffer, base::BindOnce(&FakeVideoDecoderTest::DecodeDone,
151 base::Unretained(this)));
152 base::RunLoop().RunUntilIdle();
155 void ReadOneFrame() {
156 last_decoded_frame_.reset();
159 } while (!last_decoded_frame_.get() && pending_decode_requests_ == 0);
162 void ReadAllFrames() {
165 } while (num_input_buffers_ <= kTotalBuffers); // All input buffers + EOS.
168 void EnterPendingReadState() {
169 // Pass the initial NOT_ENOUGH_DATA stage.
171 decoder_->HoldDecode();
173 ExpectReadResult(PENDING);
176 void SatisfyDecodeAndExpect(CallbackResult result) {
177 decoder_->SatisfyDecode();
178 base::RunLoop().RunUntilIdle();
179 ExpectReadResult(result);
183 SatisfyDecodeAndExpect(OK);
186 // Callback for VideoDecoder::Reset().
187 void OnDecoderReset() {
188 DCHECK(is_reset_pending_);
189 is_reset_pending_ = false;
192 void ExpectResetResult(CallbackResult result) {
195 EXPECT_TRUE(is_reset_pending_);
198 EXPECT_FALSE(is_reset_pending_);
205 void ResetAndExpect(CallbackResult result) {
206 is_reset_pending_ = true;
207 decoder_->Reset(base::BindOnce(&FakeVideoDecoderTest::OnDecoderReset,
208 base::Unretained(this)));
209 base::RunLoop().RunUntilIdle();
210 ExpectResetResult(result);
213 void EnterPendingResetState() {
214 decoder_->HoldNextReset();
215 ResetAndExpect(PENDING);
218 void SatisfyReset() {
219 decoder_->SatisfyReset();
220 base::RunLoop().RunUntilIdle();
221 ExpectResetResult(OK);
226 base::RunLoop().RunUntilIdle();
228 // All pending callbacks must have been fired.
229 DCHECK_EQ(pending_decode_requests_, 0);
230 DCHECK(!is_reset_pending_);
233 base::test::SingleThreadTaskEnvironment task_environment_;
234 VideoDecoderConfig current_config_;
236 std::unique_ptr<FakeVideoDecoder> decoder_;
238 int num_input_buffers_;
239 int num_decoded_frames_;
240 int num_bytes_decoded_;
241 int total_bytes_in_buffers_;
243 // Callback result/status.
244 DecoderStatus last_decode_status_;
245 scoped_refptr<VideoFrame> last_decoded_frame_;
246 int pending_decode_requests_;
247 bool is_reset_pending_;
250 INSTANTIATE_TEST_SUITE_P(NoParallelDecode,
251 FakeVideoDecoderTest,
252 ::testing::Values(FakeVideoDecoderTestParams(9, 1),
253 FakeVideoDecoderTestParams(0, 1)));
254 INSTANTIATE_TEST_SUITE_P(ParallelDecode,
255 FakeVideoDecoderTest,
256 ::testing::Values(FakeVideoDecoderTestParams(9, 3),
257 FakeVideoDecoderTestParams(0, 3)));
259 TEST_P(FakeVideoDecoderTest, Initialize) {
263 TEST_P(FakeVideoDecoderTest, SimulateFailureToInitialize) {
264 decoder_->SimulateFailureToInit();
265 InitializeWithConfigAndExpectResult(TestVideoConfig::Normal(), false);
267 EXPECT_THAT(last_decode_status_, IsDecodeErrorStatus());
270 TEST_P(FakeVideoDecoderTest, Read_AllFrames) {
273 EXPECT_EQ(kTotalBuffers, num_decoded_frames_);
274 EXPECT_EQ(total_bytes_in_buffers_, num_bytes_decoded_);
277 TEST_P(FakeVideoDecoderTest, Read_DecodingDelay) {
280 while (num_input_buffers_ < kTotalBuffers) {
282 EXPECT_EQ(num_input_buffers_,
283 num_decoded_frames_ + GetParam().decoding_delay);
287 TEST_P(FakeVideoDecoderTest, Read_ZeroDelay) {
288 decoder_ = std::make_unique<FakeVideoDecoder>(
290 base::BindRepeating(&FakeVideoDecoderTest::OnBytesDecoded,
291 base::Unretained(this)));
294 while (num_input_buffers_ < kTotalBuffers) {
296 EXPECT_EQ(num_input_buffers_, num_decoded_frames_);
300 TEST_P(FakeVideoDecoderTest, Read_Pending_NotEnoughData) {
301 if (GetParam().decoding_delay < 1)
305 decoder_->HoldDecode();
307 ExpectReadResult(PENDING);
308 SatisfyDecodeAndExpect(NOT_ENOUGH_DATA);
310 // Verify that FrameReady() hasn't been called.
311 EXPECT_FALSE(last_decoded_frame_.get());
314 TEST_P(FakeVideoDecoderTest, Read_Pending_OK) {
316 EnterPendingReadState();
317 SatisfyDecodeAndExpect(OK);
320 TEST_P(FakeVideoDecoderTest, Read_Parallel) {
321 if (GetParam().max_decode_requests < 2)
325 decoder_->HoldDecode();
326 for (int i = 0; i < GetParam().max_decode_requests; ++i) {
328 ExpectReadResult(PENDING);
330 EXPECT_EQ(GetParam().max_decode_requests, pending_decode_requests_);
331 SatisfyDecodeAndExpect(
332 GetParam().max_decode_requests > GetParam().decoding_delay
337 TEST_P(FakeVideoDecoderTest, ReadWithHold_DecodingDelay) {
340 // Hold all decodes and satisfy one decode at a time.
341 decoder_->HoldDecode();
342 int num_decodes_satisfied = 0;
343 while (num_decoded_frames_ == 0) {
344 while (pending_decode_requests_ < decoder_->GetMaxDecodeRequests())
346 decoder_->SatisfySingleDecode();
347 ++num_decodes_satisfied;
348 base::RunLoop().RunUntilIdle();
351 DCHECK_EQ(num_decoded_frames_, 1);
352 DCHECK_EQ(num_decodes_satisfied, GetParam().decoding_delay + 1);
355 TEST_P(FakeVideoDecoderTest, Reinitialize) {
358 InitializeWithConfigAndExpectResult(TestVideoConfig::Large(), true);
362 TEST_P(FakeVideoDecoderTest, SimulateFailureToReinitialize) {
365 decoder_->SimulateFailureToInit();
366 InitializeWithConfigAndExpectResult(TestVideoConfig::Normal(), false);
368 EXPECT_THAT(last_decode_status_, IsDecodeErrorStatus());
371 // Reinitializing the decoder during the middle of the decoding process can
372 // cause dropped frames.
373 TEST_P(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
374 if (GetParam().decoding_delay < 1)
381 EXPECT_LT(num_decoded_frames_, kTotalBuffers);
384 TEST_P(FakeVideoDecoderTest, Reset) {
390 TEST_P(FakeVideoDecoderTest, Reset_DuringPendingRead) {
392 EnterPendingReadState();
393 ResetAndExpect(PENDING);
394 SatisfyDecodeAndExpect(ABORTED);
397 TEST_P(FakeVideoDecoderTest, Reset_Pending) {
399 EnterPendingResetState();
403 TEST_P(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) {
405 EnterPendingReadState();
406 EnterPendingResetState();
407 SatisfyDecodeAndExpect(ABORTED);
411 TEST_P(FakeVideoDecoderTest, Destroy) {
414 ExpectReadResult(OK);
418 TEST_P(FakeVideoDecoderTest, Destroy_DuringPendingInitialization) {
419 EnterPendingInitState();
423 TEST_P(FakeVideoDecoderTest, Destroy_DuringPendingRead) {
425 EnterPendingReadState();
429 TEST_P(FakeVideoDecoderTest, Destroy_DuringPendingReset) {
431 EnterPendingResetState();
435 TEST_P(FakeVideoDecoderTest, Destroy_DuringPendingReadAndPendingReset) {
437 EnterPendingReadState();
438 EnterPendingResetState();