2 * Copyright 2016, The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef MEDIA_HIDL_TEST_COMMON_H
18 #define MEDIA_HIDL_TEST_COMMON_H
21 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
24 #include <media/stagefright/foundation/ALooper.h>
25 #include <utils/Condition.h>
26 #include <utils/List.h>
27 #include <utils/Mutex.h>
29 #include <media/openmax/OMX_Index.h>
30 #include <media/openmax/OMX_Core.h>
31 #include <media/openmax/OMX_Component.h>
32 #include <media/openmax/OMX_IndexExt.h>
33 #include <media/openmax/OMX_AudioExt.h>
34 #include <media/openmax/OMX_VideoExt.h>
36 /* TIME OUTS (Wait time in dequeueMessage()) */
38 /* As component is switching states (loaded<->idle<->execute), dequeueMessage()
39 * expects the events to be received within this duration */
40 #define DEFAULT_TIMEOUT 100000
41 /* Time interval between successive Input/Output enqueues */
42 #define DEFAULT_TIMEOUT_Q 2000
43 /* While the component is amidst a process call, asynchronous commands like
44 * flush, change states can get delayed (at max by process call time). Instead
45 * of waiting on DEFAULT_TIMEOUT, we give an additional leeway. */
46 #define DEFAULT_TIMEOUT_PE 500000
48 /* Breakout Timeout :: 5 sec*/
49 #define TIMEOUT_COUNTER_Q (5000000 / DEFAULT_TIMEOUT_Q)
50 #define TIMEOUT_COUNTER_PE (5000000 / DEFAULT_TIMEOUT_PE)
53 * Random Index used for monkey testing while get/set parameters
55 #define RANDOM_INDEX 1729
57 #define ALIGN_POWER_OF_TWO(value, n) \
58 (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
67 * TODO: below definitions are borrowed from Conversion.h.
68 * This is not the ideal way to do it. Loose these definitions once you
69 * include Conversion.h
71 inline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
72 return static_cast<uint32_t>(l);
75 inline android::hardware::media::omx::V1_0::Status toStatus(
76 android::status_t l) {
77 return static_cast<android::hardware::media::omx::V1_0::Status>(l);
80 inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
82 t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
86 inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
87 return static_cast<uint32_t>(l);
96 android::hardware::media::omx::V1_0::CodecBuffer omxBuffer;
97 ::android::sp<IMemory> mMemory;
108 * Handle Callback functions EmptythisBuffer(), FillthisBuffer(),
111 struct CodecObserver : public IOmxObserver {
113 CodecObserver(std::function<void(Message, const BufferInfo*)> fn)
115 Return<void> onMessages(const hidl_vec<Message>& messages) override {
116 android::Mutex::Autolock autoLock(msgLock);
117 for (hidl_vec<Message>::const_iterator it = messages.begin();
118 it != messages.end(); ++it) {
119 msgQueue.push_back(*it);
121 msgCondition.signal();
124 android::hardware::media::omx::V1_0::Status dequeueMessage(
125 Message* msg, int64_t timeoutUs,
126 android::Vector<BufferInfo>* iBuffers = nullptr,
127 android::Vector<BufferInfo>* oBuffers = nullptr) {
128 int64_t finishBy = android::ALooper::GetNowUs() + timeoutUs;
129 android::Mutex::Autolock autoLock(msgLock);
131 android::List<Message>::iterator it = msgQueue.begin();
132 while (it != msgQueue.end()) {
134 android::hardware::media::omx::V1_0::Message::Type::EVENT) {
136 it = msgQueue.erase(it);
137 // OMX_EventBufferFlag event is sent when the component has
138 // processed a buffer with its EOS flag set. This event is
139 // not sent by soft omx components. Vendor components can
140 // send this. From IOMX point of view, we will ignore this
142 if (msg->data.eventData.event == OMX_EventBufferFlag)
144 return ::android::hardware::media::omx::V1_0::Status::OK;
145 } else if (it->type == android::hardware::media::omx::V1_0::
146 Message::Type::FILL_BUFFER_DONE) {
149 for (i = 0; i < oBuffers->size(); ++i) {
150 if ((*oBuffers)[i].id ==
151 it->data.bufferData.buffer) {
152 if (callBack) callBack(*it, &(*oBuffers)[i]);
153 oBuffers->editItemAt(i).owner = client;
154 it = msgQueue.erase(it);
158 EXPECT_LE(i, oBuffers->size());
160 } else if (it->type == android::hardware::media::omx::V1_0::
161 Message::Type::EMPTY_BUFFER_DONE) {
164 for (i = 0; i < iBuffers->size(); ++i) {
165 if ((*iBuffers)[i].id ==
166 it->data.bufferData.buffer) {
167 if (callBack) callBack(*it, &(*iBuffers)[i]);
168 iBuffers->editItemAt(i).owner = client;
169 it = msgQueue.erase(it);
173 EXPECT_LE(i, iBuffers->size());
176 EXPECT_TRUE(false) << "Received unexpected message";
180 int64_t delayUs = finishBy - android::ALooper::GetNowUs();
181 if (delayUs < 0) return toStatus(android::TIMED_OUT);
183 ? msgCondition.wait(msgLock)
184 : msgCondition.waitRelative(msgLock, delayUs * 1000ll);
188 android::List<Message> msgQueue;
189 android::Mutex msgLock;
190 android::Condition msgCondition;
191 std::function<void(Message, const BufferInfo*)> callBack;
195 * Useful Wrapper utilities
198 void InitOMXParams(T* params) {
199 params->nSize = sizeof(T);
200 params->nVersion.s.nVersionMajor = 1;
201 params->nVersion.s.nVersionMinor = 0;
202 params->nVersion.s.nRevision = 0;
203 params->nVersion.s.nStep = 0;
207 Return<android::hardware::media::omx::V1_0::Status> getParam(
208 sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
209 android::hardware::media::omx::V1_0::Status status;
210 InitOMXParams(params);
211 omxNode->getParameter(
212 toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
213 [&status, ¶ms](android::hardware::media::omx::V1_0::Status _s,
214 hidl_vec<uint8_t> const& outParams) {
216 std::copy(outParams.data(), outParams.data() + outParams.size(),
217 static_cast<uint8_t*>(static_cast<void*>(params)));
223 Return<android::hardware::media::omx::V1_0::Status> setParam(
224 sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
225 InitOMXParams(params);
226 return omxNode->setParameter(toRawIndexType(omxIdx),
227 inHidlBytes(params, sizeof(*params)));
231 Return<android::hardware::media::omx::V1_0::Status> getPortParam(
232 sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
233 android::hardware::media::omx::V1_0::Status status;
234 InitOMXParams(params);
235 params->nPortIndex = nPortIndex;
236 omxNode->getParameter(
237 toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
238 [&status, ¶ms](android::hardware::media::omx::V1_0::Status _s,
239 hidl_vec<uint8_t> const& outParams) {
241 std::copy(outParams.data(), outParams.data() + outParams.size(),
242 static_cast<uint8_t*>(static_cast<void*>(params)));
248 Return<android::hardware::media::omx::V1_0::Status> setPortParam(
249 sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
250 InitOMXParams(params);
251 params->nPortIndex = nPortIndex;
252 return omxNode->setParameter(toRawIndexType(omxIdx),
253 inHidlBytes(params, sizeof(*params)));
257 Return<android::hardware::media::omx::V1_0::Status> getPortConfig(
258 sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
259 android::hardware::media::omx::V1_0::Status status;
260 InitOMXParams(params);
261 params->nPortIndex = nPortIndex;
263 toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
264 [&status, ¶ms](android::hardware::media::omx::V1_0::Status _s,
265 hidl_vec<uint8_t> const& outParams) {
267 std::copy(outParams.data(), outParams.data() + outParams.size(),
268 static_cast<uint8_t*>(static_cast<void*>(params)));
274 Return<android::hardware::media::omx::V1_0::Status> setPortConfig(
275 sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
276 InitOMXParams(params);
277 params->nPortIndex = nPortIndex;
278 return omxNode->setConfig(toRawIndexType(omxIdx),
279 inHidlBytes(params, sizeof(*params)));
283 * common functions declarations
285 Return<android::hardware::media::omx::V1_0::Status> setRole(
286 sp<IOmxNode> omxNode, const char* role);
288 Return<android::hardware::media::omx::V1_0::Status> setPortBufferSize(
289 sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_U32 size);
291 Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
292 sp<IOmxNode> omxNode, OMX_U32 portIndex,
293 OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
296 Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
297 sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding);
299 void allocateBuffer(sp<IOmxNode> omxNode, BufferInfo* buffer, OMX_U32 portIndex,
300 OMX_U32 nBufferSize, PortMode portMode);
302 void allocatePortBuffers(sp<IOmxNode> omxNode,
303 android::Vector<BufferInfo>* buffArray,
305 PortMode portMode = PortMode::PRESET_BYTE_BUFFER);
307 void changeStateLoadedtoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
308 android::Vector<BufferInfo>* iBuffer,
309 android::Vector<BufferInfo>* oBuffer,
310 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
311 PortMode* portMode = nullptr);
313 void changeStateIdletoLoaded(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
314 android::Vector<BufferInfo>* iBuffer,
315 android::Vector<BufferInfo>* oBuffer,
316 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput);
318 void changeStateIdletoExecute(sp<IOmxNode> omxNode, sp<CodecObserver> observer);
320 void changeStateExecutetoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
321 android::Vector<BufferInfo>* iBuffer,
322 android::Vector<BufferInfo>* oBuffer);
324 size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray);
326 void dispatchOutputBuffer(sp<IOmxNode> omxNode,
327 android::Vector<BufferInfo>* buffArray,
329 PortMode portMode = PortMode::PRESET_BYTE_BUFFER);
331 void dispatchInputBuffer(sp<IOmxNode> omxNode,
332 android::Vector<BufferInfo>* buffArray,
333 size_t bufferIndex, int bytesCount, uint32_t flags,
335 PortMode portMode = PortMode::PRESET_BYTE_BUFFER);
337 void flushPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
338 android::Vector<BufferInfo>* iBuffer,
339 android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
340 OMX_U32 kPortIndexOutput,
341 int64_t timeoutUs = DEFAULT_TIMEOUT_PE);
343 typedef void (*portreconfig)(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
344 android::Vector<BufferInfo>* iBuffer,
345 android::Vector<BufferInfo>* oBuffer,
346 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
347 Message msg, PortMode oPortMode, void* args);
348 void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
349 android::Vector<BufferInfo>* iBuffer,
350 android::Vector<BufferInfo>* oBuffer, bool signalEOS,
351 bool& eosFlag, PortMode* portMode = nullptr,
352 portreconfig fptr = nullptr, OMX_U32 kPortIndexInput = 0,
353 OMX_U32 kPortIndexOutput = 1, void* args = nullptr);
355 #endif // MEDIA_HIDL_TEST_COMMON_H