Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 <stdint.h> | 5 #include <stdint.h> |
| 6 #include <string.h> | 6 #include <string.h> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| 11 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
| 12 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
| 13 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
| 14 #include "content/renderer/media/rtc_video_decoder.h" | 14 #include "content/renderer/media/rtc_video_decoder.h" |
| 15 #include "media/base/gmock_callback_support.h" | 15 #include "media/base/gmock_callback_support.h" |
| 16 #include "media/renderers/mock_gpu_video_accelerator_factories.h" | 16 #include "media/renderers/mock_gpu_video_accelerator_factories.h" |
| 17 #include "media/video/mock_video_decode_accelerator.h" | 17 #include "media/video/mock_video_decode_accelerator.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 19 |
| 20 using ::testing::_; | 20 using ::testing::_; |
| 21 using ::testing::Invoke; | 21 using ::testing::Invoke; |
| 22 using ::testing::Return; | 22 using ::testing::Return; |
| 23 using ::testing::SaveArg; | 23 using ::testing::SaveArg; |
| 24 using ::testing::Values; | |
| 24 using ::testing::WithArgs; | 25 using ::testing::WithArgs; |
| 25 | 26 |
| 26 namespace content { | 27 namespace content { |
| 27 | 28 |
| 28 // TODO(wuchengli): add MockSharedMemroy so more functions can be tested. | 29 // TODO(wuchengli): add MockSharedMemroy so more functions can be tested. |
| 29 class RTCVideoDecoderTest : public ::testing::Test, | 30 class RTCVideoDecoderTest |
| 30 webrtc::DecodedImageCallback { | 31 : public ::testing::TestWithParam<webrtc::VideoCodecType>, |
| 32 webrtc::DecodedImageCallback { | |
| 31 public: | 33 public: |
| 32 RTCVideoDecoderTest() | 34 RTCVideoDecoderTest() |
| 33 : mock_gpu_factories_( | 35 : mock_gpu_factories_( |
| 34 new media::MockGpuVideoAcceleratorFactories(nullptr)), | 36 new media::MockGpuVideoAcceleratorFactories(nullptr)), |
| 35 vda_thread_("vda_thread"), | 37 vda_thread_("vda_thread"), |
| 36 idle_waiter_(false, false) { | 38 idle_waiter_(false, false) { |
| 37 memset(&codec_, 0, sizeof(codec_)); | 39 memset(&codec_, 0, sizeof(codec_)); |
| 38 } | 40 } |
| 39 | 41 |
| 40 void SetUp() override { | 42 void SetUp() override { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 } | 96 } |
| 95 | 97 |
| 96 void NotifyResetDone() { | 98 void NotifyResetDone() { |
| 97 DVLOG(2) << "NotifyResetDone"; | 99 DVLOG(2) << "NotifyResetDone"; |
| 98 vda_task_runner_->PostTask( | 100 vda_task_runner_->PostTask( |
| 99 FROM_HERE, | 101 FROM_HERE, |
| 100 base::Bind(&RTCVideoDecoder::NotifyResetDone, | 102 base::Bind(&RTCVideoDecoder::NotifyResetDone, |
| 101 base::Unretained(rtc_decoder_.get()))); | 103 base::Unretained(rtc_decoder_.get()))); |
| 102 } | 104 } |
| 103 | 105 |
| 106 void NotifyError(media::VideoDecodeAccelerator::Error error) { | |
| 107 DVLOG(2) << "NotifyError"; | |
| 108 vda_task_runner_->PostTask( | |
| 109 FROM_HERE, | |
| 110 base::Bind(&RTCVideoDecoder::NotifyError, | |
| 111 base::Unretained(rtc_decoder_.get()), error)); | |
| 112 } | |
| 113 | |
| 104 void RunUntilIdle() { | 114 void RunUntilIdle() { |
| 105 DVLOG(2) << "RunUntilIdle"; | 115 DVLOG(2) << "RunUntilIdle"; |
| 106 vda_task_runner_->PostTask(FROM_HERE, | 116 vda_task_runner_->PostTask(FROM_HERE, |
| 107 base::Bind(&base::WaitableEvent::Signal, | 117 base::Bind(&base::WaitableEvent::Signal, |
| 108 base::Unretained(&idle_waiter_))); | 118 base::Unretained(&idle_waiter_))); |
| 109 idle_waiter_.Wait(); | 119 idle_waiter_.Wait(); |
| 110 } | 120 } |
| 111 | 121 |
| 122 void SetUpResetVDA() { | |
| 123 mock_reset_vda_ = new media::MockVideoDecodeAccelerator; | |
| 124 EXPECT_CALL(*mock_gpu_factories_.get(), DoCreateVideoDecodeAccelerator()) | |
| 125 .WillRepeatedly(Return(mock_reset_vda_)); | |
| 126 EXPECT_CALL(*mock_reset_vda_, Initialize(_, _)) | |
| 127 .Times(1) | |
| 128 .WillRepeatedly(Return(true)); | |
| 129 EXPECT_CALL(*mock_reset_vda_, Reset()).Times(1); | |
| 130 EXPECT_CALL(*mock_reset_vda_, Destroy()).Times(1); | |
| 131 } | |
| 132 | |
| 112 protected: | 133 protected: |
| 113 scoped_ptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_; | 134 scoped_ptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_; |
| 114 media::MockVideoDecodeAccelerator* mock_vda_; | 135 media::MockVideoDecodeAccelerator* mock_vda_; |
| 136 media::MockVideoDecodeAccelerator* mock_reset_vda_; | |
| 115 scoped_ptr<RTCVideoDecoder> rtc_decoder_; | 137 scoped_ptr<RTCVideoDecoder> rtc_decoder_; |
| 116 webrtc::VideoCodec codec_; | 138 webrtc::VideoCodec codec_; |
| 117 base::Thread vda_thread_; | 139 base::Thread vda_thread_; |
| 118 media::VideoDecodeAccelerator::Capabilities capabilities_; | 140 media::VideoDecodeAccelerator::Capabilities capabilities_; |
| 119 | 141 |
| 120 private: | 142 private: |
| 121 scoped_refptr<base::SingleThreadTaskRunner> vda_task_runner_; | 143 scoped_refptr<base::SingleThreadTaskRunner> vda_task_runner_; |
| 122 | 144 |
| 123 base::Lock lock_; | 145 base::Lock lock_; |
| 124 base::WaitableEvent idle_waiter_; | 146 base::WaitableEvent idle_waiter_; |
| 125 }; | 147 }; |
| 126 | 148 |
| 127 TEST_F(RTCVideoDecoderTest, CreateReturnsNullOnUnsupportedCodec) { | 149 TEST_F(RTCVideoDecoderTest, CreateReturnsNullOnUnsupportedCodec) { |
| 128 CreateDecoder(webrtc::kVideoCodecVP8); | 150 CreateDecoder(webrtc::kVideoCodecVP8); |
| 129 scoped_ptr<RTCVideoDecoder> null_rtc_decoder(RTCVideoDecoder::Create( | 151 scoped_ptr<RTCVideoDecoder> null_rtc_decoder(RTCVideoDecoder::Create( |
| 130 webrtc::kVideoCodecI420, mock_gpu_factories_.get())); | 152 webrtc::kVideoCodecI420, mock_gpu_factories_.get())); |
| 131 EXPECT_EQ(NULL, null_rtc_decoder.get()); | 153 EXPECT_EQ(NULL, null_rtc_decoder.get()); |
| 132 } | 154 } |
| 133 | 155 |
| 134 TEST_F(RTCVideoDecoderTest, CreateAndInitSucceedsForH264Codec) { | 156 TEST_P(RTCVideoDecoderTest, CreateAndInitSucceeds) { |
| 135 CreateDecoder(webrtc::kVideoCodecH264); | 157 const webrtc::VideoCodecType codec_type = GetParam(); |
| 158 CreateDecoder(codec_type); | |
| 136 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1)); | 159 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1)); |
| 137 } | 160 } |
| 138 | 161 |
| 139 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) { | 162 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) { |
| 140 CreateDecoder(webrtc::kVideoCodecVP8); | 163 CreateDecoder(webrtc::kVideoCodecVP8); |
| 141 codec_.codecSpecific.VP8.feedbackModeOn = true; | 164 codec_.codecSpecific.VP8.feedbackModeOn = true; |
| 142 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1)); | 165 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1)); |
| 143 } | 166 } |
| 144 | 167 |
| 145 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) { | 168 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 RTCVideoDecoder::ID_HALF + 2, RTCVideoDecoder::ID_HALF)); | 253 RTCVideoDecoder::ID_HALF + 2, RTCVideoDecoder::ID_HALF)); |
| 231 | 254 |
| 232 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_LAST, | 255 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_LAST, |
| 233 RTCVideoDecoder::ID_LAST)); | 256 RTCVideoDecoder::ID_LAST)); |
| 234 EXPECT_TRUE( | 257 EXPECT_TRUE( |
| 235 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_LAST)); | 258 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_LAST)); |
| 236 EXPECT_FALSE( | 259 EXPECT_FALSE( |
| 237 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST)); | 260 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST)); |
| 238 } | 261 } |
| 239 | 262 |
| 263 | |
| 264 TEST_P(RTCVideoDecoderTest, DecodeResetsAfterError) { | |
| 265 const webrtc::VideoCodecType codec_type = GetParam(); | |
| 266 CreateDecoder(codec_type); | |
| 267 Initialize(); | |
| 268 | |
| 269 const gfx::Size kInputFrameSize(16, 16); | |
|
tommi (sloooow) - chröme
2016/03/19 09:25:49
This isn't a compile time constant (static), so sh
emircan
2016/03/21 19:25:10
I will put them as const static vars.
| |
| 270 webrtc::EncodedImage input_image; | |
| 271 input_image._completeFrame = true; | |
| 272 input_image._encodedWidth = kInputFrameSize.width(); | |
| 273 input_image._encodedHeight = kInputFrameSize.height(); | |
| 274 input_image._frameType = webrtc::kVideoFrameDelta; | |
| 275 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, | |
| 276 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); | |
|
tommi (sloooow) - chröme
2016/03/19 09:25:49
Nit: nullptr
emircan
2016/03/21 19:25:10
Done, changing here and rest of the class.
| |
| 277 RunUntilIdle(); | |
| 278 | |
| 279 // Notify the decoder about a platform error. | |
| 280 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | |
| 281 RunUntilIdle(); | |
| 282 | |
| 283 // Expect decode call to reset decoder, and set up a new VDA to track it. | |
| 284 SetUpResetVDA(); | |
| 285 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, | |
| 286 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); | |
| 287 } | |
| 288 | |
| 289 INSTANTIATE_TEST_CASE_P(, | |
|
tommi (sloooow) - chröme
2016/03/19 09:25:50
Intentionally empty?
emircan
2016/03/21 19:25:10
Yes, but I guess it would be better to write out t
| |
| 290 RTCVideoDecoderTest, | |
| 291 Values(webrtc::kVideoCodecVP8, | |
| 292 webrtc::kVideoCodecH264)); | |
| 293 | |
| 240 } // content | 294 } // content |
| OLD | NEW |