Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 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.h" | |
| 7 #include "base/threading/platform_thread.h" | |
| 8 #include "content/renderer/media/rtc_video_decoder.h" | |
| 9 #include "media/base/gmock_callback_support.h" | |
| 10 #include "media/base/mock_filters.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 | |
| 13 using ::testing::_; | |
| 14 | |
| 15 namespace content { | |
| 16 | |
| 17 class RTCVideoDecoderTest | |
| 18 : public ::testing::Test, | |
| 19 public base::PlatformThread::Delegate, | |
| 20 webrtc::DecodedImageCallback { | |
| 21 public: | |
| 22 RTCVideoDecoderTest() | |
| 23 : decoder_(new media::MockVideoDecoder()), | |
| 24 loop_idle_waiter_(false, false), | |
| 25 num_delivered_frames_(0), | |
| 26 num_delivered_encoded_image_(0), | |
| 27 loop_ready_waiter_(false, false), | |
| 28 thread_(base::kNullThreadHandle), | |
| 29 is_tearing_down_(false) { | |
| 30 memset(&codec_, 0, sizeof(codec_)); | |
| 31 } | |
| 32 | |
| 33 virtual void SetUp() OVERRIDE { | |
| 34 CHECK(base::PlatformThread::Create(0, this, &thread_)); | |
| 35 loop_ready_waiter_.Wait(); | |
| 36 bridge_.reset(new RTCVideoDecoder(decoder_, loop_proxy_)); | |
|
Ami GONE FROM CHROMIUM
2013/05/14 22:57:24
|bridge_| is now a strange name for the variable c
wuchengli
2013/05/15 15:30:46
Changed |bridge_| to |rtc_decoder_| and changed |d
| |
| 37 } | |
| 38 | |
| 39 virtual void TearDown() OVERRIDE { | |
| 40 if (thread_ != base::kNullThreadHandle) { | |
| 41 { | |
| 42 base::AutoLock auto_lock(lock_); | |
| 43 is_tearing_down_ = true; | |
| 44 } | |
| 45 base::PlatformThread::Join(thread_); | |
| 46 } | |
| 47 } | |
| 48 | |
| 49 virtual void ThreadMain() OVERRIDE { | |
| 50 MessageLoop message_loop; | |
| 51 loop_proxy_ = message_loop.message_loop_proxy(); | |
| 52 loop_ready_waiter_.Signal(); | |
| 53 LOG(INFO) << "ThreadMain()"; | |
| 54 while (true) { | |
| 55 message_loop.RunUntilIdle(); | |
| 56 loop_idle_waiter_.Signal(); | |
| 57 loop_idle_waiter_.Reset(); | |
| 58 base::AutoLock auto_lock(lock_); | |
| 59 if (is_tearing_down_) { | |
| 60 break; | |
| 61 } | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) | |
| 66 OVERRIDE { | |
| 67 num_delivered_frames_++; | |
|
Ami GONE FROM CHROMIUM
2013/05/14 22:57:24
nit: prefer pre-{de,in}crement to post-, where the
wuchengli
2013/05/15 15:30:46
All done.
| |
| 68 return WEBRTC_VIDEO_CODEC_OK; | |
| 69 } | |
| 70 | |
| 71 void Initialize() { | |
| 72 EXPECT_CALL(*decoder_, Initialize(_, _, _)) | |
| 73 .WillOnce(media::RunCallback<1>(media::PIPELINE_OK)); | |
| 74 EXPECT_CALL(*decoder_, Read(_)) | |
| 75 .WillRepeatedly( | |
| 76 Invoke(this, &RTCVideoDecoderTest::FrameRequested)); | |
| 77 EXPECT_CALL(*decoder_, Stop(_)) | |
| 78 .WillRepeatedly(media::RunClosure<0>()); | |
| 79 EXPECT_CALL(*decoder_, Reset(_)) | |
| 80 .WillRepeatedly(media::RunClosure<0>()); | |
| 81 | |
| 82 codec_.codecType = webrtc::kVideoCodecVP8; | |
| 83 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->InitDecode(&codec_, 1)); | |
| 84 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | |
| 85 bridge_->RegisterDecodeCompleteCallback(this)); | |
| 86 } | |
| 87 | |
| 88 void FrameRequested(const media::VideoDecoder::ReadCB& read_cb) { | |
| 89 DCHECK_EQ(loop_proxy_, base::MessageLoopProxy::current()); | |
| 90 EXPECT_TRUE(read_cb_.is_null()); | |
| 91 read_cb_ = read_cb; | |
| 92 SimulateDecoding(); | |
| 93 } | |
| 94 | |
| 95 void SimulateDecoding() { | |
| 96 CHECK(!read_cb_.is_null()); | |
| 97 base::AutoLock auto_lock(lock_); | |
| 98 if (num_delivered_encoded_image_ <= 0) { | |
| 99 return; | |
| 100 } | |
| 101 num_delivered_encoded_image_--; | |
| 102 | |
| 103 loop_proxy_->PostTask( | |
| 104 FROM_HERE, | |
| 105 base::Bind(read_cb_, media::VideoDecoder::kOk, | |
| 106 media::VideoFrame::CreateEmptyFrame())); | |
| 107 read_cb_.Reset(); | |
| 108 } | |
| 109 | |
| 110 protected: | |
| 111 media::MockVideoDecoder* decoder_; | |
| 112 scoped_ptr<RTCVideoDecoder> bridge_; | |
| 113 webrtc::VideoCodec codec_; | |
| 114 base::WaitableEvent loop_idle_waiter_; | |
| 115 int num_delivered_frames_; | |
| 116 int num_delivered_encoded_image_; | |
| 117 | |
| 118 private: | |
| 119 scoped_refptr<base::MessageLoopProxy> loop_proxy_; | |
| 120 base::WaitableEvent loop_ready_waiter_; | |
| 121 base::PlatformThreadHandle thread_; | |
| 122 | |
| 123 base::Lock lock_; | |
| 124 bool is_tearing_down_; | |
| 125 media::VideoDecoder::ReadCB read_cb_; | |
| 126 }; | |
| 127 | |
| 128 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnNonVP8Codec) { | |
| 129 codec_.codecType = webrtc::kVideoCodecI420; | |
| 130 EXPECT_NE(WEBRTC_VIDEO_CODEC_OK, bridge_->InitDecode(&codec_, 1)); | |
| 131 } | |
| 132 | |
| 133 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) { | |
| 134 codec_.codecType = webrtc::kVideoCodecVP8; | |
| 135 codec_.codecSpecific.VP8.feedbackModeOn = true; | |
| 136 EXPECT_NE(WEBRTC_VIDEO_CODEC_OK, bridge_->InitDecode(&codec_, 1)); | |
| 137 } | |
| 138 | |
| 139 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnDecoderInitFailure) { | |
| 140 EXPECT_CALL(*decoder_, Initialize(_, _, _)) | |
| 141 .WillOnce(media::RunCallback<1>(media::DECODER_ERROR_NOT_SUPPORTED)); | |
| 142 | |
| 143 codec_.codecType = webrtc::kVideoCodecVP8; | |
| 144 EXPECT_NE(WEBRTC_VIDEO_CODEC_OK, bridge_->InitDecode(&codec_, 1)); | |
| 145 } | |
| 146 | |
| 147 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsOkOnSuccessfulDecoderInit) { | |
| 148 Initialize(); | |
| 149 } | |
| 150 | |
| 151 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorBeforeInitDecode) { | |
| 152 webrtc::EncodedImage input_image; | |
| 153 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, | |
| 154 bridge_->Decode(input_image, false, NULL, NULL, 0)); | |
| 155 } | |
| 156 | |
| 157 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnDamagedBitstream) { | |
| 158 Initialize(); | |
| 159 webrtc::EncodedImage input_image; | |
| 160 input_image._completeFrame = false; | |
| 161 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, | |
| 162 bridge_->Decode(input_image, false, NULL, NULL, 0)); | |
| 163 } | |
| 164 | |
| 165 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) { | |
| 166 Initialize(); | |
| 167 webrtc::EncodedImage input_image; | |
| 168 input_image._completeFrame = true; | |
| 169 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, | |
| 170 bridge_->Decode(input_image, true, NULL, NULL, 0)); | |
| 171 } | |
| 172 | |
| 173 TEST_F(RTCVideoDecoderTest, DecodeReturnsOkAndGetsDecodedFrame) { | |
| 174 Initialize(); | |
| 175 webrtc::EncodedImage input_image; | |
| 176 input_image._completeFrame = true; | |
| 177 unsigned char data = 123; | |
| 178 input_image._buffer = &data; | |
| 179 input_image._length = sizeof(data); | |
| 180 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | |
| 181 bridge_->Decode(input_image, false, NULL, NULL, 0)); | |
| 182 num_delivered_encoded_image_++; //XXX : lock? | |
| 183 loop_idle_waiter_.Wait(); | |
| 184 SimulateDecoding(); | |
| 185 loop_idle_waiter_.Wait(); | |
| 186 // Check output. | |
| 187 EXPECT_EQ(1, num_delivered_frames_); //XXX: lock? | |
|
Ami GONE FROM CHROMIUM
2013/05/14 22:57:24
If all you need is sequencing (not mutual exclusio
wuchengli
2013/05/15 15:30:46
Yes. It's only sequencing. The comments were remov
| |
| 188 } | |
| 189 | |
| 190 TEST_F(RTCVideoDecoderTest, ResetReturnsOk) { | |
| 191 Initialize(); | |
| 192 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->Reset()); | |
| 193 } | |
| 194 | |
| 195 TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) { | |
| 196 Initialize(); | |
| 197 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->Release()); | |
| 198 } | |
| 199 | |
| 200 } // content | |
| OLD | NEW |