/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved. * Description : iapi hddec * Author : sdk * Create : 2019/11/21 */ #include #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; }