/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved. * Description: function define * Author: Hisilicon * Create: 2019-04-12 */ #include #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; }