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. 4 5 #include "base/bind.h" 6 #include "base/message_loop/message_loop.h" 7 #include "base/synchronization/waitable_event.h" 8 #include "base/threading/thread.h" 9 #include "content/renderer/media/rtc_video_decoder.h" 10 #include "media/base/gmock_callback_support.h" 11 #include "media/filters/mock_gpu_video_accelerator_factories.h" 12 #include "media/video/mock_video_decode_accelerator.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 using ::testing::_; 16 using ::testing::Invoke; 17 using ::testing::Return; 18 using ::testing::SaveArg; 19 using ::testing::WithArgs; 20 21 namespace content { 22 23 // TODO(wuchengli): add MockSharedMemroy so more functions can be tested. 24 class RTCVideoDecoderTest : public ::testing::Test, 25 webrtc::DecodedImageCallback { 26 public: 27 RTCVideoDecoderTest() 28 : mock_gpu_factories_(new media::MockGpuVideoAcceleratorFactories), 29 vda_thread_("vda_thread"), 30 idle_waiter_(false, false) { 31 memset(&codec_, 0, sizeof(codec_)); 32 } 33 34 virtual void SetUp() OVERRIDE { 35 ASSERT_TRUE(vda_thread_.Start()); 36 vda_task_runner_ = vda_thread_.message_loop_proxy(); 37 mock_vda_ = new media::MockVideoDecodeAccelerator; 38 EXPECT_CALL(*mock_gpu_factories_.get(), GetTaskRunner()) 39 .WillRepeatedly(Return(vda_task_runner_)); 40 EXPECT_CALL(*mock_gpu_factories_.get(), DoCreateVideoDecodeAccelerator()) 41 .WillRepeatedly(Return(mock_vda_)); 42 EXPECT_CALL(*mock_gpu_factories_.get(), CreateSharedMemory(_)) 43 .WillRepeatedly(Return(static_cast<base::SharedMemory*>(NULL))); 44 EXPECT_CALL(*mock_vda_, Initialize(_, _)) 45 .Times(1) 46 .WillRepeatedly(Return(true)); 47 EXPECT_CALL(*mock_vda_, Destroy()).Times(1); 48 } 49 50 virtual void TearDown() OVERRIDE { 51 VLOG(2) << "TearDown"; 52 EXPECT_TRUE(vda_thread_.IsRunning()); 53 RunUntilIdle(); // Wait until all callbascks complete. 54 vda_task_runner_->DeleteSoon(FROM_HERE, rtc_decoder_.release()); 55 // Make sure the decoder is released before stopping the thread. 56 RunUntilIdle(); 57 vda_thread_.Stop(); 58 } 59 60 virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) OVERRIDE { 61 VLOG(2) << "Decoded"; 62 EXPECT_EQ(vda_task_runner_, base::MessageLoopProxy::current()); 63 return WEBRTC_VIDEO_CODEC_OK; 64 } 65 66 void CreateDecoder(webrtc::VideoCodecType codec_type) { 67 VLOG(2) << "CreateDecoder"; 68 codec_.codecType = codec_type; 69 rtc_decoder_ = 70 RTCVideoDecoder::Create(codec_type, mock_gpu_factories_); 71 } 72 73 void Initialize() { 74 VLOG(2) << "Initialize"; 75 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1)); 76 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, 77 rtc_decoder_->RegisterDecodeCompleteCallback(this)); 78 } 79 80 void NotifyResetDone() { 81 VLOG(2) << "NotifyResetDone"; 82 vda_task_runner_->PostTask( 83 FROM_HERE, 84 base::Bind(&RTCVideoDecoder::NotifyResetDone, 85 base::Unretained(rtc_decoder_.get()))); 86 } 87 88 void RunUntilIdle() { 89 VLOG(2) << "RunUntilIdle"; 90 vda_task_runner_->PostTask(FROM_HERE, 91 base::Bind(&base::WaitableEvent::Signal, 92 base::Unretained(&idle_waiter_))); 93 idle_waiter_.Wait(); 94 } 95 96 protected: 97 scoped_refptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_; 98 media::MockVideoDecodeAccelerator* mock_vda_; 99 scoped_ptr<RTCVideoDecoder> rtc_decoder_; 100 webrtc::VideoCodec codec_; 101 base::Thread vda_thread_; 102 103 private: 104 scoped_refptr<base::SingleThreadTaskRunner> vda_task_runner_; 105 106 base::Lock lock_; 107 base::WaitableEvent idle_waiter_; 108 }; 109 110 TEST_F(RTCVideoDecoderTest, CreateReturnsNullOnUnsupportedCodec) { 111 CreateDecoder(webrtc::kVideoCodecVP8); 112 scoped_ptr<RTCVideoDecoder> null_rtc_decoder( 113 RTCVideoDecoder::Create(webrtc::kVideoCodecI420, mock_gpu_factories_)); 114 EXPECT_EQ(NULL, null_rtc_decoder.get()); 115 } 116 117 TEST_F(RTCVideoDecoderTest, CreateAndInitSucceedsForH264Codec) { 118 CreateDecoder(webrtc::kVideoCodecH264); 119 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1)); 120 } 121 122 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) { 123 CreateDecoder(webrtc::kVideoCodecVP8); 124 codec_.codecSpecific.VP8.feedbackModeOn = true; 125 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1)); 126 } 127 128 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) { 129 CreateDecoder(webrtc::kVideoCodecVP8); 130 webrtc::EncodedImage input_image; 131 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, 132 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); 133 } 134 135 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnIncompleteFrame) { 136 CreateDecoder(webrtc::kVideoCodecVP8); 137 Initialize(); 138 webrtc::EncodedImage input_image; 139 input_image._completeFrame = false; 140 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, 141 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); 142 } 143 144 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) { 145 CreateDecoder(webrtc::kVideoCodecVP8); 146 Initialize(); 147 webrtc::EncodedImage input_image; 148 input_image._completeFrame = true; 149 bool missingFrames = true; 150 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, 151 rtc_decoder_->Decode(input_image, missingFrames, NULL, NULL, 0)); 152 } 153 154 TEST_F(RTCVideoDecoderTest, ResetReturnsOk) { 155 CreateDecoder(webrtc::kVideoCodecVP8); 156 Initialize(); 157 EXPECT_CALL(*mock_vda_, Reset()) 158 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); 159 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Reset()); 160 } 161 162 TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) { 163 CreateDecoder(webrtc::kVideoCodecVP8); 164 Initialize(); 165 EXPECT_CALL(*mock_vda_, Reset()) 166 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); 167 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release()); 168 } 169 170 TEST_F(RTCVideoDecoderTest, InitDecodeAfterRelease) { 171 CreateDecoder(webrtc::kVideoCodecVP8); 172 EXPECT_CALL(*mock_vda_, Reset()) 173 .WillRepeatedly(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); 174 Initialize(); 175 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release()); 176 Initialize(); 177 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release()); 178 } 179 180 TEST_F(RTCVideoDecoderTest, IsBufferAfterReset) { 181 CreateDecoder(webrtc::kVideoCodecVP8); 182 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_INVALID)); 183 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 184 RTCVideoDecoder::ID_INVALID)); 185 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF - 2, 186 RTCVideoDecoder::ID_HALF + 2)); 187 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF + 2, 188 RTCVideoDecoder::ID_HALF - 2)); 189 190 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(0, 0)); 191 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_LAST)); 192 EXPECT_FALSE( 193 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF - 2)); 194 EXPECT_TRUE( 195 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF + 2)); 196 197 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 0)); 198 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 199 RTCVideoDecoder::ID_HALF - 2)); 200 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 201 RTCVideoDecoder::ID_HALF + 2)); 202 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 203 RTCVideoDecoder::ID_LAST)); 204 } 205 206 TEST_F(RTCVideoDecoderTest, IsFirstBufferAfterReset) { 207 CreateDecoder(webrtc::kVideoCodecVP8); 208 EXPECT_TRUE( 209 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_INVALID)); 210 EXPECT_FALSE( 211 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_INVALID)); 212 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(0, 0)); 213 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset(1, 0)); 214 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(2, 0)); 215 216 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_HALF, 217 RTCVideoDecoder::ID_HALF)); 218 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset( 219 RTCVideoDecoder::ID_HALF + 1, RTCVideoDecoder::ID_HALF)); 220 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset( 221 RTCVideoDecoder::ID_HALF + 2, RTCVideoDecoder::ID_HALF)); 222 223 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_LAST, 224 RTCVideoDecoder::ID_LAST)); 225 EXPECT_TRUE( 226 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_LAST)); 227 EXPECT_FALSE( 228 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST)); 229 } 230 231 } // content 232