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/synchronization/waitable_event.h" 6 #include "base/task_runner_util.h" 7 #include "base/threading/thread.h" 8 #include "content/renderer/media/rtc_video_decoder_factory_tv.h" 9 #include "media/base/decoder_buffer.h" 10 #include "media/base/video_decoder_config.h" 11 #include "testing/gmock/include/gmock/gmock.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "third_party/webrtc/modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h" 14 #include "ui/gfx/rect.h" 15 16 using ::testing::_; 17 using ::testing::Return; 18 19 namespace content { 20 21 class RTCVideoDecoderFactoryTvTest : public ::testing::Test { 22 public: 23 RTCVideoDecoderFactoryTvTest() 24 : factory_(new RTCVideoDecoderFactoryTv), 25 decoder_(NULL), 26 is_demuxer_acquired_(false), 27 video_stream_(NULL), 28 size_(1280, 720), 29 input_image_(&data_, sizeof(data_), sizeof(data_)), 30 data_('a'), 31 read_event_(false, false), 32 decoder_thread_("Test decoder thread"), 33 decoder_thread_event_(false, false) { 34 memset(&codec_, 0, sizeof(codec_)); 35 message_loop_proxy_ = base::MessageLoopProxy::current(); 36 input_image_._frameType = webrtc::kKeyFrame; 37 input_image_._encodedWidth = size_.width(); 38 input_image_._encodedHeight = size_.height(); 39 input_image_._completeFrame = true; 40 decoder_thread_.Start(); 41 } 42 43 virtual ~RTCVideoDecoderFactoryTvTest() { 44 if (is_demuxer_acquired_) { 45 factory_->ReleaseDemuxer(); 46 is_demuxer_acquired_ = false; 47 } 48 if (decoder_) { 49 factory_->DestroyVideoDecoder(decoder_); 50 decoder_ = NULL; 51 } 52 53 decoder_thread_.Stop(); 54 } 55 56 void ReadCallback(media::DemuxerStream::Status status, 57 const scoped_refptr<media::DecoderBuffer>& decoder_buffer) { 58 switch (status) { 59 case media::DemuxerStream::kOk: 60 EXPECT_TRUE(decoder_buffer); 61 break; 62 case media::DemuxerStream::kConfigChanged: 63 case media::DemuxerStream::kAborted: 64 EXPECT_FALSE(decoder_buffer); 65 break; 66 } 67 last_decoder_buffer_ = decoder_buffer; 68 read_event_.Signal(); 69 } 70 71 void ExpectEqualsAndSignal(int32_t expected, int32_t actual) { 72 EXPECT_EQ(expected, actual); 73 decoder_thread_event_.Signal(); 74 } 75 76 void ExpectNotEqualsAndSignal(int32_t unexpected, int32_t actual) { 77 EXPECT_NE(unexpected, actual); 78 decoder_thread_event_.Signal(); 79 } 80 81 protected: 82 base::Callback<void(int32_t)> BindExpectEquals(int32_t expected) { 83 return base::Bind(&RTCVideoDecoderFactoryTvTest::ExpectEqualsAndSignal, 84 base::Unretained(this), 85 expected); 86 } 87 88 base::Callback<void(int32_t)> BindExpectNotEquals(int32_t unexpected) { 89 return base::Bind(&RTCVideoDecoderFactoryTvTest::ExpectNotEqualsAndSignal, 90 base::Unretained(this), 91 unexpected); 92 } 93 94 base::Callback<int32_t(void)> BindInitDecode(const webrtc::VideoCodec* codec, 95 int32_t num_cores) { 96 return base::Bind(&webrtc::VideoDecoder::InitDecode, 97 base::Unretained(decoder_), 98 codec, 99 num_cores); 100 } 101 102 base::Callback<int32_t(void)> BindDecode( 103 const webrtc::EncodedImage& input_image, 104 bool missing_frames, 105 const webrtc::RTPFragmentationHeader* fragmentation, 106 const webrtc::CodecSpecificInfo* info, 107 int64_t render_time_ms) { 108 return base::Bind(&webrtc::VideoDecoder::Decode, 109 base::Unretained(decoder_), 110 input_image, 111 missing_frames, 112 fragmentation, 113 info, 114 render_time_ms); 115 } 116 117 void CreateDecoderAndAcquireDemuxer() { 118 decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8); 119 ASSERT_TRUE(decoder_); 120 ASSERT_TRUE(factory_->AcquireDemuxer()); 121 is_demuxer_acquired_ = true; 122 } 123 124 void InitDecode() { 125 codec_.codecType = webrtc::kVideoCodecVP8; 126 codec_.width = size_.width(); 127 codec_.height = size_.height(); 128 base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(), 129 FROM_HERE, 130 BindInitDecode(&codec_, 1), 131 BindExpectEquals(WEBRTC_VIDEO_CODEC_OK)); 132 decoder_thread_event_.Wait(); 133 base::PostTaskAndReplyWithResult( 134 decoder_thread_.message_loop_proxy(), 135 FROM_HERE, 136 base::Bind(&webrtc::VideoDecoder::RegisterDecodeCompleteCallback, 137 base::Unretained(decoder_), 138 &decode_complete_callback_), 139 BindExpectEquals(WEBRTC_VIDEO_CODEC_OK)); 140 decoder_thread_event_.Wait(); 141 } 142 143 void GetVideoStream() { 144 video_stream_ = factory_->GetStream(media::DemuxerStream::VIDEO); 145 ASSERT_TRUE(video_stream_); 146 EXPECT_EQ(media::kCodecVP8, video_stream_->video_decoder_config().codec()); 147 EXPECT_EQ(size_, video_stream_->video_decoder_config().coded_size()); 148 EXPECT_EQ(gfx::Rect(size_), 149 video_stream_->video_decoder_config().visible_rect()); 150 EXPECT_EQ(size_, video_stream_->video_decoder_config().natural_size()); 151 } 152 153 void PostDecodeAndWait(int32_t expected, 154 const webrtc::EncodedImage& input_image, 155 bool missing_frames, 156 const webrtc::RTPFragmentationHeader* fragmentation, 157 const webrtc::CodecSpecificInfo* info, 158 int64_t render_time_ms) { 159 base::PostTaskAndReplyWithResult( 160 decoder_thread_.message_loop_proxy(), 161 FROM_HERE, 162 BindDecode( 163 input_image, missing_frames, fragmentation, info, render_time_ms), 164 BindExpectEquals(expected)); 165 decoder_thread_event_.Wait(); 166 } 167 168 RTCVideoDecoderFactoryTv* factory_; 169 webrtc::VideoDecoder* decoder_; 170 bool is_demuxer_acquired_; 171 base::MessageLoopProxy* message_loop_proxy_; 172 media::DemuxerStream* video_stream_; 173 webrtc::VideoCodec codec_; 174 gfx::Size size_; 175 webrtc::EncodedImage input_image_; 176 unsigned char data_; 177 webrtc::MockDecodedImageCallback decode_complete_callback_; 178 base::WaitableEvent read_event_; 179 base::Thread decoder_thread_; 180 base::WaitableEvent decoder_thread_event_; 181 scoped_refptr<media::DecoderBuffer> last_decoder_buffer_; 182 }; 183 184 TEST_F(RTCVideoDecoderFactoryTvTest, CreateAndDestroyDecoder) { 185 // Only VP8 decoder is supported. 186 ASSERT_FALSE(factory_->CreateVideoDecoder(webrtc::kVideoCodecI420)); 187 decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8); 188 ASSERT_TRUE(decoder_); 189 // Only one decoder at a time will be created. 190 ASSERT_FALSE(factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8)); 191 factory_->DestroyVideoDecoder(decoder_); 192 } 193 194 TEST_F(RTCVideoDecoderFactoryTvTest, AcquireDemuxerAfterCreateDecoder) { 195 decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8); 196 ASSERT_TRUE(decoder_); 197 ASSERT_TRUE(factory_->AcquireDemuxer()); 198 is_demuxer_acquired_ = true; 199 // Demuxer can be acquired only once. 200 ASSERT_FALSE(factory_->AcquireDemuxer()); 201 } 202 203 TEST_F(RTCVideoDecoderFactoryTvTest, AcquireDemuxerBeforeCreateDecoder) { 204 ASSERT_TRUE(factory_->AcquireDemuxer()); 205 is_demuxer_acquired_ = true; 206 decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8); 207 ASSERT_TRUE(decoder_); 208 } 209 210 TEST_F(RTCVideoDecoderFactoryTvTest, InitDecodeReturnsErrorOnNonVP8Codec) { 211 CreateDecoderAndAcquireDemuxer(); 212 codec_.codecType = webrtc::kVideoCodecI420; 213 base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(), 214 FROM_HERE, 215 BindInitDecode(&codec_, 1), 216 BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK)); 217 decoder_thread_event_.Wait(); 218 } 219 220 TEST_F(RTCVideoDecoderFactoryTvTest, InitDecodeReturnsErrorOnFeedbackMode) { 221 CreateDecoderAndAcquireDemuxer(); 222 codec_.codecType = webrtc::kVideoCodecVP8; 223 codec_.codecSpecific.VP8.feedbackModeOn = true; 224 base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(), 225 FROM_HERE, 226 BindInitDecode(&codec_, 1), 227 BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK)); 228 decoder_thread_event_.Wait(); 229 } 230 231 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorBeforeInitDecode) { 232 CreateDecoderAndAcquireDemuxer(); 233 PostDecodeAndWait( 234 WEBRTC_VIDEO_CODEC_UNINITIALIZED, input_image_, false, NULL, NULL, 0); 235 } 236 237 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnDamagedBitstream) { 238 CreateDecoderAndAcquireDemuxer(); 239 InitDecode(); 240 input_image_._completeFrame = false; 241 PostDecodeAndWait( 242 WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0); 243 } 244 245 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnMissingFrames) { 246 CreateDecoderAndAcquireDemuxer(); 247 InitDecode(); 248 PostDecodeAndWait( 249 WEBRTC_VIDEO_CODEC_ERROR, input_image_, true, NULL, NULL, 0); 250 } 251 252 TEST_F(RTCVideoDecoderFactoryTvTest, GetNonVideoStreamFails) { 253 CreateDecoderAndAcquireDemuxer(); 254 InitDecode(); 255 EXPECT_FALSE(factory_->GetStream(media::DemuxerStream::AUDIO)); 256 EXPECT_FALSE(factory_->GetStream(media::DemuxerStream::UNKNOWN)); 257 } 258 259 TEST_F(RTCVideoDecoderFactoryTvTest, GetVideoStreamSucceeds) { 260 CreateDecoderAndAcquireDemuxer(); 261 InitDecode(); 262 GetVideoStream(); 263 } 264 265 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnNonKeyFrameAtFirst) { 266 CreateDecoderAndAcquireDemuxer(); 267 InitDecode(); 268 GetVideoStream(); 269 input_image_._frameType = webrtc::kDeltaFrame; 270 PostDecodeAndWait( 271 WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0); 272 } 273 274 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeUpdatesVideoSizeOnKeyFrame) { 275 CreateDecoderAndAcquireDemuxer(); 276 InitDecode(); 277 GetVideoStream(); 278 gfx::Size new_size(320, 240); 279 input_image_._encodedWidth = new_size.width(); 280 input_image_._encodedHeight = new_size.height(); 281 PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0); 282 EXPECT_EQ(new_size, video_stream_->video_decoder_config().coded_size()); 283 EXPECT_EQ(gfx::Rect(new_size), 284 video_stream_->video_decoder_config().visible_rect()); 285 EXPECT_EQ(new_size, video_stream_->video_decoder_config().natural_size()); 286 } 287 288 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeAdjustsTimestampFromZero) { 289 CreateDecoderAndAcquireDemuxer(); 290 InitDecode(); 291 GetVideoStream(); 292 PostDecodeAndWait( 293 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10000); 294 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback, 295 base::Unretained(this))); 296 read_event_.Wait(); 297 EXPECT_EQ(base::TimeDelta::FromMilliseconds(0), 298 last_decoder_buffer_->GetTimestamp()); 299 PostDecodeAndWait( 300 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10033); 301 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback, 302 base::Unretained(this))); 303 read_event_.Wait(); 304 EXPECT_EQ(base::TimeDelta::FromMilliseconds(33), 305 last_decoder_buffer_->GetTimestamp()); 306 } 307 308 TEST_F(RTCVideoDecoderFactoryTvTest, DecodePassesDataCorrectly) { 309 CreateDecoderAndAcquireDemuxer(); 310 InitDecode(); 311 GetVideoStream(); 312 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback, 313 base::Unretained(this))); 314 PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0); 315 read_event_.Wait(); 316 EXPECT_EQ(static_cast<int>(sizeof(data_)), 317 last_decoder_buffer_->GetDataSize()); 318 EXPECT_EQ(data_, last_decoder_buffer_->GetData()[0]); 319 } 320 321 TEST_F(RTCVideoDecoderFactoryTvTest, NextReadTriggersDecodeCompleteCallback) { 322 EXPECT_CALL(decode_complete_callback_, Decoded(_)) 323 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); 324 325 CreateDecoderAndAcquireDemuxer(); 326 InitDecode(); 327 GetVideoStream(); 328 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback, 329 base::Unretained(this))); 330 PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0); 331 read_event_.Wait(); 332 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback, 333 base::Unretained(this))); 334 } 335 336 TEST_F(RTCVideoDecoderFactoryTvTest, ResetReturnsOk) { 337 CreateDecoderAndAcquireDemuxer(); 338 InitDecode(); 339 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Reset()); 340 } 341 342 TEST_F(RTCVideoDecoderFactoryTvTest, ReleaseReturnsOk) { 343 CreateDecoderAndAcquireDemuxer(); 344 InitDecode(); 345 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); 346 } 347 348 } // content 349