diff options
Diffstat (limited to 'libqdmetadata')
-rw-r--r-- | libqdmetadata/Android.bp | 21 | ||||
-rw-r--r-- | libqdmetadata/Makefile.am | 16 | ||||
-rw-r--r-- | libqdmetadata/qdMetaData.cpp | 642 | ||||
-rw-r--r-- | libqdmetadata/qd_utils.cpp | 279 |
4 files changed, 958 insertions, 0 deletions
diff --git a/libqdmetadata/Android.bp b/libqdmetadata/Android.bp new file mode 100644 index 00000000..235fe653 --- /dev/null +++ b/libqdmetadata/Android.bp @@ -0,0 +1,21 @@ +cc_library_shared { + name: "libqdMetaData", + vendor: true, + cflags: [ + "-Wno-sign-conversion", + "-DLOG_TAG=\"qdmetadata\"", + "-D__QTI_DISPLAY_GRALLOC__", + ], + shared_libs: [ + "liblog", + "libcutils", + "libutils", + "libhidlbase", + "libgralloc.qti", + "libgralloctypes", + ], + header_libs: ["libhardware_headers", "display_intf_headers"], + srcs: ["qdMetaData.cpp", "qd_utils.cpp"], + export_header_lib_headers: ["display_intf_headers"], +} + diff --git a/libqdmetadata/Makefile.am b/libqdmetadata/Makefile.am new file mode 100644 index 00000000..1fa7e644 --- /dev/null +++ b/libqdmetadata/Makefile.am @@ -0,0 +1,16 @@ +h_sources = qdMetaData.h + +cpp_sources = qdMetaData.cpp + +AM_CPPFLAGS += -D__QTI_NO_GRALLOC4__ + +qdMetaData_includedir = $(pkgincludedir)/display +qdMetaData_include_HEADERS = $(h_sources) + +lib_LTLIBRARIES = libqdMetaData.la +libqdMetaData_la_CC = @CC@ +libqdMetaData_la_SOURCES = $(cpp_sources) +libqdMetaData_la_CFLAGS = $(AM_CFLAGS) -DLOG_TAG=\"DisplayMetaData\" +libqdMetaData_la_CPPFLAGS = $(AM_CPPFLAGS) +libqdMetaData_LDADD = -lcutils -llog +libqdMetaData_la_LDFLAGS = -shared -avoid-version
\ No newline at end of file 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; +} diff --git a/libqdmetadata/qd_utils.cpp b/libqdmetadata/qd_utils.cpp new file mode 100644 index 00000000..ac5d094b --- /dev/null +++ b/libqdmetadata/qd_utils.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2013, 2018, 2020 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 <unistd.h> +#include <gralloc_priv.h> +#include "qd_utils.h" + +static const int kFBNodeMax = 4; +namespace qdutils { + +static int parseLine(char *input, char *tokens[], const uint32_t maxToken, uint32_t *count) { + char *tmpToken = NULL; + char *tmpPtr; + uint32_t index = 0; + const char *delim = ", =\n"; + if (!input) { + return -1; + } + tmpToken = strtok_r(input, delim, &tmpPtr); + while (tmpToken && index < maxToken) { + tokens[index++] = tmpToken; + tmpToken = strtok_r(NULL, delim, &tmpPtr); + } + *count = index; + + return 0; +} + +static int getExternalNode(const char *type) { + FILE *displayDeviceFP = NULL; + char fbType[MAX_FRAME_BUFFER_NAME_SIZE]; + char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE]; + int j = 0; + + for(j = 0; j < kFBNodeMax; j++) { + snprintf (msmFbTypePath, sizeof(msmFbTypePath), + "/sys/devices/virtual/graphics/fb%d/msm_fb_type", j); + displayDeviceFP = fopen(msmFbTypePath, "r"); + if(displayDeviceFP) { + fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE, + displayDeviceFP); + if(strncmp(fbType, type, strlen(type)) == 0) { + ALOGD("%s: %s is at fb%d", __func__, type, j); + fclose(displayDeviceFP); + break; + } + fclose(displayDeviceFP); + } else { + ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath); + } + } + + if (j < kFBNodeMax) + return j; + else + ALOGE("%s: Failed to find %s node", __func__, type); + + return -1; +} + +int getHDMINode(void) { + return getExternalNode("dtv panel"); +} + +int getEdidRawData(char *buffer) +{ + int size; + int edidFile; + char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE]; + int node_id = getHDMINode(); + + if (node_id < 0) { + ALOGE("%s no HDMI node found", __func__); + return 0; + } + + snprintf(msmFbTypePath, sizeof(msmFbTypePath), + "/sys/devices/virtual/graphics/fb%d/edid_raw_data", node_id); + + edidFile = open(msmFbTypePath, O_RDONLY, 0); + + if (edidFile < 0) { + ALOGE("%s no edid raw data found %s", __func__,msmFbTypePath); + return 0; + } + + size = (int)read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE); + close(edidFile); + return size; +} + +bool isDPConnected() { + char connectPath[MAX_FRAME_BUFFER_NAME_SIZE]; + FILE *connectFile = NULL; + size_t len = MAX_STRING_LENGTH; + char stringBuffer[MAX_STRING_LENGTH]; + char *line = stringBuffer; + + int nodeId = getExternalNode("dp panel"); + if (nodeId < 0) { + ALOGE("%s no DP node found", __func__); + return false; + } + + snprintf(connectPath, sizeof(connectPath), + "/sys/devices/virtual/graphics/fb%d/connected", nodeId); + + connectFile = fopen(connectPath, "rb"); + if (!connectFile) { + ALOGW("Failed to open connect node for device node %s", connectPath); + return false; + } + + if (getline(&line, &len, connectFile) < 0) { + fclose(connectFile); + return false; + } + + fclose(connectFile); + + return atoi(line); +} + +int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) { + if (!panelBpp || !patternType) { + return -1; + } + + char configPath[MAX_FRAME_BUFFER_NAME_SIZE]; + FILE *configFile = NULL; + uint32_t tokenCount = 0; + const uint32_t maxCount = 10; + char *tokens[maxCount] = { NULL }; + size_t len = MAX_STRING_LENGTH; + char stringBuffer[MAX_STRING_LENGTH]; + char *line = stringBuffer; + + int nodeId = getExternalNode("dp panel"); + if (nodeId < 0) { + ALOGE("%s no DP node found", __func__); + return -EINVAL; + } + + snprintf(configPath, sizeof(configPath), + "/sys/devices/virtual/graphics/fb%d/config", nodeId); + + configFile = fopen(configPath, "rb"); + if (!configFile) { + ALOGW("Failed to open config node for device node %s", configPath); + return -EINVAL; + } + + while (getline(&line, &len, configFile) != -1) { + if (!parseLine(line, tokens, maxCount, &tokenCount)) { + if (tokens[0] != NULL) { + if (!strncmp(tokens[0], "bpp", strlen("bpp"))) { + *panelBpp = static_cast<uint32_t>(atoi(tokens[1])); + } else if (!strncmp(tokens[0], "pattern", strlen("pattern"))) { + *patternType = static_cast<uint32_t>(atoi(tokens[1])); + } + } + } + } + + fclose(configFile); + + return 0; +} + +DriverType getDriverType() { + const char *fb_caps = "/sys/devices/virtual/graphics/fb0/mdp/caps"; + // 0 - File exists + return access(fb_caps, F_OK) ? DriverType::DRM : DriverType::FB; +} + +const char *GetHALPixelFormatString(int format) { + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + return "RGBA_8888"; + case HAL_PIXEL_FORMAT_RGBX_8888: + return "RGBX_8888"; + case HAL_PIXEL_FORMAT_RGB_888: + return "RGB_888"; + case HAL_PIXEL_FORMAT_RGB_565: + return "RGB_565"; + case HAL_PIXEL_FORMAT_BGR_565: + return "BGR_565"; + case HAL_PIXEL_FORMAT_BGRA_8888: + return "BGRA_8888"; + case HAL_PIXEL_FORMAT_RGBA_5551: + return "RGBA_5551"; + case HAL_PIXEL_FORMAT_RGBA_4444: + return "RGBA_4444"; + case HAL_PIXEL_FORMAT_YV12: + return "YV12"; + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + return "YCbCr_422_SP_NV16"; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + return "YCrCb_420_SP_NV21"; + case HAL_PIXEL_FORMAT_YCbCr_422_I: + return "YCbCr_422_I_YUY2"; + case HAL_PIXEL_FORMAT_YCrCb_422_I: + return "YCrCb_422_I_YVYU"; + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + return "NV12_ENCODEABLE"; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: + return "YCbCr_420_SP_TILED_TILE_4x2"; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + return "YCbCr_420_SP"; + case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: + return "YCrCb_420_SP_ADRENO"; + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + return "YCrCb_422_SP"; + case HAL_PIXEL_FORMAT_R_8: + return "R_8"; + case HAL_PIXEL_FORMAT_RG_88: + return "RG_88"; + case HAL_PIXEL_FORMAT_INTERLACE: + return "INTERLACE"; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + return "YCbCr_420_SP_VENUS"; + case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: + return "YCrCb_420_SP_VENUS"; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + return "YCbCr_420_SP_VENUS_UBWC"; + case HAL_PIXEL_FORMAT_RGBA_1010102: + return "RGBA_1010102"; + case HAL_PIXEL_FORMAT_ARGB_2101010: + return "ARGB_2101010"; + case HAL_PIXEL_FORMAT_RGBX_1010102: + return "RGBX_1010102"; + case HAL_PIXEL_FORMAT_XRGB_2101010: + return "XRGB_2101010"; + case HAL_PIXEL_FORMAT_BGRA_1010102: + return "BGRA_1010102"; + case HAL_PIXEL_FORMAT_ABGR_2101010: + return "ABGR_2101010"; + case HAL_PIXEL_FORMAT_BGRX_1010102: + return "BGRX_1010102"; + case HAL_PIXEL_FORMAT_XBGR_2101010: + return "XBGR_2101010"; + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + return "YCbCr_420_P010"; + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + return "YCbCr_420_TP10_UBWC"; + case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS: + return "YCbCr_420_P010_VENUS"; + default: + return "Unknown_format"; + } +} + +}; //namespace qdutils |