Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / renderer / media / rtc_video_decoder_unittest.cc
blob98b4e52bc01cd681c4118f693a3cf736ebfef0db
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/location.h"
7 #include "base/single_thread_task_runner.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "base/threading/thread.h"
11 #include "content/renderer/media/rtc_video_decoder.h"
12 #include "media/base/gmock_callback_support.h"
13 #include "media/renderers/mock_gpu_video_accelerator_factories.h"
14 #include "media/video/mock_video_decode_accelerator.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 using ::testing::_;
18 using ::testing::Invoke;
19 using ::testing::Return;
20 using ::testing::SaveArg;
21 using ::testing::WithArgs;
23 namespace content {
25 // TODO(wuchengli): add MockSharedMemroy so more functions can be tested.
26 class RTCVideoDecoderTest : public ::testing::Test,
27 webrtc::DecodedImageCallback {
28 public:
29 RTCVideoDecoderTest()
30 : mock_gpu_factories_(new media::MockGpuVideoAcceleratorFactories),
31 vda_thread_("vda_thread"),
32 idle_waiter_(false, false) {
33 memset(&codec_, 0, sizeof(codec_));
36 void SetUp() override {
37 ASSERT_TRUE(vda_thread_.Start());
38 vda_task_runner_ = vda_thread_.task_runner();
39 mock_vda_ = new media::MockVideoDecodeAccelerator;
41 media::VideoDecodeAccelerator::SupportedProfile supported_profile;
42 supported_profile.min_resolution.SetSize(16, 16);
43 supported_profile.max_resolution.SetSize(1920, 1088);
44 supported_profile.profile = media::H264PROFILE_MAIN;
45 supported_profiles_.push_back(supported_profile);
46 supported_profile.profile = media::VP8PROFILE_ANY;
47 supported_profiles_.push_back(supported_profile);
49 EXPECT_CALL(*mock_gpu_factories_.get(), GetTaskRunner())
50 .WillRepeatedly(Return(vda_task_runner_));
51 EXPECT_CALL(*mock_gpu_factories_.get(),
52 GetVideoDecodeAcceleratorSupportedProfiles())
53 .WillRepeatedly(Return(supported_profiles_));
54 EXPECT_CALL(*mock_gpu_factories_.get(), DoCreateVideoDecodeAccelerator())
55 .WillRepeatedly(Return(mock_vda_));
56 EXPECT_CALL(*mock_vda_, Initialize(_, _))
57 .Times(1)
58 .WillRepeatedly(Return(true));
59 EXPECT_CALL(*mock_vda_, Destroy()).Times(1);
62 void TearDown() override {
63 DVLOG(2) << "TearDown";
64 EXPECT_TRUE(vda_thread_.IsRunning());
65 RunUntilIdle(); // Wait until all callbascks complete.
66 vda_task_runner_->DeleteSoon(FROM_HERE, rtc_decoder_.release());
67 // Make sure the decoder is released before stopping the thread.
68 RunUntilIdle();
69 vda_thread_.Stop();
72 int32_t Decoded(webrtc::VideoFrame& decoded_image) override {
73 DVLOG(2) << "Decoded";
74 EXPECT_EQ(vda_task_runner_, base::ThreadTaskRunnerHandle::Get());
75 return WEBRTC_VIDEO_CODEC_OK;
78 void CreateDecoder(webrtc::VideoCodecType codec_type) {
79 DVLOG(2) << "CreateDecoder";
80 codec_.codecType = codec_type;
81 rtc_decoder_ =
82 RTCVideoDecoder::Create(codec_type, mock_gpu_factories_);
85 void Initialize() {
86 DVLOG(2) << "Initialize";
87 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1));
88 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
89 rtc_decoder_->RegisterDecodeCompleteCallback(this));
92 void NotifyResetDone() {
93 DVLOG(2) << "NotifyResetDone";
94 vda_task_runner_->PostTask(
95 FROM_HERE,
96 base::Bind(&RTCVideoDecoder::NotifyResetDone,
97 base::Unretained(rtc_decoder_.get())));
100 void RunUntilIdle() {
101 DVLOG(2) << "RunUntilIdle";
102 vda_task_runner_->PostTask(FROM_HERE,
103 base::Bind(&base::WaitableEvent::Signal,
104 base::Unretained(&idle_waiter_)));
105 idle_waiter_.Wait();
108 protected:
109 scoped_refptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_;
110 media::MockVideoDecodeAccelerator* mock_vda_;
111 scoped_ptr<RTCVideoDecoder> rtc_decoder_;
112 webrtc::VideoCodec codec_;
113 base::Thread vda_thread_;
114 media::VideoDecodeAccelerator::SupportedProfiles supported_profiles_;
116 private:
117 scoped_refptr<base::SingleThreadTaskRunner> vda_task_runner_;
119 base::Lock lock_;
120 base::WaitableEvent idle_waiter_;
123 TEST_F(RTCVideoDecoderTest, CreateReturnsNullOnUnsupportedCodec) {
124 CreateDecoder(webrtc::kVideoCodecVP8);
125 scoped_ptr<RTCVideoDecoder> null_rtc_decoder(
126 RTCVideoDecoder::Create(webrtc::kVideoCodecI420, mock_gpu_factories_));
127 EXPECT_EQ(NULL, null_rtc_decoder.get());
130 TEST_F(RTCVideoDecoderTest, CreateAndInitSucceedsForH264Codec) {
131 CreateDecoder(webrtc::kVideoCodecH264);
132 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1));
135 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) {
136 CreateDecoder(webrtc::kVideoCodecVP8);
137 codec_.codecSpecific.VP8.feedbackModeOn = true;
138 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1));
141 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) {
142 CreateDecoder(webrtc::kVideoCodecVP8);
143 webrtc::EncodedImage input_image;
144 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
145 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0));
148 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnIncompleteFrame) {
149 CreateDecoder(webrtc::kVideoCodecVP8);
150 Initialize();
151 webrtc::EncodedImage input_image;
152 input_image._completeFrame = false;
153 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
154 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0));
157 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) {
158 CreateDecoder(webrtc::kVideoCodecVP8);
159 Initialize();
160 webrtc::EncodedImage input_image;
161 input_image._completeFrame = true;
162 bool missingFrames = true;
163 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
164 rtc_decoder_->Decode(input_image, missingFrames, NULL, NULL, 0));
167 TEST_F(RTCVideoDecoderTest, ResetReturnsOk) {
168 CreateDecoder(webrtc::kVideoCodecVP8);
169 Initialize();
170 EXPECT_CALL(*mock_vda_, Reset())
171 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
172 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Reset());
175 TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) {
176 CreateDecoder(webrtc::kVideoCodecVP8);
177 Initialize();
178 EXPECT_CALL(*mock_vda_, Reset())
179 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
180 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
183 TEST_F(RTCVideoDecoderTest, InitDecodeAfterRelease) {
184 CreateDecoder(webrtc::kVideoCodecVP8);
185 EXPECT_CALL(*mock_vda_, Reset())
186 .WillRepeatedly(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
187 Initialize();
188 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
189 Initialize();
190 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
193 TEST_F(RTCVideoDecoderTest, IsBufferAfterReset) {
194 CreateDecoder(webrtc::kVideoCodecVP8);
195 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_INVALID));
196 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
197 RTCVideoDecoder::ID_INVALID));
198 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF - 2,
199 RTCVideoDecoder::ID_HALF + 2));
200 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF + 2,
201 RTCVideoDecoder::ID_HALF - 2));
203 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(0, 0));
204 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_LAST));
205 EXPECT_FALSE(
206 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF - 2));
207 EXPECT_TRUE(
208 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF + 2));
210 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 0));
211 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
212 RTCVideoDecoder::ID_HALF - 2));
213 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
214 RTCVideoDecoder::ID_HALF + 2));
215 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
216 RTCVideoDecoder::ID_LAST));
219 TEST_F(RTCVideoDecoderTest, IsFirstBufferAfterReset) {
220 CreateDecoder(webrtc::kVideoCodecVP8);
221 EXPECT_TRUE(
222 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_INVALID));
223 EXPECT_FALSE(
224 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_INVALID));
225 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(0, 0));
226 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset(1, 0));
227 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(2, 0));
229 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_HALF,
230 RTCVideoDecoder::ID_HALF));
231 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset(
232 RTCVideoDecoder::ID_HALF + 1, RTCVideoDecoder::ID_HALF));
233 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(
234 RTCVideoDecoder::ID_HALF + 2, RTCVideoDecoder::ID_HALF));
236 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_LAST,
237 RTCVideoDecoder::ID_LAST));
238 EXPECT_TRUE(
239 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_LAST));
240 EXPECT_FALSE(
241 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST));
244 } // content