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