You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
435 lines
12 KiB
435 lines
12 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
|
|
* Description : iapi hddec
|
|
* Author : sdk
|
|
* Create : 2019/11/21
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include "soc_log.h"
|
|
#include "uapi_hddec.h"
|
|
#include "mpi_hddec_ext.h"
|
|
#include "securec.h"
|
|
|
|
static ext_hddec_video_format_convert g_hddec_vid_format[] = {
|
|
{ UAPI_FORMAT_YUV_SEMIPLANAR_422_VU, EXT_DRV_PIXEL_FMT_NV61_2X1 },
|
|
{ UAPI_FORMAT_YUV_SEMIPLANAR_420_VU, EXT_DRV_PIXEL_FMT_NV21 },
|
|
{ UAPI_FORMAT_YUV_SEMIPLANAR_400, EXT_DRV_PIXEL_FMT_NV80 },
|
|
{ UAPI_FORMAT_YUV_SEMIPLANAR_411_VU, EXT_DRV_PIXEL_FMT_NV12_411 },
|
|
{ UAPI_FORMAT_YUV_SEMIPLANAR_422_UV, EXT_DRV_PIXEL_FMT_NV61 },
|
|
{ UAPI_FORMAT_YUV_SEMIPLANAR_444_VU, EXT_DRV_PIXEL_FMT_NV42 },
|
|
{ UAPI_FORMAT_YUV_PACKAGE_UYVY, EXT_DRV_PIXEL_FMT_UYVY },
|
|
{ UAPI_FORMAT_YUV_PACKAGE_YUYV, EXT_DRV_PIXEL_FMT_YUYV },
|
|
{ UAPI_FORMAT_YUV_SEMIPLANAR_420_UV, EXT_DRV_PIXEL_FMT_NV12 },
|
|
{ UAPI_FORMAT_YUV_PLANAR_400, EXT_DRV_PIXEL_FMT_YUV400 },
|
|
{ UAPI_FORMAT_YUV_SEMIPLANAR_400, EXT_DRV_PIXEL_FMT_NV80 },
|
|
{ UAPI_FORMAT_YUV_PLANAR_411_VU, EXT_DRV_PIXEL_FMT_YUV411 },
|
|
{ UAPI_FORMAT_YUV_PLANAR_420_VU, EXT_DRV_PIXEL_FMT_YUV420P },
|
|
{ UAPI_FORMAT_YUV_PLANAR_422_UV, EXT_DRV_PIXEL_FMT_YUV422_1X2 },
|
|
{ UAPI_FORMAT_YUV_PLANAR_422_VU, EXT_DRV_PIXEL_FMT_YUV422_2X1 },
|
|
{ UAPI_FORMAT_YUV_PLANAR_444_UV, EXT_DRV_PIXEL_FMT_YUV_444 },
|
|
{ UAPI_FORMAT_YUV_PLANAR_410_VU, EXT_DRV_PIXEL_FMT_YUV410P },
|
|
{ UAPI_FORMAT_RGB888, EXT_DRV_PIXEL_FMT_RGB24 },
|
|
{ UAPI_FORMAT_ARGB8888, EXT_DRV_PIXEL_FMT_ARGB8888 },
|
|
{ UAPI_FORMAT_YUV_TILE_420_VU, EXT_DRV_PIXEL_FMT_NV21 },
|
|
{ UAPI_FORMAT_YUV_TILE_420_UV, EXT_DRV_PIXEL_FMT_NV12 },
|
|
{ UAPI_FORMAT_RGB_SEMIPLANAR_444, EXT_DRV_PIXEL_FMT_NV42_RGB },
|
|
};
|
|
|
|
/* HDDEC初始化 */
|
|
td_s32 uapi_hddec_init(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = ext_mpi_hddec_init();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* HDDEC去初始化 */
|
|
td_s32 uapi_hddec_deinit(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = ext_mpi_hddec_de_init();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 信源连接 */
|
|
td_s32 uapi_hddec_connect(const uapi_hddec_src_attr *src_attr)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_src_attr source_att;
|
|
|
|
if (src_attr == NULL) {
|
|
soc_log_err("src_attr is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (src_attr->src_type != UAPI_VIDEO_SOURCE_VGA &&
|
|
src_attr->src_type != UAPI_VIDEO_SOURCE_YPBPR &&
|
|
src_attr->src_type != UAPI_VIDEO_SOURCE_SCART) {
|
|
soc_log_err("src_type is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
source_att.index = src_attr->index;
|
|
switch (src_attr->src_type) {
|
|
case UAPI_VIDEO_SOURCE_VGA: {
|
|
source_att.src_type = EXT_DRV_HDDEC_SRC_VGA;
|
|
break;
|
|
}
|
|
case UAPI_VIDEO_SOURCE_YPBPR: {
|
|
source_att.src_type = EXT_DRV_HDDEC_SRC_YPBPR;
|
|
break;
|
|
}
|
|
case UAPI_VIDEO_SOURCE_SCART: {
|
|
source_att.src_type = EXT_DRV_HDDEC_SRC_SCART;
|
|
break;
|
|
}
|
|
default: {
|
|
soc_log_err("src_type is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
ret = ext_mpi_hddec_connect(&source_att);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 断开连接 */
|
|
td_s32 uapi_hddec_disconnect(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = ext_mpi_hddec_dis_connect();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 获取离线信源的信号是否存在,阻塞接口 */
|
|
td_s32 uapi_hddec_get_offline_status(const uapi_hddec_src_attr *src_attr, td_bool *exist)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_src_attr source_att;
|
|
|
|
if (src_attr == NULL || exist == NULL) {
|
|
soc_log_err("NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (src_attr->src_type != UAPI_VIDEO_SOURCE_VGA &&
|
|
src_attr->src_type != UAPI_VIDEO_SOURCE_YPBPR &&
|
|
src_attr->src_type != UAPI_VIDEO_SOURCE_SCART) {
|
|
soc_log_err("src_type is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
source_att.index = src_attr->index;
|
|
switch (src_attr->src_type) {
|
|
case UAPI_VIDEO_SOURCE_VGA: {
|
|
source_att.src_type = EXT_DRV_HDDEC_SRC_VGA;
|
|
break;
|
|
}
|
|
case UAPI_VIDEO_SOURCE_YPBPR: {
|
|
source_att.src_type = EXT_DRV_HDDEC_SRC_YPBPR;
|
|
break;
|
|
}
|
|
case UAPI_VIDEO_SOURCE_SCART: {
|
|
source_att.src_type = EXT_DRV_HDDEC_SRC_SCART;
|
|
break;
|
|
}
|
|
default: {
|
|
soc_log_err("src_type is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
ret = ext_mpi_hddec_get_offline_status(&source_att, exist);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 检测当前decode状态 */
|
|
td_s32 uapi_hddec_get_signal_status(uapi_sig_status *sig_status)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_signal_status signal_state;
|
|
|
|
if (sig_status == NULL) {
|
|
soc_log_err("sig_status is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_mpi_hddec_get_signal_status(&signal_state);
|
|
*sig_status = (uapi_sig_status)signal_state;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 检测当前的decodeTiming信息 */
|
|
td_s32 uapi_hddec_get_timing_info(uapi_hddec_timing_info *timing_info)
|
|
{
|
|
td_s32 ret;
|
|
size_t max_index;
|
|
td_u32 index;
|
|
ext_drv_hddec_timing_info timing;
|
|
|
|
if (timing_info == NULL) {
|
|
soc_log_err("timing_info is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_mpi_hddec_get_timing_info(&timing);
|
|
timing_info->interlace = timing.interlace;
|
|
timing_info->frame_rate = timing.frame_rate;
|
|
timing_info->oversample = (uapi_oversample)timing.oversample;
|
|
timing_info->bit_depth = (uapi_pixel_bit_depth)timing.bit_width;
|
|
timing_info->timing_index = timing.timing_index;
|
|
timing_info->width = timing.width;
|
|
timing_info->height = timing.height;
|
|
|
|
timing_info->color_space.color_primary = (uapi_color_primary)timing.color_space.color_primary;
|
|
timing_info->color_space.color_space = (uapi_color_space)timing.color_space.color_space;
|
|
timing_info->color_space.quantify_range = (uapi_color_quantify_range)timing.color_space.quantify_range;
|
|
timing_info->color_space.matrix_coef = (uapi_color_matrix_coeffs)timing.color_space.matrix_coef;
|
|
timing_info->color_space.transfer_type = (uapi_color_transfer_curve)timing.color_space.transfer_type;
|
|
|
|
max_index = sizeof(g_hddec_vid_format) / sizeof(g_hddec_vid_format[0]);
|
|
for (index = 0; index < max_index; index++) {
|
|
if (timing.pix_fmt == g_hddec_vid_format[index].drv_video_format) {
|
|
timing_info->pix_fmt = (uapi_video_pixel_format)g_hddec_vid_format[index].iapi_video_format;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 检测当前的decode非标信息 */
|
|
td_s32 uapi_hddec_get_nonstd_info(uapi_video_nonstd_info *nonstd_info)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_nonstd_info nonstd;
|
|
|
|
if (nonstd_info == NULL) {
|
|
soc_log_err("nonstd_info is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_mpi_hddec_get_non_std_info(&nonstd);
|
|
nonstd_info->is_non_std = nonstd.non_std;
|
|
nonstd_info->v_freq = nonstd.v_freq;
|
|
nonstd_info->height = nonstd.height;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 启动自动颜色校正 */
|
|
td_s32 uapi_hddec_calibrate_color(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = ext_mpi_hddec_start_calibrate_color();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 获取自动颜色校正状态 */
|
|
td_s32 uapi_hddec_get_calibration_status(uapi_hddec_color_calib_status *calib_status)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_color_calib_status calib_state;
|
|
|
|
if (calib_status == NULL) {
|
|
soc_log_err("calib_status is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_mpi_hddec_get_calibration_status(&calib_state);
|
|
*calib_status = (uapi_hddec_color_calib_status)calib_state;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 获取手动设置自动颜色校正参数 */
|
|
td_s32 uapi_hddec_get_calibration_param(uapi_hddec_color_calib_param *calib_param)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_color_calib_param calibration_param;
|
|
|
|
if (calib_param == NULL) {
|
|
soc_log_err("calib_param is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_mpi_hddec_get_calibration_param(&calibration_param);
|
|
calib_param->r_gain = calibration_param.r_gain;
|
|
calib_param->g_gain = calibration_param.g_gain;
|
|
calib_param->b_gain = calibration_param.b_gain;
|
|
calib_param->r_offset = calibration_param.r_offset;
|
|
calib_param->g_offset = calibration_param.g_offset;
|
|
calib_param->b_offset = calibration_param.b_offset;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 手动设置自动颜色校正 */
|
|
td_s32 uapi_hddec_set_calibration_param(const uapi_hddec_color_calib_param *calib_param)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_color_calib_param calibration_param;
|
|
|
|
if (calib_param == NULL) {
|
|
soc_log_err("calib_param is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
calibration_param.r_gain = calib_param->r_gain;
|
|
calibration_param.g_gain = calib_param->g_gain;
|
|
calibration_param.b_gain = calib_param->b_gain;
|
|
calibration_param.r_offset = calib_param->r_offset;
|
|
calibration_param.g_offset = calib_param->g_offset;
|
|
calibration_param.b_offset = calib_param->b_offset;
|
|
ret = ext_mpi_hddec_set_calibration_param(&calibration_param);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 启动VGA图像自动调整 */
|
|
td_s32 uapi_hddec_adjust_image_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = ext_mpi_hddec_start_adjust_image_param();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 获取VGA图像自动调整状态 */
|
|
td_s32 uapi_hddec_get_adjust_status(uapi_hddec_adjust_status *adjust_status)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_adjust_status adjust_state;
|
|
|
|
if (adjust_status == NULL) {
|
|
soc_log_err("adjust_status is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_mpi_hddec_get_adjust_status(&adjust_state);
|
|
*adjust_status = (uapi_hddec_adjust_status)adjust_state;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 获取手动调整可调范围 */
|
|
td_s32 uapi_hddec_get_adjust_range(uapi_hddec_adjust_type adjust_type, uapi_sys_range *range)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_adjust_type adjust;
|
|
ext_range range_info;
|
|
|
|
if (adjust_type >= UAPI_HDDEC_ADJUST_TYPE_MAX ||
|
|
adjust_type < UAPI_HDDEC_ADJUST_TYPE_HPOS) {
|
|
soc_log_err("adjust type is invalid.\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (range == NULL) {
|
|
soc_log_err("range is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
adjust = (ext_drv_hddec_adjust_type)adjust_type;
|
|
ret = ext_mpi_hddec_get_adjust_range(adjust, &range_info);
|
|
range->min = range_info.min;
|
|
range->max = range_info.max;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 获取调整参数 */
|
|
td_s32 uapi_hddec_get_adjust_param(uapi_hddec_adjust_type adjust_type, td_u32 *param)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_adjust_type adjust;
|
|
|
|
if (adjust_type >= UAPI_HDDEC_ADJUST_TYPE_MAX ||
|
|
adjust_type < UAPI_HDDEC_ADJUST_TYPE_HPOS) {
|
|
soc_log_err("adjust type is invalid.\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (param == NULL) {
|
|
soc_log_err("param is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
adjust = (ext_drv_hddec_adjust_type)adjust_type;
|
|
ret = ext_mpi_hddec_get_adjust_param(adjust, param);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 设置手动调整参数 */
|
|
td_s32 uapi_hddec_set_adjust_param(uapi_hddec_adjust_type adjust_type, td_u32 param)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_adjust_type adjust;
|
|
|
|
if (adjust_type >= UAPI_HDDEC_ADJUST_TYPE_MAX ||
|
|
adjust_type < UAPI_HDDEC_ADJUST_TYPE_HPOS) {
|
|
soc_log_err("adjust type is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
adjust = (ext_drv_hddec_adjust_type)adjust_type;
|
|
ret = ext_mpi_hddec_set_adjust_param(adjust, param);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 更新edid */
|
|
td_s32 uapi_hddec_update_edid(const uapi_hddec_edid *edid)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_edid edid_info;
|
|
|
|
if (edid == NULL) {
|
|
soc_log_err("edid is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
errno_t err_ret = memcpy_s(edid_info.edid_data, sizeof(edid_info.edid_data),
|
|
edid, UAPI_HDDEC_EDID_SIZE * sizeof(td_u8));
|
|
if (err_ret != EOK) {
|
|
soc_log_err("secure func call error\n");
|
|
return err_ret;
|
|
}
|
|
ret = ext_mpi_hddec_update_edid(&edid_info);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* 获取hddec能力 */
|
|
td_s32 uapi_hddec_get_capability(uapi_hddec_capability *capability)
|
|
{
|
|
td_s32 ret;
|
|
ext_drv_hddec_capability cap;
|
|
|
|
if (capability == NULL) {
|
|
soc_log_err("capability is NULL pointer!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_mpi_hddec_get_capability(&cap);
|
|
capability->vga_max = cap.vga_max;
|
|
capability->ypbpr_max = cap.ypbpr_max;
|
|
capability->scart_max = cap.scart_max;
|
|
|
|
return ret;
|
|
}
|
|
|