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

Side by Side Diff: media/omx/omx_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/omx_configurator.cc ('k') | media/omx/run_all_unittests.cc » ('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 #include "base/command_line.h"
6 #include "base/logging.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/openmax/il/OMX_Component.h"
10 #include "third_party/openmax/il/OMX_Core.h"
11
12 namespace media {
13
14 // Defines the maximum number of buffers created for I/O ports.
15 static const int kMaxBufferNum = 256;
16
17 template <typename T>
18 static void ResetHeader(T* param) {
19 memset(param, 0, sizeof(T));
20 // TODO(hclam): Make this version number configurable.
21 param->nVersion.nVersion = 0x00000101;
22 param->nSize = sizeof(T);
23 }
24
25 class OmxTest : public testing::Test {
26 public:
27 OmxTest()
28 : handle_(NULL),
29 event_(false, false),
30 empty_buffer_(false, false),
31 fill_buffer_(false, false),
32 last_event_type_(OMX_EventMax),
33 last_event_data1_(0),
34 last_event_data2_(0) {
35 memset(input_buffers_, 0, sizeof(input_buffers_));
36 memset(output_buffers_, 0, sizeof(output_buffers_));
37 }
38
39 protected:
40 virtual void SetUp() {
41 // Initialize OpenMAX.
42 EXPECT_EQ(OMX_ErrorNone, OMX_Init());
43 }
44
45 virtual void TearDown() {
46 EXPECT_EQ(OMX_ErrorNone, OMX_Deinit());
47 }
48
49 void InitComponent(std::string component_name) {
50 // TODO(hclam): Remove static when bug in driver is fixed.
51 static OMX_CALLBACKTYPE callback = { &EventHandler,
52 &EmptyBufferCallback,
53 &FillBufferCallback };
54
55 OMX_ERRORTYPE omxresult = OMX_GetHandle(
56 (void**)&handle_,
57 const_cast<OMX_STRING>(component_name.c_str()),
58 this, &callback);
59 EXPECT_EQ(OMX_ErrorNone, omxresult);
60 CHECK(handle_);
61 }
62
63 void DeinitComponent() {
64 if (handle_)
65 OMX_FreeHandle(handle_);
66 }
67
68 void AllocateBuffers(int port) {
69 int count = 0;
70 int size = 0;
71 OMX_BUFFERHEADERTYPE** buffers = NULL;
72 if (port == input_port_) {
73 count = input_buffer_count_;
74 size = input_buffer_size_;
75 buffers = input_buffers_;
76 } else if (port == output_port_) {
77 count = output_buffer_count_;
78 size = output_buffer_size_;
79 buffers = output_buffers_;
80 } else {
81 NOTREACHED() << "Not a valid port";
82 }
83 for (int i = 0; i < count; ++i) {
84 EXPECT_EQ(OMX_ErrorNone,
85 OMX_AllocateBuffer(handle_, buffers + i,
86 port, NULL, size));
87 }
88 }
89
90 void ReleaseBuffers(int port) {
91 int count = 0;
92 OMX_BUFFERHEADERTYPE** buffers = NULL;
93 if (port == input_port_) {
94 count = input_buffer_count_;
95 buffers = input_buffers_;
96 } else if (port == output_port_) {
97 count = output_buffer_count_;
98 buffers = output_buffers_;
99 } else {
100 NOTREACHED() << "Not a valid port";
101 }
102 for (int i = 0; i < count; ++i) {
103 CHECK(buffers[i]);
104 EXPECT_EQ(OMX_ErrorNone,
105 OMX_FreeBuffer(handle_, port, buffers[i]));
106 buffers[i] = NULL;
107 }
108 }
109
110 void TransitionLoadedToIdle() {
111 EXPECT_EQ(OMX_ErrorNone,
112 OMX_SendCommand(handle_, OMX_CommandStateSet,
113 OMX_StateIdle, 0));
114 AllocateBuffers(input_port_);
115 AllocateBuffers(output_port_);
116 event_.Wait();
117 EXPECT_EQ(OMX_EventCmdComplete, last_event_type_);
118 EXPECT_EQ(OMX_CommandStateSet, last_event_data1_);
119 EXPECT_EQ(OMX_StateIdle, last_event_data2_);
120 }
121
122 void TransitionIdleToLoaded() {
123 EXPECT_EQ(OMX_ErrorNone,
124 OMX_SendCommand(handle_, OMX_CommandStateSet,
125 OMX_StateLoaded, 0));
126 ReleaseBuffers(input_port_);
127 ReleaseBuffers(output_port_);
128 event_.Wait();
129 EXPECT_EQ(OMX_EventCmdComplete, last_event_type_);
130 EXPECT_EQ(OMX_CommandStateSet, last_event_data1_);
131 EXPECT_EQ(OMX_StateLoaded, last_event_data2_);
132 }
133
134 void TransitionIdleToExecuting() {
135 EXPECT_EQ(OMX_ErrorNone,
136 OMX_SendCommand(handle_, OMX_CommandStateSet,
137 OMX_StateExecuting, 0));
138 event_.Wait();
139 EXPECT_EQ(OMX_EventCmdComplete, last_event_type_);
140 EXPECT_EQ(OMX_CommandStateSet, last_event_data1_);
141 EXPECT_EQ(OMX_StateExecuting, last_event_data2_);
142 }
143
144 void TransitionExecutingToIdle() {
145 EXPECT_EQ(OMX_ErrorNone,
146 OMX_SendCommand(handle_, OMX_CommandStateSet,
147 OMX_StateIdle, 0));
148 event_.Wait();
149 EXPECT_EQ(OMX_EventCmdComplete, last_event_type_);
150 EXPECT_EQ(OMX_CommandStateSet, last_event_data1_);
151 EXPECT_EQ(OMX_StateIdle, last_event_data2_);
152 }
153
154 void GetComponentsOfRole(std::string role) {
155 OMX_U32 roles = 0;
156 OMX_U8** component_names = NULL;
157 const int kSize = 256;
158
159 LOG(INFO) << "GetComponentsOfRole: " << role;
160 EXPECT_EQ(OMX_ErrorNone, OMX_GetComponentsOfRole(
161 const_cast<OMX_STRING>(role.c_str()), &roles, 0));
162
163 // TODO(hclam): Should assert the component number.
164 LOG(INFO) << "Components: " << roles;
165
166 if (roles) {
167 component_names = new OMX_U8*[roles];
168 for (size_t i = 0; i < roles; ++i)
169 component_names[i] = new OMX_U8[kSize];
170
171 OMX_U32 roles_backup = roles;
172 EXPECT_EQ(OMX_ErrorNone,
173 OMX_GetComponentsOfRole(
174 const_cast<OMX_STRING>(role.c_str()),
175 &roles, component_names));
176 ASSERT_EQ(roles_backup, roles);
177
178 for (size_t i = 0; i < roles; ++i) {
179 LOG(INFO) << "Component name: " << component_names[i];
180 delete [] component_names[i];
181 }
182 delete [] component_names;
183 }
184 }
185
186 OMX_ERRORTYPE EventHandlerInternal(
187 OMX_HANDLETYPE component, OMX_EVENTTYPE event,
188 OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data) {
189 last_event_type_ = event;
190 last_event_data1_ = static_cast<int>(data1);
191 last_event_data2_ = static_cast<int>(data2);
192 // TODO(hclam): Save |event_data|.
193 event_.Signal();
194 return OMX_ErrorNone;
195 }
196
197 OMX_ERRORTYPE EmptyBufferCallbackInternal(
198 OMX_HANDLETYPE component, OMX_BUFFERHEADERTYPE* buffer) {
199 // TODO(hclam): Add code here.
200 empty_buffer_.Signal();
201 return OMX_ErrorNone;
202 }
203
204 OMX_ERRORTYPE FillBufferCallbackInternal(
205 OMX_HANDLETYPE component, OMX_BUFFERHEADERTYPE* buffer) {
206 // TODO(hclam): Add code here.
207 fill_buffer_.Signal();
208 return OMX_ErrorNone;
209 }
210
211 // Static callback methods.
212 static OMX_ERRORTYPE EventHandler(
213 OMX_HANDLETYPE component, OMX_PTR priv_data,
214 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2,
215 OMX_PTR event_data) {
216 return static_cast<OmxTest*>(priv_data)
217 ->EventHandlerInternal(component,
218 event, data1, data2, event_data);
219 }
220
221 static OMX_ERRORTYPE EmptyBufferCallback(
222 OMX_HANDLETYPE component, OMX_PTR priv_data,
223 OMX_BUFFERHEADERTYPE* buffer) {
224 return static_cast<OmxTest*>(priv_data)
225 ->EmptyBufferCallbackInternal(component, buffer);
226 }
227
228 static OMX_ERRORTYPE FillBufferCallback(
229 OMX_HANDLETYPE component, OMX_PTR priv_data,
230 OMX_BUFFERHEADERTYPE* buffer) {
231 return static_cast<OmxTest*>(priv_data)
232 ->FillBufferCallbackInternal(component, buffer);
233 }
234
235 OMX_COMPONENTTYPE* handle_;
236 int input_port_;
237 int output_port_;
238 int input_buffer_count_;
239 int input_buffer_size_;
240 int output_buffer_count_;
241 int output_buffer_size_;
242 OMX_BUFFERHEADERTYPE* input_buffers_[kMaxBufferNum];
243 OMX_BUFFERHEADERTYPE* output_buffers_[kMaxBufferNum];
244
245 base::WaitableEvent event_;
246 base::WaitableEvent empty_buffer_;
247 base::WaitableEvent fill_buffer_;
248
249 OMX_EVENTTYPE last_event_type_;
250 int last_event_data1_;
251 int last_event_data2_;
252 };
253
254 class OmxVideoDecoderTest : public OmxTest {
255 protected:
256 void Configure(OMX_VIDEO_CODINGTYPE codec,
257 int width, int height) {
258 // Obtain port IDs.
259 OMX_PORT_PARAM_TYPE port_param;
260 ResetHeader(&port_param);
261 EXPECT_EQ(OMX_ErrorNone,
262 OMX_GetParameter(handle_,
263 OMX_IndexParamVideoInit,
264 &port_param));
265
266 input_port_ = port_param.nStartPortNumber;
267 output_port_ = port_param.nStartPortNumber + 1;
268 LOG(INFO) << "Input port number: " << input_port_;
269 LOG(INFO) << "Output port number: " << output_port_;
270
271 // Get and set parameters for input port.
272 LOG(INFO) << "Input port width: " << width;
273 LOG(INFO) << "Input port height: " << height;
274 LOG(INFO) << "Input port codec: " << codec;
275 OMX_PARAM_PORTDEFINITIONTYPE port_format;
276 ResetHeader(&port_format);
277 port_format.nPortIndex = input_port_;
278 EXPECT_EQ(OMX_ErrorNone,
279 OMX_GetParameter(handle_,
280 OMX_IndexParamPortDefinition,
281 &port_format));
282 EXPECT_EQ(OMX_DirInput, port_format.eDir);
283 port_format.format.video.eCompressionFormat = codec;
284 port_format.format.video.nFrameWidth = width;
285 port_format.format.video.nFrameHeight = height;
286 EXPECT_EQ(OMX_ErrorNone,
287 OMX_SetParameter(handle_,
288 OMX_IndexParamPortDefinition,
289 &port_format));
290
291 // TODO(hclam): Add configurations to output port.
292
293 // Get Parameters for input port.
294 ResetHeader(&port_format);
295 port_format.nPortIndex = input_port_;
296 EXPECT_EQ(OMX_ErrorNone,
297 OMX_GetParameter(handle_,
298 OMX_IndexParamPortDefinition,
299 &port_format));
300 EXPECT_EQ(OMX_DirInput, port_format.eDir);
301 input_buffer_count_ = port_format.nBufferCountMin;
302 input_buffer_size_ = port_format.nBufferSize;
303 CHECK(input_buffer_count_ < kMaxBufferNum);
304
305 // Get parameters for output port.
306 ResetHeader(&port_format);
307 port_format.nPortIndex = output_port_;
308 EXPECT_EQ(OMX_ErrorNone,
309 OMX_GetParameter(handle_,
310 OMX_IndexParamPortDefinition,
311 &port_format));
312 EXPECT_EQ(OMX_DirOutput, port_format.eDir);
313 output_buffer_count_ = port_format.nBufferCountMin;
314 output_buffer_size_ = port_format.nBufferSize;
315 CHECK(output_buffer_count_ < kMaxBufferNum);
316
317 LOG(INFO) << "Input buffer count: " << input_buffer_count_;
318 LOG(INFO) << "Input buffer size: " << input_buffer_size_;
319 LOG(INFO) << "Output buffer count: " << output_buffer_count_;
320 LOG(INFO) << "Output buffer size: " << output_buffer_size_;
321 }
322
323 std::string component() {
324 return CommandLine::ForCurrentProcess()
325 ->GetSwitchValueASCII("video-decoder-component");
326 }
327
328 OMX_VIDEO_CODINGTYPE codec() {
329 std::string codec = CommandLine::ForCurrentProcess()
330 ->GetSwitchValueASCII("video-decoder-codec");
331 if (codec == "h264")
332 return OMX_VIDEO_CodingAVC;
333 return OMX_VIDEO_CodingAutoDetect;
334 }
335 };
336
337 TEST_F(OmxTest, SimpleInit) {
338 // A empty test case will test basic init/deinit of OpenMAX library.
339 }
340
341 TEST_F(OmxTest, GetComponentsOfRole) {
342 // Roles video decoders.
343 GetComponentsOfRole("video_decoder.avc");
344 GetComponentsOfRole("video_decoder.mpeg4");
345 GetComponentsOfRole("video_decoder.vc1");
346
347 // TODO(hclam): Add roles of encoders.
348 }
349
350 TEST_F(OmxVideoDecoderTest, GetHandle) {
351 // TODO(hclam): Should use GetComponentsOfRole instead.
352 InitComponent(component());
353 DeinitComponent();
354 }
355
356 TEST_F(OmxVideoDecoderTest, Configuration) {
357 InitComponent(component());
358 // TODO(hclam): Make resolution configurable.
359 Configure(codec(), 1024, 768);
360 DeinitComponent();
361 }
362
363 TEST_F(OmxVideoDecoderTest, TransitionToIdle) {
364 InitComponent(component());
365 Configure(codec(), 1024, 768);
366 TransitionLoadedToIdle();
367 TransitionIdleToLoaded();
368 DeinitComponent();
369 }
370
371 TEST_F(OmxVideoDecoderTest, FreeHandleWhenIdle) {
372 InitComponent(component());
373 Configure(codec(), 1024, 768);
374 TransitionLoadedToIdle();
375 DeinitComponent();
376 }
377
378 TEST_F(OmxVideoDecoderTest, TransitionToExecuting) {
379 InitComponent(component());
380 Configure(codec(), 1024, 768);
381 TransitionLoadedToIdle();
382 TransitionIdleToExecuting();
383 TransitionExecutingToIdle();
384 TransitionIdleToLoaded();
385 DeinitComponent();
386 }
387
388 TEST_F(OmxVideoDecoderTest, FreeHandleWhenExecuting) {
389 InitComponent(component());
390 Configure(codec(), 1024, 768);
391 TransitionLoadedToIdle();
392 TransitionIdleToExecuting();
393 DeinitComponent();
394 }
395
396 TEST_F(OmxVideoDecoderTest, CallbacksAreCopied) {
397 // Allocate a callback struct on stack and clear it with zero.
398 // This make sure OpenMAX library will copy the content of the
399 // struct.
400 OMX_CALLBACKTYPE callback = { &EventHandler,
401 &EmptyBufferCallback,
402 &FillBufferCallback };
403
404 OMX_ERRORTYPE omxresult = OMX_GetHandle(
405 (void**)&handle_,
406 const_cast<OMX_STRING>(component().c_str()),
407 this, &callback);
408 EXPECT_EQ(OMX_ErrorNone, omxresult);
409 CHECK(handle_);
410 memset(&callback, 0, sizeof(callback));
411
412 // Then configure the component as usual.
413 Configure(codec(), 1024, 768);
414 TransitionLoadedToIdle();
415 TransitionIdleToExecuting();
416 TransitionExecutingToIdle();
417 TransitionIdleToLoaded();
418 DeinitComponent();
419 }
420
421 } // namespace media
OLDNEW
« no previous file with comments | « media/omx/omx_configurator.cc ('k') | media/omx/run_all_unittests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698