Split Treble conversion module into two sides: impl and utils.
impl is on the HAL side. utils is on the framework side.
Test: Compiles
Bug: 31399200
Change-Id: Ib88a80f406fa2b897aa7c65f5faba6cdd9d6a700
diff --git a/include/media/OMXBuffer.h b/include/media/OMXBuffer.h
index b4b9284..6f79182 100644
--- a/include/media/OMXBuffer.h
+++ b/include/media/OMXBuffer.h
@@ -36,7 +36,14 @@
::android::OMXBuffer const& l);
inline bool convertTo(::android::OMXBuffer* l,
::android::hardware::media::omx::V1_0::CodecBuffer const& t);
-}}}}}
+}
+namespace utils {
+ inline bool wrapAs(::android::hardware::media::omx::V1_0::CodecBuffer* t,
+ ::android::OMXBuffer const& l);
+ inline bool convertTo(::android::OMXBuffer* l,
+ ::android::hardware::media::omx::V1_0::CodecBuffer const& t);
+}
+}}}}
class GraphicBuffer;
class IMemory;
@@ -93,6 +100,12 @@
friend inline bool (::android::hardware::media::omx::V1_0::implementation::
convertTo)(OMXBuffer* l,
::android::hardware::media::omx::V1_0::CodecBuffer const& t);
+ friend inline bool (::android::hardware::media::omx::V1_0::utils::
+ wrapAs)(::android::hardware::media::omx::V1_0::CodecBuffer* t,
+ OMXBuffer const& l);
+ friend inline bool (::android::hardware::media::omx::V1_0::utils::
+ convertTo)(OMXBuffer* l,
+ ::android::hardware::media::omx::V1_0::CodecBuffer const& t);
enum BufferType {
kBufferTypeInvalid = 0,
diff --git a/include/media/OMXFenceParcelable.h b/include/media/OMXFenceParcelable.h
index f529301..2a8da87 100644
--- a/include/media/OMXFenceParcelable.h
+++ b/include/media/OMXFenceParcelable.h
@@ -26,12 +26,20 @@
// This is needed temporarily for the OMX HIDL transition.
namespace hardware {
struct hidl_handle;
-namespace media { namespace omx { namespace V1_0 { namespace implementation {
+namespace media { namespace omx { namespace V1_0 {
+namespace implementation {
void wrapAs(::android::OMXFenceParcelable* l,
::android::hardware::hidl_handle const& t);
bool convertTo(::android::OMXFenceParcelable* l,
::android::hardware::hidl_handle const& t);
-}}}}}
+}
+namespace utils {
+ void wrapAs(::android::OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+ bool convertTo(::android::OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+}
+}}}}
struct OMXFenceParcelable : public Parcelable {
OMXFenceParcelable() : mFenceFd(-1) {}
@@ -56,6 +64,12 @@
friend bool (::android::hardware::media::omx::V1_0::implementation::
convertTo)(OMXFenceParcelable* l,
::android::hardware::hidl_handle const& t);
+ friend void (::android::hardware::media::omx::V1_0::utils::
+ wrapAs)(OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+ friend bool (::android::hardware::media::omx::V1_0::utils::
+ convertTo)(OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
};
inline status_t OMXFenceParcelable::readFromParcel(const Parcel* parcel) {
diff --git a/media/libstagefright/omx/hal/1.0/Android.mk b/media/libstagefright/omx/hal/1.0/Android.mk
index ccd19d8..c14e909 100644
--- a/media/libstagefright/omx/hal/1.0/Android.mk
+++ b/media/libstagefright/omx/hal/1.0/Android.mk
@@ -1,45 +1,3 @@
LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.media.omx@1.0-impl
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
- WGraphicBufferSource.cpp \
- WOmx.cpp \
- WOmxBufferProducer.cpp \
- WOmxBufferSource.cpp \
- WOmxNode.cpp \
- WOmxObserver.cpp \
- WOmxProducerListener.cpp \
- Omx.cpp \
- OmxNode.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libmedia \
- libstagefright_foundation \
- libstagefright_omx \
- libui \
- libgui \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libhidlmemory \
- libutils \
- libcutils \
- libbinder \
- liblog \
- android.hardware.media.omx@1.0 \
- android.hardware.graphics.common@1.0 \
- android.hardware.media@1.0 \
- android.hidl.base@1.0 \
-
-LOCAL_C_INCLUDES += \
- $(TOP) \
- $(TOP)/frameworks/av/include/media \
- $(TOP)/frameworks/av/media/libstagefright/include \
- $(TOP)/frameworks/av/media/libstagefright/omx \
- $(TOP)/frameworks/native/include/media/hardware \
- $(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/frameworks/native/include \
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/omx/hal/1.0/impl/Android.mk b/media/libstagefright/omx/hal/1.0/impl/Android.mk
new file mode 100644
index 0000000..ccd19d8
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/impl/Android.mk
@@ -0,0 +1,45 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.media.omx@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ WGraphicBufferSource.cpp \
+ WOmx.cpp \
+ WOmxBufferProducer.cpp \
+ WOmxBufferSource.cpp \
+ WOmxNode.cpp \
+ WOmxObserver.cpp \
+ WOmxProducerListener.cpp \
+ Omx.cpp \
+ OmxNode.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libmedia \
+ libstagefright_foundation \
+ libstagefright_omx \
+ libui \
+ libgui \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libhidlmemory \
+ libutils \
+ libcutils \
+ libbinder \
+ liblog \
+ android.hardware.media.omx@1.0 \
+ android.hardware.graphics.common@1.0 \
+ android.hardware.media@1.0 \
+ android.hidl.base@1.0 \
+
+LOCAL_C_INCLUDES += \
+ $(TOP) \
+ $(TOP)/frameworks/av/include/media \
+ $(TOP)/frameworks/av/media/libstagefright/include \
+ $(TOP)/frameworks/av/media/libstagefright/omx \
+ $(TOP)/frameworks/native/include/media/hardware \
+ $(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/native/include \
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/omx/hal/1.0/Conversion.h b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/Conversion.h
rename to media/libstagefright/omx/hal/1.0/impl/Conversion.h
diff --git a/media/libstagefright/omx/hal/1.0/Omx.cpp b/media/libstagefright/omx/hal/1.0/impl/Omx.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/Omx.cpp
rename to media/libstagefright/omx/hal/1.0/impl/Omx.cpp
diff --git a/media/libstagefright/omx/hal/1.0/Omx.h b/media/libstagefright/omx/hal/1.0/impl/Omx.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/Omx.h
rename to media/libstagefright/omx/hal/1.0/impl/Omx.h
diff --git a/media/libstagefright/omx/hal/1.0/OmxNode.cpp b/media/libstagefright/omx/hal/1.0/impl/OmxNode.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/OmxNode.cpp
rename to media/libstagefright/omx/hal/1.0/impl/OmxNode.cpp
diff --git a/media/libstagefright/omx/hal/1.0/OmxNode.h b/media/libstagefright/omx/hal/1.0/impl/OmxNode.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/OmxNode.h
rename to media/libstagefright/omx/hal/1.0/impl/OmxNode.h
diff --git a/media/libstagefright/omx/hal/1.0/WGraphicBufferSource.cpp b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WGraphicBufferSource.cpp
rename to media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
diff --git a/media/libstagefright/omx/hal/1.0/WGraphicBufferSource.h b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WGraphicBufferSource.h
rename to media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
diff --git a/media/libstagefright/omx/hal/1.0/WOmx.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmx.cpp
rename to media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
diff --git a/media/libstagefright/omx/hal/1.0/WOmx.h b/media/libstagefright/omx/hal/1.0/impl/WOmx.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmx.h
rename to media/libstagefright/omx/hal/1.0/impl/WOmx.h
diff --git a/media/libstagefright/omx/hal/1.0/WOmxBufferProducer.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxBufferProducer.cpp
rename to media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.cpp
diff --git a/media/libstagefright/omx/hal/1.0/WOmxBufferProducer.h b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxBufferProducer.h
rename to media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.h
diff --git a/media/libstagefright/omx/hal/1.0/WOmxBufferSource.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxBufferSource.cpp
rename to media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.cpp
diff --git a/media/libstagefright/omx/hal/1.0/WOmxBufferSource.h b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxBufferSource.h
rename to media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.h
diff --git a/media/libstagefright/omx/hal/1.0/WOmxNode.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxNode.cpp
rename to media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
diff --git a/media/libstagefright/omx/hal/1.0/WOmxNode.h b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxNode.h
rename to media/libstagefright/omx/hal/1.0/impl/WOmxNode.h
diff --git a/media/libstagefright/omx/hal/1.0/WOmxObserver.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxObserver.cpp
rename to media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
diff --git a/media/libstagefright/omx/hal/1.0/WOmxObserver.h b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxObserver.h
rename to media/libstagefright/omx/hal/1.0/impl/WOmxObserver.h
diff --git a/media/libstagefright/omx/hal/1.0/WOmxProducerListener.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.cpp
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxProducerListener.cpp
rename to media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.cpp
diff --git a/media/libstagefright/omx/hal/1.0/WOmxProducerListener.h b/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/WOmxProducerListener.h
rename to media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.h
diff --git a/media/libstagefright/omx/hal/1.0/utils/Android.mk b/media/libstagefright/omx/hal/1.0/utils/Android.mk
new file mode 100644
index 0000000..6930c87
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/Android.mk
@@ -0,0 +1,42 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.media.omx@1.0-utils
+LOCAL_SRC_FILES := \
+ WGraphicBufferSource.cpp \
+ WOmx.cpp \
+ WOmxBufferProducer.cpp \
+ WOmxBufferSource.cpp \
+ WOmxNode.cpp \
+ WOmxObserver.cpp \
+ WOmxProducerListener.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libmedia \
+ libstagefright_foundation \
+ libstagefright_omx \
+ libui \
+ libgui \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libhidlmemory \
+ libutils \
+ libcutils \
+ libbinder \
+ liblog \
+ android.hardware.media.omx@1.0 \
+ android.hardware.graphics.common@1.0 \
+ android.hardware.media@1.0 \
+ android.hidl.base@1.0 \
+
+LOCAL_C_INCLUDES += \
+ $(TOP) \
+ $(TOP)/frameworks/av/include/media \
+ $(TOP)/frameworks/av/media/libstagefright/include \
+ $(TOP)/frameworks/av/media/libstagefright/omx \
+ $(TOP)/frameworks/native/include/media/hardware \
+ $(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/native/include \
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/omx/hal/1.0/utils/Conversion.h b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
new file mode 100644
index 0000000..6a99d8c
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
@@ -0,0 +1,2154 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <hidlmemory/mapping.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+#include <unistd.h>
+#include <vector>
+#include <list>
+
+#include <binder/Binder.h>
+#include <binder/Status.h>
+#include <ui/FenceTime.h>
+
+#include <OMXFenceParcelable.h>
+#include <cutils/native_handle.h>
+#include <gui/IGraphicBufferProducer.h>
+
+#include <IOMX.h>
+#include <VideoAPI.h>
+#include <OMXBuffer.h>
+#include <android/IOMXBufferSource.h>
+#include <android/IGraphicBufferSource.h>
+
+#include <android/hardware/media/omx/1.0/types.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxBufferProducer.h>
+#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/IOmxProducerListener.h>
+#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ::android::String8;
+using ::android::OMXFenceParcelable;
+
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::omx_message;
+
+using ::android::hardware::media::omx::V1_0::ColorAspects;
+using ::android::hardware::media::V1_0::Rect;
+using ::android::hardware::media::V1_0::Region;
+
+using ::android::hardware::graphics::common::V1_0::Dataspace;
+
+using ::android::hardware::graphics::common::V1_0::PixelFormat;
+
+using ::android::OMXBuffer;
+
+using ::android::hardware::media::V1_0::AnwBuffer;
+using ::android::GraphicBuffer;
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::IOMX;
+
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::IOMXNode;
+
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::IOMXObserver;
+
+using ::android::hardware::media::omx::V1_0::IOmxBufferSource;
+using ::android::IOMXBufferSource;
+
+using ::android::hardware::media::omx::V1_0::IOmxBufferProducer;
+using ::android::IGraphicBufferProducer;
+
+// native_handle_t helper functions.
+
+/**
+ * \brief Take an fd and create a native handle containing only the given fd.
+ * The created handle will need to be deleted manually with
+ * `native_handle_delete()`.
+ *
+ * \param[in] fd The source file descriptor (of type `int`).
+ * \return The create `native_handle_t*` that contains the given \p fd. If the
+ * supplied \p fd is negative, the created native handle will contain no file
+ * descriptors.
+ *
+ * If the native handle cannot be created, the return value will be
+ * `nullptr`.
+ *
+ * This function does not duplicate the file descriptor.
+ */
+inline native_handle_t* native_handle_create_from_fd(int fd) {
+ if (fd < 0) {
+ return native_handle_create(0, 0);
+ }
+ native_handle_t* nh = native_handle_create(1, 0);
+ if (nh == nullptr) {
+ return nullptr;
+ }
+ nh->data[0] = fd;
+ return nh;
+}
+
+/**
+ * \brief Extract a file descriptor from a native handle.
+ *
+ * \param[in] nh The source `native_handle_t*`.
+ * \param[in] index The index of the file descriptor in \p nh to read from. This
+ * input has the default value of `0`.
+ * \return The `index`-th file descriptor in \p nh. If \p nh does not have
+ * enough file descriptors, the returned value will be `-1`.
+ *
+ * This function does not duplicate the file descriptor.
+ */
+inline int native_handle_read_fd(native_handle_t const* nh, int index = 0) {
+ return ((nh == nullptr) || (nh->numFds == 0) ||
+ (nh->numFds <= index) || (index < 0)) ?
+ -1 : nh->data[index];
+}
+
+/**
+ * Conversion functions
+ * ====================
+ *
+ * There are two main directions of conversion:
+ * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
+ * input. The wrapper has type `TargetType`.
+ * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
+ * corresponds to the input. The lifetime of the output does not depend on the
+ * lifetime of the input.
+ * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
+ * that cannot be copied and/or moved efficiently, or when there are multiple
+ * output arguments.
+ * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
+ * `TargetType` that cannot be copied and/or moved efficiently, or when there
+ * are multiple output arguments.
+ *
+ * `wrapIn()` and `convertTo()` functions will take output arguments before
+ * input arguments. Some of these functions might return a value to indicate
+ * success or error.
+ *
+ * In converting or wrapping something as a Treble type that contains a
+ * `hidl_handle`, `native_handle_t*` will need to be created and returned as
+ * an additional output argument, hence only `wrapIn()` or `convertTo()` would
+ * be available. The caller must call `native_handle_delete()` to deallocate the
+ * returned native handle when it is no longer needed.
+ *
+ * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
+ * not perform duplication of file descriptors, while `toTargetType()` and
+ * `convertTo()` do.
+ */
+
+/**
+ * \brief Convert `binder::Status` to `Return<void>`.
+ *
+ * \param[in] l The source `binder::Status`.
+ * \return The corresponding `Return<void>`.
+ */
+// convert: ::android::binder::Status -> Return<void>
+inline Return<void> toHardwareStatus(
+ ::android::binder::Status const& l) {
+ if (l.exceptionCode() == ::android::binder::Status::EX_SERVICE_SPECIFIC) {
+ return ::android::hardware::Status::fromServiceSpecificError(
+ l.serviceSpecificErrorCode(),
+ l.exceptionMessage());
+ }
+ return ::android::hardware::Status::fromExceptionCode(
+ l.exceptionCode(),
+ l.exceptionMessage());
+}
+
+/**
+ * \brief Convert `Return<void>` to `binder::Status`.
+ *
+ * \param[in] t The source `Return<void>`.
+ * \return The corresponding `binder::Status`.
+ */
+// convert: Return<void> -> ::android::binder::Status
+inline ::android::binder::Status toBinderStatus(
+ Return<void> const& t) {
+ return ::android::binder::Status::fromExceptionCode(
+ t.isOk() ? OK : UNKNOWN_ERROR,
+ t.description().c_str());
+}
+
+/**
+ * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
+ * calls.
+ *
+ * \param[in] t The source `Return<Status>`.
+ * \return The corresponding `status_t`.
+ *
+ * This function first check if \p t has a transport error. If it does, then the
+ * return value is the transport error code. Otherwise, the return value is
+ * converted from `Status` contained inside \p t.
+ *
+ * Note:
+ * - This `Status` is omx-specific. It is defined in `types.hal`.
+ * - The name of this function is not `convert`.
+ */
+// convert: Status -> status_t
+inline status_t toStatusT(Return<Status> const& t) {
+ return t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR;
+}
+
+/**
+ * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
+ *
+ * \param[in] t The source `Return<void>`.
+ * \return The corresponding `status_t`.
+ */
+// convert: Return<void> -> status_t
+inline status_t toStatusT(Return<void> const& t) {
+ return t.isOk() ? OK : UNKNOWN_ERROR;
+}
+
+/**
+ * \brief Convert `Status` to `status_t`. This is for legacy binder calls.
+ *
+ * \param[in] t The source `Status`.
+ * \return the corresponding `status_t`.
+ */
+// convert: Status -> status_t
+inline status_t toStatusT(Status const& t) {
+ return static_cast<status_t>(t);
+}
+
+/**
+ * \brief Convert `status_t` to `Status`.
+ *
+ * \param[in] l The source `status_t`.
+ * \return The corresponding `Status`.
+ */
+// convert: status_t -> Status
+inline Status toStatus(status_t l) {
+ return static_cast<Status>(l);
+}
+
+/**
+ * \brief Wrap `native_handle_t*` in `hidl_handle`.
+ *
+ * \param[in] nh The source `native_handle_t*`.
+ * \return The `hidl_handle` that points to \p nh.
+ */
+// wrap: native_handle_t* -> hidl_handle
+inline hidl_handle inHidlHandle(native_handle_t const* nh) {
+ return hidl_handle(nh);
+}
+
+/**
+ * \brief Wrap an `omx_message` and construct the corresponding `Message`.
+ *
+ * \param[out] t The wrapper of type `Message`.
+ * \param[out] nh The native_handle_t referred to by `t->fence`.
+ * \param[in] l The source `omx_message`.
+ * \return `true` if the wrapping is successful; `false` otherwise.
+ *
+ * Upon success, \p nh will be created to hold the file descriptor stored in
+ * `l.fenceFd`, and `t->fence` will point to \p nh. \p nh will need to be
+ * destroyed manually by `native_handle_delete()` when \p t is no longer needed.
+ *
+ * Upon failure, \p nh will not be created and will not need to be deleted. \p t
+ * will be invalid.
+ */
+// wrap, omx_message -> Message, native_handle_t*
+inline bool wrapAs(Message* t, native_handle_t** nh, omx_message const& l) {
+ *nh = native_handle_create_from_fd(l.fenceFd);
+ if (!*nh) {
+ return false;
+ }
+ t->fence = inHidlHandle(*nh);
+ switch (l.type) {
+ case omx_message::EVENT:
+ t->type = Message::Type::EVENT;
+ t->data.eventData.data1 = l.u.event_data.data1;
+ t->data.eventData.data2 = l.u.event_data.data2;
+ t->data.eventData.data3 = l.u.event_data.data3;
+ t->data.eventData.data4 = l.u.event_data.data4;
+ break;
+ case omx_message::EMPTY_BUFFER_DONE:
+ t->type = Message::Type::EMPTY_BUFFER_DONE;
+ t->data.bufferData.buffer = l.u.buffer_data.buffer;
+ break;
+ case omx_message::FILL_BUFFER_DONE:
+ t->type = Message::Type::FILL_BUFFER_DONE;
+ t->data.extendedBufferData.buffer = l.u.extended_buffer_data.buffer;
+ t->data.extendedBufferData.rangeOffset =
+ l.u.extended_buffer_data.range_offset;
+ t->data.extendedBufferData.rangeLength =
+ l.u.extended_buffer_data.range_length;
+ t->data.extendedBufferData.flags = l.u.extended_buffer_data.flags;
+ t->data.extendedBufferData.timestampUs =
+ l.u.extended_buffer_data.timestamp;
+ break;
+ case omx_message::FRAME_RENDERED:
+ t->type = Message::Type::FRAME_RENDERED;
+ t->data.renderData.timestampUs = l.u.render_data.timestamp;
+ t->data.renderData.systemTimeNs = l.u.render_data.nanoTime;
+ break;
+ default:
+ native_handle_delete(*nh);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * \brief Wrap a `Message` inside an `omx_message`.
+ *
+ * \param[out] l The wrapper of type `omx_message`.
+ * \param[in] t The source `Message`.
+ * \return `true` if the wrapping is successful; `false` otherwise.
+ */
+// wrap: Message -> omx_message
+inline bool wrapAs(omx_message* l, Message const& t) {
+ l->fenceFd = native_handle_read_fd(t.fence);
+ switch (t.type) {
+ case Message::Type::EVENT:
+ l->type = omx_message::EVENT;
+ l->u.event_data.data1 = t.data.eventData.data1;
+ l->u.event_data.data2 = t.data.eventData.data2;
+ l->u.event_data.data3 = t.data.eventData.data3;
+ l->u.event_data.data4 = t.data.eventData.data4;
+ break;
+ case Message::Type::EMPTY_BUFFER_DONE:
+ l->type = omx_message::EMPTY_BUFFER_DONE;
+ l->u.buffer_data.buffer = t.data.bufferData.buffer;
+ break;
+ case Message::Type::FILL_BUFFER_DONE:
+ l->type = omx_message::FILL_BUFFER_DONE;
+ l->u.extended_buffer_data.buffer = t.data.extendedBufferData.buffer;
+ l->u.extended_buffer_data.range_offset =
+ t.data.extendedBufferData.rangeOffset;
+ l->u.extended_buffer_data.range_length =
+ t.data.extendedBufferData.rangeLength;
+ l->u.extended_buffer_data.flags = t.data.extendedBufferData.flags;
+ l->u.extended_buffer_data.timestamp =
+ t.data.extendedBufferData.timestampUs;
+ break;
+ case Message::Type::FRAME_RENDERED:
+ l->type = omx_message::FRAME_RENDERED;
+ l->u.render_data.timestamp = t.data.renderData.timestampUs;
+ l->u.render_data.nanoTime = t.data.renderData.systemTimeNs;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+/**
+ * \brief Similar to `wrapTo(omx_message*, Message const&)`, but the output will
+ * have an extended lifetime.
+ *
+ * \param[out] l The output `omx_message`.
+ * \param[in] t The source `Message`.
+ * \return `true` if the conversion is successful; `false` otherwise.
+ *
+ * This function calls `wrapto()`, then attempts to duplicate the file
+ * descriptor for the fence if it is not `-1`. If duplication fails, `false`
+ * will be returned.
+ */
+// convert: Message -> omx_message
+inline bool convertTo(omx_message* l, Message const& t) {
+ if (!wrapAs(l, t)) {
+ return false;
+ }
+ if (l->fenceFd == -1) {
+ return true;
+ }
+ l->fenceFd = dup(l->fenceFd);
+ return l->fenceFd != -1;
+}
+
+/**
+ * \brief Wrap an `OMXFenceParcelable` inside a `hidl_handle`.
+ *
+ * \param[out] t The wrapper of type `hidl_handle`.
+ * \param[out] nh The native handle created to hold the file descriptor inside
+ * \p l.
+ * \param[in] l The source `OMXFenceParcelable`, which essentially contains one
+ * file descriptor.
+ * \return `true` if \p t and \p nh are successfully created to wrap around \p
+ * l; `false` otherwise.
+ *
+ * On success, \p nh needs to be deleted by the caller with
+ * `native_handle_delete()` after \p t and \p nh are no longer needed.
+ *
+ * On failure, \p nh will not need to be deleted, and \p t will hold an invalid
+ * value.
+ */
+// wrap: OMXFenceParcelable -> hidl_handle, native_handle_t*
+inline bool wrapAs(hidl_handle* t, native_handle_t** nh,
+ OMXFenceParcelable const& l) {
+ *nh = native_handle_create_from_fd(l.get());
+ if (!*nh) {
+ return false;
+ }
+ *t = *nh;
+ return true;
+}
+
+/**
+ * \brief Wrap a `hidl_handle` inside an `OMXFenceParcelable`.
+ *
+ * \param[out] l The wrapper of type `OMXFenceParcelable`.
+ * \param[in] t The source `hidl_handle`.
+ */
+// wrap: hidl_handle -> OMXFenceParcelable
+inline void wrapAs(OMXFenceParcelable* l, hidl_handle const& t) {
+ l->mFenceFd = native_handle_read_fd(t);
+}
+
+/**
+ * \brief Convert a `hidl_handle` to `OMXFenceParcelable`. If `hidl_handle`
+ * contains file descriptors, the first file descriptor will be duplicated and
+ * stored in the output `OMXFenceParcelable`.
+ *
+ * \param[out] l The output `OMXFenceParcelable`.
+ * \param[in] t The input `hidl_handle`.
+ * \return `false` if \p t contains a valid file descriptor but duplication
+ * fails; `true` otherwise.
+ */
+// convert: hidl_handle -> OMXFenceParcelable
+inline bool convertTo(OMXFenceParcelable* l, hidl_handle const& t) {
+ int fd = native_handle_read_fd(t);
+ if (fd != -1) {
+ fd = dup(fd);
+ if (fd == -1) {
+ return false;
+ }
+ }
+ l->mFenceFd = fd;
+ return true;
+}
+
+/**
+ * \brief Convert `::android::ColorAspects` to `ColorAspects`.
+ *
+ * \param[in] l The source `::android::ColorAspects`.
+ * \return The corresponding `ColorAspects`.
+ */
+// convert: ::android::ColorAspects -> ColorAspects
+inline ColorAspects toHardwareColorAspects(::android::ColorAspects const& l) {
+ return ColorAspects{
+ static_cast<ColorAspects::Range>(l.mRange),
+ static_cast<ColorAspects::Primaries>(l.mPrimaries),
+ static_cast<ColorAspects::Transfer>(l.mTransfer),
+ static_cast<ColorAspects::MatrixCoeffs>(l.mMatrixCoeffs)};
+}
+
+/**
+ * \brief Convert `int32_t` to `ColorAspects`.
+ *
+ * \param[in] l The source `int32_t`.
+ * \return The corresponding `ColorAspects`.
+ */
+// convert: int32_t -> ColorAspects
+inline ColorAspects toHardwareColorAspects(int32_t l) {
+ return ColorAspects{
+ static_cast<ColorAspects::Range>((l >> 24) & 0xFF),
+ static_cast<ColorAspects::Primaries>((l >> 16) & 0xFF),
+ static_cast<ColorAspects::Transfer>(l & 0xFF),
+ static_cast<ColorAspects::MatrixCoeffs>((l >> 8) & 0xFF)};
+}
+
+/**
+ * \brief Convert `ColorAspects` to `::android::ColorAspects`.
+ *
+ * \param[in] t The source `ColorAspects`.
+ * \return The corresponding `::android::ColorAspects`.
+ */
+// convert: ColorAspects -> ::android::ColorAspects
+inline int32_t toCompactColorAspects(ColorAspects const& t) {
+ return static_cast<int32_t>(
+ (static_cast<uint32_t>(t.range) << 24) |
+ (static_cast<uint32_t>(t.primaries) << 16) |
+ (static_cast<uint32_t>(t.transfer)) |
+ (static_cast<uint32_t>(t.matrixCoeffs) << 8));
+}
+
+/**
+ * \brief Convert `int32_t` to `Dataspace`.
+ *
+ * \param[in] l The source `int32_t`.
+ * \result The corresponding `Dataspace`.
+ */
+// convert: int32_t -> Dataspace
+inline Dataspace toHardwareDataspace(int32_t l) {
+ return static_cast<Dataspace>(l);
+}
+
+/**
+ * \brief Convert `Dataspace` to `int32_t`.
+ *
+ * \param[in] t The source `Dataspace`.
+ * \result The corresponding `int32_t`.
+ */
+// convert: Dataspace -> int32_t
+inline int32_t toRawDataspace(Dataspace const& t) {
+ return static_cast<int32_t>(t);
+}
+
+/**
+ * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
+ *
+ * \param[in] l The pointer to the beginning of the opaque buffer.
+ * \param[in] size The size of the buffer.
+ * \return A `hidl_vec<uint8_t>` that points to the buffer.
+ */
+// wrap: void*, size_t -> hidl_vec<uint8_t>
+inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
+ hidl_vec<uint8_t> t;
+ t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
+ return t;
+}
+
+/**
+ * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
+ *
+ * \param[in] l The pointer to the beginning of the opaque buffer.
+ * \param[in] size The size of the buffer.
+ * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
+ */
+// convert: void*, size_t -> hidl_vec<uint8_t>
+inline hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
+ hidl_vec<uint8_t> t;
+ t.resize(size);
+ uint8_t const* src = static_cast<uint8_t const*>(l);
+ std::copy(src, src + size, t.data());
+ return t;
+}
+
+/**
+ * \brief Wrap `OMXBuffer` in `CodecBuffer`.
+ *
+ * \param[out] t The wrapper of type `CodecBuffer`.
+ * \param[in] l The source `OMXBuffer`.
+ * \return `true` if the wrapping is successful; `false` otherwise.
+ */
+// wrap: OMXBuffer -> CodecBuffer
+inline bool wrapAs(CodecBuffer* t, OMXBuffer const& l) {
+ t->nativeHandle = hidl_handle();
+ t->sharedMemory = hidl_memory();
+ switch (l.mBufferType) {
+ case OMXBuffer::kBufferTypeInvalid: {
+ t->type = CodecBuffer::Type::INVALID;
+ return true;
+ }
+ case OMXBuffer::kBufferTypePreset: {
+ t->type = CodecBuffer::Type::PRESET;
+ t->attr.preset.rangeLength = static_cast<uint32_t>(l.mRangeLength);
+ t->attr.preset.rangeOffset = static_cast<uint32_t>(l.mRangeOffset);
+ return true;
+ }
+ case OMXBuffer::kBufferTypeHidlMemory: {
+ t->type = CodecBuffer::Type::SHARED_MEM;
+ t->sharedMemory = l.mHidlMemory;
+ return true;
+ }
+ case OMXBuffer::kBufferTypeSharedMem: {
+ // This is not supported.
+ return false;
+ }
+ case OMXBuffer::kBufferTypeANWBuffer: {
+ t->type = CodecBuffer::Type::ANW_BUFFER;
+ t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
+ t->attr.anwBuffer.height = l.mGraphicBuffer->getHeight();
+ t->attr.anwBuffer.stride = l.mGraphicBuffer->getStride();
+ t->attr.anwBuffer.format = static_cast<PixelFormat>(
+ l.mGraphicBuffer->getPixelFormat());
+ t->attr.anwBuffer.layerCount = l.mGraphicBuffer->getLayerCount();
+ t->attr.anwBuffer.usage = l.mGraphicBuffer->getUsage();
+ t->nativeHandle = hidl_handle(l.mGraphicBuffer->handle);
+ return true;
+ }
+ case OMXBuffer::kBufferTypeNativeHandle: {
+ t->type = CodecBuffer::Type::NATIVE_HANDLE;
+ t->nativeHandle = hidl_handle(l.mNativeHandle->handle());
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * \brief Convert `CodecBuffer` to `OMXBuffer`.
+ *
+ * \param[out] l The destination `OMXBuffer`.
+ * \param[in] t The source `CodecBuffer`.
+ * \return `true` if successful; `false` otherwise.
+ */
+// convert: CodecBuffer -> OMXBuffer
+inline bool convertTo(OMXBuffer* l, CodecBuffer const& t) {
+ switch (t.type) {
+ case CodecBuffer::Type::INVALID: {
+ *l = OMXBuffer();
+ return true;
+ }
+ case CodecBuffer::Type::PRESET: {
+ *l = OMXBuffer(
+ t.attr.preset.rangeOffset,
+ t.attr.preset.rangeLength);
+ return true;
+ }
+ case CodecBuffer::Type::SHARED_MEM: {
+ *l = OMXBuffer(t.sharedMemory);
+ return true;
+ }
+ case CodecBuffer::Type::ANW_BUFFER: {
+ *l = OMXBuffer(sp<GraphicBuffer>(new GraphicBuffer(
+ t.attr.anwBuffer.width,
+ t.attr.anwBuffer.height,
+ static_cast<::android::PixelFormat>(
+ t.attr.anwBuffer.format),
+ t.attr.anwBuffer.layerCount,
+ t.attr.anwBuffer.usage,
+ t.attr.anwBuffer.stride,
+ native_handle_clone(t.nativeHandle),
+ true)));
+ return true;
+ }
+ case CodecBuffer::Type::NATIVE_HANDLE: {
+ *l = OMXBuffer(NativeHandle::create(
+ native_handle_clone(t.nativeHandle), true));
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * \brief Convert `IOMX::ComponentInfo` to `IOmx::ComponentInfo`.
+ *
+ * \param[out] t The destination `IOmx::ComponentInfo`.
+ * \param[in] l The source `IOMX::ComponentInfo`.
+ */
+// convert: IOMX::ComponentInfo -> IOmx::ComponentInfo
+inline bool convertTo(IOmx::ComponentInfo* t, IOMX::ComponentInfo const& l) {
+ t->mName = l.mName.string();
+ t->mRoles.resize(l.mRoles.size());
+ size_t i = 0;
+ for (auto& role : l.mRoles) {
+ t->mRoles[i++] = role.string();
+ }
+ return true;
+}
+
+/**
+ * \brief Convert `IOmx::ComponentInfo` to `IOMX::ComponentInfo`.
+ *
+ * \param[out] l The destination `IOMX::ComponentInfo`.
+ * \param[in] t The source `IOmx::ComponentInfo`.
+ */
+// convert: IOmx::ComponentInfo -> IOMX::ComponentInfo
+inline bool convertTo(IOMX::ComponentInfo* l, IOmx::ComponentInfo const& t) {
+ l->mName = t.mName.c_str();
+ l->mRoles.clear();
+ for (size_t i = 0; i < t.mRoles.size(); ++i) {
+ l->mRoles.push_back(String8(t.mRoles[i].c_str()));
+ }
+ return true;
+}
+
+/**
+ * \brief Convert `OMX_BOOL` to `bool`.
+ *
+ * \param[in] l The source `OMX_BOOL`.
+ * \return The destination `bool`.
+ */
+// convert: OMX_BOOL -> bool
+inline bool toRawBool(OMX_BOOL l) {
+ return l == OMX_FALSE ? false : true;
+}
+
+/**
+ * \brief Convert `bool` to `OMX_BOOL`.
+ *
+ * \param[in] t The source `bool`.
+ * \return The destination `OMX_BOOL`.
+ */
+// convert: bool -> OMX_BOOL
+inline OMX_BOOL toEnumBool(bool t) {
+ return t ? OMX_TRUE : OMX_FALSE;
+}
+
+/**
+ * \brief Convert `OMX_COMMANDTYPE` to `uint32_t`.
+ *
+ * \param[in] l The source `OMX_COMMANDTYPE`.
+ * \return The underlying value of type `uint32_t`.
+ *
+ * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`.
+ */
+// convert: OMX_COMMANDTYPE -> uint32_t
+inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
+ return static_cast<uint32_t>(l);
+}
+
+/**
+ * \brief Convert `uint32_t` to `OMX_COMMANDTYPE`.
+ *
+ * \param[in] t The source `uint32_t`.
+ * \return The corresponding enum value of type `OMX_COMMANDTYPE`.
+ *
+ * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`.
+ */
+// convert: uint32_t -> OMX_COMMANDTYPE
+inline OMX_COMMANDTYPE toEnumCommandType(uint32_t t) {
+ return static_cast<OMX_COMMANDTYPE>(t);
+}
+
+/**
+ * \brief Convert `OMX_INDEXTYPE` to `uint32_t`.
+ *
+ * \param[in] l The source `OMX_INDEXTYPE`.
+ * \return The underlying value of type `uint32_t`.
+ *
+ * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`.
+ */
+// convert: OMX_INDEXTYPE -> uint32_t
+inline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
+ return static_cast<uint32_t>(l);
+}
+
+/**
+ * \brief Convert `uint32_t` to `OMX_INDEXTYPE`.
+ *
+ * \param[in] t The source `uint32_t`.
+ * \return The corresponding enum value of type `OMX_INDEXTYPE`.
+ *
+ * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`.
+ */
+// convert: uint32_t -> OMX_INDEXTYPE
+inline OMX_INDEXTYPE toEnumIndexType(uint32_t t) {
+ return static_cast<OMX_INDEXTYPE>(t);
+}
+
+/**
+ * \brief Convert `IOMX::PortMode` to `PortMode`.
+ *
+ * \param[in] l The source `IOMX::PortMode`.
+ * \return The destination `PortMode`.
+ */
+// convert: IOMX::PortMode -> PortMode
+inline PortMode toHardwarePortMode(IOMX::PortMode l) {
+ return static_cast<PortMode>(l);
+}
+
+/**
+ * \brief Convert `PortMode` to `IOMX::PortMode`.
+ *
+ * \param[in] t The source `PortMode`.
+ * \return The destination `IOMX::PortMode`.
+ */
+// convert: PortMode -> IOMX::PortMode
+inline IOMX::PortMode toIOMXPortMode(PortMode t) {
+ return static_cast<IOMX::PortMode>(t);
+}
+
+/**
+ * \brief Convert `OMX_TICKS` to `uint64_t`.
+ *
+ * \param[in] l The source `OMX_TICKS`.
+ * \return The destination `uint64_t`.
+ */
+// convert: OMX_TICKS -> uint64_t
+inline uint64_t toRawTicks(OMX_TICKS l) {
+#ifndef OMX_SKIP64BIT
+ return static_cast<uint64_t>(l);
+#else
+ return static_cast<uint64_t>(l.nLowPart) |
+ static_cast<uint64_t>(l.nHighPart << 32);
+#endif
+}
+
+/**
+ * \brief Convert `uint64_t` to `OMX_TICKS`.
+ *
+ * \param[in] l The source `uint64_t`.
+ * \return The destination `OMX_TICKS`.
+ */
+// convert: uint64_t -> OMX_TICKS
+inline OMX_TICKS toOMXTicks(uint64_t t) {
+#ifndef OMX_SKIP64BIT
+ return static_cast<OMX_TICKS>(t);
+#else
+ return OMX_TICKS{
+ static_cast<uint32_t>(t & 0xFFFFFFFF),
+ static_cast<uint32_t>(t >> 32)};
+#endif
+}
+
+/**
+ * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
+ *
+ * \param[out] t The wrapper of type `AnwBuffer`.
+ * \param[in] l The source `GraphicBuffer`.
+ */
+// wrap: GraphicBuffer -> AnwBuffer
+inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
+ t->attr.width = l.getWidth();
+ t->attr.height = l.getHeight();
+ t->attr.stride = l.getStride();
+ t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
+ t->attr.layerCount = l.getLayerCount();
+ t->attr.usage = l.getUsage();
+ t->attr.id = l.getId();
+ t->attr.generationNumber = l.getGenerationNumber();
+ t->nativeHandle = hidl_handle(l.handle);
+}
+
+/**
+ * \brief Convert `AnwBuffer` to `GraphicBuffer`.
+ *
+ * \param[out] l The destination `GraphicBuffer`.
+ * \param[in] t The source `AnwBuffer`.
+ *
+ * This function will duplicate all file descriptors in \p t.
+ */
+// convert: AnwBuffer -> GraphicBuffer
+// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
+inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
+ native_handle_t* handle = t.nativeHandle == nullptr ?
+ nullptr : native_handle_clone(t.nativeHandle);
+
+ size_t const numInts = 12 + (handle ? handle->numInts : 0);
+ int32_t* ints = new int32_t[numInts];
+
+ size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
+ int* fds = new int[numFds];
+
+ ints[0] = 'GBFR';
+ ints[1] = static_cast<int32_t>(t.attr.width);
+ ints[2] = static_cast<int32_t>(t.attr.height);
+ ints[3] = static_cast<int32_t>(t.attr.stride);
+ ints[4] = static_cast<int32_t>(t.attr.format);
+ ints[5] = static_cast<int32_t>(t.attr.layerCount);
+ ints[6] = static_cast<int32_t>(t.attr.usage);
+ ints[7] = static_cast<int32_t>(t.attr.id >> 32);
+ ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
+ ints[9] = static_cast<int32_t>(t.attr.generationNumber);
+ ints[10] = 0;
+ ints[11] = 0;
+ if (handle) {
+ ints[10] = static_cast<int32_t>(handle->numFds);
+ ints[11] = static_cast<int32_t>(handle->numInts);
+ int* intsStart = handle->data + handle->numFds;
+ std::copy(handle->data, intsStart, fds);
+ std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
+ }
+
+ void const* constBuffer = static_cast<void const*>(ints);
+ size_t size = numInts * sizeof(int32_t);
+ int const* constFds = static_cast<int const*>(fds);
+ status_t status = l->unflatten(constBuffer, size, constFds, numFds);
+
+ delete [] fds;
+ delete [] ints;
+ native_handle_delete(handle);
+ return status == NO_ERROR;
+}
+
+/**
+ * Conversion functions for types outside media
+ * ============================================
+ *
+ * Some objects in libui and libgui that were made to go through binder calls do
+ * not expose ways to read or write their fields to the public. To pass an
+ * object of this kind through the HIDL boundary, translation functions need to
+ * work around the access restriction by using the publicly available
+ * `flatten()` and `unflatten()` functions.
+ *
+ * All `flatten()` and `unflatten()` overloads follow the same convention as
+ * follows:
+ *
+ * status_t flatten(ObjectType const& object,
+ * [OtherType const& other, ...]
+ * void*& buffer, size_t& size,
+ * int*& fds, size_t& numFds)
+ *
+ * status_t unflatten(ObjectType* object,
+ * [OtherType* other, ...,]
+ * void*& buffer, size_t& size,
+ * int*& fds, size_t& numFds)
+ *
+ * The number of `other` parameters varies depending on the `ObjectType`. For
+ * example, in the process of unflattening an object that contains
+ * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
+ * be created.
+ *
+ * The last four parameters always work the same way in all overloads of
+ * `flatten()` and `unflatten()`:
+ * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
+ * `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
+ * `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
+ * size (in ints) of the fd buffer pointed to by `fds`.
+ * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
+ * from, `size` is the size (in bytes) of the non-fd buffer pointed to by
+ * `buffer`, `fds` is the pointer to the fd buffer to be read from, and
+ * `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
+ * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
+ * will be advanced, while `size` and `numFds` will be decreased to reflect
+ * how much storage/data of the two buffers (fd and non-fd) have been used.
+ * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
+ * `numFds` are invalid.
+ *
+ * The return value of a successful `flatten()` or `unflatten()` call will be
+ * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
+ *
+ * For each object type that supports flattening, there will be two accompanying
+ * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
+ * return the size of the non-fd buffer that the object will need for
+ * flattening. `getFdCount()` will return the size of the fd buffer that the
+ * object will need for flattening.
+ *
+ * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
+ * `flatten()` and `unflatten()`, are similar to functions of the same name in
+ * the abstract class `Flattenable`. The only difference is that functions in
+ * this file are not member functions of the object type. For example, we write
+ *
+ * flatten(x, buffer, size, fds, numFds)
+ *
+ * instead of
+ *
+ * x.flatten(buffer, size, fds, numFds)
+ *
+ * because we cannot modify the type of `x`.
+ *
+ * There is one exception to the naming convention: `hidl_handle` that
+ * represents a fence. The four functions for this "Fence" type have the word
+ * "Fence" attched to their names because the object type, which is
+ * `hidl_handle`, does not carry the special meaning that the object itself can
+ * only contain zero or one file descriptor.
+ */
+
+// Ref: frameworks/native/libs/ui/Fence.cpp
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten a fence.
+ *
+ * \param[in] fence The input fence of type `hidl_handle`.
+ * \return The required size of the flat buffer.
+ *
+ * The current version of this function always returns 4, which is the number of
+ * bytes required to store the number of file descriptors contained in the fd
+ * part of the flat buffer.
+ */
+inline size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
+ return 4;
+};
+
+/**
+ * \brief Return the number of file descriptors contained in a fence.
+ *
+ * \param[in] fence The input fence of type `hidl_handle`.
+ * \return `0` if \p fence does not contain a valid file descriptor, or `1`
+ * otherwise.
+ */
+inline size_t getFenceFdCount(hidl_handle const& fence) {
+ return native_handle_read_fd(fence) == -1 ? 0 : 1;
+}
+
+/**
+ * \brief Unflatten `Fence` to `hidl_handle`.
+ *
+ * \param[out] fence The destination `hidl_handle`.
+ * \param[out] nh The underlying native handle.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will point to a newly created
+ * native handle, which needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+inline status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < 4) {
+ return NO_MEMORY;
+ }
+
+ uint32_t numFdsInHandle;
+ FlattenableUtils::read(buffer, size, numFdsInHandle);
+
+ if (numFdsInHandle > 1) {
+ return BAD_VALUE;
+ }
+
+ if (numFds < numFdsInHandle) {
+ return NO_MEMORY;
+ }
+
+ if (numFdsInHandle) {
+ *nh = native_handle_create_from_fd(*fds);
+ if (*nh == nullptr) {
+ return NO_MEMORY;
+ }
+ *fence = hidl_handle(*nh);
+ ++fds;
+ --numFds;
+ } else {
+ *nh = nullptr;
+ *fence = hidl_handle();
+ }
+
+ return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `hidl_handle` as `Fence`.
+ *
+ * \param[in] t The source `hidl_handle`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+inline status_t flattenFence(hidl_handle const& fence,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+ if (size < getFenceFlattenedSize(fence) ||
+ numFds < getFenceFdCount(fence)) {
+ return NO_MEMORY;
+ }
+ // Cast to uint32_t since the size of a size_t can vary between 32- and
+ // 64-bit processes
+ FlattenableUtils::write(buffer, size,
+ static_cast<uint32_t>(getFenceFdCount(fence)));
+ int fd = native_handle_read_fd(fence);
+ if (fd != -1) {
+ *fds = fd;
+ ++fds;
+ --numFds;
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Wrap `Fence` in `hidl_handle`.
+ *
+ * \param[out] t The wrapper of type `hidl_handle`.
+ * \param[out] nh The native handle pointed to by \p t.
+ * \param[in] l The source `Fence`.
+ *
+ * On success, \p nh will hold a newly created native handle, which must be
+ * deleted manually with `native_handle_delete()` afterwards.
+ */
+// wrap: Fence -> hidl_handle
+inline bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
+ size_t const baseSize = l.getFlattenedSize();
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = l.getFdCount();
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = static_cast<int*>(baseFds.get());
+ size_t numFds = baseNumFds;
+ if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
+ != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Convert `hidl_handle` to `Fence`.
+ *
+ * \param[out] l The destination `Fence`. `l` must not have been used
+ * (`l->isValid()` must return `false`) before this function is called.
+ * \param[in] t The source `hidl_handle`.
+ *
+ * If \p t contains a valid file descriptor, it will be duplicated.
+ */
+// convert: hidl_handle -> Fence
+inline bool convertTo(Fence* l, hidl_handle const& t) {
+ int fd = native_handle_read_fd(t);
+ if (fd != -1) {
+ fd = dup(fd);
+ if (fd == -1) {
+ return false;
+ }
+ }
+ native_handle_t* nh = native_handle_create_from_fd(fd);
+ if (nh == nullptr) {
+ if (fd != -1) {
+ close(fd);
+ }
+ return false;
+ }
+
+ size_t const baseSize = getFenceFlattenedSize(t);
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ native_handle_delete(nh);
+ return false;
+ }
+
+ size_t const baseNumFds = getFenceFdCount(t);
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ native_handle_delete(nh);
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = static_cast<int*>(baseFds.get());
+ size_t numFds = baseNumFds;
+ if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
+ native_handle_delete(nh);
+ return false;
+ }
+ native_handle_delete(nh);
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `FenceTimeSnapshot`.
+ *
+ * \param[in] t The input `FenceTimeSnapshot`.
+ * \return The required size of the flat buffer.
+ */
+inline size_t getFlattenedSize(
+ IOmxBufferProducer::FenceTimeSnapshot const& t) {
+ constexpr size_t min = sizeof(t.state);
+ switch (t.state) {
+ case IOmxBufferProducer::FenceTimeSnapshot::State::EMPTY:
+ return min;
+ case IOmxBufferProducer::FenceTimeSnapshot::State::FENCE:
+ return min + getFenceFlattenedSize(t.fence);
+ case IOmxBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
+ return min + sizeof(
+ ::android::FenceTime::Snapshot::signalTime);
+ }
+ return 0;
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `FenceTimeSnapshot`.
+ *
+ * \param[in] t The input `FenceTimeSnapshot`.
+ * \return The number of file descriptors contained in \p snapshot.
+ */
+inline size_t getFdCount(
+ IOmxBufferProducer::FenceTimeSnapshot const& t) {
+ return t.state ==
+ IOmxBufferProducer::FenceTimeSnapshot::State::FENCE ?
+ getFenceFdCount(t.fence) : 0;
+}
+
+/**
+ * \brief Flatten `FenceTimeSnapshot`.
+ *
+ * \param[in] t The source `FenceTimeSnapshot`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate the file descriptor in `t.fence` if `t.state ==
+ * FENCE`.
+ */
+inline status_t flatten(IOmxBufferProducer::FenceTimeSnapshot const& t,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+ if (size < getFlattenedSize(t)) {
+ return NO_MEMORY;
+ }
+
+ switch (t.state) {
+ case IOmxBufferProducer::FenceTimeSnapshot::State::EMPTY:
+ FlattenableUtils::write(buffer, size,
+ ::android::FenceTime::Snapshot::State::EMPTY);
+ return NO_ERROR;
+ case IOmxBufferProducer::FenceTimeSnapshot::State::FENCE:
+ FlattenableUtils::write(buffer, size,
+ ::android::FenceTime::Snapshot::State::FENCE);
+ return flattenFence(t.fence, buffer, size, fds, numFds);
+ case IOmxBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
+ FlattenableUtils::write(buffer, size,
+ ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
+ FlattenableUtils::write(buffer, size, t.signalTimeNs);
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Unflatten `FenceTimeSnapshot`.
+ *
+ * \param[out] t The destination `FenceTimeSnapshot`.
+ * \param[out] nh The underlying native handle.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR` and the constructed snapshot contains a
+ * file descriptor, \p nh will be created to hold that file descriptor. In this
+ * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
+ */
+inline status_t unflatten(
+ IOmxBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < sizeof(t->state)) {
+ return NO_MEMORY;
+ }
+
+ ::android::FenceTime::Snapshot::State state;
+ FlattenableUtils::read(buffer, size, state);
+ switch (state) {
+ case ::android::FenceTime::Snapshot::State::EMPTY:
+ t->state = IOmxBufferProducer::FenceTimeSnapshot::State::EMPTY;
+ return NO_ERROR;
+ case ::android::FenceTime::Snapshot::State::FENCE:
+ t->state = IOmxBufferProducer::FenceTimeSnapshot::State::FENCE;
+ return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
+ case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
+ t->state = IOmxBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
+ if (size < sizeof(t->signalTimeNs)) {
+ return NO_MEMORY;
+ }
+ FlattenableUtils::read(buffer, size, t->signalTimeNs);
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+}
+
+// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
+
+/**
+ * \brief Return a lower bound on the size of the non-fd buffer required to
+ * flatten `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return A lower bound on the size of the flat buffer.
+ */
+constexpr size_t minFlattenedSize(
+ IOmxBufferProducer::FrameEventsDelta const& /* t */) {
+ return sizeof(uint64_t) + // mFrameNumber
+ sizeof(uint8_t) + // mIndex
+ sizeof(uint8_t) + // mAddPostCompositeCalled
+ sizeof(uint8_t) + // mAddRetireCalled
+ sizeof(uint8_t) + // mAddReleaseCalled
+ sizeof(nsecs_t) + // mPostedTime
+ sizeof(nsecs_t) + // mRequestedPresentTime
+ sizeof(nsecs_t) + // mLatchTime
+ sizeof(nsecs_t) + // mFirstRefreshStartTime
+ sizeof(nsecs_t); // mLastRefreshStartTime
+}
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return The required size of the flat buffer.
+ */
+inline size_t getFlattenedSize(
+ IOmxBufferProducer::FrameEventsDelta const& t) {
+ return minFlattenedSize(t) +
+ getFlattenedSize(t.gpuCompositionDoneFence) +
+ getFlattenedSize(t.displayPresentFence) +
+ getFlattenedSize(t.displayRetireFence) +
+ getFlattenedSize(t.releaseFence);
+};
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return The number of file descriptors contained in \p t.
+ */
+inline size_t getFdCount(
+ IOmxBufferProducer::FrameEventsDelta const& t) {
+ return getFdCount(t.gpuCompositionDoneFence) +
+ getFdCount(t.displayPresentFence) +
+ getFdCount(t.displayRetireFence) +
+ getFdCount(t.releaseFence);
+};
+
+/**
+ * \brief Unflatten `FrameEventsDelta`.
+ *
+ * \param[out] t The destination `FrameEventsDelta`.
+ * \param[out] nh The underlying array of native handles.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
+ * populated with `nullptr` or newly created handles. Each non-null slot in \p
+ * nh will need to be deleted manually with `native_handle_delete()`.
+ */
+inline status_t unflatten(IOmxBufferProducer::FrameEventsDelta* t,
+ std::vector<native_handle_t*>* nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < minFlattenedSize(*t)) {
+ return NO_MEMORY;
+ }
+ FlattenableUtils::read(buffer, size, t->frameNumber);
+
+ // These were written as uint8_t for alignment.
+ uint8_t temp = 0;
+ FlattenableUtils::read(buffer, size, temp);
+ size_t index = static_cast<size_t>(temp);
+ if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+ return BAD_VALUE;
+ }
+ t->index = static_cast<uint32_t>(index);
+
+ FlattenableUtils::read(buffer, size, temp);
+ t->addPostCompositeCalled = static_cast<bool>(temp);
+ FlattenableUtils::read(buffer, size, temp);
+ t->addRetireCalled = static_cast<bool>(temp);
+ FlattenableUtils::read(buffer, size, temp);
+ t->addReleaseCalled = static_cast<bool>(temp);
+
+ FlattenableUtils::read(buffer, size, t->postedTimeNs);
+ FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
+ FlattenableUtils::read(buffer, size, t->latchTimeNs);
+ FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
+ FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
+ FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
+
+ // Fences
+ IOmxBufferProducer::FenceTimeSnapshot* tSnapshot[4];
+ tSnapshot[0] = &t->gpuCompositionDoneFence;
+ tSnapshot[1] = &t->displayPresentFence;
+ tSnapshot[2] = &t->displayRetireFence;
+ tSnapshot[3] = &t->releaseFence;
+ nh->resize(4);
+ for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
+ status_t status = unflatten(
+ tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
+ buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ while (snapshotIndex > 0) {
+ --snapshotIndex;
+ if ((*nh)[snapshotIndex] != nullptr) {
+ native_handle_delete((*nh)[snapshotIndex]);
+ }
+ }
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `FrameEventsDelta`.
+ *
+ * \param[in] t The source `FrameEventsDelta`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate file descriptors contained in \p t.
+ */
+// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
+// FrameEventsDelta::flatten
+inline status_t flatten(IOmxBufferProducer::FrameEventsDelta const& t,
+ void*& buffer, size_t& size, int*& fds, size_t numFds) {
+ // Check that t.index is within a valid range.
+ if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
+ || t.index > std::numeric_limits<uint8_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ FlattenableUtils::write(buffer, size, t.frameNumber);
+
+ // These are static_cast to uint8_t for alignment.
+ FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
+ FlattenableUtils::write(
+ buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
+ FlattenableUtils::write(
+ buffer, size, static_cast<uint8_t>(t.addRetireCalled));
+ FlattenableUtils::write(
+ buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
+
+ FlattenableUtils::write(buffer, size, t.postedTimeNs);
+ FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
+ FlattenableUtils::write(buffer, size, t.latchTimeNs);
+ FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
+ FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
+ FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
+
+ // Fences
+ IOmxBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
+ tSnapshot[0] = &t.gpuCompositionDoneFence;
+ tSnapshot[1] = &t.displayPresentFence;
+ tSnapshot[2] = &t.displayRetireFence;
+ tSnapshot[3] = &t.releaseFence;
+ for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
+ status_t status = flatten(
+ *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `IOmxBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[in] t The input `IOmxBufferProducer::FrameEventHistoryDelta`.
+ * \return The required size of the flat buffer.
+ */
+inline size_t getFlattenedSize(
+ IOmxBufferProducer::FrameEventHistoryDelta const& t) {
+ size_t size = 4;
+ for (size_t i = 0; i < t.size(); ++i) {
+ size += getFlattenedSize(t[i]);
+ }
+ return size;
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `IOmxBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[in] t The input `IOmxBufferProducer::FrameEventHistoryDelta`.
+ * \return The number of file descriptors contained in \p t.
+ */
+inline size_t getFdCount(
+ IOmxBufferProducer::FrameEventHistoryDelta const& t) {
+ size_t numFds = 0;
+ for (size_t i = 0; i < t.size(); ++i) {
+ numFds += getFdCount(t[i]);
+ }
+ return numFds;
+}
+
+/**
+ * \brief Unflatten `FrameEventHistoryDelta`.
+ *
+ * \param[out] t The destination `FrameEventHistoryDelta`.
+ * \param[out] nh The underlying array of arrays of native handles.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
+ * newly created handles. The second dimension of \p nh will be 4. Each non-null
+ * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
+ */
+inline status_t unflatten(
+ IOmxBufferProducer::FrameEventHistoryDelta* t,
+ std::vector<std::vector<native_handle_t*> >* nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < 4) {
+ return NO_MEMORY;
+ }
+
+ uint32_t deltaCount = 0;
+ FlattenableUtils::read(buffer, size, deltaCount);
+ if (static_cast<size_t>(deltaCount) >
+ ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+ return BAD_VALUE;
+ }
+ t->resize(deltaCount);
+ nh->resize(deltaCount);
+ for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
+ status_t status = unflatten(
+ &((*t)[deltaIndex]), &((*nh)[deltaIndex]),
+ buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `FrameEventHistoryDelta`.
+ *
+ * \param[in] t The source `FrameEventHistoryDelta`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate file descriptors contained in \p t.
+ */
+inline status_t flatten(
+ IOmxBufferProducer::FrameEventHistoryDelta const& t,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+ if (t.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+ return BAD_VALUE;
+ }
+ if (size < getFlattenedSize(t)) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
+ for (size_t deltaIndex = 0; deltaIndex < t.size(); ++deltaIndex) {
+ status_t status = flatten(t[deltaIndex], buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Wrap `::android::FrameEventHistoryData` in
+ * `IOmxBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[out] t The wrapper of type
+ * `IOmxBufferProducer::FrameEventHistoryDelta`.
+ * \param[out] nh The array of array of native handles that are referred to by
+ * members of \p t.
+ * \param[in] l The source `::android::FrameEventHistoryDelta`.
+ *
+ * On success, each member of \p nh will be either `nullptr` or a newly created
+ * native handle. All the non-`nullptr` elements must be deleted individually
+ * with `native_handle_delete()`.
+ */
+inline bool wrapAs(IOmxBufferProducer::FrameEventHistoryDelta* t,
+ std::vector<std::vector<native_handle_t*> >* nh,
+ ::android::FrameEventHistoryDelta const& l) {
+
+ size_t const baseSize = l.getFlattenedSize();
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = l.getFdCount();
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = baseFds.get();
+ size_t numFds = baseNumFds;
+ if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Convert `IOmxBufferProducer::FrameEventHistoryDelta` to
+ * `::android::FrameEventHistoryDelta`.
+ *
+ * \param[out] l The destination `::android::FrameEventHistoryDelta`.
+ * \param[in] t The source `IOmxBufferProducer::FrameEventHistoryDelta`.
+ *
+ * This function will duplicate all file descriptors contained in \p t.
+ */
+inline bool convertTo(
+ ::android::FrameEventHistoryDelta* l,
+ IOmxBufferProducer::FrameEventHistoryDelta const& t) {
+
+ size_t const baseSize = getFlattenedSize(t);
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = getFdCount(t);
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = static_cast<int*>(baseFds.get());
+ size_t numFds = baseNumFds;
+ if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+// Ref: frameworks/native/libs/ui/Region.cpp
+
+/**
+ * \brief Return the size of the buffer required to flatten `Region`.
+ *
+ * \param[in] t The input `Region`.
+ * \return The required size of the flat buffer.
+ */
+inline size_t getFlattenedSize(Region const& t) {
+ return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
+}
+
+/**
+ * \brief Unflatten `Region`.
+ *
+ * \param[out] t The destination `Region`.
+ * \param[in,out] buffer The pointer to the flat buffer.
+ * \param[in,out] size The size of the flat buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+inline status_t unflatten(Region* t, void const*& buffer, size_t& size) {
+ if (size < sizeof(uint32_t)) {
+ return NO_MEMORY;
+ }
+
+ uint32_t numRects = 0;
+ FlattenableUtils::read(buffer, size, numRects);
+ if (size < numRects * sizeof(Rect)) {
+ return NO_MEMORY;
+ }
+ if (numRects > (UINT32_MAX / sizeof(Rect))) {
+ return NO_MEMORY;
+ }
+
+ t->resize(numRects);
+ for (size_t r = 0; r < numRects; ++r) {
+ ::android::Rect rect(::android::Rect::EMPTY_RECT);
+ status_t status = rect.unflatten(buffer, size);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ FlattenableUtils::advance(buffer, size, sizeof(rect));
+ (*t)[r] = Rect{
+ static_cast<int32_t>(rect.left),
+ static_cast<int32_t>(rect.top),
+ static_cast<int32_t>(rect.right),
+ static_cast<int32_t>(rect.bottom)};
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `Region`.
+ *
+ * \param[in] t The source `Region`.
+ * \param[in,out] buffer The pointer to the flat buffer.
+ * \param[in,out] size The size of the flat buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+inline status_t flatten(Region const& t, void*& buffer, size_t& size) {
+ if (size < getFlattenedSize(t)) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
+ for (size_t r = 0; r < t.size(); ++r) {
+ ::android::Rect rect(
+ static_cast<int32_t>(t[r].left),
+ static_cast<int32_t>(t[r].top),
+ static_cast<int32_t>(t[r].right),
+ static_cast<int32_t>(t[r].bottom));
+ status_t status = rect.flatten(buffer, size);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ FlattenableUtils::advance(buffer, size, sizeof(rect));
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Convert `::android::Region` to `Region`.
+ *
+ * \param[out] t The destination `Region`.
+ * \param[in] l The source `::android::Region`.
+ */
+// convert: ::android::Region -> Region
+inline bool convertTo(Region* t, ::android::Region const& l) {
+ size_t const baseSize = l.getFlattenedSize();
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ if (l.flatten(buffer, size) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ if (unflatten(t, constBuffer, size) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Convert `Region` to `::android::Region`.
+ *
+ * \param[out] l The destination `::android::Region`.
+ * \param[in] t The source `Region`.
+ */
+// convert: Region -> ::android::Region
+inline bool convertTo(::android::Region* l, Region const& t) {
+ size_t const baseSize = getFlattenedSize(t);
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ if (flatten(t, buffer, size) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ if (l->unflatten(constBuffer, size) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+// Ref: frameworks/native/libs/gui/IGraphicBufferProducer.cpp:
+// IGraphicBufferProducer::QueueBufferInput
+
+/**
+ * \brief Return a lower bound on the size of the buffer required to flatten
+ * `IOmxBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `IOmxBufferProducer::QueueBufferInput`.
+ * \return A lower bound on the size of the flat buffer.
+ */
+constexpr size_t minFlattenedSize(
+ IOmxBufferProducer::QueueBufferInput const& /* t */) {
+ return sizeof(int64_t) + // timestamp
+ sizeof(int) + // isAutoTimestamp
+ sizeof(android_dataspace) + // dataSpace
+ sizeof(::android::Rect) + // crop
+ sizeof(int) + // scalingMode
+ sizeof(uint32_t) + // transform
+ sizeof(uint32_t) + // stickyTransform
+ sizeof(bool); // getFrameTimestamps
+}
+
+/**
+ * \brief Return the size of the buffer required to flatten
+ * `IOmxBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `IOmxBufferProducer::QueueBufferInput`.
+ * \return The required size of the flat buffer.
+ */
+inline size_t getFlattenedSize(IOmxBufferProducer::QueueBufferInput const& t) {
+ return minFlattenedSize(t) +
+ getFenceFlattenedSize(t.fence) +
+ getFlattenedSize(t.surfaceDamage);
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `IOmxBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `IOmxBufferProducer::QueueBufferInput`.
+ * \return The number of file descriptors contained in \p t.
+ */
+inline size_t getFdCount(
+ IOmxBufferProducer::QueueBufferInput const& t) {
+ return getFenceFdCount(t.fence);
+}
+
+/**
+ * \brief Flatten `IOmxBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The source `IOmxBufferProducer::QueueBufferInput`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate the file descriptor in `t.fence`. */
+inline status_t flatten(IOmxBufferProducer::QueueBufferInput const& t,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+ if (size < getFlattenedSize(t)) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::write(buffer, size, t.timestamp);
+ FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
+ FlattenableUtils::write(buffer, size,
+ static_cast<android_dataspace_t>(t.dataSpace));
+ FlattenableUtils::write(buffer, size, ::android::Rect(
+ static_cast<int32_t>(t.crop.left),
+ static_cast<int32_t>(t.crop.top),
+ static_cast<int32_t>(t.crop.right),
+ static_cast<int32_t>(t.crop.bottom)));
+ FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
+ FlattenableUtils::write(buffer, size, t.transform);
+ FlattenableUtils::write(buffer, size, t.stickyTransform);
+ FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
+
+ status_t status = flattenFence(t.fence, buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return flatten(t.surfaceDamage, buffer, size);
+}
+
+/**
+ * \brief Unflatten `IOmxBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] t The destination `IOmxBufferProducer::QueueBufferInput`.
+ * \param[out] nh The underlying native handle for `t->fence`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR` and `t->fence` contains a valid file
+ * descriptor, \p nh will be a newly created native handle holding that file
+ * descriptor. \p nh needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+inline status_t unflatten(
+ IOmxBufferProducer::QueueBufferInput* t, native_handle_t** nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < minFlattenedSize(*t)) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::read(buffer, size, t->timestamp);
+ int lIsAutoTimestamp;
+ FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
+ t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
+ android_dataspace_t lDataSpace;
+ FlattenableUtils::read(buffer, size, lDataSpace);
+ t->dataSpace = static_cast<Dataspace>(lDataSpace);
+ Rect lCrop;
+ FlattenableUtils::read(buffer, size, lCrop);
+ t->crop = Rect{
+ static_cast<int32_t>(lCrop.left),
+ static_cast<int32_t>(lCrop.top),
+ static_cast<int32_t>(lCrop.right),
+ static_cast<int32_t>(lCrop.bottom)};
+ int lScalingMode;
+ FlattenableUtils::read(buffer, size, lScalingMode);
+ t->scalingMode = static_cast<int32_t>(lScalingMode);
+ FlattenableUtils::read(buffer, size, t->transform);
+ FlattenableUtils::read(buffer, size, t->stickyTransform);
+ FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
+
+ status_t status = unflattenFence(&(t->fence), nh,
+ buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return unflatten(&(t->surfaceDamage), buffer, size);
+}
+
+/**
+ * \brief Wrap `IGraphicBufferProducer::QueueBufferInput` in
+ * `IOmxBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] t The wrapper of type
+ * `IOmxBufferProducer::QueueBufferInput`.
+ * \param[out] nh The underlying native handle for `t->fence`.
+ * \param[in] l The source `IGraphicBufferProducer::QueueBufferInput`.
+ *
+ * If the return value is `true` and `t->fence` contains a valid file
+ * descriptor, \p nh will be a newly created native handle holding that file
+ * descriptor. \p nh needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+inline bool wrapAs(
+ IOmxBufferProducer::QueueBufferInput* t,
+ native_handle_t** nh,
+ IGraphicBufferProducer::QueueBufferInput const& l) {
+
+ size_t const baseSize = l.getFlattenedSize();
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = l.getFdCount();
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = baseFds.get();
+ size_t numFds = baseNumFds;
+ if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Convert `IOmxBufferProducer::QueueBufferInput` to
+ * `IGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] l The destination `IGraphicBufferProducer::QueueBufferInput`.
+ * \param[in] t The source `IOmxBufferProducer::QueueBufferInput`.
+ *
+ * If `t.fence` has a valid file descriptor, it will be duplicated.
+ */
+inline bool convertTo(
+ IGraphicBufferProducer::QueueBufferInput* l,
+ IOmxBufferProducer::QueueBufferInput const& t) {
+
+ size_t const baseSize = getFlattenedSize(t);
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = getFdCount(t);
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = baseFds.get();
+ size_t numFds = baseNumFds;
+ if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+// Ref: frameworks/native/libs/gui/IGraphicBufferProducer.cpp:
+// IGraphicBufferProducer::QueueBufferOutput
+
+/**
+ * \brief Wrap `IGraphicBufferProducer::QueueBufferOutput` in
+ * `IOmxBufferProducer::QueueBufferOutput`.
+ *
+ * \param[out] t The wrapper of type
+ * `IOmxBufferProducer::QueueBufferOutput`.
+ * \param[out] nh The array of array of native handles that are referred to by
+ * members of \p t.
+ * \param[in] l The source `IGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * On success, each member of \p nh will be either `nullptr` or a newly created
+ * native handle. All the non-`nullptr` elements must be deleted individually
+ * with `native_handle_delete()`.
+ */
+// wrap: IGraphicBufferProducer::QueueBufferOutput ->
+// IOmxBufferProducer::QueueBufferOutput
+inline bool wrapAs(IOmxBufferProducer::QueueBufferOutput* t,
+ std::vector<std::vector<native_handle_t*> >* nh,
+ IGraphicBufferProducer::QueueBufferOutput const& l) {
+ if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
+ return false;
+ }
+ t->width = l.width;
+ t->height = l.height;
+ t->transformHint = l.transformHint;
+ t->numPendingBuffers = l.numPendingBuffers;
+ t->nextFrameNumber = l.nextFrameNumber;
+ return true;
+}
+
+/**
+ * \brief Convert `IOmxBufferProducer::QueueBufferOutput` to
+ * `IGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * \param[out] l The destination `IGraphicBufferProducer::QueueBufferOutput`.
+ * \param[in] t The source `IOmxBufferProducer::QueueBufferOutput`.
+ *
+ * This function will duplicate all file descriptors contained in \p t.
+ */
+// convert: IOmxBufferProducer::QueueBufferOutput ->
+// IGraphicBufferProducer::QueueBufferOutput
+inline bool convertTo(
+ IGraphicBufferProducer::QueueBufferOutput* l,
+ IOmxBufferProducer::QueueBufferOutput const& t) {
+ if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
+ return false;
+ }
+ l->width = t.width;
+ l->height = t.height;
+ l->transformHint = t.transformHint;
+ l->numPendingBuffers = t.numPendingBuffers;
+ l->nextFrameNumber = t.nextFrameNumber;
+ return true;
+}
+
+/**
+ * \brief Convert `IGraphicBufferProducer::DisconnectMode` to
+ * `IOmxBufferProducer::DisconnectMode`.
+ *
+ * \param[in] l The source `IGraphicBufferProducer::DisconnectMode`.
+ * \return The corresponding `IOmxBufferProducer::DisconnectMode`.
+ */
+inline IOmxBufferProducer::DisconnectMode toOmxDisconnectMode(
+ IGraphicBufferProducer::DisconnectMode l) {
+ switch (l) {
+ case IGraphicBufferProducer::DisconnectMode::Api:
+ return IOmxBufferProducer::DisconnectMode::API;
+ case IGraphicBufferProducer::DisconnectMode::AllLocal:
+ return IOmxBufferProducer::DisconnectMode::ALL_LOCAL;
+ }
+ return IOmxBufferProducer::DisconnectMode::API;
+}
+
+/**
+ * \brief Convert `IOmxBufferProducer::DisconnectMode` to
+ * `IGraphicBufferProducer::DisconnectMode`.
+ *
+ * \param[in] l The source `IOmxBufferProducer::DisconnectMode`.
+ * \return The corresponding `IGraphicBufferProducer::DisconnectMode`.
+ */
+inline IGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
+ IOmxBufferProducer::DisconnectMode t) {
+ switch (t) {
+ case IOmxBufferProducer::DisconnectMode::API:
+ return IGraphicBufferProducer::DisconnectMode::Api;
+ case IOmxBufferProducer::DisconnectMode::ALL_LOCAL:
+ return IGraphicBufferProducer::DisconnectMode::AllLocal;
+ }
+ return IGraphicBufferProducer::DisconnectMode::Api;
+}
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
diff --git a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
new file mode 100644
index 0000000..037e9b2
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WGraphicBufferSource.h"
+#include "Conversion.h"
+#include "WOmxNode.h"
+#include <stagefright/foundation/ColorUtils.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using android::ColorUtils;
+
+// LWGraphicBufferSource
+LWGraphicBufferSource::LWGraphicBufferSource(
+ sp<TGraphicBufferSource> const& base) : mBase(base) {
+}
+
+::android::binder::Status LWGraphicBufferSource::configure(
+ const sp<IOMXNode>& omxNode, int32_t dataSpace) {
+ return toBinderStatus(mBase->configure(
+ new TWOmxNode(omxNode), toHardwareDataspace(dataSpace)));
+}
+
+::android::binder::Status LWGraphicBufferSource::setSuspend(bool suspend) {
+ return toBinderStatus(mBase->setSuspend(suspend));
+}
+
+::android::binder::Status LWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+ int64_t repeatAfterUs) {
+ return toBinderStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
+}
+
+::android::binder::Status LWGraphicBufferSource::setMaxFps(float maxFps) {
+ return toBinderStatus(mBase->setMaxFps(maxFps));
+}
+
+::android::binder::Status LWGraphicBufferSource::setTimeLapseConfig(
+ int64_t timePerFrameUs, int64_t timePerCaptureUs) {
+ return toBinderStatus(mBase->setTimeLapseConfig(
+ timePerFrameUs, timePerCaptureUs));
+}
+
+::android::binder::Status LWGraphicBufferSource::setStartTimeUs(
+ int64_t startTimeUs) {
+ return toBinderStatus(mBase->setStartTimeUs(startTimeUs));
+}
+
+::android::binder::Status LWGraphicBufferSource::setColorAspects(
+ int32_t aspects) {
+ return toBinderStatus(mBase->setColorAspects(
+ toHardwareColorAspects(aspects)));
+}
+
+::android::binder::Status LWGraphicBufferSource::setTimeOffsetUs(
+ int64_t timeOffsetsUs) {
+ return toBinderStatus(mBase->setTimeOffsetUs(timeOffsetsUs));
+}
+
+::android::binder::Status LWGraphicBufferSource::signalEndOfInputStream() {
+ return toBinderStatus(mBase->signalEndOfInputStream());
+}
+
+::android::IBinder* LWGraphicBufferSource::onAsBinder() {
+ return nullptr;
+}
+
+// TWGraphicBufferSource
+TWGraphicBufferSource::TWGraphicBufferSource(
+ sp<LGraphicBufferSource> const& base) : mBase(base) {
+}
+
+Return<void> TWGraphicBufferSource::configure(
+ const sp<IOmxNode>& omxNode, Dataspace dataspace) {
+ return toHardwareStatus(mBase->configure(
+ new LWOmxNode(omxNode),
+ toRawDataspace(dataspace)));
+}
+
+Return<void> TWGraphicBufferSource::setSuspend(bool suspend) {
+ return toHardwareStatus(mBase->setSuspend(suspend));
+}
+
+Return<void> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+ int64_t repeatAfterUs) {
+ return toHardwareStatus(mBase->setRepeatPreviousFrameDelayUs(
+ repeatAfterUs));
+}
+
+Return<void> TWGraphicBufferSource::setMaxFps(float maxFps) {
+ return toHardwareStatus(mBase->setMaxFps(maxFps));
+}
+
+Return<void> TWGraphicBufferSource::setTimeLapseConfig(
+ int64_t timePerFrameUs, int64_t timePerCaptureUs) {
+ return toHardwareStatus(mBase->setTimeLapseConfig(
+ timePerFrameUs, timePerCaptureUs));
+}
+
+Return<void> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
+ return toHardwareStatus(mBase->setStartTimeUs(startTimeUs));
+}
+
+Return<void> TWGraphicBufferSource::setColorAspects(
+ const ColorAspects& aspects) {
+ return toHardwareStatus(mBase->setColorAspects(toCompactColorAspects(
+ aspects)));
+}
+
+Return<void> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
+ return toHardwareStatus(mBase->setTimeOffsetUs(timeOffsetUs));
+}
+
+Return<void> TWGraphicBufferSource::signalEndOfInputStream() {
+ return toHardwareStatus(mBase->signalEndOfInputStream());
+}
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
new file mode 100644
index 0000000..17a4486
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERSOURCE_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERSOURCE_H
+
+#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <frameworks/native/include/binder/Binder.h>
+#include <IOMX.h>
+#include <android/IGraphicBufferSource.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+
+#include <android/hardware/graphics/common/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::graphics::common::V1_0::Dataspace;
+using ::android::hardware::media::omx::V1_0::ColorAspects;
+using ::android::hardware::media::omx::V1_0::IGraphicBufferSource;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ::android::IOMXNode;
+
+/**
+ * Wrapper classes for conversion
+ * ==============================
+ *
+ * Naming convention:
+ * - LW = Legacy Wrapper --- It wraps a Treble object inside a legacy object.
+ * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
+ */
+
+typedef ::android::IGraphicBufferSource LGraphicBufferSource;
+typedef ::android::hardware::media::omx::V1_0::IGraphicBufferSource
+ TGraphicBufferSource;
+
+struct LWGraphicBufferSource : public LGraphicBufferSource {
+ sp<TGraphicBufferSource> mBase;
+ LWGraphicBufferSource(sp<TGraphicBufferSource> const& base);
+ ::android::binder::Status configure(
+ const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
+ ::android::binder::Status setSuspend(bool suspend) override;
+ ::android::binder::Status setRepeatPreviousFrameDelayUs(
+ int64_t repeatAfterUs) override;
+ ::android::binder::Status setMaxFps(float maxFps) override;
+ ::android::binder::Status setTimeLapseConfig(
+ int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
+ ::android::binder::Status setStartTimeUs(int64_t startTimeUs) override;
+ ::android::binder::Status setColorAspects(int32_t aspects) override;
+ ::android::binder::Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
+ ::android::binder::Status signalEndOfInputStream() override;
+protected:
+ ::android::IBinder* onAsBinder() override;
+};
+
+struct TWGraphicBufferSource : public TGraphicBufferSource {
+ sp<LGraphicBufferSource> mBase;
+ TWGraphicBufferSource(sp<LGraphicBufferSource> const& base);
+ Return<void> configure(
+ const sp<IOmxNode>& omxNode, Dataspace dataspace) override;
+ Return<void> setSuspend(bool suspend) override;
+ Return<void> setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
+ Return<void> setMaxFps(float maxFps) override;
+ Return<void> setTimeLapseConfig(
+ int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
+ Return<void> setStartTimeUs(int64_t startTimeUs) override;
+ Return<void> setColorAspects(const ColorAspects& aspects) override;
+ Return<void> setTimeOffsetUs(int64_t timeOffsetUs) override;
+ Return<void> signalEndOfInputStream() override;
+};
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERSOURCE_H
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
new file mode 100644
index 0000000..07c9255
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WOmx.h"
+#include "WOmxNode.h"
+#include "WOmxObserver.h"
+#include "WOmxBufferProducer.h"
+#include "WGraphicBufferSource.h"
+#include "Conversion.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+// LWOmx
+LWOmx::LWOmx(sp<IOmx> const& base) : mBase(base) {
+}
+
+status_t LWOmx::listNodes(List<IOMX::ComponentInfo>* list) {
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->listNodes(
+ [&fnStatus, list](
+ Status status,
+ hidl_vec<IOmx::ComponentInfo> const& nodeList) {
+ fnStatus = toStatusT(status);
+ list->clear();
+ for (size_t i = 0; i < nodeList.size(); ++i) {
+ auto newInfo = list->insert(
+ list->end(), IOMX::ComponentInfo());
+ convertTo(&*newInfo, nodeList[i]);
+ }
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmx::allocateNode(
+ char const* name,
+ sp<IOMXObserver> const& observer,
+ sp<IOMXNode>* omxNode) {
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->allocateNode(
+ name, new TWOmxObserver(observer),
+ [&fnStatus, omxNode](Status status, sp<IOmxNode> const& node) {
+ fnStatus = toStatusT(status);
+ *omxNode = new LWOmxNode(node);
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmx::createInputSurface(
+ sp<::android::IGraphicBufferProducer>* bufferProducer,
+ sp<::android::IGraphicBufferSource>* bufferSource) {
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->createInputSurface(
+ [&fnStatus, bufferProducer, bufferSource] (
+ Status status,
+ sp<IOmxBufferProducer> const& tProducer,
+ sp<IGraphicBufferSource> const& tSource) {
+ fnStatus = toStatusT(status);
+ *bufferProducer = new LWOmxBufferProducer(tProducer);
+ *bufferSource = new LWGraphicBufferSource(tSource);
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+::android::IBinder* LWOmx::onAsBinder() {
+ return nullptr;
+}
+
+// TWOmx
+TWOmx::TWOmx(sp<IOMX> const& base) : mBase(base) {
+}
+
+Return<void> TWOmx::listNodes(listNodes_cb _hidl_cb) {
+ List<IOMX::ComponentInfo> lList;
+ Status status = toStatus(mBase->listNodes(&lList));
+
+ hidl_vec<IOmx::ComponentInfo> tList;
+ tList.resize(lList.size());
+ size_t i = 0;
+ for (auto const& lInfo : lList) {
+ convertTo(&(tList[i++]), lInfo);
+ }
+ _hidl_cb(status, tList);
+ return Void();
+}
+
+Return<void> TWOmx::allocateNode(
+ const hidl_string& name,
+ const sp<IOmxObserver>& observer,
+ allocateNode_cb _hidl_cb) {
+ sp<IOMXNode> omxNode;
+ Status status = toStatus(mBase->allocateNode(
+ name, new LWOmxObserver(observer), &omxNode));
+ _hidl_cb(status, new TWOmxNode(omxNode));
+ return Void();
+}
+
+Return<void> TWOmx::createInputSurface(createInputSurface_cb _hidl_cb) {
+ sp<::android::IGraphicBufferProducer> lProducer;
+ sp<::android::IGraphicBufferSource> lSource;
+ status_t status = mBase->createInputSurface(&lProducer, &lSource);
+ _hidl_cb(toStatus(status),
+ new TWOmxBufferProducer(lProducer),
+ new TWGraphicBufferSource(lSource));
+ return Void();
+}
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmx.h b/media/libstagefright/omx/hal/1.0/utils/WOmx.h
new file mode 100644
index 0000000..26affad
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmx.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMX_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMX_H
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <IOMX.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::Status;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ::android::List;
+using ::android::IOMX;
+
+/**
+ * Wrapper classes for conversion
+ * ==============================
+ *
+ * Naming convention:
+ * - LW = Legacy Wrapper --- It wraps a Treble object inside a legacy object.
+ * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
+ */
+
+struct LWOmx : public IOMX {
+ sp<IOmx> mBase;
+ LWOmx(sp<IOmx> const& base);
+ status_t listNodes(List<IOMX::ComponentInfo>* list) override;
+ status_t allocateNode(
+ char const* name,
+ sp<IOMXObserver> const& observer,
+ sp<IOMXNode>* omxNode) override;
+ status_t createInputSurface(
+ sp<::android::IGraphicBufferProducer>* bufferProducer,
+ sp<::android::IGraphicBufferSource>* bufferSource) override;
+protected:
+ ::android::IBinder* onAsBinder() override;
+};
+
+struct TWOmx : public IOmx {
+ sp<IOMX> mBase;
+ TWOmx(sp<IOMX> const& base);
+ Return<void> listNodes(listNodes_cb _hidl_cb) override;
+ Return<void> allocateNode(
+ const hidl_string& name,
+ const sp<IOmxObserver>& observer,
+ allocateNode_cb _hidl_cb) override;
+ Return<void> createInputSurface(createInputSurface_cb _hidl_cb) override;
+
+};
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMX_H
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
new file mode 100644
index 0000000..49f2706
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
@@ -0,0 +1,594 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WOmxBufferProducer.h"
+#include "WOmxProducerListener.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+// TWOmxBufferProducer
+TWOmxBufferProducer::TWOmxBufferProducer(
+ sp<IGraphicBufferProducer> const& base):
+ mBase(base) {
+}
+
+Return<void> TWOmxBufferProducer::requestBuffer(
+ int32_t slot, requestBuffer_cb _hidl_cb) {
+ sp<GraphicBuffer> buf;
+ status_t status = mBase->requestBuffer(slot, &buf);
+ AnwBuffer anwBuffer;
+ wrapAs(&anwBuffer, *buf);
+ _hidl_cb(toStatus(status), anwBuffer);
+ return Void();
+}
+
+Return<Status> TWOmxBufferProducer::setMaxDequeuedBufferCount(
+ int32_t maxDequeuedBuffers) {
+ return toStatus(mBase->setMaxDequeuedBufferCount(
+ static_cast<int>(maxDequeuedBuffers)));
+}
+
+Return<Status> TWOmxBufferProducer::setAsyncMode(bool async) {
+ return toStatus(mBase->setAsyncMode(async));
+}
+
+Return<void> TWOmxBufferProducer::dequeueBuffer(
+ uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t usage,
+ bool getFrameTimestamps, dequeueBuffer_cb _hidl_cb) {
+ int slot;
+ sp<Fence> fence;
+ ::android::FrameEventHistoryDelta outTimestamps;
+ status_t status = mBase->dequeueBuffer(
+ &slot, &fence,
+ width, height,
+ static_cast<::android::PixelFormat>(format), usage,
+ getFrameTimestamps ? &outTimestamps : nullptr);
+
+ hidl_handle tFence;
+ native_handle_t* nh;
+ if (!wrapAs(&tFence, &nh, *fence)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::dequeueBuffer(): "
+ "Cannot wrap Fence in hidl_handle"));
+ }
+ FrameEventHistoryDelta tOutTimestamps;
+ std::vector<std::vector<native_handle_t*> > nhAA;
+ if (getFrameTimestamps && !wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) {
+ native_handle_delete(nh);
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::dequeueBuffer(): "
+ "Cannot wrap Fence in hidl_handle"));
+ }
+
+ _hidl_cb(toStatus(status),
+ static_cast<int32_t>(slot),
+ tFence,
+ tOutTimestamps);
+ native_handle_delete(nh);
+ if (getFrameTimestamps) {
+ for (auto& nhA : nhAA) {
+ for (auto& handle : nhA) {
+ if (handle != nullptr) {
+ native_handle_delete(handle);
+ }
+ }
+ }
+ }
+ return Void();
+}
+
+Return<Status> TWOmxBufferProducer::detachBuffer(int32_t slot) {
+ return toStatus(mBase->detachBuffer(slot));
+}
+
+Return<void> TWOmxBufferProducer::detachNextBuffer(
+ detachNextBuffer_cb _hidl_cb) {
+ sp<GraphicBuffer> outBuffer;
+ sp<Fence> outFence;
+ status_t status = mBase->detachNextBuffer(&outBuffer, &outFence);
+
+ AnwBuffer tBuffer;
+ wrapAs(&tBuffer, *outBuffer);
+ hidl_handle tFence;
+ native_handle_t* nh;
+ if (!wrapAs(&tFence, &nh, *outFence)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::detachNextBuffer(): "
+ "Cannot wrap Fence in hidl_handle"));
+ }
+
+ _hidl_cb(toStatus(status), tBuffer, tFence);
+ native_handle_delete(nh);
+ return Void();
+}
+
+Return<void> TWOmxBufferProducer::attachBuffer(
+ const AnwBuffer& buffer,
+ attachBuffer_cb _hidl_cb) {
+ int outSlot;
+ sp<GraphicBuffer> lBuffer = new GraphicBuffer();
+ if (!convertTo(lBuffer.get(), buffer)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::attachBuffer(): "
+ "Cannot convert AnwBuffer to GraphicBuffer"));
+ }
+ status_t status = mBase->attachBuffer(&outSlot, lBuffer);
+
+ _hidl_cb(toStatus(status), static_cast<int32_t>(outSlot));
+ return Void();
+}
+
+Return<void> TWOmxBufferProducer::queueBuffer(
+ int32_t slot, const QueueBufferInput& input,
+ queueBuffer_cb _hidl_cb) {
+ IGraphicBufferProducer::QueueBufferInput lInput(
+ 0, false, HAL_DATASPACE_UNKNOWN,
+ ::android::Rect(0, 0, 1, 1),
+ NATIVE_WINDOW_SCALING_MODE_FREEZE,
+ 0, ::android::Fence::NO_FENCE);
+ if (!convertTo(&lInput, input)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::queueBuffer(): "
+ "Cannot convert IOmxBufferProducer::QueueBufferInput "
+ "to IGraphicBufferProducer::QueueBufferInput"));
+ }
+ IGraphicBufferProducer::QueueBufferOutput lOutput;
+ status_t status = mBase->queueBuffer(
+ static_cast<int>(slot), lInput, &lOutput);
+
+ QueueBufferOutput tOutput;
+ std::vector<std::vector<native_handle_t*> > nhAA;
+ if (!wrapAs(&tOutput, &nhAA, lOutput)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::queueBuffer(): "
+ "Cannot wrap IGraphicBufferProducer::QueueBufferOutput "
+ "in IOmxBufferProducer::QueueBufferOutput"));
+ }
+
+ _hidl_cb(toStatus(status), tOutput);
+ for (auto& nhA : nhAA) {
+ for (auto& nh : nhA) {
+ if (nh != nullptr) {
+ native_handle_delete(nh);
+ }
+ }
+ }
+ return Void();
+}
+
+Return<Status> TWOmxBufferProducer::cancelBuffer(
+ int32_t slot, const hidl_handle& fence) {
+ sp<Fence> lFence = new Fence();
+ if (!convertTo(lFence.get(), fence)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::cancelBuffer(): "
+ "Cannot convert hidl_handle to Fence"));
+ }
+ return toStatus(mBase->cancelBuffer(static_cast<int>(slot), lFence));
+}
+
+Return<void> TWOmxBufferProducer::query(int32_t what, query_cb _hidl_cb) {
+ int lValue;
+ int lReturn = mBase->query(static_cast<int>(what), &lValue);
+ _hidl_cb(static_cast<int32_t>(lReturn), static_cast<int32_t>(lValue));
+ return Void();
+}
+
+Return<void> TWOmxBufferProducer::connect(
+ const sp<IOmxProducerListener>& listener,
+ int32_t api, bool producerControlledByApp, connect_cb _hidl_cb) {
+ sp<IProducerListener> lListener = new LWOmxProducerListener(listener);
+ IGraphicBufferProducer::QueueBufferOutput lOutput;
+ status_t status = mBase->connect(lListener,
+ static_cast<int>(api),
+ producerControlledByApp,
+ &lOutput);
+
+ QueueBufferOutput tOutput;
+ std::vector<std::vector<native_handle_t*> > nhAA;
+ if (!wrapAs(&tOutput, &nhAA, lOutput)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::connect(): "
+ "Cannot wrap IGraphicBufferProducer::QueueBufferOutput "
+ "in IOmxBufferProducer::QueueBufferOutput"));
+ }
+
+ _hidl_cb(toStatus(status), tOutput);
+ for (auto& nhA : nhAA) {
+ for (auto& nh : nhA) {
+ if (nh != nullptr) {
+ native_handle_delete(nh);
+ }
+ }
+ }
+ return Void();
+}
+
+Return<Status> TWOmxBufferProducer::disconnect(
+ int32_t api, DisconnectMode mode) {
+ return toStatus(mBase->disconnect(
+ static_cast<int>(api),
+ toGuiDisconnectMode(mode)));
+}
+
+Return<Status> TWOmxBufferProducer::setSidebandStream(const hidl_handle& stream) {
+ return toStatus(mBase->setSidebandStream(NativeHandle::create(
+ native_handle_clone(stream), true)));
+}
+
+Return<void> TWOmxBufferProducer::allocateBuffers(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t usage) {
+ mBase->allocateBuffers(
+ width, height,
+ static_cast<::android::PixelFormat>(format),
+ usage);
+ return Void();
+}
+
+Return<Status> TWOmxBufferProducer::allowAllocation(bool allow) {
+ return toStatus(mBase->allowAllocation(allow));
+}
+
+Return<Status> TWOmxBufferProducer::setGenerationNumber(uint32_t generationNumber) {
+ return toStatus(mBase->setGenerationNumber(generationNumber));
+}
+
+Return<void> TWOmxBufferProducer::getConsumerName(getConsumerName_cb _hidl_cb) {
+ _hidl_cb(mBase->getConsumerName().string());
+ return Void();
+}
+
+Return<Status> TWOmxBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
+ return toStatus(mBase->setSharedBufferMode(sharedBufferMode));
+}
+
+Return<Status> TWOmxBufferProducer::setAutoRefresh(bool autoRefresh) {
+ return toStatus(mBase->setAutoRefresh(autoRefresh));
+}
+
+Return<Status> TWOmxBufferProducer::setDequeueTimeout(int64_t timeoutNs) {
+ return toStatus(mBase->setDequeueTimeout(timeoutNs));
+}
+
+Return<void> TWOmxBufferProducer::getLastQueuedBuffer(
+ getLastQueuedBuffer_cb _hidl_cb) {
+ sp<GraphicBuffer> lOutBuffer = new GraphicBuffer();
+ sp<Fence> lOutFence = new Fence();
+ float lOutTransformMatrix[16];
+ status_t status = mBase->getLastQueuedBuffer(
+ &lOutBuffer, &lOutFence, lOutTransformMatrix);
+
+ AnwBuffer tOutBuffer;
+ wrapAs(&tOutBuffer, *lOutBuffer);
+ hidl_handle tOutFence;
+ native_handle_t* nh;
+ if (!wrapAs(&tOutFence, &nh, *lOutFence)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::getLastQueuedBuffer(): "
+ "Cannot wrap Fence in hidl_handle"));
+ }
+ hidl_array<float, 16> tOutTransformMatrix(lOutTransformMatrix);
+
+ _hidl_cb(toStatus(status), tOutBuffer, tOutFence, tOutTransformMatrix);
+ native_handle_delete(nh);
+ return Void();
+}
+
+Return<void> TWOmxBufferProducer::getFrameTimestamps(
+ getFrameTimestamps_cb _hidl_cb) {
+ ::android::FrameEventHistoryDelta lDelta;
+ mBase->getFrameTimestamps(&lDelta);
+
+ FrameEventHistoryDelta tDelta;
+ std::vector<std::vector<native_handle_t*> > nhAA;
+ if (!wrapAs(&tDelta, &nhAA, lDelta)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE,
+ String8("TWOmxBufferProducer::getFrameTimestamps(): "
+ "Cannot wrap ::android::FrameEventHistoryDelta "
+ "in FrameEventHistoryDelta"));
+ }
+
+ _hidl_cb(tDelta);
+ for (auto& nhA : nhAA) {
+ for (auto& nh : nhA) {
+ if (nh != nullptr) {
+ native_handle_delete(nh);
+ }
+ }
+ }
+ return Void();
+}
+
+Return<void> TWOmxBufferProducer::getUniqueId(getUniqueId_cb _hidl_cb) {
+ uint64_t outId;
+ status_t status = mBase->getUniqueId(&outId);
+ _hidl_cb(toStatus(status), outId);
+ return Void();
+}
+
+// LWOmxBufferProducer
+
+LWOmxBufferProducer::LWOmxBufferProducer(sp<IOmxBufferProducer> const& base) :
+ mBase(base) {
+}
+
+status_t LWOmxBufferProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
+ *buf = new GraphicBuffer();
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->requestBuffer(
+ static_cast<int32_t>(slot),
+ [&fnStatus, &buf] (Status status, AnwBuffer const& buffer) {
+ fnStatus = toStatusT(status);
+ if (!convertTo(buf->get(), buffer)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxBufferProducer::setMaxDequeuedBufferCount(
+ int maxDequeuedBuffers) {
+ return toStatusT(mBase->setMaxDequeuedBufferCount(
+ static_cast<int32_t>(maxDequeuedBuffers)));
+}
+
+status_t LWOmxBufferProducer::setAsyncMode(bool async) {
+ return toStatusT(mBase->setAsyncMode(async));
+}
+
+status_t LWOmxBufferProducer::dequeueBuffer(
+ int* slot, sp<Fence>* fence,
+ uint32_t w, uint32_t h, ::android::PixelFormat format,
+ uint32_t usage, FrameEventHistoryDelta* outTimestamps) {
+ *fence = new Fence();
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->dequeueBuffer(
+ w, h, static_cast<PixelFormat>(format), usage,
+ outTimestamps != nullptr,
+ [&fnStatus, slot, fence, outTimestamps] (
+ Status status,
+ int32_t tSlot,
+ hidl_handle const& tFence,
+ IOmxBufferProducer::FrameEventHistoryDelta const& tTs) {
+ fnStatus = toStatusT(status);
+ *slot = tSlot;
+ if (!convertTo(fence->get(), tFence)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ if (outTimestamps && !convertTo(outTimestamps, tTs)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxBufferProducer::detachBuffer(int slot) {
+ return toStatusT(mBase->detachBuffer(static_cast<int>(slot)));
+}
+
+status_t LWOmxBufferProducer::detachNextBuffer(
+ sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
+ *outBuffer = new GraphicBuffer();
+ *outFence = new Fence();
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->detachNextBuffer(
+ [&fnStatus, outBuffer, outFence] (
+ Status status,
+ AnwBuffer const& tBuffer,
+ hidl_handle const& tFence) {
+ fnStatus = toStatusT(status);
+ if (!convertTo(outFence->get(), tFence)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ if (!convertTo(outBuffer->get(), tBuffer)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxBufferProducer::attachBuffer(
+ int* outSlot, const sp<GraphicBuffer>& buffer) {
+ AnwBuffer tBuffer;
+ wrapAs(&tBuffer, *buffer);
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->attachBuffer(tBuffer,
+ [&fnStatus, outSlot] (Status status, int32_t slot) {
+ fnStatus = toStatusT(status);
+ *outSlot = slot;
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxBufferProducer::queueBuffer(
+ int slot,
+ const QueueBufferInput& input,
+ QueueBufferOutput* output) {
+ IOmxBufferProducer::QueueBufferInput tInput;
+ native_handle_t* nh;
+ if (!wrapAs(&tInput, &nh, input)) {
+ return BAD_VALUE;
+ }
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->queueBuffer(slot, tInput,
+ [&fnStatus, output] (
+ Status status,
+ IOmxBufferProducer::QueueBufferOutput const& tOutput) {
+ fnStatus = toStatusT(status);
+ if (!convertTo(output, tOutput)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ }));
+ native_handle_delete(nh);
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxBufferProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
+ hidl_handle tFence;
+ native_handle_t* nh;
+ if (!wrapAs(&tFence, &nh, *fence)) {
+ return BAD_VALUE;
+ }
+
+ status_t status = toStatusT(mBase->cancelBuffer(
+ static_cast<int32_t>(slot), tFence));
+ native_handle_delete(nh);
+ return status;
+}
+
+int LWOmxBufferProducer::query(int what, int* value) {
+ int result;
+ status_t transStatus = toStatusT(mBase->query(
+ static_cast<int32_t>(what),
+ [&result, value] (int32_t tResult, int32_t tValue) {
+ result = static_cast<int>(tResult);
+ *value = static_cast<int>(tValue);
+ }));
+ return transStatus == NO_ERROR ? result : static_cast<int>(transStatus);
+}
+
+status_t LWOmxBufferProducer::connect(
+ const sp<IProducerListener>& listener, int api,
+ bool producerControlledByApp, QueueBufferOutput* output) {
+ sp<IOmxProducerListener> tListener = new TWOmxProducerListener(listener);
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->connect(
+ tListener, static_cast<int32_t>(api), producerControlledByApp,
+ [&fnStatus, output] (
+ Status status,
+ IOmxBufferProducer::QueueBufferOutput const& tOutput) {
+ fnStatus = toStatusT(status);
+ if (!convertTo(output, tOutput)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxBufferProducer::disconnect(int api, DisconnectMode mode) {
+ return toStatusT(mBase->disconnect(
+ static_cast<int32_t>(api), toOmxDisconnectMode(mode)));
+}
+
+status_t LWOmxBufferProducer::setSidebandStream(
+ const sp<NativeHandle>& stream) {
+ return toStatusT(mBase->setSidebandStream(stream->handle()));
+}
+
+void LWOmxBufferProducer::allocateBuffers(uint32_t width, uint32_t height,
+ ::android::PixelFormat format, uint32_t usage) {
+ mBase->allocateBuffers(
+ width, height, static_cast<PixelFormat>(format), usage);
+}
+
+status_t LWOmxBufferProducer::allowAllocation(bool allow) {
+ return toStatusT(mBase->allowAllocation(allow));
+}
+
+status_t LWOmxBufferProducer::setGenerationNumber(uint32_t generationNumber) {
+ return toStatusT(mBase->setGenerationNumber(generationNumber));
+}
+
+String8 LWOmxBufferProducer::getConsumerName() const {
+ String8 lName;
+ mBase->getConsumerName([&lName] (hidl_string const& name) {
+ lName = name.c_str();
+ });
+ return lName;
+}
+
+status_t LWOmxBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
+ return toStatusT(mBase->setSharedBufferMode(sharedBufferMode));
+}
+
+status_t LWOmxBufferProducer::setAutoRefresh(bool autoRefresh) {
+ return toStatusT(mBase->setAutoRefresh(autoRefresh));
+}
+
+status_t LWOmxBufferProducer::setDequeueTimeout(nsecs_t timeout) {
+ return toStatusT(mBase->setDequeueTimeout(static_cast<int64_t>(timeout)));
+}
+
+status_t LWOmxBufferProducer::getLastQueuedBuffer(
+ sp<GraphicBuffer>* outBuffer,
+ sp<Fence>* outFence,
+ float outTransformMatrix[16]) {
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->getLastQueuedBuffer(
+ [&fnStatus, outBuffer, outFence, &outTransformMatrix] (
+ Status status,
+ AnwBuffer const& buffer,
+ hidl_handle const& fence,
+ hidl_array<float, 16> const& transformMatrix) {
+ fnStatus = toStatusT(status);
+ *outBuffer = new GraphicBuffer();
+ if (!convertTo(outBuffer->get(), buffer)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ *outFence = new Fence();
+ if (!convertTo(outFence->get(), fence)) {
+ fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
+ }
+ std::copy(transformMatrix.data(),
+ transformMatrix.data() + 16,
+ outTransformMatrix);
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+void LWOmxBufferProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) {
+ mBase->getFrameTimestamps([outDelta] (
+ IOmxBufferProducer::FrameEventHistoryDelta const& tDelta) {
+ convertTo(outDelta, tDelta);
+ });
+}
+
+status_t LWOmxBufferProducer::getUniqueId(uint64_t* outId) const {
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->getUniqueId(
+ [&fnStatus, outId] (Status status, uint64_t id) {
+ fnStatus = toStatusT(status);
+ *outId = id;
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+::android::IBinder* LWOmxBufferProducer::onAsBinder() {
+ return nullptr;
+}
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h
new file mode 100644
index 0000000..46abd27
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXBUFFERPRODUCER_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXBUFFERPRODUCER_H
+
+#include <android/hardware/media/omx/1.0/IOmxBufferProducer.h>
+#include <binder/Binder.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/IProducerListener.h>
+#include "Conversion.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::hardware::media::omx::V1_0::IOmxBufferProducer;
+using ::android::hardware::media::omx::V1_0::IOmxProducerListener;
+using ::android::hardware::media::omx::V1_0::Status;
+using ::android::hardware::media::V1_0::AnwBuffer;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ::android::IGraphicBufferProducer;
+using ::android::IProducerListener;
+
+struct TWOmxBufferProducer : public IOmxBufferProducer {
+ sp<IGraphicBufferProducer> mBase;
+ TWOmxBufferProducer(sp<IGraphicBufferProducer> const& base);
+ Return<void> requestBuffer(int32_t slot, requestBuffer_cb _hidl_cb)
+ override;
+ Return<Status> setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers)
+ override;
+ Return<Status> setAsyncMode(bool async) override;
+ Return<void> dequeueBuffer(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t usage,
+ bool getFrameTimestamps, dequeueBuffer_cb _hidl_cb) override;
+ Return<Status> detachBuffer(int32_t slot) override;
+ Return<void> detachNextBuffer(detachNextBuffer_cb _hidl_cb) override;
+ Return<void> attachBuffer(const AnwBuffer& buffer, attachBuffer_cb _hidl_cb)
+ override;
+ Return<void> queueBuffer(
+ int32_t slot, const IOmxBufferProducer::QueueBufferInput& input,
+ queueBuffer_cb _hidl_cb) override;
+ Return<Status> cancelBuffer(int32_t slot, const hidl_handle& fence)
+ override;
+ Return<void> query(int32_t what, query_cb _hidl_cb) override;
+ Return<void> connect(const sp<IOmxProducerListener>& listener,
+ int32_t api, bool producerControlledByApp,
+ connect_cb _hidl_cb) override;
+ Return<Status> disconnect(
+ int32_t api,
+ IOmxBufferProducer::DisconnectMode mode) override;
+ Return<Status> setSidebandStream(const hidl_handle& stream) override;
+ Return<void> allocateBuffers(
+ uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t usage) override;
+ Return<Status> allowAllocation(bool allow) override;
+ Return<Status> setGenerationNumber(uint32_t generationNumber) override;
+ Return<void> getConsumerName(getConsumerName_cb _hidl_cb) override;
+ Return<Status> setSharedBufferMode(bool sharedBufferMode) override;
+ Return<Status> setAutoRefresh(bool autoRefresh) override;
+ Return<Status> setDequeueTimeout(int64_t timeoutNs) override;
+ Return<void> getLastQueuedBuffer(getLastQueuedBuffer_cb _hidl_cb) override;
+ Return<void> getFrameTimestamps(getFrameTimestamps_cb _hidl_cb) override;
+ Return<void> getUniqueId(getUniqueId_cb _hidl_cb) override;
+};
+
+struct LWOmxBufferProducer : public IGraphicBufferProducer {
+ sp<IOmxBufferProducer> mBase;
+ LWOmxBufferProducer(sp<IOmxBufferProducer> const& base);
+
+ status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
+ status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override;
+ status_t setAsyncMode(bool async) override;
+ status_t dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w,
+ uint32_t h, ::android::PixelFormat format, uint32_t usage,
+ FrameEventHistoryDelta* outTimestamps) override;
+ status_t detachBuffer(int slot) override;
+ status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence)
+ override;
+ status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer)
+ override;
+ status_t queueBuffer(int slot,
+ const QueueBufferInput& input,
+ QueueBufferOutput* output) override;
+ status_t cancelBuffer(int slot, const sp<Fence>& fence) override;
+ int query(int what, int* value) override;
+ status_t connect(const sp<IProducerListener>& listener, int api,
+ bool producerControlledByApp, QueueBufferOutput* output) override;
+ status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api)
+ override;
+ status_t setSidebandStream(const sp<NativeHandle>& stream) override;
+ void allocateBuffers(uint32_t width, uint32_t height,
+ ::android::PixelFormat format, uint32_t usage) override;
+ status_t allowAllocation(bool allow) override;
+ status_t setGenerationNumber(uint32_t generationNumber) override;
+ String8 getConsumerName() const override;
+ status_t setSharedBufferMode(bool sharedBufferMode) override;
+ status_t setAutoRefresh(bool autoRefresh) override;
+ status_t setDequeueTimeout(nsecs_t timeout) override;
+ status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
+ sp<Fence>* outFence, float outTransformMatrix[16]) override;
+ void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override;
+ status_t getUniqueId(uint64_t* outId) const override;
+protected:
+ ::android::IBinder* onAsBinder() override;
+};
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXBUFFERPRODUCER_H
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
new file mode 100644
index 0000000..1ebd9a7
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WOmxBufferSource.h"
+#include "Conversion.h"
+#include <utils/String8.h>
+#include <cutils/native_handle.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+// LWOmxBufferSource
+LWOmxBufferSource::LWOmxBufferSource(sp<IOmxBufferSource> const& base) :
+ mBase(base) {
+}
+
+::android::binder::Status LWOmxBufferSource::onOmxExecuting() {
+ return toBinderStatus(mBase->onOmxExecuting());
+}
+
+::android::binder::Status LWOmxBufferSource::onOmxIdle() {
+ return toBinderStatus(mBase->onOmxIdle());
+}
+
+::android::binder::Status LWOmxBufferSource::onOmxLoaded() {
+ return toBinderStatus(mBase->onOmxLoaded());
+}
+
+::android::binder::Status LWOmxBufferSource::onInputBufferAdded(
+ int32_t bufferId) {
+ return toBinderStatus(mBase->onInputBufferAdded(
+ static_cast<uint32_t>(bufferId)));
+}
+
+::android::binder::Status LWOmxBufferSource::onInputBufferEmptied(
+ int32_t bufferId, OMXFenceParcelable const& fenceParcel) {
+ hidl_handle fence;
+ native_handle_t* fenceNh;
+ if (!wrapAs(&fence, &fenceNh, fenceParcel)) {
+ return ::android::binder::Status::fromExceptionCode(
+ ::android::binder::Status::EX_BAD_PARCELABLE,
+ "Invalid fence");
+ }
+ ::android::binder::Status status = toBinderStatus(
+ mBase->onInputBufferEmptied(
+ static_cast<uint32_t>(bufferId), fence));
+ if (native_handle_delete(fenceNh) != 0) {
+ return ::android::binder::Status::fromExceptionCode(
+ ::android::binder::Status::EX_NULL_POINTER,
+ "Cannot delete native handle");
+ }
+ return status;
+}
+
+::android::IBinder* LWOmxBufferSource::onAsBinder() {
+ return nullptr;
+}
+
+// TWOmxBufferSource
+TWOmxBufferSource::TWOmxBufferSource(sp<IOMXBufferSource> const& base) :
+ mBase(base) {
+}
+
+Return<void> TWOmxBufferSource::onOmxExecuting() {
+ return toHardwareStatus(mBase->onOmxExecuting());
+}
+
+Return<void> TWOmxBufferSource::onOmxIdle() {
+ return toHardwareStatus(mBase->onOmxIdle());
+}
+
+Return<void> TWOmxBufferSource::onOmxLoaded() {
+ return toHardwareStatus(mBase->onOmxLoaded());
+}
+
+Return<void> TWOmxBufferSource::onInputBufferAdded(uint32_t buffer) {
+ return toHardwareStatus(mBase->onInputBufferAdded(
+ static_cast<int32_t>(buffer)));
+}
+
+Return<void> TWOmxBufferSource::onInputBufferEmptied(
+ uint32_t buffer, hidl_handle const& fence) {
+ OMXFenceParcelable fenceParcelable;
+ if (!convertTo(&fenceParcelable, fence)) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_BAD_PARCELABLE);
+ }
+ return toHardwareStatus(mBase->onInputBufferEmptied(
+ static_cast<int32_t>(buffer), fenceParcelable));
+}
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
new file mode 100644
index 0000000..3bf35c5
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXBUFFERSOURCE_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXBUFFERSOURCE_H
+
+#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <frameworks/native/include/binder/Binder.h>
+#include <android/IOMXBufferSource.h>
+#include <OMXFenceParcelable.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::media::omx::V1_0::IOmxBufferSource;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ::android::OMXFenceParcelable;
+using ::android::IOMXBufferSource;
+
+/**
+ * Wrapper classes for conversion
+ * ==============================
+ *
+ * Naming convention:
+ * - LW = Legacy Wrapper --- It wraps a Treble object inside a legacy object.
+ * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
+ */
+
+struct LWOmxBufferSource : public IOMXBufferSource {
+ sp<IOmxBufferSource> mBase;
+ LWOmxBufferSource(sp<IOmxBufferSource> const& base);
+ ::android::binder::Status onOmxExecuting() override;
+ ::android::binder::Status onOmxIdle() override;
+ ::android::binder::Status onOmxLoaded() override;
+ ::android::binder::Status onInputBufferAdded(int32_t bufferID) override;
+ ::android::binder::Status onInputBufferEmptied(
+ int32_t bufferID, OMXFenceParcelable const& fenceParcel) override;
+protected:
+ ::android::IBinder* onAsBinder() override;
+};
+
+struct TWOmxBufferSource : public IOmxBufferSource {
+ sp<IOMXBufferSource> mBase;
+ TWOmxBufferSource(sp<IOMXBufferSource> const& base);
+ Return<void> onOmxExecuting() override;
+ Return<void> onOmxIdle() override;
+ Return<void> onOmxLoaded() override;
+ Return<void> onInputBufferAdded(uint32_t buffer) override;
+ Return<void> onInputBufferEmptied(
+ uint32_t buffer, hidl_handle const& fence) override;
+};
+
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXBUFFERSOURCE_H
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
new file mode 100644
index 0000000..dc04b67
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
@@ -0,0 +1,441 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <IOMX.h>
+#include <OMXNodeInstance.h>
+#include "WOmxNode.h"
+#include "WOmxBufferSource.h"
+#include "Conversion.h"
+
+#include <algorithm>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::Void;
+
+// LWOmxNode
+LWOmxNode::LWOmxNode(sp<IOmxNode> const& base) : mBase(base) {
+}
+
+status_t LWOmxNode::freeNode() {
+ return toStatusT(mBase->freeNode());
+}
+
+status_t LWOmxNode::sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_S32 param) {
+ return toStatusT(mBase->sendCommand(
+ toRawCommandType(cmd), param));
+}
+
+status_t LWOmxNode::getParameter(
+ OMX_INDEXTYPE index, void *params, size_t size) {
+ hidl_vec<uint8_t> tParams = inHidlBytes(params, size);
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->getParameter(
+ toRawIndexType(index),
+ tParams,
+ [&fnStatus, params, size](
+ Status status, hidl_vec<uint8_t> const& outParams) {
+ fnStatus = toStatusT(status);
+ std::copy(
+ outParams.data(),
+ outParams.data() + outParams.size(),
+ static_cast<uint8_t*>(params));
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxNode::setParameter(
+ OMX_INDEXTYPE index, const void *params, size_t size) {
+ hidl_vec<uint8_t> tParams = inHidlBytes(params, size);
+ return toStatusT(mBase->setParameter(
+ toRawIndexType(index), tParams));
+}
+
+status_t LWOmxNode::getConfig(
+ OMX_INDEXTYPE index, void *params, size_t size) {
+ hidl_vec<uint8_t> tParams = inHidlBytes(params, size);
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->getConfig(
+ toRawIndexType(index),
+ tParams,
+ [&fnStatus, params, size](
+ Status status, hidl_vec<uint8_t> const& outParams) {
+ fnStatus = toStatusT(status);
+ std::copy(
+ outParams.data(),
+ outParams.data() + size,
+ static_cast<uint8_t*>(params));
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxNode::setConfig(
+ OMX_INDEXTYPE index, const void *params, size_t size) {
+ hidl_vec<uint8_t> tParams = inHidlBytes(params, size);
+ return toStatusT(mBase->setConfig(toRawIndexType(index), tParams));
+}
+
+status_t LWOmxNode::setPortMode(
+ OMX_U32 port_index, IOMX::PortMode mode) {
+ return toStatusT(mBase->setPortMode(port_index, toHardwarePortMode(mode)));
+}
+
+status_t LWOmxNode::prepareForAdaptivePlayback(
+ OMX_U32 portIndex, OMX_BOOL enable,
+ OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
+ return toStatusT(mBase->prepareForAdaptivePlayback(
+ portIndex, toRawBool(enable), maxFrameWidth, maxFrameHeight));
+}
+
+status_t LWOmxNode::configureVideoTunnelMode(
+ OMX_U32 portIndex, OMX_BOOL tunneled,
+ OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->configureVideoTunnelMode(
+ portIndex,
+ toRawBool(tunneled),
+ audioHwSync,
+ [&fnStatus, sidebandHandle](
+ Status status, hidl_handle const& outSidebandHandle) {
+ fnStatus = toStatusT(status);
+ *sidebandHandle = outSidebandHandle == nullptr ?
+ nullptr : native_handle_clone(outSidebandHandle);
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxNode::getGraphicBufferUsage(
+ OMX_U32 portIndex, OMX_U32* usage) {
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->getGraphicBufferUsage(
+ portIndex,
+ [&fnStatus, usage](
+ Status status, uint32_t outUsage) {
+ fnStatus = toStatusT(status);
+ *usage = outUsage;
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxNode::setInputSurface(
+ const sp<IOMXBufferSource> &bufferSource) {
+ return toStatusT(mBase->setInputSurface(
+ new TWOmxBufferSource(bufferSource)));
+}
+
+status_t LWOmxNode::allocateSecureBuffer(
+ OMX_U32 portIndex, size_t size, buffer_id *buffer,
+ void **buffer_data, sp<NativeHandle> *native_handle) {
+ *buffer_data = nullptr;
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->allocateSecureBuffer(
+ portIndex,
+ static_cast<uint64_t>(size),
+ [&fnStatus, buffer, buffer_data, native_handle](
+ Status status,
+ uint32_t outBuffer,
+ hidl_handle const& outNativeHandle) {
+ fnStatus = toStatusT(status);
+ *buffer = outBuffer;
+ *native_handle = NativeHandle::create(
+ native_handle_clone(outNativeHandle), true);
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxNode::useBuffer(
+ OMX_U32 portIndex, const OMXBuffer &omxBuffer, buffer_id *buffer) {
+ CodecBuffer codecBuffer;
+ if (!wrapAs(&codecBuffer, omxBuffer)) {
+ return BAD_VALUE;
+ }
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->useBuffer(
+ portIndex,
+ codecBuffer,
+ [&fnStatus, buffer](Status status, uint32_t outBuffer) {
+ fnStatus = toStatusT(status);
+ *buffer = outBuffer;
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxNode::freeBuffer(
+ OMX_U32 portIndex, buffer_id buffer) {
+ return toStatusT(mBase->freeBuffer(portIndex, buffer));
+}
+
+status_t LWOmxNode::fillBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuffer, int fenceFd) {
+ CodecBuffer codecBuffer;
+ if (!wrapAs(&codecBuffer, omxBuffer)) {
+ return BAD_VALUE;
+ }
+ native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd);
+ if (!fenceNh) {
+ return NO_MEMORY;
+ }
+ status_t status = toStatusT(mBase->fillBuffer(
+ buffer, codecBuffer, fenceNh));
+ native_handle_delete(fenceNh);
+ return status;
+}
+
+status_t LWOmxNode::emptyBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuffer,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
+ CodecBuffer codecBuffer;
+ if (!wrapAs(&codecBuffer, omxBuffer)) {
+ return BAD_VALUE;
+ }
+ native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd);
+ if (!fenceNh) {
+ return NO_MEMORY;
+ }
+ status_t status = toStatusT(mBase->emptyBuffer(
+ buffer,
+ codecBuffer,
+ flags,
+ toRawTicks(timestamp),
+ fenceNh));
+ native_handle_delete(fenceNh);
+ return status;
+}
+status_t LWOmxNode::getExtensionIndex(
+ const char *parameter_name,
+ OMX_INDEXTYPE *index) {
+ status_t fnStatus;
+ status_t transStatus = toStatusT(mBase->getExtensionIndex(
+ hidl_string(parameter_name),
+ [&fnStatus, index](Status status, uint32_t outIndex) {
+ fnStatus = toStatusT(status);
+ *index = toEnumIndexType(outIndex);
+ }));
+ return transStatus == NO_ERROR ? fnStatus : transStatus;
+}
+
+status_t LWOmxNode::dispatchMessage(const omx_message &lMsg) {
+ Message tMsg;
+ native_handle_t* nh;
+ if (!wrapAs(&tMsg, &nh, lMsg)) {
+ return NO_MEMORY;
+ }
+ status_t status = toStatusT(mBase->dispatchMessage(tMsg));
+ native_handle_delete(nh);
+ return status;
+}
+
+// TODO: this is temporary, will be removed when quirks move to OMX side.
+status_t LWOmxNode::setQuirks(OMX_U32 quirks) {
+ return toStatusT(mBase->setQuirks(static_cast<uint32_t>(quirks)));;
+}
+
+::android::IBinder* LWOmxNode::onAsBinder() {
+ return nullptr;
+}
+
+// TWOmxNode
+TWOmxNode::TWOmxNode(sp<IOMXNode> const& base) : mBase(base) {
+}
+
+Return<Status> TWOmxNode::freeNode() {
+ return toStatus(mBase->freeNode());
+}
+
+Return<Status> TWOmxNode::sendCommand(uint32_t cmd, int32_t param) {
+ return toStatus(mBase->sendCommand(toEnumCommandType(cmd), param));
+}
+
+Return<void> TWOmxNode::getParameter(
+ uint32_t index, hidl_vec<uint8_t> const& inParams,
+ getParameter_cb _hidl_cb) {
+ hidl_vec<uint8_t> params(inParams);
+ Status status = toStatus(mBase->getParameter(
+ toEnumIndexType(index),
+ static_cast<void*>(params.data()),
+ params.size()));
+ _hidl_cb(status, params);
+ return Void();
+}
+
+Return<Status> TWOmxNode::setParameter(
+ uint32_t index, hidl_vec<uint8_t> const& params) {
+ return toStatus(mBase->setParameter(
+ toEnumIndexType(index),
+ static_cast<void const*>(params.data()),
+ params.size()));
+}
+
+Return<void> TWOmxNode::getConfig(
+ uint32_t index, const hidl_vec<uint8_t>& inConfig,
+ getConfig_cb _hidl_cb) {
+ hidl_vec<uint8_t> config(inConfig);
+ Status status = toStatus(mBase->getConfig(
+ toEnumIndexType(index),
+ static_cast<void*>(config.data()),
+ config.size()));
+ _hidl_cb(status, config);
+ return Void();
+}
+
+Return<Status> TWOmxNode::setConfig(
+ uint32_t index, const hidl_vec<uint8_t>& config) {
+ return toStatus(mBase->setConfig(
+ toEnumIndexType(index),
+ static_cast<void const*>(config.data()),
+ config.size()));
+}
+
+Return<Status> TWOmxNode::setPortMode(uint32_t portIndex, PortMode mode) {
+ return toStatus(mBase->setPortMode(portIndex, toIOMXPortMode(mode)));
+}
+
+Return<Status> TWOmxNode::prepareForAdaptivePlayback(
+ uint32_t portIndex, bool enable,
+ uint32_t maxFrameWidth, uint32_t maxFrameHeight) {
+ return toStatus(mBase->prepareForAdaptivePlayback(
+ portIndex,
+ toEnumBool(enable),
+ maxFrameWidth,
+ maxFrameHeight));
+}
+
+Return<void> TWOmxNode::configureVideoTunnelMode(
+ uint32_t portIndex, bool tunneled, uint32_t audioHwSync,
+ configureVideoTunnelMode_cb _hidl_cb) {
+ native_handle_t* sidebandHandle = nullptr;
+ Status status = toStatus(mBase->configureVideoTunnelMode(
+ portIndex,
+ toEnumBool(tunneled),
+ audioHwSync,
+ &sidebandHandle));
+ _hidl_cb(status, hidl_handle(sidebandHandle));
+ return Void();
+}
+
+Return<void> TWOmxNode::getGraphicBufferUsage(
+ uint32_t portIndex, getGraphicBufferUsage_cb _hidl_cb) {
+ OMX_U32 usage;
+ Status status = toStatus(mBase->getGraphicBufferUsage(
+ portIndex, &usage));
+ _hidl_cb(status, usage);
+ return Void();
+}
+
+Return<Status> TWOmxNode::setInputSurface(
+ const sp<IOmxBufferSource>& bufferSource) {
+ return toStatus(mBase->setInputSurface(new LWOmxBufferSource(
+ bufferSource)));
+}
+
+Return<void> TWOmxNode::allocateSecureBuffer(
+ uint32_t portIndex, uint64_t size,
+ allocateSecureBuffer_cb _hidl_cb) {
+ IOMX::buffer_id buffer;
+ void* bufferData;
+ sp<NativeHandle> nativeHandle;
+ Status status = toStatus(mBase->allocateSecureBuffer(
+ portIndex,
+ static_cast<size_t>(size),
+ &buffer,
+ &bufferData,
+ &nativeHandle));
+ _hidl_cb(status, buffer, nativeHandle->handle());
+ return Void();
+}
+
+Return<void> TWOmxNode::useBuffer(
+ uint32_t portIndex, const CodecBuffer& codecBuffer,
+ useBuffer_cb _hidl_cb) {
+ IOMX::buffer_id buffer;
+ OMXBuffer omxBuffer;
+ if (!convertTo(&omxBuffer, codecBuffer)) {
+ _hidl_cb(Status::BAD_VALUE, 0);
+ return Void();
+ }
+ Status status = toStatus(mBase->useBuffer(
+ portIndex, omxBuffer, &buffer));
+ _hidl_cb(status, buffer);
+ return Void();
+}
+
+Return<Status> TWOmxNode::freeBuffer(uint32_t portIndex, uint32_t buffer) {
+ return toStatus(mBase->freeBuffer(portIndex, buffer));
+}
+
+Return<Status> TWOmxNode::fillBuffer(
+ uint32_t buffer, const CodecBuffer& codecBuffer,
+ const hidl_handle& fence) {
+ OMXBuffer omxBuffer;
+ if (!convertTo(&omxBuffer, codecBuffer)) {
+ return Status::BAD_VALUE;
+ }
+ return toStatus(mBase->fillBuffer(
+ buffer,
+ omxBuffer,
+ native_handle_read_fd(fence)));
+}
+
+Return<Status> TWOmxNode::emptyBuffer(
+ uint32_t buffer, const CodecBuffer& codecBuffer, uint32_t flags,
+ uint64_t timestampUs, const hidl_handle& fence) {
+ OMXBuffer omxBuffer;
+ if (!convertTo(&omxBuffer, codecBuffer)) {
+ return Status::BAD_VALUE;
+ }
+ return toStatus(mBase->emptyBuffer(
+ buffer,
+ omxBuffer,
+ flags,
+ toOMXTicks(timestampUs),
+ native_handle_read_fd(fence)));
+}
+
+Return<void> TWOmxNode::getExtensionIndex(
+ const hidl_string& parameterName,
+ getExtensionIndex_cb _hidl_cb) {
+ OMX_INDEXTYPE index;
+ Status status = toStatus(mBase->getExtensionIndex(
+ parameterName, &index));
+ _hidl_cb(status, toRawIndexType(index));
+ return Void();
+}
+
+Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) {
+ omx_message lMsg;
+ if (!wrapAs(&lMsg, tMsg)) {
+ return Status::BAD_VALUE;
+ }
+ return toStatus(mBase->dispatchMessage(lMsg));
+}
+
+Return<void> TWOmxNode::setQuirks(uint32_t quirks) {
+ mBase->setQuirks(static_cast<OMX_U32>(quirks));
+ return Void();
+}
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
new file mode 100644
index 0000000..cb0b1a7
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXNODE_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXNODE_H
+
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <utils/Errors.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hardware::media::omx::V1_0::IOmxBufferSource;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::PortMode;
+using ::android::hardware::media::omx::V1_0::Status;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+/**
+ * Wrapper classes for conversion
+ * ==============================
+ *
+ * Naming convention:
+ * - LW = Legacy Wrapper --- It wraps a Treble object inside a legacy object.
+ * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
+ */
+
+struct LWOmxNode : public IOMXNode {
+ sp<IOmxNode> mBase;
+ LWOmxNode(sp<IOmxNode> const& base);
+ status_t freeNode() override;
+ status_t sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_S32 param) override;
+ status_t getParameter(
+ OMX_INDEXTYPE index, void *params, size_t size) override;
+ status_t setParameter(
+ OMX_INDEXTYPE index, const void *params, size_t size) override;
+ status_t getConfig(
+ OMX_INDEXTYPE index, void *params, size_t size) override;
+ status_t setConfig(
+ OMX_INDEXTYPE index, const void *params, size_t size) override;
+ status_t setPortMode(
+ OMX_U32 port_index, IOMX::PortMode mode) override;
+ status_t prepareForAdaptivePlayback(
+ OMX_U32 portIndex, OMX_BOOL enable,
+ OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) override;
+ status_t configureVideoTunnelMode(
+ OMX_U32 portIndex, OMX_BOOL tunneled,
+ OMX_U32 audioHwSync, native_handle_t **sidebandHandle) override;
+ status_t getGraphicBufferUsage(
+ OMX_U32 port_index, OMX_U32* usage) override;
+ status_t setInputSurface(
+ const sp<IOMXBufferSource> &bufferSource) override;
+ status_t allocateSecureBuffer(
+ OMX_U32 port_index, size_t size, buffer_id *buffer,
+ void **buffer_data, sp<NativeHandle> *native_handle) override;
+ status_t useBuffer(
+ OMX_U32 port_index, const OMXBuffer &omxBuf,
+ buffer_id *buffer) override;
+ status_t freeBuffer(
+ OMX_U32 port_index, buffer_id buffer) override;
+ status_t fillBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf,
+ int fenceFd = -1) override;
+ status_t emptyBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) override;
+ status_t getExtensionIndex(
+ const char *parameter_name,
+ OMX_INDEXTYPE *index) override;
+ status_t dispatchMessage(const omx_message &msg) override;
+
+ // TODO: this is temporary, will be removed when quirks move to OMX side.
+ status_t setQuirks(OMX_U32 quirks) override;
+protected:
+ ::android::IBinder* onAsBinder() override;
+};
+
+struct TWOmxNode : public IOmxNode {
+ sp<IOMXNode> mBase;
+ TWOmxNode(sp<IOMXNode> const& base);
+
+ Return<Status> freeNode() override;
+ Return<Status> sendCommand(uint32_t cmd, int32_t param) override;
+ Return<void> getParameter(
+ uint32_t index, hidl_vec<uint8_t> const& inParams,
+ getParameter_cb _hidl_cb) override;
+ Return<Status> setParameter(
+ uint32_t index, hidl_vec<uint8_t> const& params) override;
+ Return<void> getConfig(
+ uint32_t index, hidl_vec<uint8_t> const& inConfig,
+ getConfig_cb _hidl_cb) override;
+ Return<Status> setConfig(
+ uint32_t index, hidl_vec<uint8_t> const& config) override;
+ Return<Status> setPortMode(uint32_t portIndex, PortMode mode) override;
+ Return<Status> prepareForAdaptivePlayback(
+ uint32_t portIndex, bool enable,
+ uint32_t maxFrameWidth, uint32_t maxFrameHeight) override;
+ Return<void> configureVideoTunnelMode(
+ uint32_t portIndex, bool tunneled, uint32_t audioHwSync,
+ configureVideoTunnelMode_cb _hidl_cb) override;
+ Return<void> getGraphicBufferUsage(
+ uint32_t portIndex,
+ getGraphicBufferUsage_cb _hidl_cb) override;
+ Return<Status> setInputSurface(
+ sp<IOmxBufferSource> const& bufferSource) override;
+ Return<void> allocateSecureBuffer(
+ uint32_t portIndex, uint64_t size,
+ allocateSecureBuffer_cb _hidl_cb) override;
+ Return<void> useBuffer(
+ uint32_t portIndex, CodecBuffer const& codecBuffer,
+ useBuffer_cb _hidl_cb) override;
+ Return<Status> freeBuffer(uint32_t portIndex, uint32_t buffer) override;
+ Return<Status> fillBuffer(
+ uint32_t buffer, CodecBuffer const& codecBuffer,
+ const hidl_handle& fence) override;
+ Return<Status> emptyBuffer(
+ uint32_t buffer, CodecBuffer const& codecBuffer,
+ uint32_t flags, uint64_t timestampUs,
+ hidl_handle const& fence) override;
+ Return<void> getExtensionIndex(
+ hidl_string const& parameterName,
+ getExtensionIndex_cb _hidl_cb) override;
+ Return<Status> dispatchMessage(Message const& msg) override;
+ Return<void> setQuirks(uint32_t quirks) override;
+};
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXNODE_H
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
new file mode 100644
index 0000000..4773572
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WOmxObserver.h"
+
+#include <vector>
+
+#include <cutils/native_handle.h>
+#include <frameworks/native/include/binder/Binder.h>
+
+#include "Conversion.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+// LWOmxObserver
+LWOmxObserver::LWOmxObserver(sp<IOmxObserver> const& base) : mBase(base) {
+}
+
+void LWOmxObserver::onMessages(std::list<omx_message> const& lMessages) {
+ hidl_vec<Message> tMessages;
+ std::vector<native_handle_t*> handles(lMessages.size());
+ tMessages.resize(lMessages.size());
+ size_t i = 0;
+ for (auto const& message : lMessages) {
+ wrapAs(&tMessages[i], &handles[i], message);
+ ++i;
+ }
+ mBase->onMessages(tMessages);
+ for (auto& handle : handles) {
+ native_handle_delete(handle);
+ }
+}
+
+::android::IBinder* LWOmxObserver::onAsBinder() {
+ return nullptr;
+}
+
+// TWOmxObserver
+TWOmxObserver::TWOmxObserver(sp<IOMXObserver> const& base) : mBase(base) {
+}
+
+Return<void> TWOmxObserver::onMessages(const hidl_vec<Message>& tMessages) {
+ std::list<omx_message> lMessages;
+ for (size_t i = 0; i < tMessages.size(); ++i) {
+ lMessages.push_back(omx_message{});
+ wrapAs(&lMessages.back(), tMessages[i]);
+ }
+ mBase->onMessages(lMessages);
+ return Return<void>();
+}
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h
new file mode 100644
index 0000000..b1e2eb1
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXOBSERVER_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXOBSERVER_H
+
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <IOMX.h>
+#include <list>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ::android::IOMXObserver;
+using ::android::omx_message;
+
+/**
+ * Wrapper classes for conversion
+ * ==============================
+ *
+ * Naming convention:
+ * - LW = Legacy Wrapper --- It wraps a Treble object inside a legacy object.
+ * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
+ */
+
+struct LWOmxObserver : public IOMXObserver {
+ sp<IOmxObserver> mBase;
+ LWOmxObserver(sp<IOmxObserver> const& base);
+ void onMessages(std::list<omx_message> const& lMessages) override;
+protected:
+ ::android::IBinder* onAsBinder() override;
+};
+
+struct TWOmxObserver : public IOmxObserver {
+ sp<IOMXObserver> mBase;
+ TWOmxObserver(sp<IOMXObserver> const& base);
+ Return<void> onMessages(const hidl_vec<Message>& tMessages) override;
+};
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXOBSERVER_H
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
new file mode 100644
index 0000000..d43215d
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WOmxProducerListener.h"
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+// TWOmxProducerListener
+TWOmxProducerListener::TWOmxProducerListener(
+ sp<IProducerListener> const& base):
+ mBase(base) {
+}
+
+Return<void> TWOmxProducerListener::onBufferReleased() {
+ mBase->onBufferReleased();
+ return Void();
+}
+
+Return<bool> TWOmxProducerListener::needsReleaseNotify() {
+ return mBase->needsReleaseNotify();
+}
+
+// LWOmxProducerListener
+LWOmxProducerListener::LWOmxProducerListener(
+ sp<IOmxProducerListener> const& base):
+ mBase(base) {
+}
+
+void LWOmxProducerListener::onBufferReleased() {
+ mBase->onBufferReleased();
+}
+
+bool LWOmxProducerListener::needsReleaseNotify() {
+ return static_cast<bool>(mBase->needsReleaseNotify());
+}
+
+::android::IBinder* LWOmxProducerListener::onAsBinder() {
+ return nullptr;
+}
+
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h b/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h
new file mode 100644
index 0000000..5b5e830
--- /dev/null
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXPRODUCERLISTENER_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXPRODUCERLISTENER_H
+
+#include <android/hardware/media/omx/1.0/IOmxProducerListener.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <binder/IBinder.h>
+#include <gui/IProducerListener.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::media::omx::V1_0::IOmxProducerListener;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ::android::IProducerListener;
+
+struct TWOmxProducerListener : public IOmxProducerListener {
+ sp<IProducerListener> mBase;
+ TWOmxProducerListener(sp<IProducerListener> const& base);
+ Return<void> onBufferReleased() override;
+ Return<bool> needsReleaseNotify() override;
+};
+
+class LWOmxProducerListener : public IProducerListener {
+public:
+ sp<IOmxProducerListener> mBase;
+ LWOmxProducerListener(sp<IOmxProducerListener> const& base);
+ void onBufferReleased() override;
+ bool needsReleaseNotify() override;
+protected:
+ ::android::IBinder* onAsBinder() override;
+};
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXPRODUCERLISTENER_H