summaryrefslogtreecommitdiff
path: root/libqdmetadata/qdMetaData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libqdmetadata/qdMetaData.cpp')
-rw-r--r--libqdmetadata/qdMetaData.cpp642
1 files changed, 642 insertions, 0 deletions
diff --git a/libqdmetadata/qdMetaData.cpp b/libqdmetadata/qdMetaData.cpp
new file mode 100644
index 00000000..228a634c
--- /dev/null
+++ b/libqdmetadata/qdMetaData.cpp
@@ -0,0 +1,642 @@
+/*
+ * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "qdMetaData.h"
+
+#include <QtiGrallocPriv.h>
+#include <errno.h>
+#include <gralloc_priv.h>
+#ifndef __QTI_NO_GRALLOC4__
+#include <gralloctypes/Gralloc4.h>
+#endif
+#include <log/log.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <cinttypes>
+
+static int colorMetaDataToColorSpace(ColorMetaData in, ColorSpace_t *out) {
+ if (in.colorPrimaries == ColorPrimaries_BT601_6_525 ||
+ in.colorPrimaries == ColorPrimaries_BT601_6_625) {
+ if (in.range == Range_Full) {
+ *out = ITU_R_601_FR;
+ } else {
+ *out = ITU_R_601;
+ }
+ } else if (in.colorPrimaries == ColorPrimaries_BT2020) {
+ if (in.range == Range_Full) {
+ *out = ITU_R_2020_FR;
+ } else {
+ *out = ITU_R_2020;
+ }
+ } else if (in.colorPrimaries == ColorPrimaries_BT709_5) {
+ if (in.range == Range_Full) {
+ *out = ITU_R_709_FR;
+ } else {
+ *out = ITU_R_709;
+ }
+ } else {
+ ALOGE(
+ "Cannot convert ColorMetaData to ColorSpace_t. "
+ "Primaries = %d, Range = %d",
+ in.colorPrimaries, in.range);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int colorSpaceToColorMetadata(ColorSpace_t in, ColorMetaData *out) {
+ out->transfer = Transfer_sRGB;
+ switch (in) {
+ case ITU_R_601:
+ out->colorPrimaries = ColorPrimaries_BT601_6_525;
+ out->range = Range_Limited;
+ break;
+ case ITU_R_601_FR:
+ out->colorPrimaries = ColorPrimaries_BT601_6_525;
+ out->range = Range_Full;
+ break;
+ case ITU_R_709:
+ out->colorPrimaries = ColorPrimaries_BT709_5;
+ out->range = Range_Limited;
+ break;
+ case ITU_R_709_FR:
+ out->colorPrimaries = ColorPrimaries_BT709_5;
+ out->range = Range_Full;
+ break;
+ case ITU_R_2020:
+ out->colorPrimaries = ColorPrimaries_BT2020;
+ out->range = Range_Limited;
+ break;
+ case ITU_R_2020_FR:
+ out->colorPrimaries = ColorPrimaries_BT2020;
+ out->range = Range_Full;
+ break;
+ default:
+ ALOGE("Cannot convert ColorSpace_t %d to ColorMetaData", in);
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
+#ifndef __QTI_NO_GRALLOC4__
+static bool getGralloc4Array(MetaData_t *metadata, int32_t paramType) {
+ switch (paramType) {
+ case SET_VT_TIMESTAMP:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VT_TIMESTAMP)];
+ case COLOR_METADATA:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)];
+ case PP_PARAM_INTERLACED:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_PP_PARAM_INTERLACED)];
+ case SET_VIDEO_PERF_MODE:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_PERF_MODE)];
+ case SET_GRAPHICS_METADATA:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_GRAPHICS_METADATA)];
+ case SET_UBWC_CR_STATS_INFO:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_UBWC_CR_STATS_INFO)];
+ case UPDATE_BUFFER_GEOMETRY:
+ return metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(
+ ::android::gralloc4::MetadataType_Crop.value)];
+ case UPDATE_REFRESH_RATE:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_REFRESH_RATE)];
+ case UPDATE_COLOR_SPACE:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)];
+ case MAP_SECURE_BUFFER:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_MAP_SECURE_BUFFER)];
+ case LINEAR_FORMAT:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_LINEAR_FORMAT)];
+ case SET_SINGLE_BUFFER_MODE:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_SINGLE_BUFFER_MODE)];
+ case SET_CVP_METADATA:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_CVP_METADATA)];
+ case SET_VIDEO_HISTOGRAM_STATS:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_HISTOGRAM_STATS)];
+ case SET_VIDEO_TS_INFO:
+ return metadata
+ ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_TS_INFO)];
+ case GET_S3D_FORMAT:
+ return metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_S3D_FORMAT)];
+ default:
+ ALOGE("paramType %d not supported", paramType);
+ return false;
+ }
+}
+
+static void setGralloc4Array(MetaData_t *metadata, int32_t paramType, bool isSet) {
+ switch (paramType) {
+ case SET_VT_TIMESTAMP:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VT_TIMESTAMP)] = isSet;
+ break;
+ case COLOR_METADATA:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)] = isSet;
+ break;
+ case PP_PARAM_INTERLACED:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_PP_PARAM_INTERLACED)] =
+ isSet;
+ break;
+ case SET_VIDEO_PERF_MODE:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_PERF_MODE)] = isSet;
+ break;
+ case SET_GRAPHICS_METADATA:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_GRAPHICS_METADATA)] =
+ isSet;
+ break;
+ case SET_UBWC_CR_STATS_INFO:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_UBWC_CR_STATS_INFO)] =
+ isSet;
+ break;
+ case UPDATE_BUFFER_GEOMETRY:
+ metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(
+ ::android::gralloc4::MetadataType_Crop.value)] = isSet;
+ break;
+ case UPDATE_REFRESH_RATE:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_REFRESH_RATE)] = isSet;
+ break;
+ case UPDATE_COLOR_SPACE:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_COLOR_METADATA)] = isSet;
+ break;
+ case MAP_SECURE_BUFFER:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_MAP_SECURE_BUFFER)] =
+ isSet;
+ break;
+ case LINEAR_FORMAT:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_LINEAR_FORMAT)] = isSet;
+ break;
+ case SET_SINGLE_BUFFER_MODE:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_SINGLE_BUFFER_MODE)] =
+ isSet;
+ break;
+ case SET_CVP_METADATA:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_CVP_METADATA)] = isSet;
+ break;
+ case SET_VIDEO_HISTOGRAM_STATS:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_HISTOGRAM_STATS)] =
+ isSet;
+ break;
+ case SET_VIDEO_TS_INFO:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_VIDEO_TS_INFO)] =
+ isSet;
+ break;
+ case S3D_FORMAT:
+ metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_S3D_FORMAT)] = isSet;
+ break;
+ default:
+ ALOGE("paramType %d not supported in Gralloc4", paramType);
+ }
+}
+#else
+static bool getGralloc4Array(MetaData_t *metadata, int32_t paramType) {
+ return true;
+}
+
+static void setGralloc4Array(MetaData_t *metadata, int32_t paramType, bool isSet) {
+}
+#endif
+
+
+unsigned long getMetaDataSize() {
+ return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
+}
+
+// Cannot add default argument to existing function
+unsigned long getMetaDataSizeWithReservedRegion(uint64_t reserved_size) {
+ return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t) + reserved_size));
+}
+
+static int validateAndMap(private_handle_t* handle) {
+ if (private_handle_t::validate(handle)) {
+ ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
+ return -1;
+ }
+ if (handle->fd_metadata < 0) {
+ // Metadata cannot be used
+ return -1;
+ }
+
+ if (!handle->base_metadata) {
+ auto size = getMetaDataSize();
+ void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ handle->fd_metadata, 0);
+ if (base == reinterpret_cast<void*>(MAP_FAILED)) {
+ ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s",
+ __func__, handle, handle->fd_metadata, strerror(errno));
+ return -1;
+ }
+ handle->base_metadata = (uintptr_t) base;
+ auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+ if (metadata->reservedSize) {
+ auto reserved_size = metadata->reservedSize;
+ munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize());
+ handle->base_metadata = 0;
+ size = getMetaDataSizeWithReservedRegion(reserved_size);
+ void *new_base =
+ mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0);
+ if (new_base == reinterpret_cast<void *>(MAP_FAILED)) {
+ ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle,
+ handle->fd_metadata, strerror(errno));
+ return -1;
+ }
+ handle->base_metadata = (uintptr_t)new_base;
+ }
+ }
+ return 0;
+}
+
+static void unmapAndReset(private_handle_t *handle) {
+ if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
+ // If reservedSize is 0, the return value will be the same as getMetaDataSize
+ auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+ auto size = getMetaDataSizeWithReservedRegion(metadata->reservedSize);
+ munmap(reinterpret_cast<void *>(handle->base_metadata), size);
+ handle->base_metadata = 0;
+ }
+}
+
+int setMetaData(private_handle_t *handle, DispParamType paramType,
+ void *param) {
+ auto err = validateAndMap(handle);
+ if (err != 0)
+ return err;
+ return setMetaDataVa(reinterpret_cast<MetaData_t*>(handle->base_metadata),
+ paramType, param);
+}
+
+int setMetaDataVa(MetaData_t *data, DispParamType paramType,
+ void *param) {
+ if (data == nullptr)
+ return -EINVAL;
+ // If parameter is NULL reset the specific MetaData Key
+ if (!param) {
+ setGralloc4Array(data, paramType, false);
+ switch (paramType) {
+ case SET_VIDEO_PERF_MODE:
+ data->isVideoPerfMode = 0;
+ break;
+ case SET_CVP_METADATA:
+ data->cvpMetadata.size = 0;
+ break;
+ case SET_VIDEO_HISTOGRAM_STATS:
+ data->video_histogram_stats.stat_len = 0;
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ // param unset
+ return 0;
+ }
+
+ setGralloc4Array(data, paramType, true);
+ switch (paramType) {
+ case PP_PARAM_INTERLACED:
+ data->interlaced = *((int32_t *)param);
+ break;
+ case UPDATE_BUFFER_GEOMETRY: {
+ BufferDim_t in = *((BufferDim_t *)param);
+ data->crop = {0, 0, in.sliceWidth, in.sliceHeight};
+ break;
+ }
+ case UPDATE_REFRESH_RATE:
+ data->refreshrate = *((float *)param);
+ break;
+ case UPDATE_COLOR_SPACE: {
+ ColorMetaData color = {};
+ if (!colorSpaceToColorMetadata(*((ColorSpace_t *)param), &color)) {
+ data->color = color;
+ break;
+ }
+ return -EINVAL;
+ }
+ case MAP_SECURE_BUFFER:
+ data->mapSecureBuffer = *((int32_t *)param);
+ break;
+ case S3D_FORMAT:
+ data->s3dFormat = *((uint32_t *)param);
+ break;
+ case LINEAR_FORMAT:
+ data->linearFormat = *((uint32_t *)param);
+ break;
+ case SET_SINGLE_BUFFER_MODE:
+ data->isSingleBufferMode = *((uint32_t *)param);
+ break;
+ case SET_VT_TIMESTAMP:
+ data->vtTimeStamp = *((uint64_t *)param);
+ break;
+ case COLOR_METADATA:
+ data->color = *((ColorMetaData *)param);
+ break;
+ case SET_UBWC_CR_STATS_INFO: {
+ struct UBWCStats *stats = (struct UBWCStats *)param;
+ int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
+ for (int i = 0; i < numelems; i++) {
+ data->ubwcCRStats[i] = stats[i];
+ }
+ break;
+ }
+ case SET_VIDEO_PERF_MODE:
+ data->isVideoPerfMode = *((uint32_t *)param);
+ break;
+ case SET_GRAPHICS_METADATA: {
+ GraphicsMetadata payload = *((GraphicsMetadata*)(param));
+ data->graphics_metadata.size = payload.size;
+ memcpy(data->graphics_metadata.data, payload.data,
+ sizeof(data->graphics_metadata.data));
+ break;
+ }
+ case SET_CVP_METADATA: {
+ struct CVPMetadata *cvpMetadata = (struct CVPMetadata *)param;
+ if (cvpMetadata->size <= CVP_METADATA_SIZE) {
+ data->cvpMetadata.size = cvpMetadata->size;
+ memcpy(data->cvpMetadata.payload, cvpMetadata->payload,
+ cvpMetadata->size);
+ data->cvpMetadata.capture_frame_rate = cvpMetadata->capture_frame_rate;
+ data->cvpMetadata.cvp_frame_rate = cvpMetadata->cvp_frame_rate;
+ data->cvpMetadata.flags = cvpMetadata->flags;
+ memcpy(data->cvpMetadata.reserved, cvpMetadata->reserved,
+ (8 * sizeof(uint32_t)));
+ } else {
+ setGralloc4Array(data, paramType, false);
+ ALOGE("%s: cvp metadata length %d is more than max size %d", __func__,
+ cvpMetadata->size, CVP_METADATA_SIZE);
+ return -EINVAL;
+ }
+ break;
+ }
+ case SET_VIDEO_HISTOGRAM_STATS: {
+ struct VideoHistogramMetadata *vidstats = (struct VideoHistogramMetadata *)param;
+ if (vidstats->stat_len <= VIDEO_HISTOGRAM_STATS_SIZE) {
+ memcpy(data->video_histogram_stats.stats_info,
+ vidstats->stats_info, VIDEO_HISTOGRAM_STATS_SIZE);
+ data->video_histogram_stats.stat_len = vidstats->stat_len;
+ data->video_histogram_stats.frame_type = vidstats->frame_type;
+ data->video_histogram_stats.display_width = vidstats->display_width;
+ data->video_histogram_stats.display_height = vidstats->display_height;
+ data->video_histogram_stats.decode_width = vidstats->decode_width;
+ data->video_histogram_stats.decode_height = vidstats->decode_height;
+ } else {
+ setGralloc4Array(data, paramType, false);
+ ALOGE("%s: video stats length %u is more than max size %u", __func__,
+ vidstats->stat_len, VIDEO_HISTOGRAM_STATS_SIZE);
+ return -EINVAL;
+ }
+ break;
+ }
+ case SET_VIDEO_TS_INFO:
+ data->videoTsInfo = *((VideoTimestampInfo *)param);
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ return 0;
+}
+
+int clearMetaData(private_handle_t *handle, DispParamType paramType) {
+ auto err = validateAndMap(handle);
+ if (err != 0)
+ return err;
+ return clearMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+ paramType);
+}
+
+int clearMetaDataVa(MetaData_t *data, DispParamType paramType) {
+ if (data == nullptr)
+ return -EINVAL;
+ data->operation &= ~paramType;
+ switch (paramType) {
+ case SET_VIDEO_PERF_MODE:
+ data->isVideoPerfMode = 0;
+ break;
+ case SET_CVP_METADATA:
+ data->cvpMetadata.size = 0;
+ break;
+ case SET_VIDEO_HISTOGRAM_STATS:
+ data->video_histogram_stats.stat_len = 0;
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ return 0;
+}
+
+int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
+ void *param) {
+ int ret = validateAndMap(handle);
+ if (ret != 0)
+ return ret;
+ return getMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+ paramType, param);
+}
+
+int getMetaDataVa(MetaData_t *data, DispFetchParamType paramType,
+ void *param) {
+ // Make sure we send 0 only if the operation queried is present
+ int ret = -EINVAL;
+ if (data == nullptr)
+ return ret;
+ if (param == nullptr)
+ return ret;
+
+ if (!getGralloc4Array(data, paramType)) {
+ return ret;
+ }
+
+ ret = 0;
+
+ switch (paramType) {
+ case GET_PP_PARAM_INTERLACED:
+ *((int32_t *)param) = data->interlaced;
+ break;
+ case GET_BUFFER_GEOMETRY:
+ *((BufferDim_t *)param) = {data->crop.right, data->crop.bottom};
+ break;
+ case GET_REFRESH_RATE:
+ *((float *)param) = data->refreshrate;
+ break;
+ case GET_COLOR_SPACE: {
+ ColorSpace_t color_space;
+ if (!colorMetaDataToColorSpace(data->color, &color_space)) {
+ *((ColorSpace_t *)param) = color_space;
+ } else {
+ ret = -EINVAL;
+ }
+ break;
+ }
+ case GET_MAP_SECURE_BUFFER:
+ *((int32_t *)param) = data->mapSecureBuffer;
+ break;
+ case GET_S3D_FORMAT:
+ *((uint32_t *)param) = data->s3dFormat;
+ break;
+ case GET_LINEAR_FORMAT:
+ *((uint32_t *)param) = data->linearFormat;
+ break;
+ case GET_SINGLE_BUFFER_MODE:
+ *((uint32_t *)param) = data->isSingleBufferMode;
+ break;
+ case GET_VT_TIMESTAMP:
+ *((uint64_t *)param) = data->vtTimeStamp;
+ break;
+ case GET_COLOR_METADATA:
+ *((ColorMetaData *)param) = data->color;
+ break;
+ case GET_UBWC_CR_STATS_INFO: {
+ struct UBWCStats *stats = (struct UBWCStats *)param;
+ int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
+ for (int i = 0; i < numelems; i++) {
+ stats[i] = data->ubwcCRStats[i];
+ }
+ break;
+ }
+ case GET_VIDEO_PERF_MODE:
+ *((uint32_t *)param) = data->isVideoPerfMode;
+ break;
+ case GET_GRAPHICS_METADATA:
+ memcpy(param, data->graphics_metadata.data, sizeof(data->graphics_metadata.data));
+ break;
+ case GET_CVP_METADATA: {
+ struct CVPMetadata *cvpMetadata = (struct CVPMetadata *)param;
+ cvpMetadata->size = 0;
+ if (data->cvpMetadata.size <= CVP_METADATA_SIZE) {
+ cvpMetadata->size = data->cvpMetadata.size;
+ memcpy(cvpMetadata->payload, data->cvpMetadata.payload, data->cvpMetadata.size);
+ cvpMetadata->capture_frame_rate = data->cvpMetadata.capture_frame_rate;
+ cvpMetadata->cvp_frame_rate = data->cvpMetadata.cvp_frame_rate;
+ cvpMetadata->flags = data->cvpMetadata.flags;
+ memcpy(cvpMetadata->reserved, data->cvpMetadata.reserved, (8 * sizeof(uint32_t)));
+ } else {
+ ret = -EINVAL;
+ }
+ break;
+ }
+ case GET_VIDEO_HISTOGRAM_STATS: {
+ struct VideoHistogramMetadata *vidstats = (struct VideoHistogramMetadata *)param;
+ vidstats->stat_len = 0;
+ if (data->video_histogram_stats.stat_len <= VIDEO_HISTOGRAM_STATS_SIZE) {
+ memcpy(vidstats->stats_info, data->video_histogram_stats.stats_info,
+ VIDEO_HISTOGRAM_STATS_SIZE);
+ vidstats->stat_len = data->video_histogram_stats.stat_len;
+ vidstats->frame_type = data->video_histogram_stats.frame_type;
+ vidstats->display_width = data->video_histogram_stats.display_width;
+ vidstats->display_height = data->video_histogram_stats.display_height;
+ vidstats->decode_width = data->video_histogram_stats.decode_width;
+ vidstats->decode_height = data->video_histogram_stats.decode_height;
+ } else {
+ ret = -EINVAL;
+ }
+ break;
+ }
+ case GET_VIDEO_TS_INFO:
+ *((VideoTimestampInfo *)param) = data->videoTsInfo;
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst) {
+ auto err = validateAndMap(src);
+ if (err != 0)
+ return err;
+
+ err = validateAndMap(dst);
+ if (err != 0)
+ return err;
+
+ MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
+ MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataVaToHandle(MetaData_t *src_data, struct private_handle_t *dst) {
+ int err = -EINVAL;
+ if (src_data == nullptr)
+ return err;
+
+ err = validateAndMap(dst);
+ if (err != 0)
+ return err;
+
+ MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataHandleToVa(struct private_handle_t *src, MetaData_t *dst_data) {
+ int err = -EINVAL;
+ if (dst_data == nullptr)
+ return err;
+
+ err = validateAndMap(src);
+ if (err != 0)
+ return err;
+
+ MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
+ *dst_data = *src_data;
+ return 0;
+}
+
+int copyMetaDataVaToVa(MetaData_t *src_data, MetaData_t *dst_data) {
+ int err = -EINVAL;
+ if (src_data == nullptr)
+ return err;
+
+ if (dst_data == nullptr)
+ return err;
+
+ *dst_data = *src_data;
+ return 0;
+}
+
+int setMetaDataAndUnmap(struct private_handle_t *handle, enum DispParamType paramType,
+ void *param) {
+ auto ret = setMetaData(handle, paramType, param);
+ unmapAndReset(handle);
+ return ret;
+}
+
+int getMetaDataAndUnmap(struct private_handle_t *handle,
+ enum DispFetchParamType paramType,
+ void *param) {
+ auto ret = getMetaData(handle, paramType, param);
+ unmapAndReset(handle);
+ return ret;
+}