/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved. * Description : hddec * Author : sdk * Create : 2019/11/21 */ #include #include #include #include #include #include #include "soc_log.h" #include "mpi_hddec_ext.h" #include "drv_ioctl_hddec.h" #include "mpi_stat_ext.h" static td_s32 g_hddec_dev_fd = -1; static pthread_mutex_t g_hddec_mutex = PTHREAD_MUTEX_INITIALIZER; #define ext_hddec_lock() (td_void)pthread_mutex_lock(&g_hddec_mutex) #define ext_hddec_unlock() (td_void)pthread_mutex_unlock(&g_hddec_mutex) #define check_hddec_init(ret) \ do { \ ext_hddec_lock(); \ if (g_hddec_dev_fd < 0) { \ soc_log_err("please init firstly.\n"); \ (ret) = TD_FAILURE; \ } \ ext_hddec_unlock(); \ } while (0) /* HDDEC初始化 */ td_s32 ext_mpi_hddec_init(td_void) { struct stat stat_info; ext_hddec_lock(); /* already opened in the process */ if (g_hddec_dev_fd > 0) { ext_hddec_unlock(); return TD_SUCCESS; } g_hddec_dev_fd = open("/dev/soc_hddec", O_RDWR | O_NONBLOCK, 0); if (g_hddec_dev_fd < 0) { soc_log_err("open HDDEC err.\n"); ext_hddec_unlock(); return TD_FAILURE; } if (stat("/dev/soc_hddec", &stat_info) != 0) { soc_log_err("HDDEC is not exist.\n"); close(g_hddec_dev_fd); g_hddec_dev_fd = -1; ext_hddec_unlock(); return TD_FAILURE; } if (!S_ISCHR(stat_info.st_mode)) { soc_log_err("HDDEC is not device.\n"); close(g_hddec_dev_fd); g_hddec_dev_fd = -1; ext_hddec_unlock(); return TD_FAILURE; } ext_hddec_unlock(); return TD_SUCCESS; } /* HDDEC去初始化 */ td_s32 ext_mpi_hddec_de_init(td_void) { ext_hddec_lock(); if (g_hddec_dev_fd < 0) { ext_hddec_unlock(); return TD_SUCCESS; } close(g_hddec_dev_fd); g_hddec_dev_fd = -1; ext_hddec_unlock(); return TD_SUCCESS; } /* 信源连接 */ td_s32 ext_mpi_hddec_connect(const ext_drv_hddec_src_attr *src_attr) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } ext_mpi_stat_event(EXT_STAT_EVENT_CONNECT, 1); ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_CONNECT, src_attr); return ret; } /* 断开连接 */ td_s32 ext_mpi_hddec_dis_connect(td_void) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_DISCONNECT); return ret; } /* 获取离线信源的信号是否存在,阻塞接口 */ td_s32 ext_mpi_hddec_get_offline_status(const ext_drv_hddec_src_attr *src_att, td_bool *exist) { td_s32 ret = TD_SUCCESS; ext_drv_hddec_offline_param offline_param; if (src_att == NULL) { soc_log_err("offline is NULL pointer!\n"); return TD_FAILURE; } if (exist == NULL) { soc_log_err("exist_sig is NULL pointer!\n"); return TD_FAILURE; } *exist = TD_FALSE; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } offline_param.src_attr.src_type = src_att->src_type; offline_param.src_attr.index = src_att->index; ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_OFFLINE_SIG, &offline_param); if (ret != TD_SUCCESS) { soc_log_err("get offline param failed\n"); *exist = TD_FALSE; return ret; } *exist = offline_param.exist; return TD_SUCCESS; } /* 检测当前的decode状态 */ td_s32 ext_mpi_hddec_get_signal_status(ext_drv_hddec_signal_status *sig_status) { td_s32 ret = TD_SUCCESS; if (sig_status == NULL) { soc_log_err("sig_status is NULL pointer.\n"); return TD_FAILURE; } *sig_status = EXT_DRV_HDDEC_SIG_NO_SIGNAL; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } /* if mpi status change from not support to support, check whether send mpi event */ ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_SIGNAL_STATUS, sig_status); return ret; } /* 检测当前的decode_timing信息 */ td_s32 ext_mpi_hddec_get_timing_info(ext_drv_hddec_timing_info *timing_info) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (timing_info == TD_NULL) { soc_log_err("NULL ptr.\n"); return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_TIMING_INFO, timing_info); return ret; } /* 检测当前的decode非标信息 */ td_s32 ext_mpi_hddec_get_non_std_info(ext_drv_hddec_nonstd_info *non_std_info) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (non_std_info == TD_NULL) { soc_log_err("NULL ptr.\n"); return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_NONSTD_INFO, non_std_info); return ret; } /* 启动自动颜色校正 */ td_s32 ext_mpi_hddec_start_calibrate_color(td_void) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_START_CALIB); return ret; } /* 获取自动颜色校正状态 */ td_s32 ext_mpi_hddec_get_calibration_status(ext_drv_hddec_color_calib_status *calib_status) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (calib_status == TD_NULL) { soc_log_err("NULL ptr.\n"); return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_CALIB_INFO, calib_status); return ret; } /* 获取手动设置自动颜色校正参数 */ td_s32 ext_mpi_hddec_get_calibration_param(ext_drv_hddec_color_calib_param *calib_param) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (calib_param == TD_NULL) { soc_log_err("NULL ptr.\n"); return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_CALIB_PARAM, calib_param); return ret; } /* 手动设置自动颜色校正 */ td_s32 ext_mpi_hddec_set_calibration_param(const ext_drv_hddec_color_calib_param *calib_param) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (calib_param == TD_NULL) { soc_log_err("NULL ptr.\n"); return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_S_CALIB_PARAM, calib_param); return ret; } /* 启动VGA图像自动调整 */ td_s32 ext_mpi_hddec_start_adjust_image_param(td_void) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_START_ADJUST); return ret; } /* 获取VGA图像自动调整状态 */ td_s32 ext_mpi_hddec_get_adjust_status(ext_drv_hddec_adjust_status *adjust_status) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (adjust_status == TD_NULL) { soc_log_err("NULL ptr.\n"); return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_ADJUST_INFO, adjust_status); return ret; } /* 获取手动调整可调范围 */ td_s32 ext_mpi_hddec_get_adjust_range(ext_drv_hddec_adjust_type adjust_type, ext_range *range) { td_s32 ret = TD_SUCCESS; ext_drv_hddec_adjust_range adjust_range; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (range == NULL) { soc_log_err("range is NULL pointer!\n"); return TD_FAILURE; } adjust_range.type = adjust_type; ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_ADJUST_RANGE, &adjust_range); if (ret != TD_SUCCESS) { soc_log_err("get adjust range failed.\n"); return ret; } range->min = adjust_range.range.min; range->max = adjust_range.range.max; return TD_SUCCESS; } /* 获取调整的参数 */ td_s32 ext_mpi_hddec_get_adjust_param(ext_drv_hddec_adjust_type adjust_type, td_u32 *param) { td_s32 ret = TD_SUCCESS; ext_drv_hddec_adjust_param adjust_param; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (param == NULL) { soc_log_err("param is NULL pointer!\n"); return TD_FAILURE; } adjust_param.type = adjust_type; ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_ADJUST_PARAM, &adjust_param); if (ret != TD_SUCCESS) { soc_log_err("get adjust param failed.\n"); return ret; } *param = adjust_param.param; return TD_SUCCESS; } /* 设置手动调整参数 */ td_s32 ext_mpi_hddec_set_adjust_param(ext_drv_hddec_adjust_type adjust_type, td_u32 param) { td_s32 ret = TD_SUCCESS; ext_drv_hddec_adjust_param adjust_param; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (adjust_type >= EXT_DRV_HDDEC_ADJUST_TYPE_MAX) { soc_log_err("adjust is invalid.\n"); return TD_FAILURE; } adjust_param.type = adjust_type; adjust_param.param = param; ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_S_ADJUST_PARAM, &adjust_param); return ret; } /* 更新edid */ td_s32 ext_mpi_hddec_update_edid(const ext_drv_hddec_edid *edid) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_U_EDID, edid); return ret; } /* 获取能力信息 */ td_s32 ext_mpi_hddec_get_capability(ext_drv_hddec_capability *capability) { td_s32 ret = TD_SUCCESS; check_hddec_init(ret); if (ret == TD_FAILURE) { return TD_FAILURE; } if (capability == TD_NULL) { soc_log_err("NULL ptr.\n"); return TD_FAILURE; } ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_CAPABILITY, capability); return ret; }