OSDN Git Service

release-request-e04bb055-13fc-41a1-8a9f-7fb10894ec3d-for-git_oc-mr1-release-4189380...
[android-x86/hardware-interfaces.git] / media / omx / 1.0 / vts / functional / common / media_hidl_test_common.cpp
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define LOG_TAG "media_omx_hidl_video_test_common"
18
19 #ifdef __LP64__
20 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
21 #endif
22
23 #include <android-base/logging.h>
24
25 #include <android/hardware/media/omx/1.0/IOmx.h>
26 #include <android/hardware/media/omx/1.0/IOmxNode.h>
27 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
28 #include <android/hardware/media/omx/1.0/types.h>
29 #include <android/hidl/allocator/1.0/IAllocator.h>
30 #include <android/hidl/memory/1.0/IMapper.h>
31 #include <android/hidl/memory/1.0/IMemory.h>
32
33 using ::android::hardware::media::omx::V1_0::IOmx;
34 using ::android::hardware::media::omx::V1_0::IOmxObserver;
35 using ::android::hardware::media::omx::V1_0::IOmxNode;
36 using ::android::hardware::media::omx::V1_0::Message;
37 using ::android::hardware::media::omx::V1_0::CodecBuffer;
38 using ::android::hardware::media::omx::V1_0::PortMode;
39 using ::android::hardware::media::omx::V1_0::Status;
40 using ::android::hidl::allocator::V1_0::IAllocator;
41 using ::android::hidl::memory::V1_0::IMemory;
42 using ::android::hidl::memory::V1_0::IMapper;
43 using ::android::hardware::Return;
44 using ::android::hardware::Void;
45 using ::android::hardware::hidl_vec;
46 using ::android::hardware::hidl_string;
47 using ::android::sp;
48
49 #include <VtsHalHidlTargetTestBase.h>
50 #include <hidlmemory/mapping.h>
51 #include <media/hardware/HardwareAPI.h>
52 #include <media_hidl_test_common.h>
53 #include <memory>
54
55 // set component role
56 Return<android::hardware::media::omx::V1_0::Status> setRole(
57     sp<IOmxNode> omxNode, const char* role) {
58     OMX_PARAM_COMPONENTROLETYPE params;
59     strcpy((char*)params.cRole, role);
60     return setParam(omxNode, OMX_IndexParamStandardComponentRole, &params);
61 }
62
63 // get/set video component port format
64 Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
65     sp<IOmxNode> omxNode, OMX_U32 portIndex,
66     OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
67     OMX_U32 xFramerate) {
68     OMX_U32 index = 0;
69     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
70     std::vector<OMX_COLOR_FORMATTYPE> arrColorFormat;
71     std::vector<OMX_VIDEO_CODINGTYPE> arrCompressionFormat;
72     android::hardware::media::omx::V1_0::Status status;
73
74     while (1) {
75         portFormat.nIndex = index;
76         status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
77                               &portFormat);
78         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
79         if (eCompressionFormat == OMX_VIDEO_CodingUnused)
80             arrColorFormat.push_back(portFormat.eColorFormat);
81         else
82             arrCompressionFormat.push_back(portFormat.eCompressionFormat);
83         index++;
84         if (index == 512) {
85             // enumerated way too many formats, highly unusual for this to
86             // happen.
87             EXPECT_LE(index, 512U)
88                 << "Expecting OMX_ErrorNoMore but not received";
89             break;
90         }
91     }
92     if (!index) return status;
93     if (eCompressionFormat == OMX_VIDEO_CodingUnused) {
94         for (index = 0; index < arrColorFormat.size(); index++) {
95             if (arrColorFormat[index] == eColorFormat) {
96                 portFormat.eColorFormat = arrColorFormat[index];
97                 break;
98             }
99         }
100         if (index == arrColorFormat.size()) {
101             ALOGE("setting default color format %x", (int)arrColorFormat[0]);
102             portFormat.eColorFormat = arrColorFormat[0];
103         }
104         portFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
105     } else {
106         for (index = 0; index < arrCompressionFormat.size(); index++) {
107             if (arrCompressionFormat[index] == eCompressionFormat) {
108                 portFormat.eCompressionFormat = arrCompressionFormat[index];
109                 break;
110             }
111         }
112         if (index == arrCompressionFormat.size()) {
113             ALOGE("setting default compression format %x",
114                   (int)arrCompressionFormat[0]);
115             portFormat.eCompressionFormat = arrCompressionFormat[0];
116         }
117         portFormat.eColorFormat = OMX_COLOR_FormatUnused;
118     }
119     // In setParam call nIndex shall be ignored as per omx-il specification.
120     // see how this holds up by corrupting nIndex
121     portFormat.nIndex = RANDOM_INDEX;
122     portFormat.xFramerate = xFramerate;
123     status = setPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
124                           &portFormat);
125     return status;
126 }
127
128 // get/set audio component port format
129 Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
130     sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding) {
131     OMX_U32 index = 0;
132     OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
133     std::vector<OMX_AUDIO_CODINGTYPE> arrEncoding;
134     android::hardware::media::omx::V1_0::Status status;
135
136     while (1) {
137         portFormat.nIndex = index;
138         status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
139                               &portFormat);
140         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
141         arrEncoding.push_back(portFormat.eEncoding);
142         index++;
143         if (index == 512) {
144             // enumerated way too many formats, highly unusual for this to
145             // happen.
146             EXPECT_LE(index, 512U)
147                 << "Expecting OMX_ErrorNoMore but not received";
148             break;
149         }
150     }
151     if (!index) return status;
152     for (index = 0; index < arrEncoding.size(); index++) {
153         if (arrEncoding[index] == eEncoding) {
154             portFormat.eEncoding = arrEncoding[index];
155             break;
156         }
157     }
158     if (index == arrEncoding.size()) {
159         ALOGE("setting default Port format %x", (int)arrEncoding[0]);
160         portFormat.eEncoding = arrEncoding[0];
161     }
162     // In setParam call nIndex shall be ignored as per omx-il specification.
163     // see how this holds up by corrupting nIndex
164     portFormat.nIndex = RANDOM_INDEX;
165     status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
166                           &portFormat);
167     return status;
168 }
169
170 // allocate buffers needed on a component port
171 void allocatePortBuffers(sp<IOmxNode> omxNode,
172                          android::Vector<BufferInfo>* buffArray,
173                          OMX_U32 portIndex, PortMode portMode) {
174     android::hardware::media::omx::V1_0::Status status;
175     OMX_PARAM_PORTDEFINITIONTYPE portDef;
176
177     buffArray->clear();
178
179     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
180                           &portDef);
181     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
182
183     if (portMode == PortMode::PRESET_SECURE_BUFFER) {
184         for (size_t i = 0; i < portDef.nBufferCountActual; i++) {
185             BufferInfo buffer;
186             buffer.owner = client;
187             buffer.omxBuffer.type = CodecBuffer::Type::NATIVE_HANDLE;
188             omxNode->allocateSecureBuffer(
189                 portIndex, portDef.nBufferSize,
190                 [&status, &buffer](
191                     android::hardware::media::omx::V1_0::Status _s, uint32_t id,
192                     ::android::hardware::hidl_handle const& nativeHandle) {
193                     status = _s;
194                     buffer.id = id;
195                     buffer.omxBuffer.nativeHandle = nativeHandle;
196                 });
197             buffArray->push(buffer);
198             ASSERT_EQ(status,
199                       ::android::hardware::media::omx::V1_0::Status::OK);
200         }
201     } else if (portMode == PortMode::PRESET_BYTE_BUFFER ||
202                portMode == PortMode::DYNAMIC_ANW_BUFFER) {
203         sp<IAllocator> allocator = IAllocator::getService("ashmem");
204         EXPECT_NE(allocator.get(), nullptr);
205
206         for (size_t i = 0; i < portDef.nBufferCountActual; i++) {
207             BufferInfo buffer;
208             buffer.owner = client;
209             buffer.omxBuffer.type = CodecBuffer::Type::SHARED_MEM;
210             buffer.omxBuffer.attr.preset.rangeOffset = 0;
211             buffer.omxBuffer.attr.preset.rangeLength = 0;
212             bool success = false;
213             if (portMode != PortMode::PRESET_BYTE_BUFFER) {
214                 portDef.nBufferSize = sizeof(android::VideoNativeMetadata);
215             }
216             allocator->allocate(
217                 portDef.nBufferSize,
218                 [&success, &buffer](
219                     bool _s, ::android::hardware::hidl_memory const& mem) {
220                     success = _s;
221                     buffer.omxBuffer.sharedMemory = mem;
222                 });
223             ASSERT_EQ(success, true);
224             ASSERT_EQ(buffer.omxBuffer.sharedMemory.size(),
225                       portDef.nBufferSize);
226             buffer.mMemory = mapMemory(buffer.omxBuffer.sharedMemory);
227             ASSERT_NE(buffer.mMemory, nullptr);
228             if (portMode == PortMode::DYNAMIC_ANW_BUFFER) {
229                 android::VideoNativeMetadata* metaData =
230                     static_cast<android::VideoNativeMetadata*>(
231                         static_cast<void*>(buffer.mMemory->getPointer()));
232                 metaData->nFenceFd = -1;
233                 buffer.slot = -1;
234             }
235             omxNode->useBuffer(
236                 portIndex, buffer.omxBuffer,
237                 [&status, &buffer](
238                     android::hardware::media::omx::V1_0::Status _s,
239                     uint32_t id) {
240                     status = _s;
241                     buffer.id = id;
242                 });
243             buffArray->push(buffer);
244             ASSERT_EQ(status,
245                       ::android::hardware::media::omx::V1_0::Status::OK);
246         }
247     }
248 }
249
250 // State Transition : Loaded -> Idle
251 // Note: This function does not make any background checks for this transition.
252 // The callee holds the reponsibility to ensure the legality of the transition.
253 void changeStateLoadedtoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
254                              android::Vector<BufferInfo>* iBuffer,
255                              android::Vector<BufferInfo>* oBuffer,
256                              OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
257                              PortMode* portMode) {
258     android::hardware::media::omx::V1_0::Status status;
259     Message msg;
260     PortMode defaultPortMode[2], *pm;
261
262     defaultPortMode[0] = PortMode::PRESET_BYTE_BUFFER;
263     defaultPortMode[1] = PortMode::PRESET_BYTE_BUFFER;
264     pm = portMode ? portMode : defaultPortMode;
265
266     // set state to idle
267     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
268                                   OMX_StateIdle);
269     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
270
271     // Dont switch states until the ports are populated
272     status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
273     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
274
275     // allocate buffers on input port
276     allocatePortBuffers(omxNode, iBuffer, kPortIndexInput, pm[0]);
277
278     // Dont switch states until the ports are populated
279     status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
280     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
281
282     // allocate buffers on output port
283     allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput, pm[1]);
284
285     // As the ports are populated, check if the state transition is complete
286     status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
287     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
288     ASSERT_EQ(msg.type, Message::Type::EVENT);
289     ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
290     ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
291     ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
292
293     return;
294 }
295
296 // State Transition : Idle -> Loaded
297 // Note: This function does not make any background checks for this transition.
298 // The callee holds the reponsibility to ensure the legality of the transition.
299 void changeStateIdletoLoaded(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
300                              android::Vector<BufferInfo>* iBuffer,
301                              android::Vector<BufferInfo>* oBuffer,
302                              OMX_U32 kPortIndexInput,
303                              OMX_U32 kPortIndexOutput) {
304     android::hardware::media::omx::V1_0::Status status;
305     Message msg;
306
307     // set state to Loaded
308     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
309                                   OMX_StateLoaded);
310     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
311
312     // dont change state until all buffers are freed
313     status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
314     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
315
316     for (size_t i = 0; i < iBuffer->size(); ++i) {
317         status = omxNode->freeBuffer(kPortIndexInput, (*iBuffer)[i].id);
318         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
319     }
320
321     // dont change state until all buffers are freed
322     status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
323     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
324
325     for (size_t i = 0; i < oBuffer->size(); ++i) {
326         status = omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
327         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
328     }
329
330     status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
331     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
332     ASSERT_EQ(msg.type, Message::Type::EVENT);
333     ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
334     ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
335     ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded);
336
337     return;
338 }
339
340 // State Transition : Idle -> Execute
341 // Note: This function does not make any background checks for this transition.
342 // The callee holds the reponsibility to ensure the legality of the transition.
343 void changeStateIdletoExecute(sp<IOmxNode> omxNode,
344                               sp<CodecObserver> observer) {
345     android::hardware::media::omx::V1_0::Status status;
346     Message msg;
347
348     // set state to execute
349     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
350                                   OMX_StateExecuting);
351     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
352     status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
353     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
354     ASSERT_EQ(msg.type, Message::Type::EVENT);
355     ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
356     ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
357     ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
358
359     return;
360 }
361
362 // State Transition : Execute -> Idle
363 // Note: This function does not make any background checks for this transition.
364 // The callee holds the reponsibility to ensure the legality of the transition.
365 void changeStateExecutetoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
366                               android::Vector<BufferInfo>* iBuffer,
367                               android::Vector<BufferInfo>* oBuffer) {
368     android::hardware::media::omx::V1_0::Status status;
369     Message msg;
370
371     // set state to Idle
372     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
373                                   OMX_StateIdle);
374     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
375     status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
376     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
377     ASSERT_EQ(msg.type, Message::Type::EVENT);
378     ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
379     ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
380     ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
381
382     // test if client got all its buffers back
383     for (size_t i = 0; i < oBuffer->size(); ++i) {
384         EXPECT_EQ((*oBuffer)[i].owner, client);
385     }
386     for (size_t i = 0; i < iBuffer->size(); ++i) {
387         EXPECT_EQ((*iBuffer)[i].owner, client);
388     }
389 }
390
391 // get empty buffer index
392 size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray) {
393     android::Vector<BufferInfo>::iterator it = buffArray->begin();
394     while (it != buffArray->end()) {
395         if (it->owner == client) {
396             // This block of code ensures that all buffers allocated at init
397             // time are utilized
398             BufferInfo backup = *it;
399             buffArray->erase(it);
400             buffArray->push_back(backup);
401             return buffArray->size() - 1;
402         }
403         it++;
404     }
405     return buffArray->size();
406 }
407
408 // dispatch buffer to output port
409 void dispatchOutputBuffer(sp<IOmxNode> omxNode,
410                           android::Vector<BufferInfo>* buffArray,
411                           size_t bufferIndex, PortMode portMode) {
412     android::hardware::media::omx::V1_0::Status status;
413     CodecBuffer t;
414     native_handle_t* fenceNh = native_handle_create(0, 0);
415     ASSERT_NE(fenceNh, nullptr);
416     switch (portMode) {
417         case PortMode::DYNAMIC_ANW_BUFFER:
418             t = (*buffArray)[bufferIndex].omxBuffer;
419             t.type = CodecBuffer::Type::ANW_BUFFER;
420             status =
421                 omxNode->fillBuffer((*buffArray)[bufferIndex].id, t, fenceNh);
422             break;
423         case PortMode::PRESET_SECURE_BUFFER:
424         case PortMode::PRESET_BYTE_BUFFER:
425             t.sharedMemory = android::hardware::hidl_memory();
426             t.nativeHandle = android::hardware::hidl_handle();
427             t.type = CodecBuffer::Type::PRESET;
428             t.attr.preset.rangeOffset = 0;
429             t.attr.preset.rangeLength = 0;
430             status =
431                 omxNode->fillBuffer((*buffArray)[bufferIndex].id, t, fenceNh);
432             break;
433         default:
434             status = Status::NAME_NOT_FOUND;
435     }
436     native_handle_close(fenceNh);
437     native_handle_delete(fenceNh);
438     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
439     buffArray->editItemAt(bufferIndex).owner = component;
440 }
441
442 // dispatch buffer to input port
443 void dispatchInputBuffer(sp<IOmxNode> omxNode,
444                          android::Vector<BufferInfo>* buffArray,
445                          size_t bufferIndex, int bytesCount, uint32_t flags,
446                          uint64_t timestamp, PortMode portMode) {
447     android::hardware::media::omx::V1_0::Status status;
448     CodecBuffer t;
449     native_handle_t* fenceNh = native_handle_create(0, 0);
450     ASSERT_NE(fenceNh, nullptr);
451     switch (portMode) {
452         case PortMode::PRESET_SECURE_BUFFER:
453         case PortMode::PRESET_BYTE_BUFFER:
454             t.sharedMemory = android::hardware::hidl_memory();
455             t.nativeHandle = android::hardware::hidl_handle();
456             t.type = CodecBuffer::Type::PRESET;
457             t.attr.preset.rangeOffset = 0;
458             t.attr.preset.rangeLength = bytesCount;
459             status = omxNode->emptyBuffer((*buffArray)[bufferIndex].id, t,
460                                           flags, timestamp, fenceNh);
461             break;
462         default:
463             status = Status::NAME_NOT_FOUND;
464     }
465     native_handle_close(fenceNh);
466     native_handle_delete(fenceNh);
467     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
468     buffArray->editItemAt(bufferIndex).owner = component;
469 }
470
471 // Flush input and output ports
472 void flushPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
473                 android::Vector<BufferInfo>* iBuffer,
474                 android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
475                 OMX_U32 kPortIndexOutput, int64_t timeoutUs) {
476     android::hardware::media::omx::V1_0::Status status;
477     Message msg;
478
479     // Flush input port
480     status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
481                                   kPortIndexInput);
482     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
483     status = observer->dequeueMessage(&msg, timeoutUs, iBuffer, oBuffer);
484     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
485     ASSERT_EQ(msg.type, Message::Type::EVENT);
486     ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
487     ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
488     ASSERT_EQ(msg.data.eventData.data2, kPortIndexInput);
489     // test if client got all its buffers back
490     for (size_t i = 0; i < iBuffer->size(); ++i) {
491         EXPECT_EQ((*iBuffer)[i].owner, client);
492     }
493
494     // Flush output port
495     status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
496                                   kPortIndexOutput);
497     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
498     status = observer->dequeueMessage(&msg, timeoutUs, iBuffer, oBuffer);
499     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
500     ASSERT_EQ(msg.type, Message::Type::EVENT);
501     ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
502     ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
503     ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
504     // test if client got all its buffers back
505     for (size_t i = 0; i < oBuffer->size(); ++i) {
506         EXPECT_EQ((*oBuffer)[i].owner, client);
507     }
508 }
509
510 // dispatch an empty input buffer with eos flag set if requested.
511 // This call assumes that all input buffers are processed completely.
512 // feed output buffers till we receive a buffer with eos flag set
513 void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
514              android::Vector<BufferInfo>* iBuffer,
515              android::Vector<BufferInfo>* oBuffer, bool signalEOS,
516              bool& eosFlag, PortMode* portMode, portreconfig fptr,
517              OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput, void* args) {
518     android::hardware::media::omx::V1_0::Status status;
519     PortMode defaultPortMode[2], *pm;
520
521     defaultPortMode[0] = PortMode::PRESET_BYTE_BUFFER;
522     defaultPortMode[1] = PortMode::PRESET_BYTE_BUFFER;
523     pm = portMode ? portMode : defaultPortMode;
524
525     size_t i = 0;
526     if (signalEOS) {
527         if ((i = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
528             // signal an empty buffer with flag set to EOS
529             dispatchInputBuffer(omxNode, iBuffer, i, 0, OMX_BUFFERFLAG_EOS, 0);
530         } else {
531             ASSERT_TRUE(false);
532         }
533     }
534
535     int timeOut = TIMEOUT_COUNTER;
536     while (timeOut--) {
537         // Dispatch all client owned output buffers to recover remaining frames
538         while (1) {
539             if ((i = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
540                 dispatchOutputBuffer(omxNode, oBuffer, i, pm[1]);
541                 // if dispatch is successful, perhaps there is a latency
542                 // in the component. Dont be in a haste to leave. reset timeout
543                 // counter
544                 timeOut = TIMEOUT_COUNTER;
545             } else {
546                 break;
547             }
548         }
549
550         Message msg;
551         status =
552             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
553         if (status == android::hardware::media::omx::V1_0::Status::OK) {
554             if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
555                 if (fptr) {
556                     (*fptr)(omxNode, observer, iBuffer, oBuffer,
557                             kPortIndexInput, kPortIndexOutput, msg, pm[1],
558                             args);
559                 } else {
560                     // something unexpected happened
561                     EXPECT_TRUE(false);
562                 }
563             } else if (msg.data.eventData.event == OMX_EventBufferFlag) {
564                 // soft omx components donot send this, we will just ignore it
565                 // for now
566             } else {
567                 // something unexpected happened
568                 EXPECT_TRUE(false);
569             }
570         }
571         if (eosFlag == true) break;
572     }
573     // test for flag
574     EXPECT_EQ(eosFlag, true);
575     eosFlag = false;
576 }