/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2016-2019. All rights reserved. * Description: mpi api for other module * Author: Hisilicon * Create: 2016-01-1 */ #include #include #include #include #include #include #include "mpi_vplugin_define.h" #include "mpi_vplugin_ext.h" #include "mpi_memory_ext.h" #include "securec.h" #include "mpi_win_ext.h" #include "soc_errno.h" #include "drv_ioctl_vplugin.h" #include "mpi_media_ext.h" #include "uapi_video.h" #include "mpi_system_ext.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif /* __cplusplus */ #undef LOG_MODULE_ID #define LOG_MODULE_ID SOC_ID_VPLUGIN #define PLUGIN_MAX_CNT 16 #define server_vplugin_msg(val, fmt...) \ if (val) { \ soc_log_notice(fmt); \ } typedef struct { /* attach reltionship */ td_handle win_handle; /* vplugin server use buffer */ td_u32 read_pos; td_u32 write_pos; ext_drv_vplugin_stream_package_node *buf_node; ext_drv_vplugin_buf_ctrl_info *buf_ctrl; td_u32 buf_size; /* used to sync vplugin state */ ext_drv_vplugin_state vplugin_state; } mpi_vplugin_instance; typedef struct { mpi_vplugin_instance vplugin_instance[PLUGIN_MAX_CNT]; } mpi_vplugin_ctx; static td_s32 g_vplugin_dev = -1; vplugin_enable g_vplugin_module[PLUGIN_MAX_CNT] = {{0}}; static pthread_mutex_t g_vplugin_mutex = PTHREAD_MUTEX_INITIALIZER; #define ext_vplugin_lock() (void)pthread_mutex_lock(&g_vplugin_mutex) #define ext_vplugin_unlock() (void)pthread_mutex_unlock(&g_vplugin_mutex) static td_void mpi_vplugin_get_ctx(mpi_vplugin_ctx **server_ctx) { static mpi_vplugin_ctx g_vplugin_ctx; *server_ctx = &g_vplugin_ctx; } static td_s32 mpi_vplugin_get_buf_info(ext_drv_vplugin_stream_package_node *link_head, td_u32 read_pos, ext_drv_vplugin_stream_package_node **node) { if (link_head == TD_NULL) { soc_log_err("get buffer is null! \n!"); return TD_FAILURE; } if (read_pos >= PLUGIN_STREAM_NODE_CNT) { soc_log_err("%s returnread pos is over limit! read pos = %d! \n!", __func__, read_pos); return TD_FAILURE; } if (!link_head[read_pos].is_using) { soc_log_warn("%s return is_use = %d, pos = %d\n!", __func__, link_head[read_pos].is_using, read_pos); return TD_FAILURE; } if (node == NULL) { soc_log_err("%s node is null, pos = %d\n!", __func__, read_pos); return TD_FAILURE; } *node = &link_head[read_pos]; soc_log_info("%s get node %d success, size = %d\n", __func__, read_pos, sizeof(ext_drv_vplugin_stream_package_node)); return TD_SUCCESS; } static td_void mpi_vplugin_instance_init(mpi_vplugin_instance *instance) { soc_info_func_enter(); instance->read_pos = 0; instance->write_pos = 0; instance->buf_node = TD_NULL; instance->buf_size = 0; instance->vplugin_state = EXT_DRV_VPLUGIN_STATUS_NONE; soc_info_func_exit(); } td_s32 ext_mpi_vplugin_init(td_void) { td_u32 id; mpi_vplugin_ctx *vplugin_ctx = TD_NULL; mpi_vplugin_get_ctx(&vplugin_ctx); soc_info_func_enter(); if (g_vplugin_dev < 0) { g_vplugin_dev = open("/dev/soc_vplugin", O_RDWR | O_NONBLOCK, 0); if (g_vplugin_dev < 0) { soc_log_err("VPLUGIN device open error!"); return SOC_ERR_VPLUGIN_DEV_OPEN_ERR; } } for (id = 0; id < PLUGIN_MAX_CNT; id++) { mpi_vplugin_instance_init(&vplugin_ctx->vplugin_instance[id]); } soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_vplugin_deinit(td_void) { td_u32 id; td_s32 ret; mpi_vplugin_ctx *vplugin_ctx = TD_NULL; mpi_vplugin_get_ctx(&vplugin_ctx); soc_info_func_enter(); for (id = 0; id < PLUGIN_MAX_CNT; id++) { mpi_vplugin_instance_init(&vplugin_ctx->vplugin_instance[id]); } if (g_vplugin_dev < 0) { return TD_SUCCESS; } ret = close(g_vplugin_dev); if (ret != TD_SUCCESS) { return SOC_ERR_VPLUGIN_DEV_OPEN_ERR; } g_vplugin_dev = -1; soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_vplugin_create(td_handle win_handle, td_handle *vplugin_handle) { td_s32 ret; vplugin_instance_info vplugin_instance; void *vir_addr = TD_NULL; mpi_vplugin_ctx *vplugin_ctx = TD_NULL; soc_log_info("ext_mpi_vplugin_create start!\n"); if (vplugin_handle == TD_NULL) { soc_log_err("ptr vplugin_handle is NULL!\n"); return SOC_ERR_PQ_NULL_PTR; } mpi_vplugin_get_ctx(&vplugin_ctx); if (memset_s(&vplugin_instance, sizeof(vplugin_instance_info), 0, sizeof(vplugin_instance_info)) != EOK) { soc_log_err("memset_s failed\n"); return TD_FAILURE; } vplugin_instance.win_handle = win_handle; ret = ioctl(g_vplugin_dev, CMD_VPLUGIN_ATTACH_INSTANCE, &vplugin_instance); if (ret != TD_SUCCESS) { soc_log_err("set vplugin enable failed, ret=%d", ret); return ret; } soc_log_info("vplugin id = %d, size = %d, fd = %d!\n", *vplugin_handle, vplugin_instance.vplugin_fd_size, vplugin_instance.vplugin_fd); vir_addr = mmap(TD_NULL, (size_t)vplugin_instance.vplugin_fd_size, PROT_READ | PROT_WRITE, MAP_SHARED, (int)vplugin_instance.vplugin_fd, 0); if (vir_addr == MAP_FAILED) { soc_log_err("%s mmap failed; errno: %2dn", __func__, errno); vplugin_instance.win_handle = TD_INVALID_HANDLE; ret = ioctl(g_vplugin_dev, CMD_VPLUGIN_DESTROY_INSTANCE, &vplugin_instance); if (ret != TD_SUCCESS) { soc_log_err("set vplugin destroy failed, ret=%d", ret); return ret; } return TD_FAILURE; } *vplugin_handle = vplugin_instance.vplugin_handle; vplugin_ctx->vplugin_instance[*vplugin_handle].win_handle = win_handle; vplugin_ctx->vplugin_instance[*vplugin_handle].buf_node = (ext_drv_vplugin_stream_package_node *)vir_addr; vplugin_ctx->vplugin_instance[*vplugin_handle].buf_size = vplugin_instance.vplugin_fd_size; vplugin_ctx->vplugin_instance[*vplugin_handle].buf_ctrl = (ext_drv_vplugin_buf_ctrl_info *)((td_u8 *)vir_addr + sizeof(ext_drv_vplugin_stream_package_node) * PLUGIN_STREAM_NODE_CNT); soc_log_info("[%s] vplugin id = %d fd = %d fd_size = %d, offset = [0x%x]\n", __func__, *vplugin_handle, vplugin_instance.vplugin_fd, vplugin_ctx->vplugin_instance[*vplugin_handle].buf_size, ((td_u8 *)vplugin_ctx->vplugin_instance[*vplugin_handle].buf_ctrl - (td_u8 *)vplugin_ctx->vplugin_instance[*vplugin_handle].buf_node)); soc_log_info("create is ok\n"); return TD_SUCCESS; } td_s32 ext_mpi_vplugin_destroy(td_handle vplugin_handle) { td_s32 ret; void *vir_addr = TD_NULL; td_u32 buf_size = 0; mpi_vplugin_ctx *vplugin_ctx = TD_NULL; vplugin_instance_info vplugin_instance; if (memset_s(&vplugin_instance, sizeof(vplugin_instance_info), 0, sizeof(vplugin_instance_info)) != EOK) { soc_log_err("memset_s failed\n"); return TD_FAILURE; } mpi_vplugin_get_ctx(&vplugin_ctx); vir_addr = (void *)vplugin_ctx->vplugin_instance[vplugin_handle].buf_node; buf_size = vplugin_ctx->vplugin_instance[vplugin_handle].buf_size; if (vir_addr == NULL || buf_size == 0) { soc_log_err("buf addr is null or buf size(%d) is 0", buf_size); return SOC_ERR_VPLUGIN_PARAM_INVALID; } munmap(vir_addr, buf_size); vplugin_instance.vplugin_handle = vplugin_handle; vplugin_instance.win_handle = vplugin_ctx->vplugin_instance[vplugin_handle].win_handle; ret = ioctl(g_vplugin_dev, CMD_VPLUGIN_DESTROY_INSTANCE, &vplugin_instance); if (ret != TD_SUCCESS) { soc_log_err("set vplugin destroy failed, ret=%d", ret); return ret; } vplugin_ctx->vplugin_instance[vplugin_handle].read_pos = 0; vplugin_ctx->vplugin_instance[vplugin_handle].write_pos = 0; vplugin_ctx->vplugin_instance[vplugin_handle].win_handle = -1; vplugin_ctx->vplugin_instance[vplugin_handle].vplugin_state = EXT_DRV_VPLUGIN_STATUS_NONE; vplugin_ctx->vplugin_instance[vplugin_handle].buf_node = TD_NULL; vplugin_ctx->vplugin_instance[vplugin_handle].buf_size = 0; return TD_SUCCESS; } td_s32 ext_mpi_vplugin_set_enable(td_handle vplugin_handle, ext_drv_vplugin_stream_index stream_index, td_bool enable) { td_s32 ret; vplugin_enable vplugin_en = {0}; soc_info_func_enter(); mpi_vplugin_ctx *vplugin_ctx = TD_NULL; mpi_vplugin_get_ctx(&vplugin_ctx); if (vplugin_ctx == TD_NULL) { soc_log_err(" sendback_stream vplugin ctx is NULL!\n"); return TD_FAILURE; } vplugin_en.enable = enable; vplugin_en.stream_index = stream_index; vplugin_en.vplugin_handle = vplugin_handle; soc_log_info("mpi set handle 0x%0x, enable %d\n", vplugin_en.vplugin_handle, vplugin_en.enable); ret = ioctl(g_vplugin_dev, CMD_VPLUGIN_SET_ENABLE, &vplugin_en); if (ret != TD_SUCCESS) { soc_log_err("set vplugin enable failed, ret=%d", ret); return ret; } if (memcpy_s(&(g_vplugin_module[vplugin_handle]), sizeof(g_vplugin_module[vplugin_handle]), &vplugin_en, sizeof(vplugin_enable)) != EOK) { soc_log_err("memcpy_s failed\n"); return TD_FAILURE; } soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_vplugin_get_enable(td_handle vplugin_handle, ext_drv_vplugin_stream_index stream_index, td_bool *enable) { soc_info_func_enter(); if (enable == TD_NULL) { soc_log_err("ptr enable is NULL!\n"); return SOC_ERR_PQ_NULL_PTR; } vplugin_handle = g_vplugin_module[vplugin_handle].vplugin_handle; stream_index = g_vplugin_module[vplugin_handle].stream_index; *enable = g_vplugin_module[vplugin_handle].enable; soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_vplugin_get_inst_status(td_handle vplugin_handle, ext_drv_vplugin_state *inst_status) { td_s32 ret; vplugin_status status = {0}; soc_info_func_enter(); if (inst_status == TD_NULL) { soc_log_err("ptr inst_status is NULL!\n"); return SOC_ERR_PQ_NULL_PTR; } soc_log_info("mpi get_inst_status vplugin_handle %x\n", vplugin_handle); status.vplugin_handle = vplugin_handle; ret = ioctl(g_vplugin_dev, CMD_VPLUGIN_GET_INSTANCE_STATUS, &status); if (ret != TD_SUCCESS) { soc_log_err("get vplugin inst status failed, ret=%d", ret); } *inst_status = status.state; soc_info_func_exit(); return ret; } td_s32 ext_mpi_vplugin_set_param(td_handle vplugin_handle, ext_drv_vplugin_stream_index stream_index, ext_drv_vplugin_frontout_param *frontout_param, ext_drv_vplugin_backin_param *backin_param) { td_s32 ret; soc_info_func_enter(); vplugin_param param; if (frontout_param == TD_NULL) { soc_log_err("ptr frontout_param is NULL!\n"); return SOC_ERR_PQ_NULL_PTR; } if (backin_param == TD_NULL) { soc_log_err("ptr backin_param is NULL!\n"); return SOC_ERR_PQ_NULL_PTR; } param.vplugin_handle = vplugin_handle; param.stream_index = stream_index; param.frontout_param.frame_format = frontout_param->frame_format; param.frontout_param.frame_bit_depth = frontout_param->frame_bit_depth; if (memcpy_s(&(param.frontout_param.crop_rect), sizeof(param.frontout_param.crop_rect), &(frontout_param->crop_rect), sizeof(frontout_param->crop_rect)) != EOK) { soc_log_err("memcpy_s failed\n"); return TD_FAILURE; } param.frontout_param.frame_width = frontout_param->frame_width; param.frontout_param.frame_height = frontout_param->frame_height; param.backin_param.frame_format = backin_param->frame_format; param.backin_param.frame_bit_depth = backin_param->frame_bit_depth; param.backin_param.frame_stride_y = backin_param->frame_stride_y; param.backin_param.frame_stride_c = backin_param->frame_stride_c; param.backin_param.frame_width = backin_param->frame_width; param.backin_param.frame_height = backin_param->frame_height; param.backin_param.result_cnt = backin_param->result_cnt; param.backin_param.secure_frame = backin_param->secure_frame; if (memcpy_s(&(param.backin_param.result_size), sizeof(param.backin_param.result_size), &(backin_param->result_size), sizeof(backin_param->result_size)) != EOK) { soc_log_err("memcpy_s failed\n"); return TD_FAILURE; } ret = ioctl(g_vplugin_dev, CMD_VPLUGIN_SET_CONFIG_PARAM, ¶m); if (ret != TD_SUCCESS) { soc_log_err("set vplugin server config param failed, ret=%d", ret); } soc_info_func_exit(); return ret; } td_s32 ext_mpi_vplugin_get_param(td_handle vplugin_handle, ext_drv_vplugin_stream_index stream_index, ext_drv_vplugin_frontout_param *frontout_param, ext_drv_vplugin_backin_param *backin_param) { td_s32 ret; soc_info_func_enter(); vplugin_param param; if (frontout_param == TD_NULL) { soc_log_err("ptr frontout_param is NULL!\n"); return SOC_ERR_PQ_NULL_PTR; } if (backin_param == TD_NULL) { soc_log_err("ptr backin_param is NULL!\n"); return SOC_ERR_PQ_NULL_PTR; } if (memset_s(¶m, sizeof(vplugin_param), 0, sizeof(vplugin_param)) != EOK) { soc_log_err("memset_s failed\n"); return TD_FAILURE; } param.vplugin_handle = vplugin_handle; param.stream_index = stream_index; soc_log_info("mpi handle:%d index:%d\n", vplugin_handle, stream_index); ret = ioctl(g_vplugin_dev, CMD_VPLUGIN_GET_CONFIG_PARAM, ¶m); if (ret != TD_SUCCESS) { soc_log_err("set vplugin server config param failed, ret=0x%x", ret); return ret; } frontout_param->frame_format = param.frontout_param.frame_format; frontout_param->frame_bit_depth = param.frontout_param.frame_bit_depth; if (memcpy_s(&(frontout_param->crop_rect), sizeof(param.frontout_param.crop_rect), &(param.frontout_param.crop_rect), sizeof(frontout_param->crop_rect)) != EOK) { soc_log_err("memcpy_s failed\n"); return TD_FAILURE; } frontout_param->frame_width = param.frontout_param.frame_width; frontout_param->frame_height = param.frontout_param.frame_height; backin_param->frame_format = param.backin_param.frame_format; backin_param->frame_bit_depth = param.backin_param.frame_bit_depth; backin_param->frame_stride_y = param.backin_param.frame_stride_y; backin_param->frame_stride_c = param.backin_param.frame_stride_c; backin_param->frame_width = param.backin_param.frame_width; backin_param->frame_height = param.backin_param.frame_height; backin_param->result_cnt = param.backin_param.result_cnt; backin_param->secure_frame = param.backin_param.secure_frame; if (memcpy_s(&(backin_param->result_size), sizeof(param.backin_param.result_size), &(param.backin_param.result_size), sizeof(backin_param->result_size)) != EOK) { soc_log_err("memcpy_s failed\n"); return TD_FAILURE; } soc_log_info("handle:%d stream:%d\n", param.vplugin_handle, param.stream_index); soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_vplugin_catch_stream(td_handle vplugin_handle, ext_drv_vplugin_frontout_stream_package *frontout_stream_package, ext_drv_vplugin_backin_stream_package *backin_stream_package, ext_drv_vplugin_rect_info *rect_info, td_u32 timeout_ms) { TD_UNUSED(timeout_ms); td_s32 ret = 0; mpi_vplugin_ctx *vplugin_ctx = TD_NULL; size_t length; td_u32 read_pos = 0; ext_drv_vplugin_stream_package_node *node = TD_NULL; ext_drv_vplugin_buf_ctrl_info *buf_ctrl = TD_NULL; td_u32 start_time, end_time; ext_mpi_sys_get_time_stamp_ms(&start_time); if ((frontout_stream_package == TD_NULL) || (backin_stream_package == TD_NULL || rect_info == TD_NULL)) { soc_log_err("frontout_stream_package or backin_stream_package or rect_info is NULL!\n"); return SOC_ERR_VPLUGIN_PARAM_INVALID; } ext_vplugin_lock(); mpi_vplugin_get_ctx(&vplugin_ctx); if (vplugin_ctx == TD_NULL) { soc_log_err(" catch_stream vplugin ctx is NULL!\n"); ext_vplugin_unlock(); return TD_FAILURE; } buf_ctrl = vplugin_ctx->vplugin_instance[vplugin_handle].buf_ctrl; if (buf_ctrl == TD_NULL) { soc_log_err(" catch_stream vplugin buf_ctrl is NULL!\n"); ext_vplugin_unlock(); return TD_FAILURE; } buf_ctrl->catch_intval = (start_time > buf_ctrl->last_catch_time) ? (start_time - buf_ctrl->last_catch_time) : buf_ctrl->catch_intval; buf_ctrl->max_catch_intval = (buf_ctrl->catch_intval > buf_ctrl->max_catch_intval) ? buf_ctrl->catch_intval : buf_ctrl->max_catch_intval; buf_ctrl->avg_catch_intval = (buf_ctrl->avg_catch_intval * buf_ctrl->catch_try_times + buf_ctrl->catch_intval) / (buf_ctrl->catch_try_times + 1); buf_ctrl->last_catch_time = start_time; buf_ctrl->catch_try_times++; read_pos = vplugin_ctx->vplugin_instance[vplugin_handle].read_pos; soc_log_info("[mpi catch dbg] catch_stream enter vplugin_handle = [%d]\n", vplugin_handle); soc_log_info("[mpi catch dbg] catch_stream get buffer read_pos = [%d]\n", vplugin_ctx->vplugin_instance[vplugin_handle].read_pos); ret = mpi_vplugin_get_buf_info(vplugin_ctx->vplugin_instance[vplugin_handle].buf_node, read_pos, &node); if (ret != TD_SUCCESS) { soc_log_warn("[mpi catch dbg] catch_stream failed!!!\n"); ext_vplugin_unlock(); return TD_FAILURE; } node->perf_info.catch_start_time = start_time; soc_log_info("[mpi catch dbg] catch_stream enter frontout dma_handle = 0x[%llx], backin dma_handle = 0x[%llx]\n", node->stream_package_info.frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN] .frontout_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle, node->stream_package_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN] .backin_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle); ret = ioctl(g_vplugin_dev, CMD_VPLUGIN_CATCH_STREAM, &node->stream_package_info); if (ret != TD_SUCCESS) { soc_log_err("%s get buffer fd ioctrl failed, ret=0x%x", __func__, ret); } if (node->stream_package_info.frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN]. frontout_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].start_addr == -1) { soc_log_err("catch fd is invalid!\n"); } soc_log_info("[mpi catch dbg] catch_stream enter frontout fd = [%lld], backin fd = [%lld]\n", node->stream_package_info.frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN] .frontout_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].start_addr, node->stream_package_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN] .backin_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].start_addr); length = sizeof(ext_drv_video_frame); if ((memcpy_s(&(frontout_stream_package->frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame), sizeof(ext_drv_video_frame), &node->stream_package_info.frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame, length)) != EOK) { soc_log_err("memcpy set backin_param param failed\n"); ext_vplugin_unlock(); return TD_FAILURE; } frontout_stream_package->frontout_stream_cnt = node->stream_package_info.frontout_stream_package.frontout_stream_cnt; frontout_stream_package->frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_valid = TD_TRUE; frontout_stream_package->frontout_stream[EXT_DRV_VPLUGIN_STREAM_EXT_0].stream_valid = TD_FALSE; backin_stream_package->backin_stream_cnt = node->stream_package_info.backin_stream_package.backin_stream_cnt; backin_stream_package->backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_valid = TD_TRUE; backin_stream_package->backin_stream[EXT_DRV_VPLUGIN_STREAM_EXT_0].stream_valid = TD_FALSE; soc_log_info("[mpi catch dbg] catch_stream enter frontout fd = [%d], backin fd = [%d]\n", node->stream_package_info.frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN] .frontout_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].start_addr, node->stream_package_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN] .backin_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].start_addr); if ((memcpy_s(&(backin_stream_package->backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].backin_frame), sizeof(ext_drv_video_frame), &node->stream_package_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].backin_frame, length)) != EOK) { soc_log_err("memcpy set backin_param param failed\n"); ext_vplugin_unlock(); return TD_FAILURE; } rect_info->video_rect = node->rect_info.video_rect; rect_info->crop_rect = node->rect_info.crop_rect; ext_mpi_sys_get_time_stamp_ms(&end_time); node->perf_info.catch_end_time = end_time; node->perf_info.buf_state = EXT_DRV_VPLUGIN_BUF_STATE_CATCH; buf_ctrl->read_pos = read_pos; buf_ctrl->catch_success_times++; vplugin_ctx->vplugin_instance[vplugin_handle].read_pos = (read_pos + 1) % PLUGIN_STREAM_NODE_CNT; ext_vplugin_unlock(); return TD_SUCCESS; } td_s32 ext_mpi_vplugin_sendback_stream(td_handle vplugin_handle, ext_drv_vplugin_backin_stream_package *backin_stream_package, ext_drv_vplugin_frontout_stream_package *frontout_stream_package) { td_s32 ret; td_u32 write_pos = 0; size_t length; ext_drv_vplugin_stream_package_node *node = TD_NULL; mpi_vplugin_ctx *vplugin_ctx = TD_NULL; td_u32 start_time, end_time; ext_drv_vplugin_buf_ctrl_info *buf_ctrl = TD_NULL; ext_mpi_sys_get_time_stamp_ms(&start_time); ext_vplugin_lock(); mpi_vplugin_get_ctx(&vplugin_ctx); if (vplugin_ctx == TD_NULL) { soc_log_err(" sendback_stream vplugin ctx is NULL!\n"); ext_vplugin_unlock(); return TD_FAILURE; } write_pos = vplugin_ctx->vplugin_instance[vplugin_handle].write_pos; buf_ctrl = vplugin_ctx->vplugin_instance[vplugin_handle].buf_ctrl; if (buf_ctrl == TD_NULL) { soc_log_err(" sendback_stream vplugin buf_ctrl is NULL!\n"); ext_vplugin_unlock(); return TD_FAILURE; } buf_ctrl->sendback_intval = (start_time > buf_ctrl->last_sendback_time) ? (start_time - buf_ctrl->last_sendback_time) : buf_ctrl->sendback_intval; buf_ctrl->max_sendback_intval = (buf_ctrl->sendback_intval > buf_ctrl->max_sendback_intval) ? buf_ctrl->sendback_intval : buf_ctrl->max_sendback_intval; buf_ctrl->avg_sendback_intval = (buf_ctrl->avg_sendback_intval * buf_ctrl->sendback_try_times + buf_ctrl->sendback_intval) / (buf_ctrl->sendback_try_times + 1); buf_ctrl->last_sendback_time = start_time; buf_ctrl->sendback_try_times++; soc_log_info("[mpi sendback dbg] sendback_stream enter vplugin_handle = [%d], write_pos = %d\n", vplugin_handle, write_pos); ret = mpi_vplugin_get_buf_info(vplugin_ctx->vplugin_instance[vplugin_handle].buf_node, write_pos, &node); if (ret != TD_SUCCESS) { soc_log_err("[mpi sendback dbg] sendback_stream failed!!!\n"); ext_vplugin_unlock(); return TD_FAILURE; } length = sizeof(ext_drv_video_frame); node->perf_info.sendback_start_time = start_time; node->perf_info.alg_cost_time = node->perf_info.sendback_start_time - node->perf_info.catch_end_time; td_u64 dma_handle_frontout = node->stream_package_info.frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN]. frontout_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle; if ((memcpy_s(&node->stream_package_info.frontout_stream_package. frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame, sizeof(ext_drv_video_frame), &(frontout_stream_package->frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame), length)) != EOK) { soc_log_err("memcpy set backin_param param failed\n"); ext_vplugin_unlock(); return TD_FAILURE; } node->stream_package_info.frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN]. frontout_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle = dma_handle_frontout; node->stream_package_info.frontout_stream_package.frontout_stream_cnt = frontout_stream_package->frontout_stream_cnt; node->stream_package_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN]. stream_valid = backin_stream_package->backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_valid; node->stream_package_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN]. frame_vaild = backin_stream_package->backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frame_vaild; node->stream_package_info.frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_valid = frontout_stream_package->frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_valid; frontout_stream_package->frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_valid = TD_TRUE; frontout_stream_package->frontout_stream[EXT_DRV_VPLUGIN_STREAM_EXT_0].stream_valid = TD_FALSE; node->stream_package_info.backin_stream_package.backin_stream_cnt = backin_stream_package->backin_stream_cnt; td_u64 dma_hadnle_backin = node->stream_package_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN]. backin_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle; if ((memcpy_s(&node->stream_package_info.backin_stream_package. backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].backin_frame, sizeof(ext_drv_video_frame), &(backin_stream_package->backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].backin_frame), length)) != EOK) { soc_log_err("memcpy set backin_param param failed\n"); ext_vplugin_unlock(); return TD_FAILURE; } node->stream_package_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN]. backin_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle = dma_hadnle_backin; soc_log_info("[mpi catch dbg] backin drv frame_vaild = [%d]]\n", backin_stream_package->backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frame_vaild); soc_log_info("[mpi sendback] handle = [%d], read_pos = %d, is_using = %d\n", vplugin_handle, write_pos, vplugin_ctx->vplugin_instance[vplugin_handle].buf_node->is_using); node->is_using = TD_FALSE; ext_mpi_sys_get_time_stamp_ms(&end_time); node->perf_info.sendback_end_time = end_time; node->perf_info.buf_state = EXT_DRV_VPLUGIN_BUF_STATE_BACK; buf_ctrl->write_pos = write_pos; buf_ctrl->alg_cost_time = node->perf_info.alg_cost_time; buf_ctrl->max_alg_cost_time = (buf_ctrl->alg_cost_time > buf_ctrl->max_alg_cost_time) ? buf_ctrl->alg_cost_time : buf_ctrl->max_alg_cost_time; buf_ctrl->avg_alg_cost_time = (buf_ctrl->avg_alg_cost_time * buf_ctrl->sendback_success_times + buf_ctrl->alg_cost_time) / (buf_ctrl->sendback_success_times + 1); buf_ctrl->sendback_success_times++; vplugin_ctx->vplugin_instance[vplugin_handle].write_pos = (write_pos + 1) % PLUGIN_STREAM_NODE_CNT; static td_u32 send_all_num = 0; soc_log_info("send_all_num = [%d]\n", ++send_all_num); ext_vplugin_unlock(); return TD_SUCCESS; } #ifdef __cplusplus #if __cplusplus } #endif #endif /* __cplusplus */