Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 "base/macros.h" | 5 #include "base/macros.h" |
| 6 #include "base/message_loop/message_loop.h" | 6 #include "base/message_loop/message_loop.h" |
| 7 #include "base/test/test_mock_time_task_runner.h" | |
| 8 #include "base/threading/thread_task_runner_handle.h" | |
| 7 #include "media/base/android/media_codec_bridge.h" | 9 #include "media/base/android/media_codec_bridge.h" |
| 8 #include "media/base/android/media_codec_loop.h" | 10 #include "media/base/android/media_codec_loop.h" |
| 9 #include "media/base/android/mock_media_codec_bridge.h" | 11 #include "media/base/android/mock_media_codec_bridge.h" |
| 10 #include "media/base/fake_single_thread_task_runner.h" | |
| 11 #include "testing/gmock/include/gmock/gmock.h" | 12 #include "testing/gmock/include/gmock/gmock.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 14 |
| 14 using ::testing::_; | 15 using ::testing::_; |
| 15 using ::testing::AtLeast; | 16 using ::testing::AtLeast; |
| 16 using ::testing::Eq; | 17 using ::testing::Eq; |
| 17 using ::testing::Field; | 18 using ::testing::Field; |
| 18 using ::testing::InSequence; | 19 using ::testing::InSequence; |
| 19 using ::testing::Mock; | 20 using ::testing::Mock; |
| 20 using ::testing::Return; | 21 using ::testing::Return; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 39 MOCK_METHOD1(OnInputDataQueued, void(bool)); | 40 MOCK_METHOD1(OnInputDataQueued, void(bool)); |
| 40 MOCK_METHOD1(OnDecodedEos, void(const MediaCodecLoop::OutputBuffer&)); | 41 MOCK_METHOD1(OnDecodedEos, void(const MediaCodecLoop::OutputBuffer&)); |
| 41 MOCK_METHOD1(OnDecodedFrame, bool(const MediaCodecLoop::OutputBuffer&)); | 42 MOCK_METHOD1(OnDecodedFrame, bool(const MediaCodecLoop::OutputBuffer&)); |
| 42 MOCK_METHOD0(OnOutputFormatChanged, bool()); | 43 MOCK_METHOD0(OnOutputFormatChanged, bool()); |
| 43 MOCK_METHOD0(OnCodecLoopError, void()); | 44 MOCK_METHOD0(OnCodecLoopError, void()); |
| 44 }; | 45 }; |
| 45 | 46 |
| 46 class MediaCodecLoopTest : public testing::Test { | 47 class MediaCodecLoopTest : public testing::Test { |
| 47 public: | 48 public: |
| 48 MediaCodecLoopTest() | 49 MediaCodecLoopTest() |
| 49 : client_(new StrictMock<MockMediaCodecLoopClient>()), | 50 : task_runner_handle_(mock_task_runner_), |
| 50 task_runner_(new FakeSingleThreadTaskRunner(&clock_)) {} | 51 client_(new StrictMock<MockMediaCodecLoopClient>()) {} |
| 51 | 52 |
| 52 ~MediaCodecLoopTest() override {} | 53 ~MediaCodecLoopTest() override {} |
| 53 | 54 |
| 54 protected: | 55 protected: |
| 55 enum IdleExpectation { | 56 enum IdleExpectation { |
| 56 ShouldBeIdle, | 57 ShouldBeIdle, |
| 57 ShouldNotBeIdle, | 58 ShouldNotBeIdle, |
| 58 }; | 59 }; |
| 59 | 60 |
| 60 // Wait until |codec_loop_| is idle. | 61 // Wait until |codec_loop_| is idle. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 77 break; | 78 break; |
| 78 } | 79 } |
| 79 | 80 |
| 80 // Either way, we expect that MCL should not attempt to dequeue input | 81 // Either way, we expect that MCL should not attempt to dequeue input |
| 81 // buffers, either because it's idle or because we said that no input | 82 // buffers, either because it's idle or because we said that no input |
| 82 // is pending. | 83 // is pending. |
| 83 EXPECT_CALL(Codec(), DequeueInputBuffer(_, _)).Times(0); | 84 EXPECT_CALL(Codec(), DequeueInputBuffer(_, _)).Times(0); |
| 84 | 85 |
| 85 // TODO(liberato): assume that MCL doesn't retry for 30 seconds. Note | 86 // TODO(liberato): assume that MCL doesn't retry for 30 seconds. Note |
| 86 // that this doesn't actually wall-clock wait. | 87 // that this doesn't actually wall-clock wait. |
| 87 task_runner_->Sleep(base::TimeDelta::FromSeconds(30)); | 88 mock_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(30)); |
| 88 } | 89 } |
| 89 | 90 |
| 90 void ConstructCodecLoop(int sdk_int = kLollipop) { | 91 void ConstructCodecLoop(int sdk_int = kLollipop) { |
| 91 std::unique_ptr<MediaCodecBridge> codec(new MockMediaCodecBridge()); | 92 std::unique_ptr<MediaCodecBridge> codec(new MockMediaCodecBridge()); |
| 92 // Since we're providing a codec, we do not expect an error. | 93 // Since we're providing a codec, we do not expect an error. |
| 93 EXPECT_CALL(*client_, OnCodecLoopError()).Times(0); | 94 EXPECT_CALL(*client_, OnCodecLoopError()).Times(0); |
| 94 codec_loop_.reset(new MediaCodecLoop(sdk_int, client_.get(), | 95 codec_loop_.reset(new MediaCodecLoop(sdk_int, client_.get(), |
| 95 std::move(codec), task_runner_)); | 96 std::move(codec), mock_task_runner_)); |
| 96 codec_loop_->SetTestTickClock(&clock_); | 97 codec_loop_->SetTestTickClock(clock_.get()); |
| 97 Mock::VerifyAndClearExpectations(client_.get()); | 98 Mock::VerifyAndClearExpectations(client_.get()); |
| 98 } | 99 } |
| 99 | 100 |
| 100 // Set an expectation that MCL will try to get another input / output buffer, | 101 // Set an expectation that MCL will try to get another input / output buffer, |
| 101 // and not get one in DoPendingWork. | 102 // and not get one in DoPendingWork. |
| 102 void ExpectEmptyIOLoop() { | 103 void ExpectEmptyIOLoop() { |
| 103 ExpectIsAnyInputPending(false); | 104 ExpectIsAnyInputPending(false); |
| 104 EXPECT_CALL(Codec(), DequeueOutputBuffer(_, _, _, _, _, _, _)) | 105 EXPECT_CALL(Codec(), DequeueOutputBuffer(_, _, _, _, _, _, _)) |
| 105 .Times(1) | 106 .Times(1) |
| 106 .WillOnce(Return(MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER)); | 107 .WillOnce(Return(MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER)); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 Field(&MediaCodecLoop::OutputBuffer::index, Eq(buf.index)))) | 176 Field(&MediaCodecLoop::OutputBuffer::index, Eq(buf.index)))) |
| 176 .Times(1) | 177 .Times(1) |
| 177 .WillOnce(Return(true)); | 178 .WillOnce(Return(true)); |
| 178 } | 179 } |
| 179 | 180 |
| 180 MockMediaCodecBridge& Codec() { | 181 MockMediaCodecBridge& Codec() { |
| 181 return *static_cast<MockMediaCodecBridge*>(codec_loop_->GetCodec()); | 182 return *static_cast<MockMediaCodecBridge*>(codec_loop_->GetCodec()); |
| 182 } | 183 } |
| 183 | 184 |
| 184 public: | 185 public: |
| 186 // Mocks the current thread's task runner which will also be used as the | |
| 187 // MediaCodecLoop's task runner. | |
| 188 scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_ = | |
| 189 new base::TestMockTimeTaskRunner; | |
|
DaleCurtis
2017/01/25 22:33:25
()
gab
2017/02/13 19:57:00
Why? It's valid C++ without the brackets.
DaleCurtis
2017/02/13 21:03:23
Consistency with surrounding code? I thought we ha
| |
| 190 base::ThreadTaskRunnerHandle task_runner_handle_; | |
| 191 | |
| 192 // A reference to |mock_task_runner_|'s TickClock handed to |codec_loop_|. | |
| 193 std::unique_ptr<base::TickClock> clock_ = | |
| 194 mock_task_runner_->GetMockTickClock(); | |
| 195 | |
| 185 std::unique_ptr<MediaCodecLoop> codec_loop_; | 196 std::unique_ptr<MediaCodecLoop> codec_loop_; |
| 186 std::unique_ptr<MockMediaCodecLoopClient> client_; | 197 std::unique_ptr<MockMediaCodecLoopClient> client_; |
| 187 // TODO: how is the lifecycle of |clock_| handled? |task_runner_| can outlive | |
| 188 // us, since it's a refptr. | |
| 189 base::SimpleTestTickClock clock_; | |
| 190 scoped_refptr<FakeSingleThreadTaskRunner> task_runner_; | |
| 191 | 198 |
| 192 DISALLOW_COPY_AND_ASSIGN(MediaCodecLoopTest); | 199 DISALLOW_COPY_AND_ASSIGN(MediaCodecLoopTest); |
| 193 }; | 200 }; |
| 194 | 201 |
| 195 TEST_F(MediaCodecLoopTest, TestConstructionWithNullCodec) { | 202 TEST_F(MediaCodecLoopTest, TestConstructionWithNullCodec) { |
| 196 std::unique_ptr<MediaCodecBridge> codec; | 203 std::unique_ptr<MediaCodecBridge> codec; |
| 197 EXPECT_CALL(*client_, OnCodecLoopError()).Times(1); | 204 EXPECT_CALL(*client_, OnCodecLoopError()).Times(1); |
| 198 const int sdk_int = kLollipop; | 205 const int sdk_int = kLollipop; |
| 199 codec_loop_.reset( | 206 codec_loop_.reset( |
| 200 new MediaCodecLoop(sdk_int, client_.get(), std::move(codec))); | 207 new MediaCodecLoop(sdk_int, client_.get(), std::move(codec))); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 | 464 |
| 458 // MCL did work, so it will try again. | 465 // MCL did work, so it will try again. |
| 459 ExpectEmptyIOLoop(); | 466 ExpectEmptyIOLoop(); |
| 460 } | 467 } |
| 461 | 468 |
| 462 codec_loop_->OnKeyAdded(); | 469 codec_loop_->OnKeyAdded(); |
| 463 WaitUntilIdle(ShouldNotBeIdle); | 470 WaitUntilIdle(ShouldNotBeIdle); |
| 464 } | 471 } |
| 465 | 472 |
| 466 } // namespace media | 473 } // namespace media |
| OLD | NEW |