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.
441 lines
10 KiB
441 lines
10 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
|
|
* Description : hddec
|
|
* Author : sdk
|
|
* Create : 2019/11/21
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/ioctl.h>
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
|
|
#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;
|
|
}
|