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.

1630 lines
52 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
* Description: function define
* Author: Hisilicon
* Create: 2019-04-12
*/
#include <unistd.h>
#include "uapi_win.h"
#include "mpi_win_ext.h"
#include "mpi_disp_ext.h"
#include "mpi_disp_tran.h"
#include "soc_errno.h"
#include "securec.h"
#define check_vo_ptr(pointer) \
do { \
if ((pointer) == TD_NULL) { \
ext_err_win("para is null.\n"); \
return SOC_ERR_VO_NULL_PTR; \
} \
} while (0)
#define vo_win_func_enter() soc_info_func_enter()
#define vo_win_func_exit() soc_info_func_exit()
td_s32 uapi_win_init(td_void)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_init();
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_deinit(td_void)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_deinit();
vo_win_func_exit();
return ret;
}
static td_s32 iapi_win_enum_attr_check(const uapi_win_attr *win_attr)
{
if (win_attr->disp_id >= UAPI_DISPLAY2 || win_attr->video_format >= UAPI_FORMAT_MAX) {
ext_fatal_win("Para win_attr disp_id(%d) is invalid, should be less than %d!\n", win_attr->disp_id,
UAPI_FORMAT_MAX);
return SOC_ERR_VO_INVALID_PARA;
}
if (win_attr->priority >= UAPI_WIN_WIN_PRIORITY_MAX) {
ext_fatal_win("Para win_attr priority(%d) is invalid, should be less than %d!\n", win_attr->priority,
UAPI_WIN_WIN_PRIORITY_MAX);
return SOC_ERR_VO_INVALID_PARA;
}
if ((win_attr->is_virtual != TD_FALSE) && (win_attr->is_virtual != TD_TRUE)) {
ext_fatal_win("Para win_attr is_virtual(%d) is invalid!\n", win_attr->is_virtual);
return SOC_ERR_VO_INVALID_PARA;
}
if ((win_attr->enable_ai != TD_FALSE) && (win_attr->enable_ai != TD_TRUE)) {
ext_fatal_win("Para win_attr enable_ai(%d) is invalid!\n", win_attr->enable_ai);
return SOC_ERR_VO_INVALID_PARA;
}
if ((win_attr->is_virtual != TD_TRUE) && (win_attr->enable_ai == TD_TRUE)) {
ext_fatal_win("Para win_attr is_virtual(%d), enable_ai(%d) is invalid! enable_ai cannot be true here \n",
win_attr->is_virtual, win_attr->enable_ai);
return SOC_ERR_VO_INVALID_PARA;
}
if (win_attr->asp_convert_mode >= UAPI_WIN_ASPECT_CONVERT_MAX) {
ext_fatal_win("Para win_attr asp_convert_mode(%d) is invalid, should be less than %d!\n",
win_attr->asp_convert_mode, UAPI_WIN_ASPECT_CONVERT_MAX);
return SOC_ERR_VO_INVALID_PARA;
}
if (win_attr->video_format >= UAPI_FORMAT_MAX) {
ext_fatal_win("Para win_attr video_format(%d) is invalid, should be less than %d!\n", win_attr->video_format,
UAPI_FORMAT_MAX);
return SOC_ERR_VO_INVALID_PARA;
}
return TD_SUCCESS;
}
static td_s32 vo_convert_win_attr_to_mpi(const uapi_win_attr *win_attr, ext_drv_win_attr *mpi_attr)
{
td_s32 ret;
ret = iapi_win_enum_attr_check(win_attr);
if (ret != TD_SUCCESS) {
ext_err_win("iapi_win_enum_attr_check failed, ret=0x%x.\n", ret);
return ret;
}
/* conver iapi parameter to driver parameters */
ret = memset_s(mpi_attr, sizeof(ext_drv_win_attr), 0, sizeof(ext_drv_win_attr));
if (ret != TD_SUCCESS) {
ext_err_win("memset_s failed, ret=0x%x\n", ret);
return ret;
}
transfer_set_disp_id(&win_attr->disp_id, &mpi_attr->disp);
mpi_attr->is_virtual = win_attr->is_virtual;
mpi_attr->enable_ai = win_attr->enable_ai;
ret = check_and_transfer_win_priority_u_to_m(&win_attr->priority, &mpi_attr->win_priority);
if (ret != TD_SUCCESS) {
ext_err_win("check_and_transfer_win_priority_u_to_m failed, ret=0x%x.\n", ret);
return ret;
}
mpi_attr->aspect_ratio.aspect_ratio_w = 0;
mpi_attr->aspect_ratio.aspect_ratio_h = 0;
ret = check_and_transfe_ar_convert((uapi_win_aspect_mode *)&win_attr->asp_convert_mode,
&mpi_attr->aspect_ratio_mode, TD_TRUE);
if (ret != TD_SUCCESS) {
ext_err_win("check_and_transfe_ar_convert failed, ret=0x%x.\n", ret);
return ret;
}
mpi_attr->crop_rect.left_offset = win_attr->src_crop_rect.left_offset;
mpi_attr->crop_rect.top_offset = win_attr->src_crop_rect.top_offset;
mpi_attr->crop_rect.right_offset = win_attr->src_crop_rect.right_offset;
mpi_attr->crop_rect.bottom_offset = win_attr->src_crop_rect.bottom_offset;
mpi_attr->video_rect.rect_x = win_attr->video_rect.x;
mpi_attr->video_rect.rect_y = win_attr->video_rect.y;
mpi_attr->video_rect.rect_w = (td_s32)win_attr->video_rect.width;
mpi_attr->video_rect.rect_h = (td_s32)win_attr->video_rect.height;
mpi_attr->out_rect.rect_x = win_attr->output_rect.x;
mpi_attr->out_rect.rect_y = win_attr->output_rect.y;
mpi_attr->out_rect.rect_w = (td_s32)win_attr->output_rect.width;
mpi_attr->out_rect.rect_h = (td_s32)win_attr->output_rect.height;
if (win_attr->is_virtual) {
ret = transfer_set_video_format(&win_attr->video_format, &mpi_attr->data_format);
if (mpi_attr->data_format != EXT_DRV_PIXEL_FMT_NV21 && mpi_attr->data_format != EXT_DRV_PIXEL_FMT_NV61_2X1) {
ext_err_win("para enVideoFormat can't be supported.\n");
return SOC_ERR_VO_INVALID_PARA;
}
}
return ret;
}
static td_void transfer_switch_mode(uapi_win_freeze_mode *iapi_mode, ext_drv_win_freeze_mode *mpi_mode,
td_bool iapi2mpi)
{
if (iapi2mpi == TD_TRUE) {
switch (*iapi_mode) {
case UAPI_WIN_FREEZE_MODE_DISABLE:
*mpi_mode = EXT_DRV_WIN_FREEZE_DISABLE;
break;
case UAPI_WIN_FREEZE_MODE_LAST:
*mpi_mode = EXT_DRV_WIN_FREEZE_LAST;
break;
case UAPI_WIN_FREEZE_MODE_BLACK:
*mpi_mode = EXT_DRV_WIN_FREEZE_BLACK;
break;
default:
*mpi_mode = EXT_DRV_WIN_FREEZE_MAX;
break;
}
} else {
switch (*mpi_mode) {
case EXT_DRV_WIN_FREEZE_DISABLE:
*iapi_mode = UAPI_WIN_FREEZE_MODE_DISABLE;
break;
case EXT_DRV_WIN_FREEZE_LAST:
*iapi_mode = UAPI_WIN_FREEZE_MODE_LAST;
break;
case EXT_DRV_WIN_FREEZE_BLACK:
*iapi_mode = UAPI_WIN_FREEZE_MODE_BLACK;
break;
default:
*iapi_mode = UAPI_WIN_FREEZE_MODE_MAX;
break;
}
}
return;
}
static td_void transfer_reset_mode(uapi_win_reset_mode *iapi_mode, ext_drv_win_reset_mode *mpi_mode,
td_bool iapi2mpi)
{
if (iapi2mpi == TD_TRUE) {
switch (*iapi_mode) {
case UAPI_WIN_RESET_MODE_LAST:
*mpi_mode = EXT_DRV_WIN_RESET_LAST;
break;
case UAPI_WIN_RESET_MODE_BLACK:
*mpi_mode = EXT_DRV_WIN_RESET_BLACK;
break;
default:
*mpi_mode = EXT_DRV_WIN_RESET_MAX;
break;
}
} else {
switch (*mpi_mode) {
case EXT_DRV_WIN_RESET_LAST:
*iapi_mode = UAPI_WIN_RESET_MODE_LAST;
break;
case EXT_DRV_WIN_RESET_BLACK:
*iapi_mode = UAPI_WIN_RESET_MODE_BLACK;
break;
default:
*iapi_mode = UAPI_WIN_RESET_MODE_MAX;
break;
}
}
return;
}
static td_void transfer_rotation(uapi_win_rotation *iapi_rotation, ext_drv_rot_angle *mpi_rotation, td_bool flag)
{
if (flag == TD_TRUE) {
switch (*iapi_rotation) {
case UAPI_WIN_ROTATION_0:
*mpi_rotation = EXT_DRV_ROT_ANGLE_0;
break;
case UAPI_WIN_ROTATION_90:
*mpi_rotation = EXT_DRV_ROT_ANGLE_90;
break;
case UAPI_WIN_ROTATION_180:
*mpi_rotation = EXT_DRV_ROT_ANGLE_180;
break;
case UAPI_WIN_ROTATION_270:
*mpi_rotation = EXT_DRV_ROT_ANGLE_270;
break;
default:
*mpi_rotation = EXT_DRV_ROT_ANGLE_MAX;
break;
}
} else {
switch (*mpi_rotation) {
case EXT_DRV_ROT_ANGLE_0:
*iapi_rotation = UAPI_WIN_ROTATION_0;
break;
case EXT_DRV_ROT_ANGLE_90:
*iapi_rotation = UAPI_WIN_ROTATION_90;
break;
case EXT_DRV_ROT_ANGLE_180:
*iapi_rotation = UAPI_WIN_ROTATION_180;
break;
case EXT_DRV_ROT_ANGLE_270:
*iapi_rotation = UAPI_WIN_ROTATION_270;
break;
default:
*iapi_rotation = UAPI_WIN_ROTATION_MAX;
break;
}
}
return;
}
static td_void transfer_sync(uapi_win_sync *sync_mode, ext_drv_win_sync *mpi_sync_mode, td_bool iapi2mpi)
{
if (iapi2mpi == TD_TRUE) {
switch (*sync_mode) {
case UAPI_WIN_SYNC_PLAY:
*mpi_sync_mode = EXT_DRV_WIN_SYNC_PLAY;
break;
case UAPI_WIN_SYNC_DISCARD:
*mpi_sync_mode = EXT_DRV_WIN_SYNC_DISCARD;
break;
case UAPI_WIN_SYNC_REPEAT:
*mpi_sync_mode = EXT_DRV_WIN_SYNC_REPEAT;
break;
case UAPI_WIN_SYNC_PLAY_LATEST:
*mpi_sync_mode = EXT_DRV_WIN_SYNC_PLAY_LASTEST;
break;
case UAPI_WIN_SYNC_PLAY_LAST:
*mpi_sync_mode = EXT_DRV_WIN_SYNC_PLAY_LAST;
break;
default:
*mpi_sync_mode = EXT_DRV_WIN_SYNC_BUTT;
break;
}
} else {
switch (*mpi_sync_mode) {
case EXT_DRV_WIN_SYNC_PLAY:
*sync_mode = UAPI_WIN_SYNC_PLAY;
break;
case EXT_DRV_WIN_SYNC_DISCARD:
*sync_mode = UAPI_WIN_SYNC_DISCARD;
break;
case EXT_DRV_WIN_SYNC_REPEAT:
*sync_mode = UAPI_WIN_SYNC_REPEAT;
break;
case EXT_DRV_WIN_SYNC_PLAY_LASTEST:
*sync_mode = UAPI_WIN_SYNC_PLAY_LATEST;
break;
case EXT_DRV_WIN_SYNC_PLAY_LAST:
*sync_mode = UAPI_WIN_SYNC_PLAY_LAST;
break;
default:
*sync_mode = UAPI_WIN_SYNC_MAX;
break;
}
}
return;
}
static td_s32 vo_convert_win_attr_to_iapi(ext_drv_win_attr *mpi_attr, uapi_win_attr *win_attr)
{
td_s32 ret;
if (mpi_attr->disp > EXT_DRV_DISPLAY_2 || mpi_attr->data_format >= EXT_DRV_PIXEL_MAX) {
ext_fatal_win("Para win_attr is invalid!\n");
return SOC_ERR_VO_INVALID_PARA;
}
/* conver driver parameters to iapi parameter */
ret = memset_s(win_attr, sizeof(uapi_win_attr), 0, sizeof(uapi_win_attr));
if (ret != TD_SUCCESS) {
ext_err_win("memset_s failed, ret=0x%x.\n", ret);
return ret;
}
transfer_disp_id(&win_attr->disp_id, &mpi_attr->disp, TD_FALSE);
win_attr->is_virtual = mpi_attr->is_virtual;
win_attr->enable_ai = mpi_attr->enable_ai;
ret = check_and_transfe_ar_convert(&win_attr->asp_convert_mode, &mpi_attr->aspect_ratio_mode, TD_FALSE);
if (ret != TD_SUCCESS) {
ext_err_win("check_and_transfe_ar_convert failed, ret=0x%x.\n", ret);
return ret;
}
ret = check_and_transfer_win_priority_m_to_u(&win_attr->priority, &mpi_attr->win_priority);
if (ret != TD_SUCCESS) {
ext_err_win("check_and_transfer_win_priority_m_to_u failed, ret=0x%x.\n", ret);
return ret;
}
win_attr->src_crop_rect.left_offset = mpi_attr->crop_rect.left_offset;
win_attr->src_crop_rect.top_offset = mpi_attr->crop_rect.top_offset;
win_attr->src_crop_rect.right_offset = mpi_attr->crop_rect.right_offset;
win_attr->src_crop_rect.bottom_offset = mpi_attr->crop_rect.bottom_offset;
win_attr->video_rect.x = mpi_attr->video_rect.rect_x;
win_attr->video_rect.y = mpi_attr->video_rect.rect_y;
win_attr->video_rect.width = (td_u32)mpi_attr->video_rect.rect_w;
win_attr->video_rect.height = (td_u32)mpi_attr->video_rect.rect_h;
win_attr->output_rect.x = mpi_attr->out_rect.rect_x;
win_attr->output_rect.y = mpi_attr->out_rect.rect_y;
win_attr->output_rect.width = (td_u32)(mpi_attr->out_rect.rect_w);
win_attr->output_rect.height = (td_u32)(mpi_attr->out_rect.rect_h);
if (mpi_attr->is_virtual) {
ret = transfer_video_pixel_format(&win_attr->video_format, &mpi_attr->data_format, TD_FALSE);
}
return ret;
}
td_s32 uapi_win_create(const uapi_win_attr *win_attr, td_handle *win_handle)
{
ext_drv_win_attr mpi_attr;
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(win_attr);
check_vo_ptr(win_handle);
ret = memset_s((td_void *)&mpi_attr, sizeof(ext_drv_win_attr), 0, sizeof(ext_drv_win_attr));
if (ret != TD_SUCCESS) {
ext_err_win("memset_s failed, ret=0x%x\n", ret);
return ret;
}
ret = vo_convert_win_attr_to_mpi(win_attr, &mpi_attr);
if (ret != TD_SUCCESS) {
ext_err_win("vo_convert_win_attr_to_mpi failed, ret=0x%x.\n", ret);
return ret;
}
ret = ext_mpi_win_create(&mpi_attr, win_handle);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_create failed, ret=0x%x.\n", ret);
return ret;
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_destroy(td_handle win_handle)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_destroy(win_handle);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_destroy failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_enable(td_handle win_handle, td_bool enable)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_set_enable(win_handle, enable);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_set_enable failed, win_handle=0x%x, enable=%d, ret=0x%x.\n", win_handle, enable, ret);
return ret;
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_enable(td_handle win_handle, td_bool *enable)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_get_enable(win_handle, enable);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_get_enable failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_attr(td_handle win_handle, uapi_win_attr *win_attr)
{
ext_drv_win_attr mpi_attr;
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(win_attr);
ret = memset_s((td_void *)&mpi_attr, sizeof(ext_drv_win_attr), 0, sizeof(ext_drv_win_attr));
if (ret != TD_SUCCESS) {
ext_err_win("memset_s failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
ret = ext_mpi_win_get_attr(win_handle, &mpi_attr);
if (ret == TD_SUCCESS) {
ret = vo_convert_win_attr_to_iapi(&mpi_attr, win_attr);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_crop_rect(const td_handle win_handle[], const uapi_video_crop_rect croprect[],
td_u32 number)
{
td_u32 i;
td_s32 ret = TD_SUCCESS;
ext_drv_crop_rect crop_rect = { 0 };
vo_win_func_enter();
check_vo_ptr(win_handle);
check_vo_ptr(croprect);
if (number > WINDOW_NUMBER_MAX) {
ext_err_win("win number(%d) is bigger than 16\n", number);
return TD_FAILURE;
}
for (i = 0; i < number; i++) {
crop_rect.left_offset = croprect[i].left_offset;
crop_rect.top_offset = croprect[i].top_offset;
crop_rect.right_offset = croprect[i].right_offset;
crop_rect.bottom_offset = croprect[i].bottom_offset;
ret = ext_mpi_win_set_crop_rect(win_handle[i], &crop_rect);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_set_crop_rect failed, win_handle=0x%x, ret=0x%x.\n", win_handle[i], ret);
return ret;
}
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_crop_rect(td_handle win_handle, uapi_video_crop_rect *croprect)
{
td_s32 ret;
ext_drv_crop_rect crop_rect = { 0 };
vo_win_func_enter();
check_vo_ptr(croprect);
ret = ext_mpi_win_get_crop_rect(win_handle, &crop_rect);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_get_crop_rect failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
croprect->left_offset = crop_rect.left_offset;
croprect->top_offset = crop_rect.top_offset;
croprect->right_offset = crop_rect.right_offset;
croprect->bottom_offset = crop_rect.bottom_offset;
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_outrect(const td_handle win_handle[], const uapi_video_rect outrect[], td_u32 number)
{
td_u32 i;
td_s32 ret = TD_SUCCESS;
ext_drv_rect out_rect = { 0 };
vo_win_func_enter();
check_vo_ptr(win_handle);
check_vo_ptr(outrect);
if (number > WINDOW_NUMBER_MAX) {
ext_err_win("win number(%d) is bigger than 16\n", number);
return SOC_ERR_VO_INVALID_PARA;
}
for (i = 0; i < number; i++) {
out_rect.rect_x = outrect[i].x;
out_rect.rect_y = outrect[i].y;
out_rect.rect_w = (td_s32)outrect[i].width;
out_rect.rect_h = (td_s32)outrect[i].height;
ret = ext_mpi_win_set_outrect(win_handle[i], &out_rect);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_set_outrect failed, win_handle=0x%x, ret=0x%x.\n", win_handle[i], ret);
return ret;
}
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_outrect(td_handle win_handle, uapi_video_rect *outrect)
{
td_s32 ret;
ext_drv_rect out_rect = { 0 };
vo_win_func_enter();
check_vo_ptr(outrect);
ret = ext_mpi_win_get_outrect(win_handle, &out_rect);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_get_outrect failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
outrect->x = out_rect.rect_x;
outrect->y = out_rect.rect_y;
outrect->width = (td_u32)(out_rect.rect_w);
outrect->height = (td_u32)(out_rect.rect_h);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_aspect_attr(const td_handle win_handle[], uapi_win_aspect_mode aspect_mode[],
const uapi_win_aspect_attr aspect_attr[], td_u32 number)
{
td_u32 i;
ext_drv_win_aspect win_aspect = { 0 };
vo_win_func_enter();
check_vo_ptr(win_handle);
check_vo_ptr(aspect_mode);
check_vo_ptr(aspect_attr);
if (number > WINDOW_NUMBER_MAX) {
ext_err_win("win number(%d) is bigger than 16\n", number);
return TD_FAILURE;
}
for (i = 0; i < number; i++) {
td_s32 ret = check_and_transfe_ar_convert(&aspect_mode[i], &win_aspect.aspect_mode, TD_TRUE);
if (ret != TD_SUCCESS) {
ext_err_win("check_and_transfe_ar_convert failed, ret=0x%x.\n", ret);
return ret;
}
win_aspect.ext_drv_win_aspect_info.nonlinear_ratio.nonlinear_enable =
(aspect_mode[i] == UAPI_WIN_ASPECT_CONVERT_NONLINEAR) ? TD_TRUE : TD_FALSE;
if (win_aspect.ext_drv_win_aspect_info.nonlinear_ratio.nonlinear_enable == TD_TRUE) {
win_aspect.ext_drv_win_aspect_info.nonlinear_ratio.src_width = aspect_attr[i].nonlinear_ratio.src_width;
win_aspect.ext_drv_win_aspect_info.nonlinear_ratio.dst_width = aspect_attr[i].nonlinear_ratio.dst_width;
}
ret = ext_mpi_win_set_aspect_attr(win_handle[i], &win_aspect);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_set_aspect_attr failed, win_handle=0x%x, ret=0x%x.\n", win_handle[i], ret);
return ret;
}
}
vo_win_func_exit();
return TD_SUCCESS;
}
td_s32 uapi_win_set_video_rect_ratio(const td_handle win_handle[],
const uapi_win_video_rect_ratio video_rect_ratio[], td_u32 number)
{
td_u32 i;
td_s32 ret = TD_SUCCESS;
ext_drv_win_rect_ratio rect_ratio = { 0 };
vo_win_func_enter();
check_vo_ptr(win_handle);
check_vo_ptr(video_rect_ratio);
if (number > WINDOW_NUMBER_MAX) {
ext_err_win("win number(%d) is bigger than 16\n", number);
return TD_FAILURE;
}
for (i = 0; i < number; i++) {
rect_ratio.x_offset = video_rect_ratio[i].x_offset;
rect_ratio.y_offset = video_rect_ratio[i].y_offset;
rect_ratio.width = video_rect_ratio[i].width;
rect_ratio.height = video_rect_ratio[i].height;
ret = ext_mpi_win_set_video_rect_ratio(win_handle[i], &rect_ratio);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_set_video_rect_ratio failed, win_handle=0x%x, ret=0x%x.\n", win_handle[i], ret);
return ret;
}
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_aspect_attr(td_handle win_handle, uapi_win_aspect_mode *aspect_mode,
uapi_win_aspect_attr *aspect_attr)
{
td_s32 ret;
ext_drv_win_aspect aspect_info = { 0 };
vo_win_func_enter();
check_vo_ptr(win_handle);
check_vo_ptr(aspect_mode);
check_vo_ptr(aspect_attr);
ret = ext_mpi_win_get_aspect_attr(win_handle, &aspect_info);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_get_aspect_attr failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
ret = check_and_transfe_ar_convert(aspect_mode, &aspect_info.aspect_mode, TD_FALSE);
if (ret != TD_SUCCESS) {
ext_err_win("check_and_transfe_ar_convert failed, ret=0x%x.\n", ret);
return ret;
}
aspect_attr->nonlinear_ratio.src_width = aspect_info.ext_drv_win_aspect_info.nonlinear_ratio.src_width;
aspect_attr->nonlinear_ratio.dst_width = aspect_info.ext_drv_win_aspect_info.nonlinear_ratio.dst_width;
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_video_rect_ratio(td_handle win_handle, uapi_win_video_rect_ratio *video_rect_ratio)
{
td_s32 ret;
ext_drv_win_rect_ratio rect_ratio = { 0 };
vo_win_func_enter();
check_vo_ptr(win_handle);
check_vo_ptr(video_rect_ratio);
ret = ext_mpi_win_get_video_rect_ratio(win_handle, &rect_ratio);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_get_video_rect_ratio failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
video_rect_ratio->x_offset = rect_ratio.x_offset;
video_rect_ratio->y_offset = rect_ratio.y_offset;
video_rect_ratio->width = rect_ratio.width;
video_rect_ratio->height = rect_ratio.height;
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_acquire_frame(td_handle win_handle, uapi_video_frame_info *frame_info, td_u32 timeout_ms)
{
ext_drv_video_frame mpi_frame = { 0 };
td_s32 ret = TD_FAILURE;
td_u32 delay_time = 0;
vo_win_func_enter();
check_vo_ptr(frame_info);
if (timeout_ms > TIMEOUT_MAX_VALUE_MS) {
ext_err_win("timeout is too big.\n");
return SOC_ERR_VO_INVALID_PARA;
}
mpi_frame.source_fence = TD_INVALID_HANDLE; // not fence, if acquire frame with fence, then wait signal.
do {
ret = ext_mpi_win_acquire_frame(win_handle, &mpi_frame);
if (ret == TD_SUCCESS) {
ret = transfer_frame(frame_info, &mpi_frame, TD_FALSE);
if (ret != TD_SUCCESS) {
ext_fatal_win("transfer_frame failed, ret=0x%x.\n", ret);
ret = SOC_ERR_VO_FRAME_INFO_ERROR;
ext_mpi_win_release_frame(win_handle, &mpi_frame);
}
break;
}
delay_time += 1;
usleep(WINDOW_ACQUIRE_FRAME_DELAY);
} while (delay_time <= timeout_ms);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_release_frame(td_handle win_handle, uapi_video_frame_info *frame_info)
{
ext_drv_video_frame mpi_frame = { 0 };
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(frame_info);
ret = transfer_frame(frame_info, &mpi_frame, TD_TRUE);
if (ret != TD_SUCCESS) {
ext_fatal_win("transfer_frame failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return SOC_ERR_VO_FRAME_INFO_ERROR;
}
ret = ext_mpi_win_release_frame(win_handle, &mpi_frame);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_zorder(td_handle win_handle, uapi_win_zorder zorder)
{
ext_drv_disp_zorder mpi_zorder;
td_s32 ret;
vo_win_func_enter();
if (zorder >= UAPI_WIN_ZORDER_MAX) {
ext_err_win("Invalid zorder(%d) parameter!\n", zorder);
return SOC_ERR_VO_INVALID_PARA;
}
transfer_zorder(&zorder, &mpi_zorder, TD_TRUE);
ret = ext_mpi_win_set_zorder(win_handle, mpi_zorder);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_zorder(td_handle win_handle, td_u32 *zorder)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_get_zorder(win_handle, zorder);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_abs_zorder(td_handle win_handle, td_s32 abs_zorder)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_set_abs_zorder(win_handle, abs_zorder);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_abs_zorder(td_handle win_handle, td_s32 *abs_zorder)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_get_abs_zorder(win_handle, abs_zorder);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_attach_src(td_handle win_handle, td_handle src_handle)
{
td_s32 ret;
td_u8 handle = (src_handle >> 24) & 0xFF; /* 24 is number */
ext_drv_win_src_handle src = { 0 };
win_extern_func extern_func = { TD_NULL, TD_NULL, TD_NULL, TD_NULL, TD_NULL };
td_u32 module_id = MODULE_ID_MAX;
vo_win_func_enter();
if (win_handle == TD_INVALID_HANDLE) {
ext_err_win("invalid win handle\n");
return SOC_ERR_VO_INVALID_PARA;
}
if (handle == SOC_ID_AVPLAY) {
module_id = MODULE_ID_AVPLAY;
} else if (handle == SOC_ID_VI) {
module_id = MODULE_ID_VI;
} else if (handle == SOC_ID_WIN) {
src.src = src_handle;
ret = ext_mpi_win_set_source(win_handle, &src);
return ret;
} else {
ext_err_win("not support module %d\n", module_id);
return SOC_ERR_VO_INVALID_PARA;
}
ret = ext_mpi_win_extern_get_func(module_id, &extern_func);
if (ret != TD_SUCCESS) {
ext_err_win("not support module %d, win_handle=0x%x, ret=0x%x.\n", module_id, win_handle, ret);
return SOC_ERR_VO_INVALID_PARA;
}
if ((extern_func.src_attach_window == TD_NULL) ||
(extern_func.src_detach_window == TD_NULL)) {
ext_err_win(" module %d extern_func is null.\n", module_id);
return SOC_ERR_VO_INVALID_PARA;
}
ret = extern_func.src_attach_window(src_handle, win_handle);
if (ret == TD_SUCCESS) {
src.src = src_handle;
ret = ext_mpi_win_set_source(win_handle, &src);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_detach_src(td_handle win_handle, td_handle src_handle)
{
td_s32 ret;
td_u8 handle = (src_handle >> 24) & 0xFF; /* 24 is number */
ext_drv_win_src_handle src = { 0 };
win_extern_func extern_func = { TD_NULL, TD_NULL, TD_NULL, TD_NULL, TD_NULL };
td_u32 module_id = MODULE_ID_MAX;
if (win_handle == TD_INVALID_HANDLE) {
ext_err_win("invalid win handle\n");
return SOC_ERR_VO_INVALID_PARA;
}
vo_win_func_enter();
if (handle == SOC_ID_AVPLAY) {
module_id = MODULE_ID_AVPLAY;
} else if (handle == SOC_ID_VI) {
module_id = MODULE_ID_VI;
} else {
ext_err_win("not support module %d\n", module_id);
return SOC_ERR_VO_INVALID_PARA;
}
ret = ext_mpi_win_extern_get_func(module_id, &extern_func);
if (ret != TD_SUCCESS) {
ext_err_win("not support module %d, win_handle=0x%x, ret=0x%x.\n", module_id, win_handle, ret);
return SOC_ERR_VO_INVALID_PARA;
}
if ((extern_func.src_attach_window == TD_NULL) ||
(extern_func.src_detach_window == TD_NULL)) {
ext_err_win(" module %d extern_func is null.\n", module_id);
return SOC_ERR_VO_INVALID_PARA;
}
src.src = TD_INVALID_HANDLE;
ret = extern_func.src_detach_window(src_handle, win_handle);
if (ret == TD_SUCCESS) {
ret = ext_mpi_win_set_source(win_handle, &src);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_freeze_mode(td_handle win_handle, uapi_win_freeze_mode freeze_mode)
{
td_s32 ret;
ext_drv_win_freeze_mode mpi_freeze_mode = EXT_DRV_WIN_FREEZE_MAX;
vo_win_func_enter();
if (freeze_mode >= UAPI_WIN_FREEZE_MODE_MAX) {
ext_err_win("invalid freeze_mode(%d)\n", freeze_mode);
return SOC_ERR_VO_INVALID_PARA;
}
transfer_switch_mode(&freeze_mode, &mpi_freeze_mode, TD_TRUE);
ret = ext_mpi_win_set_freeze(win_handle, mpi_freeze_mode);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_freeze_mode(td_handle win_handle, uapi_win_freeze_mode *freeze_mode)
{
td_s32 ret;
ext_drv_win_freeze_mode mpi_freeze_mode;
vo_win_func_enter();
check_vo_ptr(freeze_mode);
ret = ext_mpi_win_get_freezestat(win_handle, &mpi_freeze_mode);
if (ret == TD_SUCCESS) {
transfer_switch_mode(freeze_mode, &mpi_freeze_mode, TD_FALSE);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_reset(td_handle win_handle, uapi_win_reset_mode reset_mode)
{
td_s32 ret;
ext_drv_win_reset_mode mpi_reset_mode;
vo_win_func_enter();
if (reset_mode >= UAPI_WIN_RESET_MODE_MAX) {
ext_err_win("invalid reset mode:%d\n", reset_mode);
return SOC_ERR_VO_INVALID_PARA;
}
transfer_reset_mode(&reset_mode, &mpi_reset_mode, TD_TRUE);
ret = ext_mpi_win_reset(win_handle, mpi_reset_mode);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_attach_extern_buffer(td_handle win_handle, const uapi_win_extern_buffer *ext_buffer, td_u32 cnt)
{
td_s32 ret;
td_u32 index;
ext_drv_extern_buffer mpi_ext_buffer = {0};
vo_win_func_enter();
check_vo_ptr(ext_buffer);
if (win_handle == TD_INVALID_HANDLE) {
ext_err_win("invalid win handle\n");
return SOC_ERR_VO_INVALID_PARA;
}
if ((cnt <= 0) || (cnt > UAPI_WIN_MAX_EXTERN_BUFFER_NUM) ||
(cnt > SOC_DRV_MAX_EXTERN_BUFFER_NUM)) {
ext_err_win("buf cnt is invalid! iapi max=%d, mpi max=%d, act=%d\n", UAPI_WIN_MAX_EXTERN_BUFFER_NUM,
SOC_DRV_MAX_EXTERN_BUFFER_NUM, cnt);
return SOC_ERR_VO_INVALID_PARA;
}
mpi_ext_buffer.buf_num = cnt;
for (index = 0; index < mpi_ext_buffer.buf_num; index++) {
mpi_ext_buffer.buf_array[index].frame_fd = ext_buffer[index].frame_fd;
mpi_ext_buffer.buf_array[index].frame_size = ext_buffer[index].frame_size;
mpi_ext_buffer.buf_array[index].frame_stride_y = ext_buffer[index].frame_stride_y;
mpi_ext_buffer.buf_array[index].frame_stride_c = ext_buffer[index].frame_stride_c;
mpi_ext_buffer.buf_array[index].frame_offset_y = ext_buffer[index].frame_offset_y;
mpi_ext_buffer.buf_array[index].frame_offset_c = ext_buffer[index].frame_offset_c;
mpi_ext_buffer.buf_array[index].metadata_fd = ext_buffer[index].metadata_fd;
mpi_ext_buffer.buf_array[index].metadata_size = ext_buffer[index].metadata_size;
mpi_ext_buffer.buf_array[index].metadata_offset = ext_buffer[index].metadata_offset;
}
ret = ext_mpi_win_attach_extbuffer(win_handle, &mpi_ext_buffer);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_quick_output_enable(td_handle win_handle, td_bool enable)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_set_quick_output(win_handle, enable);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_quickout_mode(td_handle win_handle, uapi_win_quickout_mode quickout_mode)
{
td_s32 ret;
ext_drv_win_quickout_mode mpi_quickout_mode;
vo_win_func_enter();
if (quickout_mode == UAPI_WIN_QUICKOUT_SUPER_LOW_DELAY) {
mpi_quickout_mode = EXT_DRV_WIN_QUICKOUT_SUPER_LOWDELAY;
} else if (quickout_mode == UAPI_WIN_QUICKOUT_NORMAL_LOW_DELAY) {
mpi_quickout_mode = EXT_DRV_WIN_QUICKOUT_NORMAL_LOWDELAY;
} else if (quickout_mode == UAPI_WIN_QUICKOUT_DISABLE) {
mpi_quickout_mode = EXT_DRV_WIN_QUICKOUT_DISABLE;
} else {
ext_err_win("quickout mode is invalid,cur:%d max:%d.\n", quickout_mode, EXT_DRV_WIN_QUICKOUT_MAX);
return SOC_ERR_VO_INVALID_PARA;
}
ret = ext_mpi_win_set_quickout_mode(win_handle, mpi_quickout_mode);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_quickout_mode(td_handle win_handle, uapi_win_quickout_mode *quickout_mode)
{
td_s32 ret;
ext_drv_win_quickout_mode mpi_quickout_mode = EXT_DRV_WIN_QUICKOUT_MAX;
vo_win_func_enter();
check_vo_ptr(quickout_mode);
ret = ext_mpi_win_get_quickout_mode(win_handle, &mpi_quickout_mode);
if (ret == TD_SUCCESS) {
if (mpi_quickout_mode == EXT_DRV_WIN_QUICKOUT_SUPER_LOWDELAY) {
*quickout_mode = UAPI_WIN_QUICKOUT_SUPER_LOW_DELAY;
} else if (mpi_quickout_mode == EXT_DRV_WIN_QUICKOUT_NORMAL_LOWDELAY) {
*quickout_mode = UAPI_WIN_QUICKOUT_NORMAL_LOW_DELAY;
} else if (mpi_quickout_mode == EXT_DRV_WIN_QUICKOUT_DISABLE) {
*quickout_mode = UAPI_WIN_QUICKOUT_DISABLE;
} else {
ext_err_win("quickout mode get is invalid, mode:%d max:%d.\n", mpi_quickout_mode, EXT_DRV_WIN_QUICKOUT_MAX);
return SOC_ERR_VO_INVALID_PARA;
}
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_quick_output_status(td_handle win_handle, td_bool *quick_enable)
{
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(quick_enable);
ret = ext_mpi_win_get_quick_output_status(win_handle, quick_enable);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_capture_picture(td_handle win_handle, uapi_video_frame_info *cap_picture)
{
ext_drv_video_frame mpi_frame = { 0 };
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(cap_picture);
ret = ext_mpi_win_capture_picture(win_handle, &mpi_frame);
if (ret == TD_SUCCESS) {
ret = transfer_frame(cap_picture, &mpi_frame, TD_FALSE);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_capture_picture_release(td_handle win_handle, uapi_video_frame_info *cap_picture)
{
ext_drv_video_frame mpi_frame = { 0 };
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(cap_picture);
ret = transfer_frame(cap_picture, &mpi_frame, TD_TRUE);
if (ret == TD_SUCCESS) {
ret = ext_mpi_win_capture_picture_release(win_handle, &mpi_frame);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_rotation(td_handle win_handle, uapi_win_rotation rotation)
{
td_s32 ret;
ext_drv_rot_angle drv_rotation = EXT_DRV_ROT_ANGLE_MAX;
vo_win_func_enter();
if (rotation >= UAPI_WIN_ROTATION_MAX) {
ext_err_win("invalid rotation:%d\n", rotation);
return SOC_ERR_VO_INVALID_PARA;
}
transfer_rotation(&rotation, &drv_rotation, TD_TRUE);
ret = ext_mpi_win_set_rotation(win_handle, drv_rotation);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_rotation(td_handle win_handle, uapi_win_rotation *rotation)
{
td_s32 ret;
ext_drv_rot_angle drv_rotation;
vo_win_func_enter();
check_vo_ptr(rotation);
ret = ext_mpi_win_get_rotation(win_handle, &drv_rotation);
if (ret == TD_SUCCESS) {
transfer_rotation(rotation, &drv_rotation, TD_FALSE);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_stereo_detpth(td_handle win_handle, td_u32 depth_level)
{
TD_UNUSED(win_handle);
TD_UNUSED(depth_level);
return SOC_ERR_VO_WIN_UNSUPPORT;
}
td_s32 uapi_win_get_stereo_detpth(td_handle win_handle, td_u32 *depth_level)
{
TD_UNUSED(win_handle);
TD_UNUSED(depth_level);
if (depth_level != TD_NULL) {
*depth_level = 0;
}
return SOC_ERR_VO_WIN_UNSUPPORT;
}
td_s32 uapi_win_get_stereo_detpth_range(td_handle win_handle, uapi_disp_range *depth_range)
{
TD_UNUSED(win_handle);
TD_UNUSED(depth_range);
if (depth_range != TD_NULL) {
depth_range->min = 0;
depth_range->max = 0;
}
return SOC_ERR_VO_WIN_UNSUPPORT;
}
td_s32 uapi_win_get_3d_view_range(td_handle win_handle, uapi_disp_range *view_range)
{
TD_UNUSED(win_handle);
TD_UNUSED(view_range);
if (view_range != TD_NULL) {
view_range->min = 0;
view_range->max = 0;
}
return SOC_ERR_VO_WIN_UNSUPPORT;
}
td_s32 uapi_win_set_3d_view_level(td_handle win_handle, td_u32 view_level)
{
TD_UNUSED(win_handle);
TD_UNUSED(view_level);
return SOC_ERR_VO_WIN_UNSUPPORT;
}
td_s32 uapi_win_get_3d_view_level(td_handle win_handle, td_u32 *view_level)
{
TD_UNUSED(win_handle);
TD_UNUSED(view_level);
if (view_level != TD_NULL) {
*view_level = 0;
}
return SOC_ERR_VO_WIN_UNSUPPORT;
}
td_s32 uapi_win_set_mute_color(td_handle win_handle, const uapi_disp_color *mute_color)
{
td_s32 ret;
ext_drv_disp_color mpi_mute_color;
vo_win_func_enter();
check_vo_ptr(mute_color);
if (mute_color->bit_depth >= UAPI_PIXEL_BIT_DEPTH_MAX) {
ext_err_win("invalid mute_color->bit_depth:%d\n", mute_color->bit_depth);
return SOC_ERR_VO_INVALID_PARA;
}
transfer_bgcolor_iapi2mpi(mute_color, &mpi_mute_color);
ret = ext_mpi_win_set_mute_color(win_handle, &mpi_mute_color);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_handle_info(uapi_disp disp_id, uapi_win_handle_info *handle_info)
{
td_u32 i;
td_s32 ret;
ext_drv_win_handle_info mpi_info = {0};
ext_drv_display disp = EXT_DRV_DISPLAY_0;
vo_win_func_enter();
if ((disp_id != UAPI_DISPLAY0) && (disp_id != UAPI_DISPLAY1)) {
ext_warn_win("Only UAPI_DISPLAY0 or UAPI_DISPLAY1 is supported, not %d!\n", disp_id);
return SOC_ERR_DISP_NOT_SUPPORT;
}
check_vo_ptr(handle_info);
transfer_disp_id(&disp_id, &disp, TD_TRUE);
ret = ext_mpi_win_get_handle_info(disp, &mpi_info);
if (ret == TD_SUCCESS) {
handle_info->win_num = mpi_info.win_num;
handle_info->main_handle = mpi_info.main_handle;
for (i = 0; i < mpi_info.win_num && i < MAX_WINDOW_NUMBER; i++) {
handle_info->win_handle[i] = mpi_info.win_handle[i];
}
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_queue_frame(td_handle win_handle, uapi_video_frame_info *frame_info, td_u32 *fence_fd)
{
ext_drv_video_frame mpi_frame;
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(frame_info);
/* before trans, do memset first. */
ret = memset_s((td_void *)&mpi_frame, sizeof(ext_drv_video_frame), 0, sizeof(ext_drv_video_frame));
if (ret != TD_SUCCESS) {
ext_err_win("memset_s failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
ret = transfer_frame(frame_info, &mpi_frame, TD_TRUE);
if (ret == TD_SUCCESS) {
/* when use iapi queue, default no source fence. */
mpi_frame.source_fence = -1;
ret = ext_mpi_win_queue_frame(win_handle, &mpi_frame, fence_fd);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_dequeue_frame(td_handle win_handle, uapi_video_frame_info *frame_info, td_u32 timeout_ms)
{
ext_drv_video_frame mpi_frame;
td_s32 ret;
td_u32 sleep_time = 0;
vo_win_func_enter();
check_vo_ptr(frame_info);
if (timeout_ms > TIMEOUT_MAX_VALUE_MS) {
ext_err_win("timeout is too big.\n");
return SOC_ERR_VO_INVALID_PARA;
}
ret = memset_s((td_void *)&mpi_frame, sizeof(ext_drv_video_frame), 0, sizeof(ext_drv_video_frame));
if (ret != TD_SUCCESS) {
ext_err_win("memset_s failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
while (1) {
ret = ext_mpi_win_dequeue_frame(win_handle, &mpi_frame);
if (ret == TD_SUCCESS) {
ret = transfer_frame(frame_info, &mpi_frame, TD_FALSE);
if (ret != TD_SUCCESS) {
ext_fatal_win("transfer_frame failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
ret = SOC_ERR_VO_FRAME_INFO_ERROR;
}
break;
}
if (sleep_time > timeout_ms) {
ret = SOC_ERR_VO_TIMEOUT;
break;
}
sleep_time++;
(td_void) usleep(1 * 1000); /* 1000 is number */
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_latest_frame(td_handle win_handle, uapi_video_frame_info *frame_info)
{
ext_drv_video_frame mpi_frame = { 0 };
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(frame_info);
ret = ext_mpi_win_get_latest_frame(win_handle, &mpi_frame);
if (ret == TD_SUCCESS) {
ret = transfer_frame(frame_info, &mpi_frame, TD_FALSE);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_sync_info(td_handle win_handle, uapi_win_sync sync_mode)
{
ext_drv_win_sync mpi_sync_mode = EXT_DRV_WIN_SYNC_PLAY;
td_s32 ret;
vo_win_func_enter();
if (sync_mode >= UAPI_WIN_SYNC_MAX) {
ext_err_win("invalid sync_mode:%d\n", sync_mode);
return SOC_ERR_VO_INVALID_PARA;
}
transfer_sync(&sync_mode, &mpi_sync_mode, TD_TRUE);
ret = ext_mpi_win_set_sync_info(win_handle, mpi_sync_mode);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_play_info(td_handle win_handle, uapi_win_play_info *play_info)
{
td_s32 ret;
ext_drv_win_play_info mpi_play_info;
vo_win_func_enter();
check_vo_ptr(play_info);
ret = ext_mpi_win_get_playinfo(win_handle, &mpi_play_info);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_get_playinfo failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
play_info->delay_time_ms = mpi_play_info.delay_time;
play_info->disp_rate = mpi_play_info.out_put_frame_rate;
play_info->frame_num = mpi_play_info.remain_frame_num;
play_info->current_disp_frame_pts_us = mpi_play_info.disp_frame_pts;
play_info->underload_cnt = mpi_play_info.underload_times;
vo_win_func_exit();
return TD_SUCCESS;
}
td_s32 uapi_win_get_hdr_type(td_handle win_handle, uapi_hdr_type *hdr_type)
{
td_s32 ret;
ext_drv_hdr_type mpi_hdr_type = EXT_DRV_HDR_TYPE_MAX;
vo_win_func_enter();
if (win_handle == TD_INVALID_HANDLE) {
ext_err_win("para win_handle is invalid.\n");
return SOC_ERR_VO_INVALID_PARA;
}
check_vo_ptr(hdr_type);
ret = ext_mpi_win_get_hdr_type(win_handle, &mpi_hdr_type);
if (ret != TD_SUCCESS) {
ext_err_win("ext_mpi_win_get_hdr_type failed, win_handle=0x%x, ret=0x%x.\n", win_handle, ret);
return ret;
}
if (mpi_hdr_type == EXT_DRV_HDR_TYPE_SDR) {
*hdr_type = UAPI_HDR_TYPE_SDR;
} else if (mpi_hdr_type == EXT_DRV_HDR_TYPE_HDR10) {
*hdr_type = UAPI_HDR_TYPE_HDR10;
} else if (mpi_hdr_type == EXT_DRV_HDR_TYPE_HLG) {
*hdr_type = UAPI_HDR_TYPE_HLG;
} else if (mpi_hdr_type == EXT_DRV_HDR_TYPE_CUVA) {
*hdr_type = UAPI_HDR_TYPE_CUVA;
} else if (mpi_hdr_type == EXT_DRV_HDR_TYPE_JTP_SL_HDR) {
*hdr_type = UAPI_HDR_TYPE_JTP_SL_HDR;
} else if (mpi_hdr_type == EXT_DRV_HDR_TYPE_DOLBYVISION) {
*hdr_type = UAPI_HDR_TYPE_DOLBYVISION;
} else {
*hdr_type = UAPI_HDR_TYPE_MAX;
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_alpha(td_handle win_handle, td_u32 alpha)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_vo_set_window_alpha(win_handle, alpha);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_alpha(td_handle win_handle, td_u32 *alpha)
{
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(alpha);
ret = ext_mpi_vo_get_window_alpha(win_handle, alpha);
vo_win_func_exit();
return ret;
}
static td_s32 transfer_ai_result_u_to_m(uapi_win_ai_result *iapi_result, ext_drv_ai_result *mpi_result)
{
td_u32 i, j;
td_u32 block_type;
vo_win_func_enter();
if ((sizeof(iapi_result->global_valid) / sizeof(iapi_result->global_valid[0]) !=
sizeof(mpi_result->global_valid) / sizeof(mpi_result->global_valid[0])) ||
(sizeof(iapi_result->block_valid) / sizeof(iapi_result->block_valid[0]) !=
sizeof(mpi_result->block_valid) / sizeof(mpi_result->block_valid[0]))) {
ext_err_win("invalid para, size not match ! iapi global:%d, block_max:%d; mpi global:%d, block_max:%d; \n",
sizeof(iapi_result->global_valid) / sizeof(iapi_result->global_valid[0]),
sizeof(iapi_result->block_valid) / sizeof(iapi_result->block_valid[0]),
sizeof(mpi_result->global_valid) / sizeof(mpi_result->global_valid[0]),
sizeof(mpi_result->block_valid) / sizeof(mpi_result->block_valid[0]));
return TD_FAILURE;
}
for (block_type = 0; block_type < UAPI_WIN_AI_BLOCK_MAX; block_type++) {
if ((iapi_result->block_result[block_type].block_num > UAPI_WIN_MAX_AI_BLOCK_NUM) ||
(iapi_result->block_result[block_type].block_num > EXT_DRV_MAX_AI_BLOCK_NUM)) {
ext_err_win("invalid para! block_type:%d, block_result.area_num:%d, iapi max is:%d, drv max is:%d \n",
block_type, iapi_result->block_result[block_type].block_num,
UAPI_WIN_MAX_AI_BLOCK_NUM, EXT_DRV_MAX_AI_BLOCK_NUM);
return TD_FAILURE;
}
}
for (i = 0; i < UAPI_WIN_AI_GLOBAL_MAX; i++) {
mpi_result->global_valid[i] = iapi_result->global_valid[i];
mpi_result->global_result[i].confidence = iapi_result->global_result[i].confidence;
}
for (i = 0; i < UAPI_WIN_AI_BLOCK_MAX; i++) {
mpi_result->block_valid[i] = iapi_result->block_valid[i];
mpi_result->block_result[i].block_num = iapi_result->block_result[i].block_num;
for (j = 0; j < iapi_result->block_result[i].block_num; j++) {
mpi_result->block_result[i].block_info[j].x0 = iapi_result->block_result[i].block_info[j].x0;
mpi_result->block_result[i].block_info[j].y0 = iapi_result->block_result[i].block_info[j].y0;
mpi_result->block_result[i].block_info[j].x1 = iapi_result->block_result[i].block_info[j].x1;
mpi_result->block_result[i].block_info[j].y1 = iapi_result->block_result[i].block_info[j].y1;
mpi_result->block_result[i].block_info[j].confidence =
iapi_result->block_result[i].block_info[j].confidence;
}
}
vo_win_func_exit();
return TD_SUCCESS;
}
td_s32 uapi_win_set_ai_window_result(td_handle win_main_handle,
const uapi_video_frame_info *frame_info,
const uapi_win_ai_result *ai_result)
{
td_s32 ret;
ext_drv_ai_result mpi_ai_result;
ext_drv_video_frame mpi_frame;
vo_win_func_enter();
check_vo_ptr(frame_info);
check_vo_ptr(ai_result);
ret = memset_s(&mpi_ai_result, sizeof(ext_drv_ai_result), 0, sizeof(ext_drv_ai_result));
if (ret != TD_SUCCESS) {
ext_err_win("memset_s-1 failed, win_handle=0x%x, ret=0x%x.\n", win_main_handle, ret);
return TD_FAILURE;
}
ret = memset_s(&mpi_frame, sizeof(ext_drv_video_frame), 0, sizeof(ext_drv_video_frame));
if (ret != TD_SUCCESS) {
ext_err_win("memset_s-2 failed, win_handle=0x%x, ret=0x%x.\n", win_main_handle, ret);
return TD_FAILURE;
}
ret = transfer_ai_result_u_to_m((uapi_win_ai_result *)ai_result, &mpi_ai_result);
if (ret != TD_SUCCESS) {
ext_err_win("transfer ai_result failed, win_handle=0x%x, ret=0x%x.\n", win_main_handle, ret);
return SOC_ERR_VO_INVALID_PARA;
}
ret = transfer_frame((uapi_video_frame_info *)frame_info, &mpi_frame, TD_TRUE);
if (ret != TD_SUCCESS) {
ext_err_win("transfer_frame failed, win_handle=0x%x, ret=0x%x.\n", win_main_handle, ret);
return SOC_ERR_VO_INVALID_PARA;
}
/* when use iapi queue frame, default no source fence. */
mpi_frame.source_fence = -1;
ret = ext_mpi_win_set_ai_result(win_main_handle, &mpi_frame, &mpi_ai_result);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_video_source(td_handle win_handle, uapi_video_source video_source)
{
td_s32 ret;
ext_drv_source mpi_src = EXT_DRV_SOURCE_MAX;
vo_win_func_enter();
if (video_source >= UAPI_VIDEO_SOURCE_MAX) {
ext_err_win("invalid source_type:%d, max is %d", video_source, UAPI_VIDEO_SOURCE_MAX);
}
transfer_source_type(&video_source, &mpi_src, TD_TRUE);
ret = ext_mpi_win_set_video_source(win_handle, mpi_src);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_video_source(td_handle win_handle, uapi_video_source *video_source)
{
td_s32 ret;
ext_drv_source mpi_src = EXT_DRV_SOURCE_MAX;
vo_win_func_enter();
check_vo_ptr(video_source);
ret = ext_mpi_win_get_video_source(win_handle, &mpi_src);
if (ret == TD_SUCCESS) {
transfer_source_type(video_source, &mpi_src, TD_FALSE);
}
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_flip(td_handle win_handle, td_bool hor_flip, td_bool ver_flip)
{
td_s32 ret;
vo_win_func_enter();
ret = ext_mpi_win_set_flip(win_handle, hor_flip, ver_flip);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_flip(td_handle win_handle, td_bool *hor_flip, td_bool *ver_flip)
{
td_s32 ret;
vo_win_func_enter();
check_vo_ptr(hor_flip);
check_vo_ptr(ver_flip);
ret = ext_mpi_win_get_flip(win_handle, hor_flip, ver_flip);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_set_source(td_handle win_handle, uapi_win_source_info *src_info)
{
td_s32 ret;
ext_drv_win_src_handle src_handle = { 0 };
vo_win_func_enter();
check_vo_ptr(src_info);
src_handle.src = src_info->src;
ret = ext_mpi_win_set_source(win_handle, &src_handle);
vo_win_func_exit();
return ret;
}
td_s32 uapi_win_get_source(td_handle win_handle, uapi_win_source_info *src_info)
{
td_s32 ret;
ext_drv_win_src_handle src_handle = { 0 };
vo_win_func_enter();
check_vo_ptr(src_info);
ret = ext_mpi_win_get_source(win_handle, &src_handle);
src_info->src = src_handle.src;
vo_win_func_exit();
return ret;
}
static td_void transfer_packing_type(uapi_video_frame_packing_type *packing_type, ext_drv_3d_type *video_3d_type,
td_bool u2m)
{
if (u2m == TD_TRUE) {
switch (*packing_type) {
case UAPI_FRAME_PACKING_TYPE_2D:
*video_3d_type = EXT_DRV_3D_NONE;
break;
case UAPI_FRAME_PACKING_TYPE_SIDE_BY_SIDE:
*video_3d_type = EXT_DRV_3D_SBS_HALF;
break;
case UAPI_FRAME_PACKING_TYPE_TOP_AND_BOTTOM:
*video_3d_type = EXT_DRV_3D_TAB;
break;
case UAPI_FRAME_PACKING_TYPE_TIME_INTERLACED:
*video_3d_type = EXT_DRV_3D_FS;
break;
case UAPI_FRAME_PACKING_TYPE_FRAME_PACKING:
*video_3d_type = EXT_DRV_3D_FPK;
break;
default:
*video_3d_type = EXT_DRV_3D_MAX;
break;
}
} else {
switch (*video_3d_type) {
case EXT_DRV_3D_NONE:
*packing_type = UAPI_FRAME_PACKING_TYPE_2D;
break;
case EXT_DRV_3D_SBS_HALF:
*packing_type = UAPI_FRAME_PACKING_TYPE_SIDE_BY_SIDE;
break;
case EXT_DRV_3D_TAB:
*packing_type = UAPI_FRAME_PACKING_TYPE_TOP_AND_BOTTOM;
break;
case EXT_DRV_3D_FS:
*packing_type = UAPI_FRAME_PACKING_TYPE_TIME_INTERLACED;
break;
case EXT_DRV_3D_FPK:
*packing_type = UAPI_FRAME_PACKING_TYPE_FRAME_PACKING;
break;
default:
*packing_type = UAPI_FRAME_PACKING_TYPE_MAX;
break;
}
}
return;
}
td_s32 uapi_win_set_frame_packing_type(td_handle win_handle, uapi_video_frame_packing_type packing_type)
{
td_s32 ret;
ext_drv_3d_type video_3d_type;
transfer_packing_type(&packing_type, &video_3d_type, TD_TRUE);
ret = ext_mpi_win_set_video_3d_type(win_handle, video_3d_type);
return ret;
}
td_s32 uapi_win_get_frame_packing_type(td_handle win_handle, uapi_video_frame_packing_type *packing_type)
{
td_s32 ret;
ext_drv_3d_type video_3d_type;
ret = ext_mpi_win_get_video_3d_type(win_handle, &video_3d_type);
transfer_packing_type(packing_type, &video_3d_type, TD_FALSE);
return ret;
}