1 /*
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_UTILS_CONVERSION_H
18 #define ANDROID_HARDWARE_MEDIA_OMX_V1_0_UTILS_CONVERSION_H
19 
20 #include <vector>
21 #include <list>
22 
23 #include <cinttypes>
24 #include <unistd.h>
25 
26 #include <hidl/MQDescriptor.h>
27 #include <hidl/Status.h>
28 
29 #include <binder/Binder.h>
30 #include <binder/Status.h>
31 #include <ui/FenceTime.h>
32 #include <cutils/native_handle.h>
33 
34 #include <ui/BufferQueueDefs.h>
35 #include <ui/GraphicBuffer.h>
36 #include <media/OMXFenceParcelable.h>
37 #include <media/OMXBuffer.h>
38 #include <media/hardware/VideoAPI.h>
39 #include <media/stagefright/MediaErrors.h>
40 
41 #include <android/hardware/media/omx/1.0/types.h>
42 #include <android/hardware/media/omx/1.0/IOmx.h>
43 #include <android/hardware/media/omx/1.0/IOmxNode.h>
44 #include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
45 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
46 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
47 
48 #include <android/IOMXBufferSource.h>
49 
50 namespace android {
51 namespace hardware {
52 namespace media {
53 namespace omx {
54 namespace V1_0 {
55 namespace utils {
56 
57 using ::android::hardware::hidl_array;
58 using ::android::hardware::hidl_string;
59 using ::android::hardware::hidl_vec;
60 using ::android::hardware::hidl_handle;
61 using ::android::hardware::Return;
62 using ::android::hardware::Void;
63 using ::android::sp;
64 
65 using ::android::String8;
66 using ::android::OMXFenceParcelable;
67 
68 using ::android::hardware::media::omx::V1_0::Message;
69 using ::android::omx_message;
70 
71 using ::android::hardware::media::omx::V1_0::ColorAspects;
72 using ::android::hardware::media::V1_0::Rect;
73 using ::android::hardware::media::V1_0::Region;
74 
75 using ::android::hardware::graphics::common::V1_0::Dataspace;
76 
77 using ::android::hardware::graphics::common::V1_0::PixelFormat;
78 
79 using ::android::OMXBuffer;
80 
81 using ::android::hardware::media::V1_0::AnwBuffer;
82 using ::android::GraphicBuffer;
83 
84 using ::android::hardware::media::omx::V1_0::IOmx;
85 using ::android::IOMX;
86 
87 using ::android::hardware::media::omx::V1_0::IOmxNode;
88 using ::android::IOMXNode;
89 
90 using ::android::hardware::media::omx::V1_0::IOmxObserver;
91 using ::android::IOMXObserver;
92 
93 using ::android::hardware::media::omx::V1_0::IOmxBufferSource;
94 using ::android::IOMXBufferSource;
95 
96 // 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  */
native_handle_create_from_fd(int fd)113 inline 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  */
136 inline 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 /**
175  * \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
toBinderStatus(Return<void> const & t)181 inline ::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 /**
189  * \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
toBinderStatus(Return<Status> const & t)195 inline ::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 /**
202  * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
203  *
204  * \param[in] t The source `Return<void>`.
205  * \return The corresponding `status_t`.
206  */
207 // convert: Return<void> -> status_t
toStatusT(Return<void> const & t)208 inline status_t toStatusT(Return<void> const& t) {
209     return t.isOk() ? OK : UNKNOWN_ERROR;
210 }
211 
212 /**
213  * \brief Convert `Status` to `status_t`. This is for legacy binder calls.
214  *
215  * \param[in] t The source `Status`.
216  * \return the corresponding `status_t`.
217  */
218 // convert: Status -> status_t
toStatusT(Status const & t)219 inline status_t toStatusT(Status const& t) {
220     switch (t) {
221     case Status::NO_ERROR:
222     case Status::NAME_NOT_FOUND:
223     case Status::WOULD_BLOCK:
224     case Status::NO_MEMORY:
225     case Status::ALREADY_EXISTS:
226     case Status::NO_INIT:
227     case Status::BAD_VALUE:
228     case Status::DEAD_OBJECT:
229     case Status::INVALID_OPERATION:
230     case Status::TIMED_OUT:
231     case Status::ERROR_UNSUPPORTED:
232     case Status::UNKNOWN_ERROR:
233     case Status::RELEASE_ALL_BUFFERS:
234         return static_cast<status_t>(t);
235     case Status::BUFFER_NEEDS_REALLOCATION:
236         return NOT_ENOUGH_DATA;
237     default:
238         ALOGW("Unrecognized status value: %" PRId32, static_cast<int32_t>(t));
239         return static_cast<status_t>(t);
240     }
241 }
242 
243 /**
244  * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
245  * calls.
246  *
247  * \param[in] t The source `Return<Status>`.
248  * \return The corresponding `status_t`.
249  *
250  * This function first check if \p t has a transport error. If it does, then the
251  * return value is the transport error code. Otherwise, the return value is
252  * converted from `Status` contained inside \p t.
253  *
254  * Note:
255  * - This `Status` is omx-specific. It is defined in `types.hal`.
256  * - The name of this function is not `convert`.
257  */
258 // convert: Status -> status_t
toStatusT(Return<Status> const & t)259 inline status_t toStatusT(Return<Status> const& t) {
260     if (t.isOk()) {
261         return toStatusT(static_cast<Status>(t));
262     } else if (t.isDeadObject()) {
263         return DEAD_OBJECT;
264     }
265     return UNKNOWN_ERROR;
266 }
267 
268 /**
269  * \brief Convert `status_t` to `Status`.
270  *
271  * \param[in] l The source `status_t`.
272  * \return The corresponding `Status`.
273  */
274 // convert: status_t -> Status
toStatus(status_t l)275 inline Status toStatus(status_t l) {
276     switch (l) {
277     case NO_ERROR:
278     case NAME_NOT_FOUND:
279     case WOULD_BLOCK:
280     case NO_MEMORY:
281     case ALREADY_EXISTS:
282     case NO_INIT:
283     case BAD_VALUE:
284     case DEAD_OBJECT:
285     case INVALID_OPERATION:
286     case TIMED_OUT:
287     case ERROR_UNSUPPORTED:
288     case UNKNOWN_ERROR:
289     case BufferQueueDefs::RELEASE_ALL_BUFFERS:
290     case BufferQueueDefs::BUFFER_NEEDS_REALLOCATION:
291         return static_cast<Status>(l);
292     case NOT_ENOUGH_DATA:
293         return Status::BUFFER_NEEDS_REALLOCATION;
294     default:
295         ALOGW("Unrecognized status value: %" PRId32, static_cast<int32_t>(l));
296         return static_cast<Status>(l);
297     }
298 }
299 
300 /**
301  * \brief Wrap `native_handle_t*` in `hidl_handle`.
302  *
303  * \param[in] nh The source `native_handle_t*`.
304  * \return The `hidl_handle` that points to \p nh.
305  */
306 // wrap: native_handle_t* -> hidl_handle
inHidlHandle(native_handle_t const * nh)307 inline hidl_handle inHidlHandle(native_handle_t const* nh) {
308     return hidl_handle(nh);
309 }
310 
311 /**
312  * \brief Wrap an `omx_message` and construct the corresponding `Message`.
313  *
314  * \param[out] t The wrapper of type `Message`.
315  * \param[out] nh The native_handle_t referred to by `t->fence`.
316  * \param[in] l The source `omx_message`.
317  * \return `true` if the wrapping is successful; `false` otherwise.
318  *
319  * Upon success, \p nh will be created to hold the file descriptor stored in
320  * `l.fenceFd`, and `t->fence` will point to \p nh. \p nh will need to be
321  * destroyed manually by `native_handle_delete()` when \p t is no longer needed.
322  *
323  * Upon failure, \p nh will not be created and will not need to be deleted. \p t
324  * will be invalid.
325  */
326 // wrap, omx_message -> Message, native_handle_t*
wrapAs(Message * t,native_handle_t ** nh,omx_message const & l)327 inline bool wrapAs(Message* t, native_handle_t** nh, omx_message const& l) {
328     *nh = native_handle_create_from_fd(l.fenceFd);
329     if (!*nh) {
330         return false;
331     }
332     t->fence = *nh;
333     switch (l.type) {
334         case omx_message::EVENT:
335             t->type = Message::Type::EVENT;
336             t->data.eventData.event = uint32_t(l.u.event_data.event);
337             t->data.eventData.data1 = l.u.event_data.data1;
338             t->data.eventData.data2 = l.u.event_data.data2;
339             t->data.eventData.data3 = l.u.event_data.data3;
340             t->data.eventData.data4 = l.u.event_data.data4;
341             break;
342         case omx_message::EMPTY_BUFFER_DONE:
343             t->type = Message::Type::EMPTY_BUFFER_DONE;
344             t->data.bufferData.buffer = l.u.buffer_data.buffer;
345             break;
346         case omx_message::FILL_BUFFER_DONE:
347             t->type = Message::Type::FILL_BUFFER_DONE;
348             t->data.extendedBufferData.buffer = l.u.extended_buffer_data.buffer;
349             t->data.extendedBufferData.rangeOffset =
350                     l.u.extended_buffer_data.range_offset;
351             t->data.extendedBufferData.rangeLength =
352                     l.u.extended_buffer_data.range_length;
353             t->data.extendedBufferData.flags = l.u.extended_buffer_data.flags;
354             t->data.extendedBufferData.timestampUs =
355                     l.u.extended_buffer_data.timestamp;
356             break;
357         case omx_message::FRAME_RENDERED:
358             t->type = Message::Type::FRAME_RENDERED;
359             t->data.renderData.timestampUs = l.u.render_data.timestamp;
360             t->data.renderData.systemTimeNs = l.u.render_data.nanoTime;
361             break;
362         default:
363             native_handle_delete(*nh);
364             return false;
365     }
366     return true;
367 }
368 
369 /**
370  * \brief Wrap a `Message` inside an `omx_message`.
371  *
372  * \param[out] l The wrapper of type `omx_message`.
373  * \param[in] t The source `Message`.
374  * \return `true` if the wrapping is successful; `false` otherwise.
375  */
376 // wrap: Message -> omx_message
wrapAs(omx_message * l,Message const & t)377 inline bool wrapAs(omx_message* l, Message const& t) {
378     l->fenceFd = native_handle_read_fd(t.fence);
379     switch (t.type) {
380         case Message::Type::EVENT:
381             l->type = omx_message::EVENT;
382             l->u.event_data.event = OMX_EVENTTYPE(t.data.eventData.event);
383             l->u.event_data.data1 = t.data.eventData.data1;
384             l->u.event_data.data2 = t.data.eventData.data2;
385             l->u.event_data.data3 = t.data.eventData.data3;
386             l->u.event_data.data4 = t.data.eventData.data4;
387             break;
388         case Message::Type::EMPTY_BUFFER_DONE:
389             l->type = omx_message::EMPTY_BUFFER_DONE;
390             l->u.buffer_data.buffer = t.data.bufferData.buffer;
391             break;
392         case Message::Type::FILL_BUFFER_DONE:
393             l->type = omx_message::FILL_BUFFER_DONE;
394             l->u.extended_buffer_data.buffer = t.data.extendedBufferData.buffer;
395             l->u.extended_buffer_data.range_offset =
396                     t.data.extendedBufferData.rangeOffset;
397             l->u.extended_buffer_data.range_length =
398                     t.data.extendedBufferData.rangeLength;
399             l->u.extended_buffer_data.flags = t.data.extendedBufferData.flags;
400             l->u.extended_buffer_data.timestamp =
401                     t.data.extendedBufferData.timestampUs;
402             break;
403         case Message::Type::FRAME_RENDERED:
404             l->type = omx_message::FRAME_RENDERED;
405             l->u.render_data.timestamp = t.data.renderData.timestampUs;
406             l->u.render_data.nanoTime = t.data.renderData.systemTimeNs;
407             break;
408         default:
409             return false;
410     }
411     return true;
412 }
413 
414 /**
415  * \brief Similar to `wrapTo(omx_message*, Message const&)`, but the output will
416  * have an extended lifetime.
417  *
418  * \param[out] l The output `omx_message`.
419  * \param[in] t The source `Message`.
420  * \return `true` if the conversion is successful; `false` otherwise.
421  *
422  * This function calls `wrapto()`, then attempts to duplicate the file
423  * descriptor for the fence if it is not `-1`. If duplication fails, `false`
424  * will be returned.
425  */
426 // convert: Message -> omx_message
convertTo(omx_message * l,Message const & t)427 inline bool convertTo(omx_message* l, Message const& t) {
428     if (!wrapAs(l, t)) {
429         return false;
430     }
431     if (l->fenceFd == -1) {
432         return true;
433     }
434     l->fenceFd = dup(l->fenceFd);
435     return l->fenceFd != -1;
436 }
437 
438 /**
439  * \brief Wrap an `OMXFenceParcelable` inside a `hidl_handle`.
440  *
441  * \param[out] t The wrapper of type `hidl_handle`.
442  * \param[out] nh The native handle created to hold the file descriptor inside
443  * \p l.
444  * \param[in] l The source `OMXFenceParcelable`, which essentially contains one
445  * file descriptor.
446  * \return `true` if \p t and \p nh are successfully created to wrap around \p
447  * l; `false` otherwise.
448  *
449  * On success, \p nh needs to be deleted by the caller with
450  * `native_handle_delete()` after \p t and \p nh are no longer needed.
451  *
452  * On failure, \p nh will not need to be deleted, and \p t will hold an invalid
453  * value.
454  */
455 // wrap: OMXFenceParcelable -> hidl_handle, native_handle_t*
wrapAs(hidl_handle * t,native_handle_t ** nh,OMXFenceParcelable const & l)456 inline bool wrapAs(hidl_handle* t, native_handle_t** nh,
457         OMXFenceParcelable const& l) {
458     *nh = native_handle_create_from_fd(l.get());
459     if (!*nh) {
460         return false;
461     }
462     *t = *nh;
463     return true;
464 }
465 
466 /**
467  * \brief Wrap a `hidl_handle` inside an `OMXFenceParcelable`.
468  *
469  * \param[out] l The wrapper of type `OMXFenceParcelable`.
470  * \param[in] t The source `hidl_handle`.
471  */
472 // wrap: hidl_handle -> OMXFenceParcelable
wrapAs(OMXFenceParcelable * l,hidl_handle const & t)473 inline void wrapAs(OMXFenceParcelable* l, hidl_handle const& t) {
474     l->mFenceFd = native_handle_read_fd(t);
475 }
476 
477 /**
478  * \brief Convert a `hidl_handle` to `OMXFenceParcelable`. If `hidl_handle`
479  * contains file descriptors, the first file descriptor will be duplicated and
480  * stored in the output `OMXFenceParcelable`.
481  *
482  * \param[out] l The output `OMXFenceParcelable`.
483  * \param[in] t The input `hidl_handle`.
484  * \return `false` if \p t contains a valid file descriptor but duplication
485  * fails; `true` otherwise.
486  */
487 // convert: hidl_handle -> OMXFenceParcelable
convertTo(OMXFenceParcelable * l,hidl_handle const & t)488 inline bool convertTo(OMXFenceParcelable* l, hidl_handle const& t) {
489     int fd = native_handle_read_fd(t);
490     if (fd != -1) {
491         fd = dup(fd);
492         if (fd == -1) {
493             return false;
494         }
495     }
496     l->mFenceFd = fd;
497     return true;
498 }
499 
500 /**
501  * \brief Convert `::android::ColorAspects` to `ColorAspects`.
502  *
503  * \param[in] l The source `::android::ColorAspects`.
504  * \return The corresponding `ColorAspects`.
505  */
506 // convert: ::android::ColorAspects -> ColorAspects
toHardwareColorAspects(::android::ColorAspects const & l)507 inline ColorAspects toHardwareColorAspects(::android::ColorAspects const& l) {
508     return ColorAspects{
509             static_cast<ColorAspects::Range>(l.mRange),
510             static_cast<ColorAspects::Primaries>(l.mPrimaries),
511             static_cast<ColorAspects::Transfer>(l.mTransfer),
512             static_cast<ColorAspects::MatrixCoeffs>(l.mMatrixCoeffs)};
513 }
514 
515 /**
516  * \brief Convert `int32_t` to `ColorAspects`.
517  *
518  * \param[in] l The source `int32_t`.
519  * \return The corresponding `ColorAspects`.
520  */
521 // convert: int32_t -> ColorAspects
toHardwareColorAspects(int32_t l)522 inline ColorAspects toHardwareColorAspects(int32_t l) {
523     return ColorAspects{
524             static_cast<ColorAspects::Range>((l >> 24) & 0xFF),
525             static_cast<ColorAspects::Primaries>((l >> 16) & 0xFF),
526             static_cast<ColorAspects::Transfer>(l & 0xFF),
527             static_cast<ColorAspects::MatrixCoeffs>((l >> 8) & 0xFF)};
528 }
529 
530 /**
531  * \brief Convert `ColorAspects` to `::android::ColorAspects`.
532  *
533  * \param[in] t The source `ColorAspects`.
534  * \return The corresponding `::android::ColorAspects`.
535  */
536 // convert: ColorAspects -> ::android::ColorAspects
toCompactColorAspects(ColorAspects const & t)537 inline int32_t toCompactColorAspects(ColorAspects const& t) {
538     return static_cast<int32_t>(
539             (static_cast<uint32_t>(t.range) << 24) |
540             (static_cast<uint32_t>(t.primaries) << 16) |
541             (static_cast<uint32_t>(t.transfer)) |
542             (static_cast<uint32_t>(t.matrixCoeffs) << 8));
543 }
544 
545 /**
546  * \brief Convert `int32_t` to `Dataspace`.
547  *
548  * \param[in] l The source `int32_t`.
549  * \result The corresponding `Dataspace`.
550  */
551 // convert: int32_t -> Dataspace
toHardwareDataspace(int32_t l)552 inline Dataspace toHardwareDataspace(int32_t l) {
553     return static_cast<Dataspace>(l);
554 }
555 
556 /**
557  * \brief Convert `Dataspace` to `int32_t`.
558  *
559  * \param[in] t The source `Dataspace`.
560  * \result The corresponding `int32_t`.
561  */
562 // convert: Dataspace -> int32_t
toRawDataspace(Dataspace const & t)563 inline int32_t toRawDataspace(Dataspace const& t) {
564     return static_cast<int32_t>(t);
565 }
566 
567 /**
568  * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
569  *
570  * \param[in] l The pointer to the beginning of the opaque buffer.
571  * \param[in] size The size of the buffer.
572  * \return A `hidl_vec<uint8_t>` that points to the buffer.
573  */
574 // wrap: void*, size_t -> hidl_vec<uint8_t>
inHidlBytes(void const * l,size_t size)575 inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
576     hidl_vec<uint8_t> t;
577     t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
578     return t;
579 }
580 
581 /**
582  * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
583  *
584  * \param[in] l The pointer to the beginning of the opaque buffer.
585  * \param[in] size The size of the buffer.
586  * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
587  */
588 // convert: void*, size_t -> hidl_vec<uint8_t>
toHidlBytes(void const * l,size_t size)589 inline hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
590     hidl_vec<uint8_t> t;
591     t.resize(size);
592     uint8_t const* src = static_cast<uint8_t const*>(l);
593     std::copy(src, src + size, t.data());
594     return t;
595 }
596 
597 /**
598  * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
599  *
600  * \param[out] t The wrapper of type `AnwBuffer`.
601  * \param[in] l The source `GraphicBuffer`.
602  */
603 // wrap: GraphicBuffer -> AnwBuffer
wrapAs(AnwBuffer * t,GraphicBuffer const & l)604 inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
605     t->attr.width = l.getWidth();
606     t->attr.height = l.getHeight();
607     t->attr.stride = l.getStride();
608     t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
609     t->attr.layerCount = l.getLayerCount();
610     t->attr.usage = l.getUsage();
611     t->attr.id = l.getId();
612     t->attr.generationNumber = l.getGenerationNumber();
613     t->nativeHandle = hidl_handle(l.handle);
614 }
615 
616 /**
617  * \brief Convert `AnwBuffer` to `GraphicBuffer`.
618  *
619  * \param[out] l The destination `GraphicBuffer`.
620  * \param[in] t The source `AnwBuffer`.
621  *
622  * This function will duplicate all file descriptors in \p t.
623  */
624 // convert: AnwBuffer -> GraphicBuffer
625 // Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
convertTo(GraphicBuffer * l,AnwBuffer const & t)626 inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
627     native_handle_t* handle = nullptr;
628 
629     if (t.nativeHandle != nullptr) {
630         handle = native_handle_clone(t.nativeHandle);
631         if (handle == nullptr) {
632             ALOGE("Failed to clone handle: numFds=%d, data[0]=%d, data[1]=%d",
633                     t.nativeHandle->numFds,
634                     (t.nativeHandle->numFds > 0) ? t.nativeHandle->data[0] : -1,
635                     (t.nativeHandle->numFds > 1) ? t.nativeHandle->data[1] : -1);
636             return false;
637         }
638     }
639 
640     size_t const numInts = 12 + (handle ? handle->numInts : 0);
641     int32_t* ints = new int32_t[numInts];
642 
643     size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
644     int* fds = new int[numFds];
645 
646     ints[0] = 'GBFR';
647     ints[1] = static_cast<int32_t>(t.attr.width);
648     ints[2] = static_cast<int32_t>(t.attr.height);
649     ints[3] = static_cast<int32_t>(t.attr.stride);
650     ints[4] = static_cast<int32_t>(t.attr.format);
651     ints[5] = static_cast<int32_t>(t.attr.layerCount);
652     ints[6] = static_cast<int32_t>(t.attr.usage);
653     ints[7] = static_cast<int32_t>(t.attr.id >> 32);
654     ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
655     ints[9] = static_cast<int32_t>(t.attr.generationNumber);
656     ints[10] = 0;
657     ints[11] = 0;
658     if (handle) {
659         ints[10] = static_cast<int32_t>(handle->numFds);
660         ints[11] = static_cast<int32_t>(handle->numInts);
661         int* intsStart = handle->data + handle->numFds;
662         std::copy(handle->data, intsStart, fds);
663         std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
664     }
665 
666     void const* constBuffer = static_cast<void const*>(ints);
667     size_t size = numInts * sizeof(int32_t);
668     int const* constFds = static_cast<int const*>(fds);
669     status_t status = l->unflatten(constBuffer, size, constFds, numFds);
670 
671     delete [] fds;
672     delete [] ints;
673     native_handle_delete(handle);
674     return status == NO_ERROR;
675 }
676 
677 /**
678  * \brief Wrap `OMXBuffer` in `CodecBuffer`.
679  *
680  * \param[out] t The wrapper of type `CodecBuffer`.
681  * \param[in] l The source `OMXBuffer`.
682  * \return `true` if the wrapping is successful; `false` otherwise.
683  */
684 // wrap: OMXBuffer -> CodecBuffer
wrapAs(CodecBuffer * t,OMXBuffer const & l)685 inline bool wrapAs(CodecBuffer* t, OMXBuffer const& l) {
686     t->sharedMemory = hidl_memory();
687     t->nativeHandle = hidl_handle();
688     switch (l.mBufferType) {
689         case OMXBuffer::kBufferTypeInvalid: {
690             t->type = CodecBuffer::Type::INVALID;
691             return true;
692         }
693         case OMXBuffer::kBufferTypePreset: {
694             t->type = CodecBuffer::Type::PRESET;
695             t->attr.preset.rangeLength = static_cast<uint32_t>(l.mRangeLength);
696             t->attr.preset.rangeOffset = static_cast<uint32_t>(l.mRangeOffset);
697             return true;
698         }
699         case OMXBuffer::kBufferTypeHidlMemory: {
700             t->type = CodecBuffer::Type::SHARED_MEM;
701             t->sharedMemory = l.mHidlMemory;
702             return true;
703         }
704         case OMXBuffer::kBufferTypeSharedMem: {
705             // This is not supported.
706             return false;
707         }
708         case OMXBuffer::kBufferTypeANWBuffer: {
709             t->type = CodecBuffer::Type::ANW_BUFFER;
710             if (l.mGraphicBuffer == nullptr) {
711                 t->attr.anwBuffer.width = 0;
712                 t->attr.anwBuffer.height = 0;
713                 t->attr.anwBuffer.stride = 0;
714                 t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
715                 t->attr.anwBuffer.layerCount = 0;
716                 t->attr.anwBuffer.usage = 0;
717                 return true;
718             }
719             t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
720             t->attr.anwBuffer.height = l.mGraphicBuffer->getHeight();
721             t->attr.anwBuffer.stride = l.mGraphicBuffer->getStride();
722             t->attr.anwBuffer.format = static_cast<PixelFormat>(
723                     l.mGraphicBuffer->getPixelFormat());
724             t->attr.anwBuffer.layerCount = l.mGraphicBuffer->getLayerCount();
725             t->attr.anwBuffer.usage = l.mGraphicBuffer->getUsage();
726             t->nativeHandle = l.mGraphicBuffer->handle;
727             return true;
728         }
729         case OMXBuffer::kBufferTypeNativeHandle: {
730             t->type = CodecBuffer::Type::NATIVE_HANDLE;
731             t->nativeHandle = l.mNativeHandle->handle();
732             return true;
733         }
734     }
735     return false;
736 }
737 
738 /**
739  * \brief Convert `CodecBuffer` to `OMXBuffer`.
740  *
741  * \param[out] l The destination `OMXBuffer`.
742  * \param[in] t The source `CodecBuffer`.
743  * \return `true` if successful; `false` otherwise.
744  */
745 // convert: CodecBuffer -> OMXBuffer
convertTo(OMXBuffer * l,CodecBuffer const & t)746 inline bool convertTo(OMXBuffer* l, CodecBuffer const& t) {
747     switch (t.type) {
748         case CodecBuffer::Type::INVALID: {
749             *l = OMXBuffer();
750             return true;
751         }
752         case CodecBuffer::Type::PRESET: {
753             *l = OMXBuffer(
754                     t.attr.preset.rangeOffset,
755                     t.attr.preset.rangeLength);
756             return true;
757         }
758         case CodecBuffer::Type::SHARED_MEM: {
759             *l = OMXBuffer(t.sharedMemory);
760             return true;
761         }
762         case CodecBuffer::Type::ANW_BUFFER: {
763             if (t.nativeHandle.getNativeHandle() == nullptr) {
764                 *l = OMXBuffer(sp<GraphicBuffer>(nullptr));
765                 return true;
766             }
767             AnwBuffer anwBuffer;
768             // Explicitly get the native_handle_t* (in stead of assigning t.nativeHandle)
769             // so that we don't do an extra native_handle_clone() in this step, as the
770             // convertion to GraphicBuffer below will do a clone regardless.
771             // If we encounter an invalid handle, the convertTo() below would fail (while
772             // the assigning of hidl_handle would abort and cause a crash).
773             anwBuffer.nativeHandle = t.nativeHandle.getNativeHandle();
774             anwBuffer.attr = t.attr.anwBuffer;
775             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
776             if (!convertTo(graphicBuffer.get(), anwBuffer)) {
777                 return false;
778             }
779             *l = OMXBuffer(graphicBuffer);
780             return true;
781         }
782         case CodecBuffer::Type::NATIVE_HANDLE: {
783             *l = OMXBuffer(NativeHandle::create(
784                     native_handle_clone(t.nativeHandle), true));
785             return true;
786         }
787     }
788     return false;
789 }
790 
791 /**
792  * \brief Convert `IOMX::ComponentInfo` to `IOmx::ComponentInfo`.
793  *
794  * \param[out] t The destination `IOmx::ComponentInfo`.
795  * \param[in] l The source `IOMX::ComponentInfo`.
796  */
797 // convert: IOMX::ComponentInfo -> IOmx::ComponentInfo
convertTo(IOmx::ComponentInfo * t,IOMX::ComponentInfo const & l)798 inline bool convertTo(IOmx::ComponentInfo* t, IOMX::ComponentInfo const& l) {
799     t->mName = l.mName.string();
800     t->mRoles.resize(l.mRoles.size());
801     size_t i = 0;
802     for (auto& role : l.mRoles) {
803         t->mRoles[i++] = role.string();
804     }
805     return true;
806 }
807 
808 /**
809  * \brief Convert `IOmx::ComponentInfo` to `IOMX::ComponentInfo`.
810  *
811  * \param[out] l The destination `IOMX::ComponentInfo`.
812  * \param[in] t The source `IOmx::ComponentInfo`.
813  */
814 // convert: IOmx::ComponentInfo -> IOMX::ComponentInfo
convertTo(IOMX::ComponentInfo * l,IOmx::ComponentInfo const & t)815 inline bool convertTo(IOMX::ComponentInfo* l, IOmx::ComponentInfo const& t) {
816     l->mName = t.mName.c_str();
817     l->mRoles.clear();
818     for (size_t i = 0; i < t.mRoles.size(); ++i) {
819         l->mRoles.push_back(String8(t.mRoles[i].c_str()));
820     }
821     return true;
822 }
823 
824 /**
825  * \brief Convert `OMX_BOOL` to `bool`.
826  *
827  * \param[in] l The source `OMX_BOOL`.
828  * \return The destination `bool`.
829  */
830 // convert: OMX_BOOL -> bool
toRawBool(OMX_BOOL l)831 inline bool toRawBool(OMX_BOOL l) {
832     return l == OMX_FALSE ? false : true;
833 }
834 
835 /**
836  * \brief Convert `bool` to `OMX_BOOL`.
837  *
838  * \param[in] t The source `bool`.
839  * \return The destination `OMX_BOOL`.
840  */
841 // convert: bool -> OMX_BOOL
toEnumBool(bool t)842 inline OMX_BOOL toEnumBool(bool t) {
843     return t ? OMX_TRUE : OMX_FALSE;
844 }
845 
846 /**
847  * \brief Convert `OMX_COMMANDTYPE` to `uint32_t`.
848  *
849  * \param[in] l The source `OMX_COMMANDTYPE`.
850  * \return The underlying value of type `uint32_t`.
851  *
852  * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`.
853  */
854 // convert: OMX_COMMANDTYPE -> uint32_t
toRawCommandType(OMX_COMMANDTYPE l)855 inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
856     return static_cast<uint32_t>(l);
857 }
858 
859 /**
860  * \brief Convert `uint32_t` to `OMX_COMMANDTYPE`.
861  *
862  * \param[in] t The source `uint32_t`.
863  * \return The corresponding enum value of type `OMX_COMMANDTYPE`.
864  *
865  * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`.
866  */
867 // convert: uint32_t -> OMX_COMMANDTYPE
toEnumCommandType(uint32_t t)868 inline OMX_COMMANDTYPE toEnumCommandType(uint32_t t) {
869     return static_cast<OMX_COMMANDTYPE>(t);
870 }
871 
872 /**
873  * \brief Convert `OMX_INDEXTYPE` to `uint32_t`.
874  *
875  * \param[in] l The source `OMX_INDEXTYPE`.
876  * \return The underlying value of type `uint32_t`.
877  *
878  * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`.
879  */
880 // convert: OMX_INDEXTYPE -> uint32_t
toRawIndexType(OMX_INDEXTYPE l)881 inline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
882     return static_cast<uint32_t>(l);
883 }
884 
885 /**
886  * \brief Convert `uint32_t` to `OMX_INDEXTYPE`.
887  *
888  * \param[in] t The source `uint32_t`.
889  * \return The corresponding enum value of type `OMX_INDEXTYPE`.
890  *
891  * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`.
892  */
893 // convert: uint32_t -> OMX_INDEXTYPE
toEnumIndexType(uint32_t t)894 inline OMX_INDEXTYPE toEnumIndexType(uint32_t t) {
895     return static_cast<OMX_INDEXTYPE>(t);
896 }
897 
898 /**
899  * \brief Convert `IOMX::PortMode` to `PortMode`.
900  *
901  * \param[in] l The source `IOMX::PortMode`.
902  * \return The destination `PortMode`.
903  */
904 // convert: IOMX::PortMode -> PortMode
toHardwarePortMode(IOMX::PortMode l)905 inline PortMode toHardwarePortMode(IOMX::PortMode l) {
906     return static_cast<PortMode>(l);
907 }
908 
909 /**
910  * \brief Convert `PortMode` to `IOMX::PortMode`.
911  *
912  * \param[in] t The source `PortMode`.
913  * \return The destination `IOMX::PortMode`.
914  */
915 // convert: PortMode -> IOMX::PortMode
toIOMXPortMode(PortMode t)916 inline IOMX::PortMode toIOMXPortMode(PortMode t) {
917     return static_cast<IOMX::PortMode>(t);
918 }
919 
920 /**
921  * \brief Convert `OMX_TICKS` to `uint64_t`.
922  *
923  * \param[in] l The source `OMX_TICKS`.
924  * \return The destination `uint64_t`.
925  */
926 // convert: OMX_TICKS -> uint64_t
toRawTicks(OMX_TICKS l)927 inline uint64_t toRawTicks(OMX_TICKS l) {
928 #ifndef OMX_SKIP64BIT
929     return static_cast<uint64_t>(l);
930 #else
931     return static_cast<uint64_t>(l.nLowPart) |
932             static_cast<uint64_t>(l.nHighPart << 32);
933 #endif
934 }
935 
936 /**
937  * \brief Convert `uint64_t` to `OMX_TICKS`.
938  *
939  * \param[in] l The source `uint64_t`.
940  * \return The destination `OMX_TICKS`.
941  */
942 // convert: uint64_t -> OMX_TICKS
toOMXTicks(uint64_t t)943 inline OMX_TICKS toOMXTicks(uint64_t t) {
944 #ifndef OMX_SKIP64BIT
945     return static_cast<OMX_TICKS>(t);
946 #else
947     return OMX_TICKS{
948             static_cast<uint32_t>(t & 0xFFFFFFFF),
949             static_cast<uint32_t>(t >> 32)};
950 #endif
951 }
952 
953 }  // namespace utils
954 }  // namespace V1_0
955 }  // namespace omx
956 }  // namespace media
957 }  // namespace hardware
958 }  // namespace android
959 
960 #endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_UTILS_CONVERSION_H
961