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

Side by Side Diff: media/omx/omx_codec_unittest.cc

Issue 7066071: Removing defunct OpenMAX code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: removed tab Created 9 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « media/omx/mock_omx.cc ('k') | media/omx/omx_configurator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 #define _CRT_SECURE_NO_WARNINGS
6
7 #if 0
8 #include <deque>
9
10 #include "base/callback.h"
11 #include "base/message_loop.h"
12 #include "base/task.h"
13 #include "media/base/buffers.h"
14 #include "media/base/mock_filters.h"
15 #include "media/base/mock_task.h"
16 #include "media/ffmpeg/ffmpeg_common.h"
17 #include "media/video/omx_video_decode_engine.h"
18 #include "media/video/video_decode_engine.h"
19 #include "media/omx/mock_omx.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using ::testing::_;
23 using ::testing::DoAll;
24 using ::testing::InSequence;
25 using ::testing::IsNull;
26 using ::testing::NotNull;
27 using ::testing::Return;
28 using ::testing::SaveArg;
29 using ::testing::SetArgumentPointee;
30 using ::testing::StrEq;
31 using ::testing::StrictMock;
32
33 namespace media {
34
35 static const int kBufferCount = 3;
36 static const int kBufferSize = 4096;
37 static const char* kComponentName = "OMX.google.video_decoder.avc";
38
39 ACTION(ReturnComponentName) {
40 strcpy(((char**)arg2)[0], kComponentName);
41 }
42
43 ACTION(GetHandle) {
44 *arg0 = MockOmx::get()->component();
45 MockOmx::get()->component()->pApplicationPrivate = arg2;
46 memcpy(MockOmx::get()->callbacks(), arg3, sizeof(OMX_CALLBACKTYPE));
47 }
48
49 ACTION(GetParameterVideoInit) {
50 ((OMX_PORT_PARAM_TYPE*)arg1)->nStartPortNumber = 0;
51 }
52
53 ACTION(GetParameterPortDefinition) {
54 OMX_PARAM_PORTDEFINITIONTYPE* port_format =
55 (OMX_PARAM_PORTDEFINITIONTYPE*)arg1;
56 CHECK(port_format->nPortIndex == 0 || port_format->nPortIndex == 1);
57 if (port_format->nPortIndex == 0)
58 port_format->eDir = OMX_DirInput;
59 else
60 port_format->eDir = OMX_DirOutput;
61 port_format->nBufferCountMin = kBufferCount;
62 port_format->nBufferCountActual = kBufferCount;
63 port_format->nBufferSize = kBufferSize;
64 }
65
66 ACTION(AllocateBuffer) {
67 *arg0 = new OMX_BUFFERHEADERTYPE();
68 memset(*arg0, 0, sizeof(OMX_BUFFERHEADERTYPE));
69 (*arg0)->nAllocLen = arg3;
70 (*arg0)->pBuffer = new uint8[arg3];
71 (*arg0)->nOutputPortIndex = 1;
72 (*arg0)->nInputPortIndex = OMX_ALL;
73 }
74
75 ACTION(UseBuffer) {
76 *arg0 = new OMX_BUFFERHEADERTYPE();
77 memset(*arg0, 0, sizeof(OMX_BUFFERHEADERTYPE));
78 (*arg0)->nOutputPortIndex = OMX_ALL;
79 (*arg0)->nInputPortIndex = 0;
80 }
81
82 ACTION(FreeBuffer) {
83 if (1 == arg1->nOutputPortIndex)
84 delete [] arg1->pBuffer;
85 delete arg1;
86 }
87
88 ACTION_P3(SendEvent, event, data1, data2) {
89 (*MockOmx::get()->callbacks()->EventHandler)(
90 MockOmx::get()->component(),
91 MockOmx::get()->component()->pApplicationPrivate,
92 event, static_cast<OMX_U32>(data1), static_cast<OMX_U32>(data2), NULL);
93 }
94
95 ACTION_P(EmptyBufferDone, output_pool_ptr) {
96 (*MockOmx::get()->callbacks()->EmptyBufferDone)(
97 MockOmx::get()->component(),
98 MockOmx::get()->component()->pApplicationPrivate,
99 arg0);
100 OMX_BUFFERHEADERTYPE* out_buffer = output_pool_ptr->front();
101 output_pool_ptr->pop_front();
102 if (arg0->nFlags & OMX_BUFFERFLAG_EOS)
103 out_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
104 out_buffer->nFilledLen = kBufferSize;
105 (*MockOmx::get()->callbacks()->FillBufferDone)(
106 MockOmx::get()->component(),
107 MockOmx::get()->component()->pApplicationPrivate,
108 out_buffer);
109 }
110
111 ACTION_P(EnqueueOutputBuffer, output_pool_ptr) {
112 output_pool_ptr->push_back(arg0);
113 }
114
115 ACTION(FillEosBuffer) {
116 arg0->nFlags = OMX_BUFFERFLAG_EOS;
117 arg0->nFilledLen = 0;
118 (*MockOmx::get()->callbacks()->FillBufferDone)(
119 MockOmx::get()->component(),
120 MockOmx::get()->component()->pApplicationPrivate,
121 arg0);
122 }
123
124 class TestBuffer : public media::Buffer {
125 public:
126 TestBuffer() : size_(0), data_(NULL) { }
127 explicit TestBuffer(int size) : size_(size) {
128 if (size)
129 data_.reset(new uint8[size]);
130 else
131 data_.reset(NULL);
132 }
133 virtual const uint8* GetData() const {
134 return data_.get();
135 }
136 virtual size_t GetDataSize() const {
137 return size_;
138 }
139 private:
140 virtual ~TestBuffer() { }
141
142 int size_;
143 scoped_array<uint8> data_;
144 DISALLOW_COPY_AND_ASSIGN(TestBuffer);
145 };
146
147 class OmxCodecTest : public testing::Test {
148 public:
149 OmxCodecTest ()
150 : input_buffer_count_(0),
151 got_eos_(false),
152 omx_engine_(new OmxVideoDecodeEngine()) {
153 av_stream_.codec = &av_codec_context_;
154 av_codec_context_.width = 16;
155 av_codec_context_.height = 16;
156 feed_done_cb_ =
157 NewCallback(this, &OmxCodecTest::EmptyBufferDoneCallback);
158 decode_done_cb_ =
159 NewCallback(this, &OmxCodecTest::FillBufferDoneCallback);
160 }
161
162 ~OmxCodecTest() {
163 }
164
165 protected:
166 void ExpectSettings() {
167 // Return the component name.
168 EXPECT_CALL(*MockOmx::get(), GetComponentsOfRole(_, _, IsNull()))
169 .WillOnce(DoAll(SetArgumentPointee<1>(1),
170 Return(OMX_ErrorNone)));
171 EXPECT_CALL(*MockOmx::get(), GetComponentsOfRole(_, _, NotNull()))
172 .WillOnce(DoAll(SetArgumentPointee<1>(1),
173 ReturnComponentName(),
174 Return(OMX_ErrorNone)));
175
176 // Handle get parameter calls.
177 EXPECT_CALL(*MockOmx::get(),
178 GetParameter(OMX_IndexParamVideoInit, NotNull()))
179 .WillRepeatedly(DoAll(GetParameterVideoInit(), Return(OMX_ErrorNone)));
180 EXPECT_CALL(*MockOmx::get(),
181 GetParameter(OMX_IndexParamPortDefinition, NotNull()))
182 .WillRepeatedly(DoAll(GetParameterPortDefinition(),
183 Return(OMX_ErrorNone)));
184
185 // Ignore all set parameter calls.
186 EXPECT_CALL(*MockOmx::get(), SetParameter(_, _))
187 .WillRepeatedly(Return(OMX_ErrorNone));
188 }
189
190 void ExpectToLoaded() {
191 InSequence s;
192
193 // Expect initialization.
194 EXPECT_CALL(*MockOmx::get(), Init())
195 .WillOnce(Return(OMX_ErrorNone));
196
197 // Return the handle.
198 EXPECT_CALL(*MockOmx::get(),
199 GetHandle(NotNull(), StrEq(kComponentName),
200 NotNull(), NotNull()))
201 .WillOnce(DoAll(GetHandle(),
202 Return(OMX_ErrorNone)));
203 }
204
205 void ExpectLoadedToIdle() {
206 InSequence s;
207
208 // Expect transition to idle.
209 EXPECT_CALL(*MockOmx::get(),
210 SendCommand(OMX_CommandStateSet, OMX_StateIdle, _))
211 .WillOnce(
212 DoAll(
213 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
214 OMX_StateIdle),
215 Return(OMX_ErrorNone)));
216
217 // Expect allocation of buffers.
218 EXPECT_CALL(*MockOmx::get(),
219 UseBuffer(NotNull(), 0, NotNull(), kBufferSize, _))
220 .Times(kBufferCount)
221 .WillRepeatedly(DoAll(UseBuffer(), Return(OMX_ErrorNone)));
222
223 // Expect allocation of output buffers and send command complete.
224 EXPECT_CALL(*MockOmx::get(),
225 AllocateBuffer(NotNull(), 1, IsNull(), kBufferSize))
226 .Times(kBufferCount)
227 .WillRepeatedly(DoAll(AllocateBuffer(), Return(OMX_ErrorNone)));
228 }
229
230 void ExpectToExecuting() {
231 InSequence s;
232
233 // Expect transition to executing.
234 EXPECT_CALL(*MockOmx::get(),
235 SendCommand(OMX_CommandStateSet, OMX_StateExecuting, _))
236 .WillOnce(DoAll(
237 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
238 OMX_StateExecuting),
239 Return(OMX_ErrorNone)));
240
241 // Expect initial FillThisBuffer() calls.
242 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
243 .Times(kBufferCount)
244 .WillRepeatedly(DoAll(EnqueueOutputBuffer(&output_pool_),
245 Return(OMX_ErrorNone)));
246 }
247
248 void ExpectToIdle() {
249 // Expect going to idle
250 EXPECT_CALL(*MockOmx::get(),
251 SendCommand(OMX_CommandStateSet, OMX_StateIdle, _))
252 .WillOnce(DoAll(
253 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet, OMX_StateIdle),
254 Return(OMX_ErrorNone)));
255 }
256
257 void ExpectIdleToLoaded() {
258 InSequence s;
259
260 // Expect transition to loaded.
261 EXPECT_CALL(*MockOmx::get(),
262 SendCommand(OMX_CommandStateSet, OMX_StateLoaded, _))
263 .WillOnce(DoAll(
264 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
265 OMX_StateLoaded),
266 Return(OMX_ErrorNone)));
267
268 // Expect free buffer for input port.
269 EXPECT_CALL(*MockOmx::get(), FreeBuffer(0, NotNull()))
270 .Times(kBufferCount)
271 .WillRepeatedly(DoAll(FreeBuffer(), Return(OMX_ErrorNone)));
272
273 EXPECT_CALL(*MockOmx::get(), FreeBuffer(1, NotNull()))
274 .Times(kBufferCount)
275 .WillRepeatedly(DoAll(FreeBuffer(), Return(OMX_ErrorNone)));
276 }
277
278 void ExpectToEmpty() {
279 InSequence s;
280
281 EXPECT_CALL(*MockOmx::get(), FreeHandle(MockOmx::get()->component()))
282 .WillOnce(Return(OMX_ErrorNone));
283 EXPECT_CALL(*MockOmx::get(), Deinit())
284 .WillOnce(Return(OMX_ErrorNone));
285 }
286
287 // TODO(hclam): Make a more generic about when to stop.
288 void ExpectStart() {
289 ExpectToLoaded();
290 ExpectLoadedToIdle();
291 ExpectToExecuting();
292 EXPECT_CALL(init_done_cb_task_, Run());
293 }
294
295 void ExpectStop() {
296 EXPECT_CALL(stop_task_, Run());
297 ExpectToIdle();
298 ExpectIdleToLoaded();
299 ExpectToEmpty();
300 }
301
302 void EmptyBufferDoneCallback(scoped_refptr<Buffer> buffer) {
303 if (buffer.get()) {
304 input_units_.push_back(buffer);
305 } else {
306 input_buffer_count_++;
307 scoped_refptr<Buffer> buffer_ref = new TestBuffer(input_buffer_count_);
308 input_units_.push_back(buffer_ref);
309 }
310 }
311
312 void FillBufferDoneCallback(scoped_refptr<VideoFrame> frame) {
313 output_units_.push_back(frame);
314 if (frame->IsEndOfStream())
315 got_eos_ = true;
316 }
317
318 void MakeEmptyBufferRequest() {
319 scoped_refptr<Buffer> buffer = input_units_.front();
320 input_units_.pop_front();
321 omx_engine_->EmptyThisBuffer(buffer);
322 }
323
324 void SendEOSInputBuffer() {
325 input_units_.pop_front();
326 scoped_refptr<Buffer> buffer_ref = new TestBuffer();
327 input_units_.push_front(buffer_ref);
328 EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
329 .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
330 .RetiresOnSaturation();
331 MakeEmptyBufferRequest();
332 message_loop_.RunAllPending();
333 }
334
335 int input_buffer_count_;
336
337 std::deque<scoped_refptr<Buffer> > input_units_;
338 std::deque<scoped_refptr<VideoFrame> > output_units_;
339 std::deque<OMX_BUFFERHEADERTYPE*> fill_this_buffer_received_;
340 std::deque<OMX_BUFFERHEADERTYPE*> output_pool_;
341
342 MockOmx mock_omx_;
343
344 bool got_eos_;
345 MessageLoop message_loop_;
346 scoped_refptr<OmxVideoDecodeEngine> omx_engine_;
347
348 AVStream av_stream_;
349 AVCodecContext av_codec_context_;
350
351 VideoDecodeEngine::ProduceVideoSampleCallback* feed_done_cb_;
352 VideoDecodeEngine::ConsumeVideoFrameCallback* decode_done_cb_;
353 TaskMocker init_done_cb_task_;
354
355 TaskMocker stop_task_;
356
357 private:
358 DISALLOW_COPY_AND_ASSIGN(OmxCodecTest);
359 };
360
361 TEST_F(OmxCodecTest, SimpleStartAndStop) {
362 ExpectSettings();
363 ExpectStart();
364 omx_engine_->Initialize(&message_loop_,
365 &av_stream_,
366 feed_done_cb_,
367 decode_done_cb_,
368 init_done_cb_task_.CreateTask());
369 message_loop_.RunAllPending();
370
371 EXPECT_EQ(kBufferCount, input_buffer_count_);
372 EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
373
374 ExpectStop();
375 omx_engine_->Stop(stop_task_.CreateTask());
376 message_loop_.RunAllPending();
377 }
378
379 TEST_F(OmxCodecTest, NormalFlow) {
380 ExpectSettings();
381 ExpectStart();
382 omx_engine_->Initialize(&message_loop_,
383 &av_stream_,
384 feed_done_cb_,
385 decode_done_cb_,
386 init_done_cb_task_.CreateTask());
387 message_loop_.RunAllPending();
388
389 EXPECT_EQ(kBufferCount, input_buffer_count_);
390 EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
391
392 // Make emptybuffer requests.
393 EXPECT_EQ(0u, output_units_.size());
394 int count = output_pool_.size();
395 for (int i = 0; i < kBufferCount; ++i) {
396 // Give input buffers to OmxVideoDecodeEngine. OmxVideoDecodeEngine will
397 // make a new FillThisBuffer() call for each read.
398 EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
399 .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
400 .RetiresOnSaturation();
401 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
402 .WillOnce(DoAll(EnqueueOutputBuffer(&output_pool_),
403 Return(OMX_ErrorNone)))
404 .RetiresOnSaturation();
405 MakeEmptyBufferRequest();
406 }
407 message_loop_.RunAllPending();
408 EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
409 EXPECT_EQ(kBufferCount, static_cast<int>(output_units_.size()));
410 EXPECT_EQ(count, static_cast<int>(output_pool_.size()));
411 output_units_.clear();
412
413 // Send EndOfStream, expect eos flag.
414 SendEOSInputBuffer();
415 EXPECT_EQ(kBufferCount - 1, static_cast<int>(input_units_.size()));
416 EXPECT_EQ(1, static_cast<int>(output_units_.size()));
417 EXPECT_EQ(count - 1, static_cast<int>(output_pool_.size()));
418 EXPECT_TRUE(got_eos_);
419
420 // Shutdown.
421 ExpectStop();
422 omx_engine_->Stop(stop_task_.CreateTask());
423 message_loop_.RunAllPending();
424 }
425
426 TEST_F(OmxCodecTest, RecycleInputBuffers) {
427 ExpectSettings();
428 ExpectStart();
429 omx_engine_->Initialize(&message_loop_,
430 &av_stream_,
431 feed_done_cb_,
432 decode_done_cb_,
433 init_done_cb_task_.CreateTask());
434 message_loop_.RunAllPending();
435
436 EXPECT_EQ(kBufferCount, input_buffer_count_);
437 EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
438
439 // Make emptybuffer requests, also recycle input buffers
440 EXPECT_EQ(0u, output_units_.size());
441 int count = output_pool_.size();
442 int repeat_count = kBufferCount * 2;
443 for (int i = 0; i < repeat_count; ++i) {
444 // Give input buffers to OmxVideoDecodeEngine. OmxVideoDecodeEngine will
445 // make a new FillThisBuffer() call for each read.
446 EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
447 .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
448 .RetiresOnSaturation();
449 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
450 .WillOnce(DoAll(EnqueueOutputBuffer(&output_pool_),
451 Return(OMX_ErrorNone)))
452 .RetiresOnSaturation();
453 MakeEmptyBufferRequest();
454 message_loop_.RunAllPending();
455 CHECK(kBufferCount == static_cast<int>(input_units_.size()));
456 CHECK(((i % kBufferCount) + 1) ==
457 static_cast<int>(input_units_.back()->GetDataSize()));
458 }
459 message_loop_.RunAllPending();
460 EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
461 EXPECT_EQ(repeat_count, static_cast<int>(output_units_.size()));
462 EXPECT_EQ(count, static_cast<int>(output_pool_.size()));
463 output_units_.clear();
464
465 // Send EndOfStream, expect eos flag.
466 SendEOSInputBuffer();
467 EXPECT_EQ(kBufferCount - 1, static_cast<int>(input_units_.size()));
468 EXPECT_EQ(1, static_cast<int>(output_units_.size()));
469 EXPECT_EQ(count - 1, static_cast<int>(output_pool_.size()));
470 EXPECT_TRUE(got_eos_);
471
472 // Shutdown.
473 ExpectStop();
474 omx_engine_->Stop(stop_task_.CreateTask());
475 message_loop_.RunAllPending();
476 }
477
478 // TODO(hclam): Add test case for dynamic port config.
479 // TODO(hclam): Create a more complicated test case so that read
480 // requests and reply from FillThisBuffer() arrives out of order.
481
482 } // namespace media
483 #endif
OLDNEW
« no previous file with comments | « media/omx/mock_omx.cc ('k') | media/omx/omx_configurator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698