blob: 9816fe1d8bfa0e14592fcf640263d032bb80f6df [file] [log] [blame]
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -08001/*
2 * Copyright 2016, 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#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
18#define ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
19
Pawin Vongmasa0d3a5ed2017-02-22 03:19:35 -080020#include <vector>
21#include <list>
22
23#include <unistd.h>
24
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080025#include <hidl/MQDescriptor.h>
26#include <hidl/Status.h>
27#include <hidlmemory/mapping.h>
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080028
29#include <binder/Binder.h>
30#include <binder/Status.h>
31#include <ui/FenceTime.h>
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080032#include <cutils/native_handle.h>
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080033
Pawin Vongmasa04563aa2017-03-09 07:02:01 -080034#include <ui/GraphicBuffer.h>
Pawin Vongmasaac7d4122017-03-01 05:48:42 -080035#include <media/OMXFenceParcelable.h>
Pawin Vongmasa0d3a5ed2017-02-22 03:19:35 -080036#include <media/OMXBuffer.h>
Pawin Vongmasaac7d4122017-03-01 05:48:42 -080037#include <media/hardware/VideoAPI.h>
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080038
Pawin Vongmasa0d3a5ed2017-02-22 03:19:35 -080039#include <android/hidl/memory/1.0/IMemory.h>
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080040#include <android/hardware/media/omx/1.0/types.h>
41#include <android/hardware/media/omx/1.0/IOmx.h>
42#include <android/hardware/media/omx/1.0/IOmxNode.h>
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080043#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
44#include <android/hardware/media/omx/1.0/IOmxObserver.h>
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080045#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
46
Pawin Vongmasa0d3a5ed2017-02-22 03:19:35 -080047#include <android/IGraphicBufferSource.h>
48#include <android/IOMXBufferSource.h>
49
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080050namespace android {
51namespace hardware {
52namespace media {
53namespace omx {
54namespace V1_0 {
55namespace utils {
56
57using ::android::hardware::hidl_array;
58using ::android::hardware::hidl_string;
59using ::android::hardware::hidl_vec;
60using ::android::hardware::hidl_handle;
61using ::android::hardware::Return;
62using ::android::hardware::Void;
63using ::android::sp;
64
65using ::android::String8;
66using ::android::OMXFenceParcelable;
67
68using ::android::hardware::media::omx::V1_0::Message;
69using ::android::omx_message;
70
71using ::android::hardware::media::omx::V1_0::ColorAspects;
72using ::android::hardware::media::V1_0::Rect;
73using ::android::hardware::media::V1_0::Region;
74
75using ::android::hardware::graphics::common::V1_0::Dataspace;
76
77using ::android::hardware::graphics::common::V1_0::PixelFormat;
78
79using ::android::OMXBuffer;
80
81using ::android::hardware::media::V1_0::AnwBuffer;
82using ::android::GraphicBuffer;
83
84using ::android::hardware::media::omx::V1_0::IOmx;
85using ::android::IOMX;
86
87using ::android::hardware::media::omx::V1_0::IOmxNode;
88using ::android::IOMXNode;
89
90using ::android::hardware::media::omx::V1_0::IOmxObserver;
91using ::android::IOMXObserver;
92
93using ::android::hardware::media::omx::V1_0::IOmxBufferSource;
94using ::android::IOMXBufferSource;
95
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -080096// native_handle_t helper functions.
97
98/**
99 * \brief Take an fd and create a native handle containing only the given fd.
100 * The created handle will need to be deleted manually with
101 * `native_handle_delete()`.
102 *
103 * \param[in] fd The source file descriptor (of type `int`).
104 * \return The create `native_handle_t*` that contains the given \p fd. If the
105 * supplied \p fd is negative, the created native handle will contain no file
106 * descriptors.
107 *
108 * If the native handle cannot be created, the return value will be
109 * `nullptr`.
110 *
111 * This function does not duplicate the file descriptor.
112 */
113inline native_handle_t* native_handle_create_from_fd(int fd) {
114 if (fd < 0) {
115 return native_handle_create(0, 0);
116 }
117 native_handle_t* nh = native_handle_create(1, 0);
118 if (nh == nullptr) {
119 return nullptr;
120 }
121 nh->data[0] = fd;
122 return nh;
123}
124
125/**
126 * \brief Extract a file descriptor from a native handle.
127 *
128 * \param[in] nh The source `native_handle_t*`.
129 * \param[in] index The index of the file descriptor in \p nh to read from. This
130 * input has the default value of `0`.
131 * \return The `index`-th file descriptor in \p nh. If \p nh does not have
132 * enough file descriptors, the returned value will be `-1`.
133 *
134 * This function does not duplicate the file descriptor.
135 */
136inline int native_handle_read_fd(native_handle_t const* nh, int index = 0) {
137 return ((nh == nullptr) || (nh->numFds == 0) ||
138 (nh->numFds <= index) || (index < 0)) ?
139 -1 : nh->data[index];
140}
141
142/**
143 * Conversion functions
144 * ====================
145 *
146 * There are two main directions of conversion:
147 * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
148 * input. The wrapper has type `TargetType`.
149 * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
150 * corresponds to the input. The lifetime of the output does not depend on the
151 * lifetime of the input.
152 * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
153 * that cannot be copied and/or moved efficiently, or when there are multiple
154 * output arguments.
155 * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
156 * `TargetType` that cannot be copied and/or moved efficiently, or when there
157 * are multiple output arguments.
158 *
159 * `wrapIn()` and `convertTo()` functions will take output arguments before
160 * input arguments. Some of these functions might return a value to indicate
161 * success or error.
162 *
163 * In converting or wrapping something as a Treble type that contains a
164 * `hidl_handle`, `native_handle_t*` will need to be created and returned as
165 * an additional output argument, hence only `wrapIn()` or `convertTo()` would
166 * be available. The caller must call `native_handle_delete()` to deallocate the
167 * returned native handle when it is no longer needed.
168 *
169 * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
170 * not perform duplication of file descriptors, while `toTargetType()` and
171 * `convertTo()` do.
172 */
173
174/**
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800175 * \brief Convert `Return<void>` to `binder::Status`.
176 *
177 * \param[in] t The source `Return<void>`.
178 * \return The corresponding `binder::Status`.
179 */
180// convert: Return<void> -> ::android::binder::Status
181inline ::android::binder::Status toBinderStatus(
182 Return<void> const& t) {
183 return ::android::binder::Status::fromExceptionCode(
184 t.isOk() ? OK : UNKNOWN_ERROR,
185 t.description().c_str());
186}
187
188/**
Robert Shihd095e652017-03-11 01:20:43 +0000189 * \brief Convert `Return<Status>` to `binder::Status`.
190 *
191 * \param[in] t The source `Return<Status>`.
192 * \return The corresponding `binder::Status`.
193 */
194// convert: Return<Status> -> ::android::binder::Status
195inline ::android::binder::Status toBinderStatus(
196 Return<Status> const& t) {
197 return ::android::binder::Status::fromStatusT(
198 t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR);
199}
200
201/**
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800202 * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
203 * calls.
204 *
205 * \param[in] t The source `Return<Status>`.
206 * \return The corresponding `status_t`.
207 *
208 * This function first check if \p t has a transport error. If it does, then the
209 * return value is the transport error code. Otherwise, the return value is
210 * converted from `Status` contained inside \p t.
211 *
212 * Note:
213 * - This `Status` is omx-specific. It is defined in `types.hal`.
214 * - The name of this function is not `convert`.
215 */
216// convert: Status -> status_t
217inline status_t toStatusT(Return<Status> const& t) {
218 return t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR;
219}
220
221/**
222 * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
223 *
224 * \param[in] t The source `Return<void>`.
225 * \return The corresponding `status_t`.
226 */
227// convert: Return<void> -> status_t
228inline status_t toStatusT(Return<void> const& t) {
229 return t.isOk() ? OK : UNKNOWN_ERROR;
230}
231
232/**
233 * \brief Convert `Status` to `status_t`. This is for legacy binder calls.
234 *
235 * \param[in] t The source `Status`.
236 * \return the corresponding `status_t`.
237 */
238// convert: Status -> status_t
239inline status_t toStatusT(Status const& t) {
240 return static_cast<status_t>(t);
241}
242
243/**
244 * \brief Convert `status_t` to `Status`.
245 *
246 * \param[in] l The source `status_t`.
247 * \return The corresponding `Status`.
248 */
249// convert: status_t -> Status
250inline Status toStatus(status_t l) {
251 return static_cast<Status>(l);
252}
253
254/**
255 * \brief Wrap `native_handle_t*` in `hidl_handle`.
256 *
257 * \param[in] nh The source `native_handle_t*`.
258 * \return The `hidl_handle` that points to \p nh.
259 */
260// wrap: native_handle_t* -> hidl_handle
261inline hidl_handle inHidlHandle(native_handle_t const* nh) {
262 return hidl_handle(nh);
263}
264
265/**
266 * \brief Wrap an `omx_message` and construct the corresponding `Message`.
267 *
268 * \param[out] t The wrapper of type `Message`.
269 * \param[out] nh The native_handle_t referred to by `t->fence`.
270 * \param[in] l The source `omx_message`.
271 * \return `true` if the wrapping is successful; `false` otherwise.
272 *
273 * Upon success, \p nh will be created to hold the file descriptor stored in
274 * `l.fenceFd`, and `t->fence` will point to \p nh. \p nh will need to be
275 * destroyed manually by `native_handle_delete()` when \p t is no longer needed.
276 *
277 * Upon failure, \p nh will not be created and will not need to be deleted. \p t
278 * will be invalid.
279 */
280// wrap, omx_message -> Message, native_handle_t*
281inline bool wrapAs(Message* t, native_handle_t** nh, omx_message const& l) {
282 *nh = native_handle_create_from_fd(l.fenceFd);
283 if (!*nh) {
284 return false;
285 }
Pawin Vongmasa8ff40182017-02-07 02:22:34 -0800286 t->fence = *nh;
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800287 switch (l.type) {
288 case omx_message::EVENT:
289 t->type = Message::Type::EVENT;
Pawin Vongmasa8a21c012016-12-27 04:30:54 +0700290 t->data.eventData.event = uint32_t(l.u.event_data.event);
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800291 t->data.eventData.data1 = l.u.event_data.data1;
292 t->data.eventData.data2 = l.u.event_data.data2;
293 t->data.eventData.data3 = l.u.event_data.data3;
294 t->data.eventData.data4 = l.u.event_data.data4;
295 break;
296 case omx_message::EMPTY_BUFFER_DONE:
297 t->type = Message::Type::EMPTY_BUFFER_DONE;
298 t->data.bufferData.buffer = l.u.buffer_data.buffer;
299 break;
300 case omx_message::FILL_BUFFER_DONE:
301 t->type = Message::Type::FILL_BUFFER_DONE;
302 t->data.extendedBufferData.buffer = l.u.extended_buffer_data.buffer;
303 t->data.extendedBufferData.rangeOffset =
304 l.u.extended_buffer_data.range_offset;
305 t->data.extendedBufferData.rangeLength =
306 l.u.extended_buffer_data.range_length;
307 t->data.extendedBufferData.flags = l.u.extended_buffer_data.flags;
308 t->data.extendedBufferData.timestampUs =
309 l.u.extended_buffer_data.timestamp;
310 break;
311 case omx_message::FRAME_RENDERED:
312 t->type = Message::Type::FRAME_RENDERED;
313 t->data.renderData.timestampUs = l.u.render_data.timestamp;
314 t->data.renderData.systemTimeNs = l.u.render_data.nanoTime;
315 break;
316 default:
317 native_handle_delete(*nh);
318 return false;
319 }
320 return true;
321}
322
323/**
324 * \brief Wrap a `Message` inside an `omx_message`.
325 *
326 * \param[out] l The wrapper of type `omx_message`.
327 * \param[in] t The source `Message`.
328 * \return `true` if the wrapping is successful; `false` otherwise.
329 */
330// wrap: Message -> omx_message
331inline bool wrapAs(omx_message* l, Message const& t) {
332 l->fenceFd = native_handle_read_fd(t.fence);
333 switch (t.type) {
334 case Message::Type::EVENT:
335 l->type = omx_message::EVENT;
Pawin Vongmasa8a21c012016-12-27 04:30:54 +0700336 l->u.event_data.event = OMX_EVENTTYPE(t.data.eventData.event);
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800337 l->u.event_data.data1 = t.data.eventData.data1;
338 l->u.event_data.data2 = t.data.eventData.data2;
339 l->u.event_data.data3 = t.data.eventData.data3;
340 l->u.event_data.data4 = t.data.eventData.data4;
341 break;
342 case Message::Type::EMPTY_BUFFER_DONE:
343 l->type = omx_message::EMPTY_BUFFER_DONE;
344 l->u.buffer_data.buffer = t.data.bufferData.buffer;
345 break;
346 case Message::Type::FILL_BUFFER_DONE:
347 l->type = omx_message::FILL_BUFFER_DONE;
348 l->u.extended_buffer_data.buffer = t.data.extendedBufferData.buffer;
349 l->u.extended_buffer_data.range_offset =
350 t.data.extendedBufferData.rangeOffset;
351 l->u.extended_buffer_data.range_length =
352 t.data.extendedBufferData.rangeLength;
353 l->u.extended_buffer_data.flags = t.data.extendedBufferData.flags;
354 l->u.extended_buffer_data.timestamp =
355 t.data.extendedBufferData.timestampUs;
356 break;
357 case Message::Type::FRAME_RENDERED:
358 l->type = omx_message::FRAME_RENDERED;
359 l->u.render_data.timestamp = t.data.renderData.timestampUs;
360 l->u.render_data.nanoTime = t.data.renderData.systemTimeNs;
361 break;
362 default:
363 return false;
364 }
365 return true;
366}
367
368/**
369 * \brief Similar to `wrapTo(omx_message*, Message const&)`, but the output will
370 * have an extended lifetime.
371 *
372 * \param[out] l The output `omx_message`.
373 * \param[in] t The source `Message`.
374 * \return `true` if the conversion is successful; `false` otherwise.
375 *
376 * This function calls `wrapto()`, then attempts to duplicate the file
377 * descriptor for the fence if it is not `-1`. If duplication fails, `false`
378 * will be returned.
379 */
380// convert: Message -> omx_message
381inline bool convertTo(omx_message* l, Message const& t) {
382 if (!wrapAs(l, t)) {
383 return false;
384 }
385 if (l->fenceFd == -1) {
386 return true;
387 }
388 l->fenceFd = dup(l->fenceFd);
389 return l->fenceFd != -1;
390}
391
392/**
393 * \brief Wrap an `OMXFenceParcelable` inside a `hidl_handle`.
394 *
395 * \param[out] t The wrapper of type `hidl_handle`.
396 * \param[out] nh The native handle created to hold the file descriptor inside
397 * \p l.
398 * \param[in] l The source `OMXFenceParcelable`, which essentially contains one
399 * file descriptor.
400 * \return `true` if \p t and \p nh are successfully created to wrap around \p
401 * l; `false` otherwise.
402 *
403 * On success, \p nh needs to be deleted by the caller with
404 * `native_handle_delete()` after \p t and \p nh are no longer needed.
405 *
406 * On failure, \p nh will not need to be deleted, and \p t will hold an invalid
407 * value.
408 */
409// wrap: OMXFenceParcelable -> hidl_handle, native_handle_t*
410inline bool wrapAs(hidl_handle* t, native_handle_t** nh,
411 OMXFenceParcelable const& l) {
412 *nh = native_handle_create_from_fd(l.get());
413 if (!*nh) {
414 return false;
415 }
416 *t = *nh;
417 return true;
418}
419
420/**
421 * \brief Wrap a `hidl_handle` inside an `OMXFenceParcelable`.
422 *
423 * \param[out] l The wrapper of type `OMXFenceParcelable`.
424 * \param[in] t The source `hidl_handle`.
425 */
426// wrap: hidl_handle -> OMXFenceParcelable
427inline void wrapAs(OMXFenceParcelable* l, hidl_handle const& t) {
428 l->mFenceFd = native_handle_read_fd(t);
429}
430
431/**
432 * \brief Convert a `hidl_handle` to `OMXFenceParcelable`. If `hidl_handle`
433 * contains file descriptors, the first file descriptor will be duplicated and
434 * stored in the output `OMXFenceParcelable`.
435 *
436 * \param[out] l The output `OMXFenceParcelable`.
437 * \param[in] t The input `hidl_handle`.
438 * \return `false` if \p t contains a valid file descriptor but duplication
439 * fails; `true` otherwise.
440 */
441// convert: hidl_handle -> OMXFenceParcelable
442inline bool convertTo(OMXFenceParcelable* l, hidl_handle const& t) {
443 int fd = native_handle_read_fd(t);
444 if (fd != -1) {
445 fd = dup(fd);
446 if (fd == -1) {
447 return false;
448 }
449 }
450 l->mFenceFd = fd;
451 return true;
452}
453
454/**
455 * \brief Convert `::android::ColorAspects` to `ColorAspects`.
456 *
457 * \param[in] l The source `::android::ColorAspects`.
458 * \return The corresponding `ColorAspects`.
459 */
460// convert: ::android::ColorAspects -> ColorAspects
461inline ColorAspects toHardwareColorAspects(::android::ColorAspects const& l) {
462 return ColorAspects{
463 static_cast<ColorAspects::Range>(l.mRange),
464 static_cast<ColorAspects::Primaries>(l.mPrimaries),
465 static_cast<ColorAspects::Transfer>(l.mTransfer),
466 static_cast<ColorAspects::MatrixCoeffs>(l.mMatrixCoeffs)};
467}
468
469/**
470 * \brief Convert `int32_t` to `ColorAspects`.
471 *
472 * \param[in] l The source `int32_t`.
473 * \return The corresponding `ColorAspects`.
474 */
475// convert: int32_t -> ColorAspects
476inline ColorAspects toHardwareColorAspects(int32_t l) {
477 return ColorAspects{
478 static_cast<ColorAspects::Range>((l >> 24) & 0xFF),
479 static_cast<ColorAspects::Primaries>((l >> 16) & 0xFF),
480 static_cast<ColorAspects::Transfer>(l & 0xFF),
481 static_cast<ColorAspects::MatrixCoeffs>((l >> 8) & 0xFF)};
482}
483
484/**
485 * \brief Convert `ColorAspects` to `::android::ColorAspects`.
486 *
487 * \param[in] t The source `ColorAspects`.
488 * \return The corresponding `::android::ColorAspects`.
489 */
490// convert: ColorAspects -> ::android::ColorAspects
491inline int32_t toCompactColorAspects(ColorAspects const& t) {
492 return static_cast<int32_t>(
493 (static_cast<uint32_t>(t.range) << 24) |
494 (static_cast<uint32_t>(t.primaries) << 16) |
495 (static_cast<uint32_t>(t.transfer)) |
496 (static_cast<uint32_t>(t.matrixCoeffs) << 8));
497}
498
499/**
500 * \brief Convert `int32_t` to `Dataspace`.
501 *
502 * \param[in] l The source `int32_t`.
503 * \result The corresponding `Dataspace`.
504 */
505// convert: int32_t -> Dataspace
506inline Dataspace toHardwareDataspace(int32_t l) {
507 return static_cast<Dataspace>(l);
508}
509
510/**
511 * \brief Convert `Dataspace` to `int32_t`.
512 *
513 * \param[in] t The source `Dataspace`.
514 * \result The corresponding `int32_t`.
515 */
516// convert: Dataspace -> int32_t
517inline int32_t toRawDataspace(Dataspace const& t) {
518 return static_cast<int32_t>(t);
519}
520
521/**
522 * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
523 *
524 * \param[in] l The pointer to the beginning of the opaque buffer.
525 * \param[in] size The size of the buffer.
526 * \return A `hidl_vec<uint8_t>` that points to the buffer.
527 */
528// wrap: void*, size_t -> hidl_vec<uint8_t>
529inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
530 hidl_vec<uint8_t> t;
531 t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
532 return t;
533}
534
535/**
536 * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
537 *
538 * \param[in] l The pointer to the beginning of the opaque buffer.
539 * \param[in] size The size of the buffer.
540 * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
541 */
542// convert: void*, size_t -> hidl_vec<uint8_t>
543inline hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
544 hidl_vec<uint8_t> t;
545 t.resize(size);
546 uint8_t const* src = static_cast<uint8_t const*>(l);
547 std::copy(src, src + size, t.data());
548 return t;
549}
550
551/**
Pawin Vongmasa9c47c972017-02-08 04:09:38 -0800552 * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
553 *
554 * \param[out] t The wrapper of type `AnwBuffer`.
555 * \param[in] l The source `GraphicBuffer`.
556 */
557// wrap: GraphicBuffer -> AnwBuffer
558inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
559 t->attr.width = l.getWidth();
560 t->attr.height = l.getHeight();
561 t->attr.stride = l.getStride();
562 t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
563 t->attr.layerCount = l.getLayerCount();
564 t->attr.usage = l.getUsage();
565 t->attr.id = l.getId();
566 t->attr.generationNumber = l.getGenerationNumber();
567 t->nativeHandle = hidl_handle(l.handle);
568}
569
570/**
571 * \brief Convert `AnwBuffer` to `GraphicBuffer`.
572 *
573 * \param[out] l The destination `GraphicBuffer`.
574 * \param[in] t The source `AnwBuffer`.
575 *
576 * This function will duplicate all file descriptors in \p t.
577 */
578// convert: AnwBuffer -> GraphicBuffer
579// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
580inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
581 native_handle_t* handle = t.nativeHandle == nullptr ?
582 nullptr : native_handle_clone(t.nativeHandle);
583
584 size_t const numInts = 12 + (handle ? handle->numInts : 0);
585 int32_t* ints = new int32_t[numInts];
586
587 size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
588 int* fds = new int[numFds];
589
590 ints[0] = 'GBFR';
591 ints[1] = static_cast<int32_t>(t.attr.width);
592 ints[2] = static_cast<int32_t>(t.attr.height);
593 ints[3] = static_cast<int32_t>(t.attr.stride);
594 ints[4] = static_cast<int32_t>(t.attr.format);
595 ints[5] = static_cast<int32_t>(t.attr.layerCount);
596 ints[6] = static_cast<int32_t>(t.attr.usage);
597 ints[7] = static_cast<int32_t>(t.attr.id >> 32);
598 ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
599 ints[9] = static_cast<int32_t>(t.attr.generationNumber);
600 ints[10] = 0;
601 ints[11] = 0;
602 if (handle) {
603 ints[10] = static_cast<int32_t>(handle->numFds);
604 ints[11] = static_cast<int32_t>(handle->numInts);
605 int* intsStart = handle->data + handle->numFds;
606 std::copy(handle->data, intsStart, fds);
607 std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
608 }
609
610 void const* constBuffer = static_cast<void const*>(ints);
611 size_t size = numInts * sizeof(int32_t);
612 int const* constFds = static_cast<int const*>(fds);
613 status_t status = l->unflatten(constBuffer, size, constFds, numFds);
614
615 delete [] fds;
616 delete [] ints;
617 native_handle_delete(handle);
618 return status == NO_ERROR;
619}
620
621/**
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800622 * \brief Wrap `OMXBuffer` in `CodecBuffer`.
623 *
624 * \param[out] t The wrapper of type `CodecBuffer`.
625 * \param[in] l The source `OMXBuffer`.
626 * \return `true` if the wrapping is successful; `false` otherwise.
627 */
628// wrap: OMXBuffer -> CodecBuffer
629inline bool wrapAs(CodecBuffer* t, OMXBuffer const& l) {
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800630 t->sharedMemory = hidl_memory();
Pawin Vongmasa9c47c972017-02-08 04:09:38 -0800631 t->nativeHandle = hidl_handle();
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800632 switch (l.mBufferType) {
633 case OMXBuffer::kBufferTypeInvalid: {
634 t->type = CodecBuffer::Type::INVALID;
635 return true;
636 }
637 case OMXBuffer::kBufferTypePreset: {
638 t->type = CodecBuffer::Type::PRESET;
639 t->attr.preset.rangeLength = static_cast<uint32_t>(l.mRangeLength);
640 t->attr.preset.rangeOffset = static_cast<uint32_t>(l.mRangeOffset);
641 return true;
642 }
643 case OMXBuffer::kBufferTypeHidlMemory: {
644 t->type = CodecBuffer::Type::SHARED_MEM;
645 t->sharedMemory = l.mHidlMemory;
646 return true;
647 }
648 case OMXBuffer::kBufferTypeSharedMem: {
649 // This is not supported.
650 return false;
651 }
652 case OMXBuffer::kBufferTypeANWBuffer: {
653 t->type = CodecBuffer::Type::ANW_BUFFER;
Pawin Vongmasa8ff40182017-02-07 02:22:34 -0800654 if (l.mGraphicBuffer == nullptr) {
655 t->attr.anwBuffer.width = 0;
656 t->attr.anwBuffer.height = 0;
657 t->attr.anwBuffer.stride = 0;
658 t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
659 t->attr.anwBuffer.layerCount = 0;
660 t->attr.anwBuffer.usage = 0;
Pawin Vongmasa8ff40182017-02-07 02:22:34 -0800661 return true;
662 }
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800663 t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
664 t->attr.anwBuffer.height = l.mGraphicBuffer->getHeight();
665 t->attr.anwBuffer.stride = l.mGraphicBuffer->getStride();
666 t->attr.anwBuffer.format = static_cast<PixelFormat>(
667 l.mGraphicBuffer->getPixelFormat());
668 t->attr.anwBuffer.layerCount = l.mGraphicBuffer->getLayerCount();
669 t->attr.anwBuffer.usage = l.mGraphicBuffer->getUsage();
Pawin Vongmasa9c47c972017-02-08 04:09:38 -0800670 t->nativeHandle = l.mGraphicBuffer->handle;
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800671 return true;
672 }
673 case OMXBuffer::kBufferTypeNativeHandle: {
674 t->type = CodecBuffer::Type::NATIVE_HANDLE;
Pawin Vongmasa9c47c972017-02-08 04:09:38 -0800675 t->nativeHandle = l.mNativeHandle->handle();
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800676 return true;
677 }
678 }
679 return false;
680}
681
682/**
683 * \brief Convert `CodecBuffer` to `OMXBuffer`.
684 *
685 * \param[out] l The destination `OMXBuffer`.
686 * \param[in] t The source `CodecBuffer`.
687 * \return `true` if successful; `false` otherwise.
688 */
689// convert: CodecBuffer -> OMXBuffer
690inline bool convertTo(OMXBuffer* l, CodecBuffer const& t) {
691 switch (t.type) {
692 case CodecBuffer::Type::INVALID: {
693 *l = OMXBuffer();
694 return true;
695 }
696 case CodecBuffer::Type::PRESET: {
697 *l = OMXBuffer(
698 t.attr.preset.rangeOffset,
699 t.attr.preset.rangeLength);
700 return true;
701 }
702 case CodecBuffer::Type::SHARED_MEM: {
703 *l = OMXBuffer(t.sharedMemory);
704 return true;
705 }
706 case CodecBuffer::Type::ANW_BUFFER: {
Pawin Vongmasa8ff40182017-02-07 02:22:34 -0800707 if (t.nativeHandle.getNativeHandle() == nullptr) {
708 *l = OMXBuffer(sp<GraphicBuffer>(nullptr));
709 return true;
710 }
Pawin Vongmasa9c47c972017-02-08 04:09:38 -0800711 AnwBuffer anwBuffer;
712 anwBuffer.nativeHandle = t.nativeHandle;
713 anwBuffer.attr = t.attr.anwBuffer;
714 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
715 if (!convertTo(graphicBuffer.get(), anwBuffer)) {
716 return false;
717 }
718 *l = OMXBuffer(graphicBuffer);
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800719 return true;
720 }
721 case CodecBuffer::Type::NATIVE_HANDLE: {
722 *l = OMXBuffer(NativeHandle::create(
723 native_handle_clone(t.nativeHandle), true));
724 return true;
725 }
726 }
727 return false;
728}
729
730/**
731 * \brief Convert `IOMX::ComponentInfo` to `IOmx::ComponentInfo`.
732 *
733 * \param[out] t The destination `IOmx::ComponentInfo`.
734 * \param[in] l The source `IOMX::ComponentInfo`.
735 */
736// convert: IOMX::ComponentInfo -> IOmx::ComponentInfo
737inline bool convertTo(IOmx::ComponentInfo* t, IOMX::ComponentInfo const& l) {
738 t->mName = l.mName.string();
739 t->mRoles.resize(l.mRoles.size());
740 size_t i = 0;
741 for (auto& role : l.mRoles) {
742 t->mRoles[i++] = role.string();
743 }
744 return true;
745}
746
747/**
748 * \brief Convert `IOmx::ComponentInfo` to `IOMX::ComponentInfo`.
749 *
750 * \param[out] l The destination `IOMX::ComponentInfo`.
751 * \param[in] t The source `IOmx::ComponentInfo`.
752 */
753// convert: IOmx::ComponentInfo -> IOMX::ComponentInfo
754inline bool convertTo(IOMX::ComponentInfo* l, IOmx::ComponentInfo const& t) {
755 l->mName = t.mName.c_str();
756 l->mRoles.clear();
757 for (size_t i = 0; i < t.mRoles.size(); ++i) {
758 l->mRoles.push_back(String8(t.mRoles[i].c_str()));
759 }
760 return true;
761}
762
763/**
764 * \brief Convert `OMX_BOOL` to `bool`.
765 *
766 * \param[in] l The source `OMX_BOOL`.
767 * \return The destination `bool`.
768 */
769// convert: OMX_BOOL -> bool
770inline bool toRawBool(OMX_BOOL l) {
771 return l == OMX_FALSE ? false : true;
772}
773
774/**
775 * \brief Convert `bool` to `OMX_BOOL`.
776 *
777 * \param[in] t The source `bool`.
778 * \return The destination `OMX_BOOL`.
779 */
780// convert: bool -> OMX_BOOL
781inline OMX_BOOL toEnumBool(bool t) {
782 return t ? OMX_TRUE : OMX_FALSE;
783}
784
785/**
786 * \brief Convert `OMX_COMMANDTYPE` to `uint32_t`.
787 *
788 * \param[in] l The source `OMX_COMMANDTYPE`.
789 * \return The underlying value of type `uint32_t`.
790 *
791 * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`.
792 */
793// convert: OMX_COMMANDTYPE -> uint32_t
794inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
795 return static_cast<uint32_t>(l);
796}
797
798/**
799 * \brief Convert `uint32_t` to `OMX_COMMANDTYPE`.
800 *
801 * \param[in] t The source `uint32_t`.
802 * \return The corresponding enum value of type `OMX_COMMANDTYPE`.
803 *
804 * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`.
805 */
806// convert: uint32_t -> OMX_COMMANDTYPE
807inline OMX_COMMANDTYPE toEnumCommandType(uint32_t t) {
808 return static_cast<OMX_COMMANDTYPE>(t);
809}
810
811/**
812 * \brief Convert `OMX_INDEXTYPE` to `uint32_t`.
813 *
814 * \param[in] l The source `OMX_INDEXTYPE`.
815 * \return The underlying value of type `uint32_t`.
816 *
817 * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`.
818 */
819// convert: OMX_INDEXTYPE -> uint32_t
820inline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
821 return static_cast<uint32_t>(l);
822}
823
824/**
825 * \brief Convert `uint32_t` to `OMX_INDEXTYPE`.
826 *
827 * \param[in] t The source `uint32_t`.
828 * \return The corresponding enum value of type `OMX_INDEXTYPE`.
829 *
830 * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`.
831 */
832// convert: uint32_t -> OMX_INDEXTYPE
833inline OMX_INDEXTYPE toEnumIndexType(uint32_t t) {
834 return static_cast<OMX_INDEXTYPE>(t);
835}
836
837/**
838 * \brief Convert `IOMX::PortMode` to `PortMode`.
839 *
840 * \param[in] l The source `IOMX::PortMode`.
841 * \return The destination `PortMode`.
842 */
843// convert: IOMX::PortMode -> PortMode
844inline PortMode toHardwarePortMode(IOMX::PortMode l) {
845 return static_cast<PortMode>(l);
846}
847
848/**
849 * \brief Convert `PortMode` to `IOMX::PortMode`.
850 *
851 * \param[in] t The source `PortMode`.
852 * \return The destination `IOMX::PortMode`.
853 */
854// convert: PortMode -> IOMX::PortMode
855inline IOMX::PortMode toIOMXPortMode(PortMode t) {
856 return static_cast<IOMX::PortMode>(t);
857}
858
859/**
860 * \brief Convert `OMX_TICKS` to `uint64_t`.
861 *
862 * \param[in] l The source `OMX_TICKS`.
863 * \return The destination `uint64_t`.
864 */
865// convert: OMX_TICKS -> uint64_t
866inline uint64_t toRawTicks(OMX_TICKS l) {
867#ifndef OMX_SKIP64BIT
868 return static_cast<uint64_t>(l);
869#else
870 return static_cast<uint64_t>(l.nLowPart) |
871 static_cast<uint64_t>(l.nHighPart << 32);
872#endif
873}
874
875/**
876 * \brief Convert `uint64_t` to `OMX_TICKS`.
877 *
878 * \param[in] l The source `uint64_t`.
879 * \return The destination `OMX_TICKS`.
880 */
881// convert: uint64_t -> OMX_TICKS
882inline OMX_TICKS toOMXTicks(uint64_t t) {
883#ifndef OMX_SKIP64BIT
884 return static_cast<OMX_TICKS>(t);
885#else
886 return OMX_TICKS{
887 static_cast<uint32_t>(t & 0xFFFFFFFF),
888 static_cast<uint32_t>(t >> 32)};
889#endif
890}
891
Pawin Vongmasaeeac97b2017-01-18 05:03:07 -0800892} // namespace utils
893} // namespace V1_0
894} // namespace omx
895} // namespace media
896} // namespace hardware
897} // namespace android
898
899#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H