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_loop_proxy_ = vda_thread_.message_loop_proxy(); 37 mock_vda_ = new media::MockVideoDecodeAccelerator; 38 EXPECT_CALL(*mock_gpu_factories_, GetMessageLoop()) 39 .WillRepeatedly(Return(vda_loop_proxy_)); 40 EXPECT_CALL(*mock_gpu_factories_, DoCreateVideoDecodeAccelerator(_, _)) 41 .WillRepeatedly( 42 Return(static_cast<media::VideoDecodeAccelerator*>(NULL))); 43 EXPECT_CALL(*mock_gpu_factories_, 44 DoCreateVideoDecodeAccelerator(media::VP8PROFILE_MAIN, _)) 45 .WillRepeatedly(Return(mock_vda_)); 46 EXPECT_CALL(*mock_gpu_factories_, Abort()).WillRepeatedly(Return()); 47 EXPECT_CALL(*mock_gpu_factories_, CreateSharedMemory(_)) 48 .WillRepeatedly(Return(static_cast<base::SharedMemory*>(NULL))); 49 EXPECT_CALL(*mock_vda_, Destroy()); 50 rtc_decoder_ = 51 RTCVideoDecoder::Create(webrtc::kVideoCodecVP8, mock_gpu_factories_); 52 } 53 54 virtual void TearDown() OVERRIDE { 55 VLOG(2) << "TearDown"; 56 if (vda_thread_.IsRunning()) { 57 RunUntilIdle(); // Wait until all callbascks complete. 58 vda_loop_proxy_->DeleteSoon(FROM_HERE, rtc_decoder_.release()); 59 // Make sure the decoder is released before stopping the thread. 60 RunUntilIdle(); 61 vda_thread_.Stop(); 62 } else { 63 rtc_decoder_.reset(); 64 } 65 } 66 67 virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) OVERRIDE { 68 VLOG(2) << "Decoded"; 69 EXPECT_EQ(vda_loop_proxy_, base::MessageLoopProxy::current()); 70 return WEBRTC_VIDEO_CODEC_OK; 71 } 72 73 void Initialize() { 74 VLOG(2) << "Initialize"; 75 codec_.codecType = webrtc::kVideoCodecVP8; 76 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1)); 77 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, 78 rtc_decoder_->RegisterDecodeCompleteCallback(this)); 79 } 80 81 void NotifyResetDone() { 82 VLOG(2) << "NotifyResetDone"; 83 vda_loop_proxy_->PostTask(FROM_HERE, 84 base::Bind(&RTCVideoDecoder::NotifyResetDone, 85 base::Unretained(rtc_decoder_.get()))); 86 } 87 88 void RunUntilIdle() { 89 VLOG(2) << "RunUntilIdle"; 90 vda_loop_proxy_->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::MessageLoopProxy> vda_loop_proxy_; 105 106 base::Lock lock_; 107 base::WaitableEvent idle_waiter_; 108 }; 109 110 TEST_F(RTCVideoDecoderTest, CreateReturnsNullOnUnsupportedCodec) { 111 scoped_ptr<RTCVideoDecoder> null_rtc_decoder( 112 RTCVideoDecoder::Create(webrtc::kVideoCodecI420, mock_gpu_factories_)); 113 EXPECT_EQ(NULL, null_rtc_decoder.get()); 114 } 115 116 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) { 117 codec_.codecType = webrtc::kVideoCodecVP8; 118 codec_.codecSpecific.VP8.feedbackModeOn = true; 119 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1)); 120 } 121 122 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) { 123 webrtc::EncodedImage input_image; 124 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, 125 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); 126 } 127 128 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnIncompleteFrame) { 129 Initialize(); 130 webrtc::EncodedImage input_image; 131 input_image._completeFrame = false; 132 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, 133 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); 134 } 135 136 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) { 137 Initialize(); 138 webrtc::EncodedImage input_image; 139 input_image._completeFrame = true; 140 bool missingFrames = true; 141 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, 142 rtc_decoder_->Decode(input_image, missingFrames, NULL, NULL, 0)); 143 } 144 145 TEST_F(RTCVideoDecoderTest, ResetReturnsOk) { 146 Initialize(); 147 EXPECT_CALL(*mock_vda_, Reset()) 148 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); 149 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Reset()); 150 } 151 152 TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) { 153 Initialize(); 154 EXPECT_CALL(*mock_vda_, Reset()) 155 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); 156 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release()); 157 } 158 159 TEST_F(RTCVideoDecoderTest, InitDecodeAfterRelease) { 160 EXPECT_CALL(*mock_vda_, Reset()) 161 .WillRepeatedly(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); 162 Initialize(); 163 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release()); 164 Initialize(); 165 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release()); 166 } 167 168 TEST_F(RTCVideoDecoderTest, VdaThreadStops) { vda_thread_.Stop(); } 169 170 TEST_F(RTCVideoDecoderTest, IsBufferAfterReset) { 171 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_INVALID)); 172 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 173 RTCVideoDecoder::ID_INVALID)); 174 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF - 2, 175 RTCVideoDecoder::ID_HALF + 2)); 176 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF + 2, 177 RTCVideoDecoder::ID_HALF - 2)); 178 179 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(0, 0)); 180 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_LAST)); 181 EXPECT_FALSE( 182 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF - 2)); 183 EXPECT_TRUE( 184 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF + 2)); 185 186 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 0)); 187 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 188 RTCVideoDecoder::ID_HALF - 2)); 189 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 190 RTCVideoDecoder::ID_HALF + 2)); 191 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 192 RTCVideoDecoder::ID_LAST)); 193 } 194 195 TEST_F(RTCVideoDecoderTest, IsFirstBufferAfterReset) { 196 EXPECT_TRUE( 197 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_INVALID)); 198 EXPECT_FALSE( 199 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_INVALID)); 200 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(0, 0)); 201 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset(1, 0)); 202 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(2, 0)); 203 204 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_HALF, 205 RTCVideoDecoder::ID_HALF)); 206 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset( 207 RTCVideoDecoder::ID_HALF + 1, RTCVideoDecoder::ID_HALF)); 208 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset( 209 RTCVideoDecoder::ID_HALF + 2, RTCVideoDecoder::ID_HALF)); 210 211 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_LAST, 212 RTCVideoDecoder::ID_LAST)); 213 EXPECT_TRUE( 214 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_LAST)); 215 EXPECT_FALSE( 216 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST)); 217 } 218 219 } // content 220