Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Side by Side Diff: content/renderer/media/rtc_video_decoder_bridge_tv_unittest.cc

Issue 14247018: Implement WebRTC in Chrome for TV (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: combined KeyHandlingDemxuer w/ KeyHandlingChunkDemuxer Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/synchronization/waitable_event.h"
6 #include "base/task_runner_util.h"
7 #include "content/renderer/media/mock_media_stream_dependency_factory.h"
8 #include "content/renderer/media/rtc_video_decoder_bridge_tv.h"
9 #include "media/base/decoder_buffer.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/webrtc/modules/video_coding/codecs/interface/mock/mock_vid eo_codec_interface.h"
13
14 using ::testing::_;
15 using ::testing::Return;
16
17 namespace content {
18
19 class RTCVideoDecoderBridgeTvTest : public ::testing::Test {
20 public:
21 RTCVideoDecoderBridgeTvTest()
22 : bridge_(RTCVideoDecoderBridgeTv::Get()),
23 demuxer_(NULL),
24 video_stream_(NULL),
25 size_(1280, 720),
26 input_image_(&data_, sizeof(data_), sizeof(data_)),
27 data_('a'),
28 read_event_(false, false),
29 decoder_thread_("Test decoeder thread"),
30 decoder_thread_event_(false, false) {}
31
32 void ReadCallback(media::DemuxerStream::Status status,
Ami GONE FROM CHROMIUM 2013/05/08 20:26:44 intentionally ignoring |status|?
wonsik 2013/05/14 12:53:57 Added some sanity checks.
33 const scoped_refptr<media::DecoderBuffer>& decoder_buffer) {
34 last_decoder_buffer_ = decoder_buffer;
35 read_event_.Signal();
36 }
37
38 void ExpectEqualsAndSignal(int32_t expected_result, int32_t actual_result) {
Ami GONE FROM CHROMIUM 2013/05/08 20:26:44 s/_result//g
Ami GONE FROM CHROMIUM 2013/05/08 20:26:44 s/_t//g
wonsik 2013/05/14 12:53:57 Done.
wonsik 2013/05/14 12:53:57 Well they are from the definition of webrtc::Video
39 EXPECT_EQ(expected_result, actual_result);
40 decoder_thread_event_.Signal();
41 }
42
43 void ExpectNotEqualsAndSignal(int32_t unexpected_result,
44 int32_t actual_result) {
45 EXPECT_NE(unexpected_result, actual_result);
46 decoder_thread_event_.Signal();
47 }
48
49 protected:
50 virtual void SetUp() OVERRIDE {
51 memset(&codec_, 0, sizeof(codec_));
52 message_loop_proxy_ = base::MessageLoopProxy::current();
53 input_image_._frameType = webrtc::kKeyFrame;
54 input_image_._encodedWidth = size_.width();
55 input_image_._encodedHeight = size_.height();
56 input_image_._completeFrame = true;
57 decoder_thread_.Start();
58 }
59
60 virtual void TearDown() OVERRIDE {
61 if (demuxer_) {
62 bridge_->ReleaseOwnership(&owner_factory_);
63 bridge_->DestroyDemuxer(demuxer_);
64 }
65 decoder_thread_.Stop();
66 }
67
68 base::Callback<void(int32_t)> BindExpectEquals(
69 int32_t expected_result) {
70 return base::Bind(&RTCVideoDecoderBridgeTvTest::ExpectEqualsAndSignal,
71 base::Unretained(this),
72 expected_result);
73 }
74
75 base::Callback<void(int32_t)> BindExpectNotEquals(
76 int32_t unexpected_result) {
77 return base::Bind(&RTCVideoDecoderBridgeTvTest::ExpectNotEqualsAndSignal,
78 base::Unretained(this),
79 unexpected_result);
80 }
81
82 base::Callback<int32_t(void)> BindInitDecode(
83 const webrtc::VideoCodec* codec,
84 int32_t num_cores) {
85 return base::Bind(&RTCVideoDecoderBridgeTv::InitDecode,
86 base::Unretained(bridge_),
87 codec,
88 num_cores);
89 }
90
91 base::Callback<int32_t(void)> BindDecode(
92 const webrtc::EncodedImage& input_image,
93 bool missing_frames,
94 const webrtc::RTPFragmentationHeader* fragmentation,
95 const webrtc::CodecSpecificInfo* info = NULL,
96 int64_t render_time_ms = -1) {
97 return base::Bind(&RTCVideoDecoderBridgeTv::Decode,
98 base::Unretained(bridge_),
99 input_image,
100 missing_frames,
101 fragmentation,
102 info,
103 render_time_ms);
104 }
105
106 void AcquireOwnershipAndCreateDemuxer() {
107 bridge_->AcquireOwnership(&owner_factory_);
Ami GONE FROM CHROMIUM 2013/05/08 20:26:44 What if this fails? (I'd say CHECK the return valu
wonsik 2013/05/14 12:53:57 Done.
108 demuxer_ = bridge_->CreateDemuxer(&owner_factory_, message_loop_proxy_);
109 }
110
111 void InitDecode() {
112 codec_.codecType = webrtc::kVideoCodecVP8;
113 codec_.width = size_.width();
114 codec_.height = size_.height();
115 base::PostTaskAndReplyWithResult(
116 decoder_thread_.message_loop_proxy(),
117 FROM_HERE,
118 BindInitDecode(&codec_, 1),
119 BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
120 decoder_thread_event_.Wait();
Ami GONE FROM CHROMIUM 2013/05/08 20:26:44 here and elsewhere, if expectations have already f
wonsik 2013/05/14 12:53:57 Done.
121 base::PostTaskAndReplyWithResult(
122 decoder_thread_.message_loop_proxy(),
123 FROM_HERE,
124 base::Bind(&RTCVideoDecoderBridgeTv::RegisterDecodeCompleteCallback,
125 base::Unretained(bridge_),
126 &decode_complete_callback_),
127 BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
128 decoder_thread_event_.Wait();
129 }
130
131 void GetVideoStream() {
132 video_stream_ = demuxer_->GetStream(media::DemuxerStream::VIDEO);
133 EXPECT_NE(static_cast<media::DemuxerStream*>(NULL), video_stream_);
134 EXPECT_EQ(media::kCodecVP8, video_stream_->video_decoder_config().codec());
135 EXPECT_EQ(size_, video_stream_->video_decoder_config().coded_size());
136 EXPECT_EQ(gfx::Rect(size_),
137 video_stream_->video_decoder_config().visible_rect());
138 EXPECT_EQ(size_, video_stream_->video_decoder_config().natural_size());
Ami GONE FROM CHROMIUM 2013/05/08 20:26:44 This would be a fantastic place to test support fo
139 }
140
141 void PostDecodeAndWait(int32_t expected_result,
142 const webrtc::EncodedImage& input_image,
143 bool missing_frames,
144 const webrtc::RTPFragmentationHeader* fragmentation,
145 const webrtc::CodecSpecificInfo* info = NULL,
146 int64_t render_time_ms = -1) {
147 base::PostTaskAndReplyWithResult(
148 decoder_thread_.message_loop_proxy(),
149 FROM_HERE,
150 BindDecode(
151 input_image, missing_frames, fragmentation, info, render_time_ms),
152 BindExpectEquals(expected_result));
153 decoder_thread_event_.Wait();
154 }
155
156 RTCVideoDecoderBridgeTv* bridge_;
157 MockMediaStreamDependencyFactory owner_factory_;
158 MockMediaStreamDependencyFactory non_owner_factory_;
159 base::MessageLoopProxy* message_loop_proxy_;
160 media::Demuxer* demuxer_;
161 media::DemuxerStream* video_stream_;
162 webrtc::VideoCodec codec_;
163 gfx::Size size_;
164 webrtc::EncodedImage input_image_;
165 unsigned char data_;
166 webrtc::MockDecodedImageCallback decode_complete_callback_;
167 base::WaitableEvent read_event_;
168 base::Thread decoder_thread_;
169 base::WaitableEvent decoder_thread_event_;
170 scoped_refptr<media::DecoderBuffer> last_decoder_buffer_;
171 };
172
173 TEST_F(RTCVideoDecoderBridgeTvTest, AcquireAndReleaseOwnership) {
174 EXPECT_TRUE(bridge_->AcquireOwnership(&owner_factory_));
175 EXPECT_FALSE(bridge_->AcquireOwnership(&non_owner_factory_));
176 bridge_->ReleaseOwnership(&owner_factory_);
177 }
178
179 TEST_F(RTCVideoDecoderBridgeTvTest, CreateDemuxerAfterAcquireOwnership) {
180 EXPECT_TRUE(bridge_->AcquireOwnership(&owner_factory_));
181 EXPECT_EQ(static_cast<media::Demuxer*>(NULL),
Ami GONE FROM CHROMIUM 2013/05/08 20:26:44 FWIW, here and elsewhere, instead of static_cast<L
wonsik 2013/05/14 12:53:57 Done.
182 bridge_->CreateDemuxer(&non_owner_factory_, message_loop_proxy_));
183 demuxer_ = bridge_->CreateDemuxer(&owner_factory_, message_loop_proxy_);
184 EXPECT_NE(static_cast<media::Demuxer*>(NULL), demuxer_);
185 }
186
187 TEST_F(RTCVideoDecoderBridgeTvTest, CreateDemuxerBeforeAcquireOwnership) {
188 RTCVideoDecoderBridgeTv* bridge_ = RTCVideoDecoderBridgeTv::Get();
189 demuxer_ = bridge_->CreateDemuxer(&owner_factory_, message_loop_proxy_);
190 EXPECT_NE(static_cast<media::Demuxer*>(NULL), demuxer_);
191 EXPECT_EQ(static_cast<media::Demuxer*>(NULL),
192 bridge_->CreateDemuxer(&non_owner_factory_, message_loop_proxy_));
193 EXPECT_FALSE(bridge_->AcquireOwnership(&non_owner_factory_));
194 EXPECT_TRUE(bridge_->AcquireOwnership(&owner_factory_));
Ami GONE FROM CHROMIUM 2013/05/08 20:26:44 here and elsewhere, always release. Since you're u
wonsik 2013/05/14 12:53:57 Done --- we're no longer using a singleton, and Te
195 }
196
197 TEST_F(RTCVideoDecoderBridgeTvTest, InitDecodeReturnsErrorOnNonVP8Codec) {
198 AcquireOwnershipAndCreateDemuxer();
199 codec_.codecType = webrtc::kVideoCodecI420;
200 base::PostTaskAndReplyWithResult(
201 decoder_thread_.message_loop_proxy(),
202 FROM_HERE,
203 BindInitDecode(&codec_, 1),
204 BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
205 decoder_thread_event_.Wait();
206 }
207
208 TEST_F(RTCVideoDecoderBridgeTvTest, InitDecodeReturnsErrorOnFeedbackMode) {
209 AcquireOwnershipAndCreateDemuxer();
210 codec_.codecType = webrtc::kVideoCodecVP8;
211 codec_.codecSpecific.VP8.feedbackModeOn = true;
212 base::PostTaskAndReplyWithResult(
213 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(RTCVideoDecoderBridgeTvTest, DecodeReturnsErrorBeforeInitDecode) {
221 AcquireOwnershipAndCreateDemuxer();
222 PostDecodeAndWait(
223 WEBRTC_VIDEO_CODEC_UNINITIALIZED, input_image_, false, NULL, NULL, 0);
224 }
225
226 TEST_F(RTCVideoDecoderBridgeTvTest, DecodeReturnsErrorOnDamagedBitstream) {
227 AcquireOwnershipAndCreateDemuxer();
228 InitDecode();
229 input_image_._completeFrame = false;
230 PostDecodeAndWait(
231 WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
232 }
233
234 TEST_F(RTCVideoDecoderBridgeTvTest, DecodeReturnsErrorOnMissingFrames) {
235 AcquireOwnershipAndCreateDemuxer();
236 InitDecode();
237 PostDecodeAndWait(
238 WEBRTC_VIDEO_CODEC_ERROR, input_image_, true, NULL, NULL, 0);
239 }
240
241 TEST_F(RTCVideoDecoderBridgeTvTest, GetNonVideoStreamFails) {
242 AcquireOwnershipAndCreateDemuxer();
243 InitDecode();
244 EXPECT_EQ(static_cast<media::DemuxerStream*>(NULL),
245 demuxer_->GetStream(media::DemuxerStream::AUDIO));
246 EXPECT_EQ(static_cast<media::DemuxerStream*>(NULL),
247 demuxer_->GetStream(media::DemuxerStream::UNKNOWN));
248 }
249
250 TEST_F(RTCVideoDecoderBridgeTvTest, GetVideoStreamSucceeds) {
251 AcquireOwnershipAndCreateDemuxer();
252 InitDecode();
253 GetVideoStream();
254 }
255
256 TEST_F(RTCVideoDecoderBridgeTvTest, DecodeReturnsErrorOnNonKeyFrameAtFirst) {
257 AcquireOwnershipAndCreateDemuxer();
258 InitDecode();
259 GetVideoStream();
260 input_image_._frameType = webrtc::kDeltaFrame;
261 PostDecodeAndWait(
262 WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
263 }
264
265 TEST_F(RTCVideoDecoderBridgeTvTest, DecodeUpdatesVideoSizeOnKeyFrame) {
266 AcquireOwnershipAndCreateDemuxer();
267 InitDecode();
268 GetVideoStream();
269 gfx::Size new_size(320, 240);
270 input_image_._encodedWidth = new_size.width();
271 input_image_._encodedHeight = new_size.height();
272 PostDecodeAndWait(
273 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
274 EXPECT_EQ(new_size, video_stream_->video_decoder_config().coded_size());
275 EXPECT_EQ(gfx::Rect(new_size),
276 video_stream_->video_decoder_config().visible_rect());
277 EXPECT_EQ(new_size, video_stream_->video_decoder_config().natural_size());
278 }
279
280 TEST_F(RTCVideoDecoderBridgeTvTest, DecodeAdjustsTimestampFromZero) {
281 AcquireOwnershipAndCreateDemuxer();
282 InitDecode();
283 GetVideoStream();
284 PostDecodeAndWait(
285 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10000);
286 video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
287 base::Unretained(this)));
288 read_event_.Wait();
289 EXPECT_EQ(base::TimeDelta::FromMilliseconds(0),
290 last_decoder_buffer_->GetTimestamp());
291 PostDecodeAndWait(
292 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10033);
293 video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
294 base::Unretained(this)));
295 read_event_.Wait();
296 EXPECT_EQ(base::TimeDelta::FromMilliseconds(33),
297 last_decoder_buffer_->GetTimestamp());
298 }
299
300 TEST_F(RTCVideoDecoderBridgeTvTest, DecodePassesDataCorrectly) {
301 AcquireOwnershipAndCreateDemuxer();
302 InitDecode();
303 GetVideoStream();
304 video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
305 base::Unretained(this)));
306 PostDecodeAndWait(
307 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
308 read_event_.Wait();
309 EXPECT_EQ(static_cast<int>(sizeof(data_)),
310 last_decoder_buffer_->GetDataSize());
311 EXPECT_EQ(data_, last_decoder_buffer_->GetData()[0]);
312 }
313
314 TEST_F(RTCVideoDecoderBridgeTvTest, NextReadTriggersDecodeCompleteCallback) {
315 EXPECT_CALL(decode_complete_callback_, Decoded(_))
316 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
317
318 AcquireOwnershipAndCreateDemuxer();
319 InitDecode();
320 GetVideoStream();
321 video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
322 base::Unretained(this)));
323 PostDecodeAndWait(
324 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
325 read_event_.Wait();
326 video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
327 base::Unretained(this)));
328 }
329
330 TEST_F(RTCVideoDecoderBridgeTvTest, ResetReturnsOk) {
331 AcquireOwnershipAndCreateDemuxer();
332 InitDecode();
333 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->Reset());
334 }
335
336 TEST_F(RTCVideoDecoderBridgeTvTest, ReleaseReturnsOk) {
337 AcquireOwnershipAndCreateDemuxer();
338 InitDecode();
339 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->Release());
340 }
341
342 } // content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698