/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2030. All rights reserved. * Description: vplugin module * Author: Hisilicon * Create: 2020-02-28 */ #include "linux/huanglong/securec.h" #include "soc_log.h" #include "osal_ext.h" #include "soc_errno.h" #include "drv_vplugin_proc.h" #include "drv_vplugin.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif #define VPLUGIN_WAIT_OUT_TIMES 500 #define VPLUGIN_INST_BUF_NAME_LEN 30 #define MEM_PAGE_SIZE 4096 #define vplugin_mem_align(size) ((((size) + (MEM_PAGE_SIZE - 1)) / MEM_PAGE_SIZE) * MEM_PAGE_SIZE) #define INVALID_FD (-1) drv_vplugin_ctx g_vplugin_ctx; #define MAX_FD_MATRIX_LENGTH 12 static td_s64 g_frontout_fd[MAX_FD_MATRIX_LENGTH][2] = {0}; /* 0 : dma; 1: fd */ static td_s32 g_frontout_index = 0; static td_s64 g_backin_fd[MAX_FD_MATRIX_LENGTH][2] = {0}; /* 0 : dma; 1: fd */ static td_s32 g_backin_index = 0; static const td_s32 g_digit_zero = 0; static const td_s32 g_digit_one = 1; static const td_s32 g_digit_two = 2; static const td_s32 g_digit_three = 3; static const td_s32 g_digit_four = 4; static const td_s32 g_digit_five = 5; osal_semaphore g_vplugin_mutex; td_s32 vplugin_osal_sem_init(td_void) { td_s32 ret; ret = osal_sem_init(&g_vplugin_mutex, 1); if (ret != TD_SUCCESS) { soc_log_err("osal_sem_init failed"); return TD_FAILURE; } return ret; } td_void vplugin_osal_sem_destroy(td_void) { if (g_vplugin_mutex.sem != TD_NULL) { osal_sem_destroy(&g_vplugin_mutex); g_vplugin_mutex.sem = TD_NULL; } return; } td_void vplugin_osal_sem_down(td_void) { osal_sem_down(&g_vplugin_mutex); } td_void vplugin_osal_sem_up(td_void) { osal_sem_up(&g_vplugin_mutex); } static td_s32 drv_vplugin_mem_alloc(const char *buf_name, drv_vplugin_mem_addr_info *buf) { td_u32 aligned_size; if (buf_name == TD_NULL || buf == TD_NULL) { soc_log_err("null ptr\n"); return SOC_ERR_VI_NULL_PTR; } aligned_size = vplugin_mem_align(buf->size); soc_log_info("org_size=%d aligned_size=%d \n", buf->size, aligned_size); buf->size = aligned_size; buf->buf_obj = osal_mem_alloc(buf_name, buf->size, buf->alloc_type, TD_NULL, 0); if (buf->buf_obj == TD_NULL) { soc_log_err("osal alloc failed\n"); goto out0; } buf->start_phy_addr = 0x0; if ((buf->alloc_type == OSAL_MMZ_TYPE) || (buf->alloc_type == OSAL_SECMMZ_TYPE)) { buf->start_phy_addr = osal_mem_phys(buf->buf_obj); } else if (buf->alloc_type == OSAL_NSSMMU_TYPE) { buf->start_phy_addr = osal_mem_nssmmu_map(buf->buf_obj, 0); } else if (buf->alloc_type == OSAL_SECSMMU_TYPE) { buf->start_phy_addr = osal_mem_secsmmu_map(buf->buf_obj, 0); } if (buf->start_phy_addr == 0x0) { soc_log_err("phys failed\n"); goto out1; } buf->buf_handle = INVALID_FD; buf->start_vir_addr = TD_NULL; return TD_SUCCESS; out1: osal_mem_free(buf->buf_obj); out0: return TD_FAILURE; } static td_void drv_vplugin_mem_release(drv_vplugin_mem_addr_info *buf) { td_s32 ret = TD_SUCCESS; if (buf == TD_NULL || buf->buf_obj == TD_NULL) { soc_log_err("null ptr\n"); return; } if (buf->start_vir_addr != TD_NULL) { osal_mem_kunmap(buf->buf_obj, buf->start_vir_addr, 0); buf->start_vir_addr = TD_NULL; } if (buf->alloc_type == OSAL_NSSMMU_TYPE) { ret = osal_mem_nssmmu_unmap(buf->buf_obj, buf->start_phy_addr, 0); } else if (buf->alloc_type == OSAL_SECSMMU_TYPE) { ret = osal_mem_secsmmu_unmap(buf->buf_obj, buf->start_phy_addr, 0); } if (ret != TD_SUCCESS) { soc_log_err("ummap dmabuf failed, mode = %d\n", buf->alloc_type); } osal_mem_free(buf->buf_obj); buf->start_phy_addr = 0x0; buf->buf_obj = TD_NULL; } static td_s32 drv_vplugin_mem_mmap(drv_vplugin_mem_addr_info *buf) { if (buf == TD_NULL) { soc_log_err("null ptr\n"); return SOC_ERR_VI_NULL_PTR; } buf->start_vir_addr = osal_mem_kmap(buf->buf_obj, 0, TD_FALSE); if (buf->start_vir_addr == TD_NULL) { return TD_FAILURE; } return TD_SUCCESS; } static td_void drv_vplugin_mem_unmap(drv_vplugin_mem_addr_info *buf) { if (buf == TD_NULL) { soc_log_err("null ptr\n"); return; } if (buf->start_vir_addr != TD_NULL) { osal_mem_kunmap(buf->buf_obj, buf->start_vir_addr, 0); buf->start_vir_addr = TD_NULL; } } td_s32 drv_vplugin_mem_alloc_and_map(const char *buf_name, drv_vplugin_mem_addr_info *buf) { td_s32 ret; ret = drv_vplugin_mem_alloc(buf_name, buf); if (ret != TD_SUCCESS) { soc_log_err("mem alloc failed\n"); return TD_FAILURE; } if (buf->is_map_viraddr == TD_TRUE) { ret = drv_vplugin_mem_mmap(buf); if (ret != TD_SUCCESS) { drv_vplugin_mem_release(buf); soc_log_err("map frame buffer failed\n"); buf->is_map_viraddr = TD_FALSE; return TD_FAILURE; } } return TD_SUCCESS; } td_void drv_vplugin_mem_unmap_and_release(drv_vplugin_mem_addr_info *buf) { drv_vplugin_mem_unmap(buf); drv_vplugin_mem_release(buf); } td_void drv_vplugin_mem_flush(drv_vplugin_mem_addr_info *buf) { if (buf == TD_NULL) { soc_log_err("null ptr\n"); return; } osal_mem_flush(buf->buf_obj); } td_s32 drv_vplugin_get_buf_fd(td_void *dma_buf) { td_s32 temp_fd; if (dma_buf == TD_NULL) { osal_printk("dma_buf is null pointer\n"); return TD_FAILURE; } temp_fd = osal_mem_create_fd(dma_buf, OSAL_O_CLOEXEC); if (temp_fd <= 0) { osal_printk("create fd failed, fd = %d\n", temp_fd); } return temp_fd; } td_void drv_vplugin_get_ctx(drv_vplugin_ctx **vplugin_ctx) { *vplugin_ctx = &g_vplugin_ctx; } td_s32 drv_vplugin_get_instance_position(td_u32 search_id, td_u32 *dst_pos) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); for (id = 0; id < PLUGIN_MAX_CNT; id++) { if (vplugin_ctx->vplugin_instance[id].vplugin_instance_id == search_id) { *dst_pos = id; break; } } if (id == PLUGIN_MAX_CNT) { soc_log_err("vplugin instance id %d not exist\n", search_id); return SOC_ERR_VPLUGIN_INVALID_ID; } return TD_SUCCESS; } td_s32 drv_vplugin_get_instance_by_vpss_handle(td_u32 search_id, td_u32 *dst_pos) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); for (id = 0; id < PLUGIN_MAX_CNT; id++) { if (vplugin_ctx->vplugin_instance[id].vpss_handle == search_id) { *dst_pos = id; break; } } if (id == PLUGIN_MAX_CNT) { soc_log_dbg("vplugin instance id %d not exist\n", search_id); return SOC_ERR_VPLUGIN_INVALID_ID; } return TD_SUCCESS; } drv_vplugin_instance *drv_vplugin_get_instance(td_handle vplugin_handle) { td_s32 ret; td_u32 inst_pos; drv_vplugin_instance *instance = TD_NULL; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); soc_log_info("%s %d\n", __func__, vplugin_handle); ret = drv_vplugin_get_instance_position(vplugin_handle, &inst_pos); if (ret != TD_SUCCESS) { soc_log_err("invalid instance id or not create instance\n"); return instance; } instance = &vplugin_ctx->vplugin_instance[inst_pos]; return instance; } static td_void drv_vplugin_clean_buffer(drv_vplugin_instance *instance) { td_u32 id; for (id = instance->read_id; id < instance->write_id; id = (id + 1) % PLUGIN_STREAM_NODE_CNT) { instance->buf_link_head[id].is_using = TD_FALSE; } instance->read_id = 0; instance->write_id = 0; } static td_void drv_vplugin_clean_buffer_fd_item(td_s64 dma_fd_matrix[][2], td_u32 idx) { dma_fd_matrix[idx][0] = TD_NULL; dma_fd_matrix[idx][1] = -1; return; } static td_void drv_vplugin_clean_buffer_fd(td_s64 dma_fd_matrix[][2], td_s32 *cnt, td_u32 max_length) { td_u32 id; for (id = 0; id < max_length; id++) { dma_fd_matrix[id][0] = TD_NULL; dma_fd_matrix[id][1] = -1; } *cnt = 0; return; } static td_void drv_vplugin_instance_init(drv_vplugin_instance *instance, td_u32 vplugin_id, ext_drv_vplugin_state state) { td_s32 ret; td_u32 size; instance->debug_enable = TD_FALSE; instance->instance_state = state; instance->vplugin_instance_id = vplugin_id; instance->win_handle = 0; instance->vpss_handle = TD_INVALID_HANDLE; instance->buf_cnt = 0; instance->read_id = 0; instance->write_id = 0; size = PLUGIN_STREAM_NODE_CNT * sizeof(ext_drv_vplugin_stream_package_node) + sizeof(ext_drv_vplugin_buf_ctrl_info); if (instance->buf_pool.start_vir_addr != TD_NULL) { ret = memset_s(instance->buf_pool.start_vir_addr, size, 0, size); if (ret != EOK) { soc_log_err("memset_s failed, err = %d\n", ret); return; } } ret = memset_s(&instance->work_record, sizeof(drv_vplugin_work_record), 0, sizeof(drv_vplugin_work_record)); if (ret != EOK) { soc_log_err("memset_s failed, err = %d\n", ret); return; } ret = memset_s(instance->stream_status, sizeof(ext_drv_vplugin_stream_status) * EXT_DRV_VPLUGIN_STREAM_MAX, 0, sizeof(ext_drv_vplugin_stream_status) * EXT_DRV_VPLUGIN_STREAM_MAX); if (ret != EOK) { soc_log_err("memset_s failed, err = %d\n", ret); return; } ret = memset_s(instance->param, sizeof(vplugin_param) * EXT_DRV_VPLUGIN_STREAM_MAX, 0, sizeof(vplugin_param) * EXT_DRV_VPLUGIN_STREAM_MAX); if (ret != EOK) { soc_log_err("memset_s failed, err = %d\n", ret); return; } } td_void drv_vplugin_print_inst_info (td_handle vplugin_handle) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); for (id = 0; id < vplugin_ctx->working_instance_cnt; id++) { soc_log_err("working_instance_cnt = %d\n", vplugin_ctx->working_instance_cnt); soc_log_err("win_handle = %d, vpss_handle = %d\n", vplugin_ctx->vplugin_instance[vplugin_handle].win_handle, vplugin_ctx->vplugin_instance[vplugin_handle].vpss_handle); soc_log_err("vplugin_instance_id = %d\n", vplugin_ctx->vplugin_instance[vplugin_handle].vplugin_instance_id); soc_log_err("instance_state = %d, server_instance_state = %d\n", vplugin_ctx->vplugin_instance[vplugin_handle].instance_state, vplugin_ctx->vplugin_instance[vplugin_handle].server_instance_state); } } static td_s32 drv_vplugin_malloc_share_buf(td_handle id) { td_s32 ret; td_char name[VPLUGIN_INST_BUF_NAME_LEN] = {0}; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); ret = snprintf_s(name, VPLUGIN_INST_BUF_NAME_LEN, VPLUGIN_INST_BUF_NAME_LEN - 1, "%s%d", "vplugin_inst_buf_", id); if (ret <= 0) { soc_log_err("vplugin instance%u snprintf_s failed, ret = 0x%x!\n", id, ret); return TD_FAILURE; } name[VPLUGIN_INST_BUF_NAME_LEN - 1] = '\0'; vplugin_ctx->vplugin_instance[id].buf_pool.alloc_type = OSAL_NSSMMU_TYPE; vplugin_ctx->vplugin_instance[id].buf_pool.size = PLUGIN_STREAM_NODE_CNT * sizeof(ext_drv_vplugin_stream_package_node) + sizeof(ext_drv_vplugin_buf_ctrl_info); vplugin_ctx->vplugin_instance[id].buf_pool.is_map_viraddr = TD_TRUE; ret = drv_vplugin_mem_alloc_and_map(name, &vplugin_ctx->vplugin_instance[id].buf_pool); if (ret != TD_SUCCESS) { drv_vplugin_mem_unmap_and_release(&vplugin_ctx->vplugin_instance[id].buf_pool); return TD_FAILURE; } soc_log_info("[drv malloc buff] vir_addr = [0x%x]!\n", vplugin_ctx->vplugin_instance[id].buf_pool.start_vir_addr); vplugin_ctx->vplugin_instance[id].vplugin_fd_size = vplugin_ctx->vplugin_instance[id].buf_pool.size; vplugin_ctx->vplugin_instance[id].buf_link_head = (ext_drv_vplugin_stream_package_node *)vplugin_ctx->vplugin_instance[id].buf_pool.start_vir_addr; vplugin_ctx->vplugin_instance[id].buf_ctrl = (ext_drv_vplugin_buf_ctrl_info *)((td_u8 *)vplugin_ctx->vplugin_instance[id].buf_pool.start_vir_addr + (PLUGIN_STREAM_NODE_CNT * sizeof(ext_drv_vplugin_stream_package_node))); soc_log_info("[%s] fd_size = %d, start_vir = [0x%x], buf_ctr = [0x%x], offset = [0x%x]\n", __func__, vplugin_ctx->vplugin_instance[id].vplugin_fd_size, vplugin_ctx->vplugin_instance[id].buf_link_head, vplugin_ctx->vplugin_instance[id].buf_ctrl, ((td_u8 *)vplugin_ctx->vplugin_instance[id].buf_ctrl - (td_u8 *)vplugin_ctx->vplugin_instance[id].buf_link_head)); return TD_SUCCESS; } static td_s32 drv_vplugin_get_instance_id(drv_vplugin_ctx *vplugin_ctx, td_u32 *inst_pos, td_u32 *inst_id) { td_u32 pos; for (pos = 0; pos < PLUGIN_MAX_CNT; pos++) { if (vplugin_ctx->vplugin_instance[pos].win_handle == TD_INVALID_HANDLE) { *inst_pos = pos; *inst_id = vplugin_ctx->vplugin_instance[pos].vplugin_instance_id; return TD_SUCCESS; } } for (pos = 0; pos < PLUGIN_MAX_CNT; pos++) { if (vplugin_ctx->vplugin_instance[pos].vplugin_instance_id == EXT_VPLUGIN_INVAL_ID) { *inst_pos = pos; *inst_id = pos; break; } } if (pos >= PLUGIN_MAX_CNT) { soc_log_err("instance cnt support max:%d\n", PLUGIN_MAX_CNT); return TD_FAILURE; } return TD_SUCCESS; } /******************************************************************************************* vpss implement SPI interface *******************************************************************************************/ td_s32 drv_vplugin_create_instance(td_handle vpss_handle, td_handle win_handle, td_handle *vplugin_handle) { td_u32 inst_pos = 0; td_u32 inst_id = 0; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); vplugin_osal_sem_down(); soc_log_info("%s start, win_handle = %d, vpss_handle = %d, \n", __func__, win_handle, vpss_handle); if (vplugin_ctx->working_instance_cnt == PLUGIN_MAX_CNT) { soc_log_err("instance cnt support max:%d\n", PLUGIN_MAX_CNT); vplugin_osal_sem_up(); return SOC_ERR_VPLUGIN_WORKING_CNT_IS_MAX; } if (drv_vplugin_get_instance_id(vplugin_ctx, &inst_pos, &inst_id) != TD_SUCCESS) { soc_log_err("%s get istance id %d faild, instance num lager than:%d\n", __func__, inst_id, PLUGIN_MAX_CNT); vplugin_osal_sem_up(); return TD_FAILURE; } if (vplugin_ctx->vplugin_instance[inst_pos].buf_pool.buf_obj != TD_NULL) { soc_log_err("vplugin pos = %d malloc_share_buf exist\n", inst_pos); } else { if (drv_vplugin_malloc_share_buf(inst_pos) != TD_SUCCESS) { soc_log_err("vplugin pos = %d malloc_share_buf failed\n", inst_pos); vplugin_osal_sem_up(); return TD_FAILURE; } } soc_log_info("drv_vplugin_malloc_share_buf buf_obj 0x%x \n", vplugin_ctx->vplugin_instance[inst_pos].buf_pool.buf_obj); vplugin_ctx->working_instance_cnt += 1; drv_vplugin_instance_init(&vplugin_ctx->vplugin_instance[inst_pos], inst_id, EXT_DRV_VPLUGIN_STATUS_NONE); *vplugin_handle = inst_id; vplugin_ctx->vplugin_instance[inst_pos].win_handle = win_handle; vplugin_ctx->vplugin_instance[inst_pos].vpss_handle = vpss_handle; vplugin_osal_sem_up(); if (drv_vplugin_proc_add(inst_id) != TD_SUCCESS) { soc_log_err("vplugin instance = %d create proc failed\n", inst_id); } soc_log_info("%s end, win_handle = %d, vpss_handle = %d, id = %d, inst_pos = %d, all_instance_cnt = %d \n", __func__, win_handle, vpss_handle, inst_id, inst_pos, vplugin_ctx->working_instance_cnt); soc_log_info("%s end, buf_cnt = %d, read_id = %d, write_id = %d, \n", __func__, vplugin_ctx->vplugin_instance[inst_pos].buf_cnt, vplugin_ctx->vplugin_instance[inst_pos].read_id, vplugin_ctx->vplugin_instance[inst_pos].write_id); return TD_SUCCESS; } td_s32 drv_vplugin_destroy_instance(td_handle vplugin_handle) { td_s32 ret; td_u32 inst_pos; drv_vplugin_instance *instance = TD_NULL; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); soc_log_info("%s %d\n", __func__, vplugin_handle); drv_vplugin_proc_del(vplugin_handle); vplugin_osal_sem_down(); ret = drv_vplugin_get_instance_position(vplugin_handle, &inst_pos); if (ret != TD_SUCCESS) { soc_log_err("invalid instance id or not create instance\n"); vplugin_osal_sem_up(); return ret; } instance = &vplugin_ctx->vplugin_instance[inst_pos]; instance->instance_state = EXT_DRV_VPLUGIN_STATUS_DESTROY; if (vplugin_ctx->vplugin_instance[inst_pos].buf_pool.buf_obj != TD_NULL) { /* release share memory */ drv_vplugin_mem_unmap_and_release(&vplugin_ctx->vplugin_instance[inst_pos].buf_pool); vplugin_ctx->vplugin_instance[inst_pos].buf_link_head = TD_NULL; } vplugin_ctx->working_instance_cnt -= 1; if (instance->stream_status[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_ready == TD_FALSE) { drv_vplugin_instance_init(instance, EXT_VPLUGIN_INVAL_ID, EXT_DRV_VPLUGIN_STATUS_DESTROY); } instance->vpss_handle = TD_INVALID_HANDLE; instance = TD_NULL; soc_log_info("vplugin instance:vplugin_debug destory finish\n"); vplugin_osal_sem_up(); return TD_SUCCESS; } td_s32 drv_vplugin_start_instance(td_handle vplugin_handle) { td_s32 ret; td_u32 inst_pos; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); soc_log_info("%s %d\n", __func__, vplugin_handle); ret = drv_vplugin_get_instance_position(vplugin_handle, &inst_pos); if (ret != TD_SUCCESS) { soc_log_err("invalid instance id or not create instance\n"); return ret; } vplugin_ctx->vplugin_instance[inst_pos].instance_state = EXT_DRV_VPLUGIN_STATUS_START; return TD_SUCCESS; } td_s32 drv_vplugin_stop_instance(td_handle vplugin_handle) { td_s32 ret; td_u32 inst_pos; drv_vplugin_instance *instance = TD_NULL; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); soc_log_info("%s %d\n", __func__, vplugin_handle); ret = drv_vplugin_get_instance_position(vplugin_handle, &inst_pos); if (ret != TD_SUCCESS) { soc_log_notice("invalid instance id or not create instance\n"); return ret; } instance = &vplugin_ctx->vplugin_instance[inst_pos]; instance->instance_state = EXT_DRV_VPLUGIN_STATUS_STOP; instance = TD_NULL; soc_log_info("vplugin instance:x stop finish\n"); return TD_SUCCESS; } td_s32 drv_vplugin_get_status(td_handle vpss_handle, ext_drv_vpss_vplugin_stream_index stream_index, ext_drv_vpss_vplugin_stream_status *stream_status) { td_s32 ret; td_u32 inst_pos; drv_vplugin_instance *instance = TD_NULL; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); ret = drv_vplugin_get_instance_by_vpss_handle(vpss_handle, &inst_pos); if (ret != TD_SUCCESS) { soc_log_notice("invalid instance id or not create instance\n"); return ret; } instance = &vplugin_ctx->vplugin_instance[inst_pos]; stream_status->stream_ready = instance->stream_status[stream_index].stream_ready; soc_log_info("%s %d, status is %d\n", __func__, vplugin_ctx->vplugin_instance[inst_pos].vplugin_instance_id, stream_status->stream_ready); return TD_SUCCESS; } td_s32 drv_vplugin_get_param(td_handle vpss_handle, ext_drv_vpss_vplugin_stream_index stream_index, ext_drv_vpss_vplugin_frontout_param *frontout_param, ext_drv_vpss_vplugin_backin_param *backin_param) { td_s32 ret; td_u32 inst_pos; drv_vplugin_instance *instance = TD_NULL; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); ret = drv_vplugin_get_instance_by_vpss_handle(vpss_handle, &inst_pos); if (ret != TD_SUCCESS) { soc_log_notice("invalid instance id or not create instance\n"); return ret; } instance = &vplugin_ctx->vplugin_instance[inst_pos]; if (memcpy_s(frontout_param, sizeof(ext_drv_vplugin_frontout_param), &(instance->param[stream_index].frontout_param), sizeof(instance->param[stream_index].frontout_param)) != EOK) { soc_log_err("save server config param failed\n"); return TD_FAILURE; } if (memcpy_s(backin_param, sizeof(ext_drv_vplugin_backin_param), &(instance->param[stream_index].backin_param), sizeof(instance->param[stream_index].backin_param)) != EOK) { soc_log_err("save server config param failed\n"); return TD_FAILURE; } soc_log_info("%s vplugin_id = %d, inst_pos = %d\n", __func__, instance->vplugin_instance_id, inst_pos); return TD_SUCCESS; } td_s32 drv_vplugin_queue_frame(td_handle vplugin_handle, ext_drv_vpss_vplugin_frontout_stream *frontout_stream, ext_drv_vpss_vplugin_backin_stream *backin_stream, ext_drv_vpss_vplugin_rect_info *rect_info) { td_s32 ret; td_u32 inst_pos; drv_vplugin_ctx *vplugin_ctx = TD_NULL; ext_drv_vplugin_stream_package_info *stream_package_info = TD_NULL; drv_vplugin_instance *instance = TD_NULL; soc_log_info("[drv queue frame]drv_vplugin_queue_frame enter vplugin_handle = [%d]\n", vplugin_handle); drv_vplugin_get_ctx(&vplugin_ctx); ret = drv_vplugin_get_instance_position(vplugin_handle, &inst_pos); if (ret != TD_SUCCESS) { soc_log_notice("invalid instance id or not create instance\n"); return ret; } vplugin_ctx->vplugin_instance[inst_pos].work_record.try_queue_cnt++; if (vplugin_ctx->vplugin_instance[inst_pos].instance_state != EXT_DRV_VPLUGIN_STATUS_START) { soc_log_notice("instance not start\n"); return SOC_ERR_VPLUGIN_INSTANCE_NOT_START; } if (vplugin_ctx->vplugin_instance[inst_pos].buf_cnt == PLUGIN_STREAM_NODE_CNT) { return SOC_ERR_VPLUGIN_FIFO_FULL; } instance = &vplugin_ctx->vplugin_instance[inst_pos]; stream_package_info = &(instance->buf_link_head[instance->write_id].stream_package_info); ret = memcpy_s(stream_package_info->frontout_stream_package.frontout_stream, sizeof(stream_package_info->frontout_stream_package.frontout_stream), frontout_stream, sizeof(ext_drv_vplugin_frontout_stream)); if (ret != EOK) { soc_log_info("%s copy frontout_stream failed!\n", __func__); return SOC_ERR_VPLUGIN_PARAM_INVALID; } /* only support one stream currently, it should adjuct when support ext stream */ stream_package_info->frontout_stream_package.frontout_stream_cnt = 1; ret = memcpy_s(stream_package_info->backin_stream_package.backin_stream, sizeof(stream_package_info->backin_stream_package.backin_stream), backin_stream, sizeof(ext_drv_vplugin_backin_stream)); if (ret != EOK) { soc_log_info("%s copy backin_stream failed!\n", __func__); return SOC_ERR_VPLUGIN_PARAM_INVALID; } instance->buf_link_head[instance->write_id].is_using = TD_TRUE; instance->buf_link_head[instance->write_id].perf_info.buf_state = EXT_DRV_VPLUGIN_BUF_STATE_QUEUE; instance->buf_link_head[instance->write_id].rect_info.crop_rect = rect_info->crop_rect; instance->buf_link_head[instance->write_id].rect_info.video_rect = rect_info->video_rect; soc_log_info("[drv queue frame] write_id = [%d], index = [%d]!\n", instance->write_id, stream_package_info->frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN]. frontout_frame.frame_index); instance->write_id = (instance->write_id + 1) % PLUGIN_STREAM_NODE_CNT; instance->buf_cnt += 1; soc_log_info("[queue_frame backin] drv fd drv dma_handle = [%llx], frame_index = %d \n", backin_stream->backin_frame.buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle, backin_stream->backin_frame.frame_index); soc_log_info("[drv queue frame] buf_cnt = %d!\n", instance->buf_cnt); vplugin_ctx->vplugin_instance[inst_pos].work_record.success_queue_cnt++; soc_log_info("[drv queue frame]drv_vplugin_queue_frame exit queue_cnt = [%d]\n", vplugin_ctx->vplugin_instance[inst_pos].work_record.success_queue_cnt); return TD_SUCCESS; } td_s32 drv_vplugin_dequeue_frame(td_handle vplugin_handle, ext_drv_vpss_vplugin_frontout_stream *frontout_stream, ext_drv_vpss_vplugin_backin_stream *backin_stream) { td_s32 ret; td_u32 inst_pos; drv_vplugin_instance *instance = TD_NULL; drv_vplugin_ctx *vplugin_ctx = TD_NULL; ext_drv_vplugin_stream_package_info *package_info = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); soc_log_info("[drv dequeue frame]drv_vplugin_dequeue_frame enter vplugin_handle = [%d]\n", vplugin_handle); ret = drv_vplugin_get_instance_position(vplugin_handle, &inst_pos); if (ret != TD_SUCCESS) { soc_log_notice("invalid instance id or not create instance\n"); return ret; } instance = &vplugin_ctx->vplugin_instance[inst_pos]; instance->work_record.try_dqueue_cnt++; if (instance->buf_cnt == 0) { soc_log_err("%d buf_cnt is 0\n", __func__); return SOC_ERR_VPLUGIN_FIFO_EMPTY; } soc_log_info("%s %d read_id [%d] , is_using %d buf cnt = %d\n", __func__, __LINE__, instance->read_id, instance->buf_link_head[instance->read_id].is_using, instance->buf_cnt); if (instance->buf_link_head[instance->read_id].is_using) { soc_log_info("read_id [%d], is_using = %d, dequeue ret!!\n", instance->read_id, instance->buf_link_head[instance->read_id].is_using); return SOC_ERR_VPLUGIN_BUF_USING; } package_info = &(instance->buf_link_head[instance->read_id].stream_package_info); memcpy_s((void *)frontout_stream, sizeof(ext_drv_vplugin_frontout_stream), package_info->frontout_stream_package.frontout_stream, sizeof(package_info->frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN])); soc_log_info("%s %d 0 = %d, 1 = %d, 2 = %d, 3 = %d, 4 = %d, 5 = %d,\n", __func__, __LINE__, vplugin_ctx->vplugin_instance[inst_pos].buf_link_head[g_digit_zero].is_using, vplugin_ctx->vplugin_instance[inst_pos].buf_link_head[g_digit_one].is_using, vplugin_ctx->vplugin_instance[inst_pos].buf_link_head[g_digit_two].is_using, vplugin_ctx->vplugin_instance[inst_pos].buf_link_head[g_digit_three].is_using, vplugin_ctx->vplugin_instance[inst_pos].buf_link_head[g_digit_four].is_using, vplugin_ctx->vplugin_instance[inst_pos].buf_link_head[g_digit_five].is_using); soc_log_info("[drv queue frame] read_id = [%d], index = [%d]!\n", instance->read_id, package_info->frontout_stream_package.frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame.frame_index); memcpy_s((void *)backin_stream, sizeof(ext_drv_vplugin_backin_stream), package_info->backin_stream_package.backin_stream, sizeof(ext_drv_vplugin_frontout_stream)); instance->buf_link_head[instance->read_id].perf_info.buf_state = EXT_DRV_VPLUGIN_BUF_STATE_DEQUEUE; instance->read_id = (instance->read_id + 1) % PLUGIN_STREAM_NODE_CNT; instance->buf_cnt -= 1; instance->work_record.success_dqueue_cnt++; if ((instance->buf_cnt == 0) && (instance->stream_status[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_ready == TD_FALSE)) { soc_log_err("buf_cnt is 0 and ins is disable!\n"); drv_vplugin_clean_buffer(instance); } soc_log_info("[drv queue frame] %s %d read_id [%d] , deque sucess cnt = %d, buf cnt = %d\n", __func__, __LINE__, instance->read_id, instance->work_record.success_dqueue_cnt, instance->buf_cnt); soc_log_info("%s %d\n", __func__, vplugin_handle); return TD_SUCCESS; } /******************************************************************************************* ioctrl call *******************************************************************************************/ static td_s32 drv_vplugin_match_instance(drv_vplugin_ctx *vplugin_ctx, td_handle win_handle, td_u32 *match_inst_pos) { td_u32 pos; if (win_handle == TD_INVALID_HANDLE) { for (pos = 0; pos < PLUGIN_MAX_CNT; pos++) { if (vplugin_ctx->vplugin_instance[pos].vplugin_instance_id == EXT_VPLUGIN_INVAL_ID) { *match_inst_pos = pos; vplugin_ctx->vplugin_instance[pos].vplugin_instance_id = pos; vplugin_ctx->vplugin_instance[pos].win_handle = TD_INVALID_HANDLE; return TD_SUCCESS; } } if (pos >= PLUGIN_MAX_CNT) { soc_log_err("instance cnt support max:%d\n", PLUGIN_MAX_CNT); return TD_FAILURE; } } for (pos = 0; pos < PLUGIN_MAX_CNT; pos++) { if (vplugin_ctx->vplugin_instance[pos].win_handle == win_handle) { *match_inst_pos = pos; break; } } if (pos >= PLUGIN_MAX_CNT) { soc_log_err("instance cnt support max:%d\n", PLUGIN_MAX_CNT); return TD_FAILURE; } return TD_SUCCESS; } td_s32 vplugin_proccess_cmd_set_enable(vplugin_enable *plugin_enable) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; if (plugin_enable == TD_NULL) { soc_log_err("%s set vplugin_enable is null\n", __func__); return TD_FAILURE; } if (plugin_enable->stream_index >= EXT_DRV_VPLUGIN_STREAM_MAX) { soc_log_err("%s set vplugin_enable stream_idx %d is invalid\n", __func__, plugin_enable->stream_index); return TD_FAILURE; } drv_vplugin_get_ctx(&vplugin_ctx); if (plugin_enable == TD_NULL) { soc_log_err("vplugin_enable is null\n"); return TD_FAILURE; } vplugin_osal_sem_down(); for (id = 0; id < PLUGIN_MAX_CNT; id++) { if (vplugin_ctx->vplugin_instance[id].vplugin_instance_id == plugin_enable->vplugin_handle) { break; } } if (id == PLUGIN_MAX_CNT) { soc_log_err("%s vplugin_handle %d not exist", __func__, plugin_enable->vplugin_handle); vplugin_osal_sem_up(); return TD_FAILURE; } vplugin_ctx->vplugin_instance[id].stream_status[plugin_enable->stream_index].stream_ready = plugin_enable->enable; vplugin_osal_sem_up(); return TD_SUCCESS; } td_s32 vplugin_proccess_cmd_get_enable(vplugin_enable *plugin_enable) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; if (plugin_enable == TD_NULL) { soc_log_err("%s get vplugin_enable is null\n", __func__); return TD_FAILURE; } if (plugin_enable->stream_index >= EXT_DRV_VPLUGIN_STREAM_MAX) { soc_log_err("%s get vplugin_enable stream_idx %d is invalid\n", __func__, plugin_enable->stream_index); return TD_FAILURE; } drv_vplugin_get_ctx(&vplugin_ctx); vplugin_osal_sem_down(); for (id = 0; id < PLUGIN_MAX_CNT; id++) { if (vplugin_ctx->vplugin_instance[id].vplugin_instance_id == plugin_enable->vplugin_handle) { break; } } if (id == PLUGIN_MAX_CNT) { soc_log_err("%s vplugin_handle %d not exist", __func__, plugin_enable->vplugin_handle); vplugin_osal_sem_up(); return TD_FAILURE; } plugin_enable->enable = (td_bool)vplugin_ctx->vplugin_instance[id].stream_status[plugin_enable->stream_index].stream_ready; vplugin_osal_sem_up(); return TD_SUCCESS; } td_s32 vplugin_proccess_cmd_set_config_param(vplugin_param *param) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_instance *instance = TD_NULL; if (param == TD_NULL) { soc_log_err("%s set param is null\n", __func__); return TD_FAILURE; } if (param->stream_index >= EXT_DRV_VPLUGIN_STREAM_MAX) { soc_log_err("%s set param stream_idx %d is invalid\n", __func__, param->stream_index); return TD_FAILURE; } drv_vplugin_get_ctx(&vplugin_ctx); vplugin_osal_sem_down(); for (id = 0; id < PLUGIN_MAX_CNT; id++) { if (vplugin_ctx->vplugin_instance[id].vplugin_instance_id == param->vplugin_handle) { break; } } if (id == PLUGIN_MAX_CNT) { soc_log_err("%s vplugin_handle %d not exist", __func__, param->vplugin_handle); vplugin_osal_sem_up(); return TD_FAILURE; } instance = &(vplugin_ctx->vplugin_instance[id]); if (memcpy_s(&(instance->param[param->stream_index]), sizeof(instance->param[param->stream_index]), param, sizeof(vplugin_param)) != EOK) { soc_log_err("save server config param failed\n"); vplugin_osal_sem_up(); return TD_FAILURE; } instance->work_record.set_param_cnt++; soc_log_info("vplugin %d, index = %d, load param frontout_param height = %d, with = %d," "backin_param height = %d, with = %d\n", param->vplugin_handle, param->stream_index, instance->param[param->stream_index].frontout_param.frame_width, instance->param[param->stream_index].frontout_param.frame_height, instance->param[param->stream_index].backin_param.frame_width, instance->param[param->stream_index].backin_param.frame_height); vplugin_osal_sem_up(); return TD_SUCCESS; } td_s32 vplugin_proccess_cmd_get_config_param(vplugin_param *param) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_instance *instance = TD_NULL; if (param == TD_NULL) { soc_log_err("%s get param is null\n", __func__); return TD_FAILURE; } if (param->stream_index >= EXT_DRV_VPLUGIN_STREAM_MAX) { soc_log_err("%s get param stream_idx %d is invalid\n", __func__, param->stream_index); return TD_FAILURE; } drv_vplugin_get_ctx(&vplugin_ctx); vplugin_osal_sem_down(); for (id = 0; id < PLUGIN_MAX_CNT; id++) { if (vplugin_ctx->vplugin_instance[id].vplugin_instance_id == param->vplugin_handle) { break; } } if (id == PLUGIN_MAX_CNT) { soc_log_err("%s vplugin_handle %d not exist", __func__, param->vplugin_handle); vplugin_osal_sem_up(); return TD_FAILURE; } instance = &(vplugin_ctx->vplugin_instance[id]); if ((memcpy_s(param, sizeof(vplugin_param), &(instance->param[param->stream_index]), sizeof(instance->param[param->stream_index]))) != EOK) { soc_log_err("save server config param failed\n"); vplugin_osal_sem_up(); return TD_FAILURE; } soc_log_info("vplugin %d, index = %d, out param frontout_param height = %d, with = %d," "backin_param height = %d, with = %d\n", param->vplugin_handle, param->stream_index, param->frontout_param.frame_width, param->frontout_param.frame_height, param->backin_param.frame_width, param->backin_param.frame_height); vplugin_osal_sem_up(); return TD_SUCCESS; } td_s32 vplugin_proccess_cmd_set_attach(vplugin_instance_info *attach) { td_u32 inst_pos; drv_vplugin_ctx *vplugin_ctx = TD_NULL; td_handle vplugin_fd = TD_NULL; if (attach == TD_NULL) { soc_log_err("%s set attach is null", __func__); return TD_FAILURE; } drv_vplugin_get_ctx(&vplugin_ctx); soc_log_info("%s win_handle = 0x%x", __func__, attach->win_handle); vplugin_osal_sem_down(); if (drv_vplugin_match_instance(vplugin_ctx, attach->win_handle, &inst_pos) != TD_SUCCESS) { soc_log_err("%s win_handle %d not find", __func__, attach->win_handle); vplugin_osal_sem_up(); return TD_FAILURE; } attach->vplugin_handle = vplugin_ctx->vplugin_instance[inst_pos].vplugin_instance_id; if (vplugin_ctx->vplugin_instance[inst_pos].buf_pool.buf_obj == TD_NULL) { if (drv_vplugin_malloc_share_buf(inst_pos) != TD_SUCCESS) { soc_log_err("%s vplugin %d malloc_share_buf failed\n", __func__, inst_pos); vplugin_osal_sem_up(); return TD_FAILURE; } } if (vplugin_ctx->vplugin_instance[inst_pos].instance_state != EXT_DRV_VPLUGIN_STATUS_CREATE || (td_s32)(vplugin_ctx->vplugin_instance[inst_pos].vplugin_fd) <= 0) { vplugin_fd = drv_vplugin_get_buf_fd(vplugin_ctx->vplugin_instance[inst_pos].buf_pool.buf_obj); if (vplugin_fd <= 0) { soc_log_err(" get fd is invalid!\n"); vplugin_osal_sem_up(); return TD_FAILURE; } vplugin_ctx->vplugin_instance[inst_pos].vplugin_fd = vplugin_fd; } else { vplugin_fd = vplugin_ctx->vplugin_instance[inst_pos].vplugin_fd; } vplugin_ctx->vplugin_instance[inst_pos].instance_state = EXT_DRV_VPLUGIN_STATUS_CREATE; attach->vplugin_fd = vplugin_fd; attach->vplugin_fd_size = vplugin_ctx->vplugin_instance[inst_pos].vplugin_fd_size; soc_log_info("%s finish, win_handle %d, vplugin_handle %d, inst_pos = %d, vplugin_fd = %d, buf_size = %d!", __func__, attach->win_handle, attach->vplugin_handle, inst_pos, vplugin_fd, vplugin_ctx->vplugin_instance[inst_pos].vplugin_fd_size); vplugin_osal_sem_up(); return TD_SUCCESS; } static void vplugin_release_instance_fd(vplugin_instance_info *attach, drv_vplugin_instance *instance) { td_s32 ret = TD_SUCCESS; if (instance->buf_cnt == 0) { drv_vplugin_clean_buffer(instance); } ret = osal_mem_close_fd((long)instance->vplugin_fd); if (ret != TD_SUCCESS) { soc_log_err("vplugin_fd[%ld] fail ret[%d]\n", (long)instance->vplugin_fd, ret); } instance->vplugin_fd = -1; if (attach->win_handle != TD_INVALID_HANDLE) { if (instance->instance_state == EXT_DRV_VPLUGIN_STATUS_DESTROY) { instance->vplugin_instance_id = EXT_VPLUGIN_INVAL_ID; instance->win_handle = 0; instance->stream_status[EXT_DRV_VPLUGIN_STREAM_MAX].stream_ready = TD_FALSE; } } } static td_void drv_vplugin_close_frame_fd(td_void) { td_u64 tmp_dma_buf; td_u32 id; td_s32 ret = TD_SUCCESS; for (id = 0; id < MAX_FD_MATRIX_LENGTH; id++) { if (g_frontout_fd[id][1] != -1) { tmp_dma_buf = (td_u64)(uintptr_t)osal_mem_handle_get(g_frontout_fd[id][1], SOC_ID_VPLUGIN); ret = osal_mem_close_fd((long)g_frontout_fd[id][1]); if (ret != TD_SUCCESS) { soc_log_err("frontout close fd[%ld] fail ret[%d]\n", (long)g_frontout_fd[id][1], ret); } if (tmp_dma_buf != TD_NULL) { osal_mem_ref_put(tmp_dma_buf, SOC_ID_VPLUGIN); tmp_dma_buf = TD_NULL; } } if (g_backin_fd[id][1] != -1) { tmp_dma_buf = (td_u64)(uintptr_t)osal_mem_handle_get(g_backin_fd[id][1], SOC_ID_VPLUGIN); ret = osal_mem_close_fd((long)g_backin_fd[id][1]); if (ret != TD_SUCCESS) { soc_log_err("backin_fd close fd[%ld] fail ret[%d]\n", (long)g_backin_fd[id][1], ret); } if (tmp_dma_buf != TD_NULL) { osal_mem_ref_put(tmp_dma_buf, SOC_ID_VPLUGIN); tmp_dma_buf = TD_NULL; } } } drv_vplugin_clean_buffer_fd(g_frontout_fd, &g_frontout_index, MAX_FD_MATRIX_LENGTH); drv_vplugin_clean_buffer_fd(g_backin_fd, &g_backin_index, MAX_FD_MATRIX_LENGTH); } td_s32 vplugin_proccess_cmd_destroy_instance(vplugin_instance_info *attach) { td_u32 inst_pos; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_instance *instance = TD_NULL; if (attach == TD_NULL) { soc_log_err("%s deattach is null", __func__); return TD_FAILURE; } drv_vplugin_get_ctx(&vplugin_ctx); // 释放vplugin instance的fd vplugin_osal_sem_down(); for (inst_pos = 0; inst_pos < PLUGIN_MAX_CNT; inst_pos++) { if (vplugin_ctx->vplugin_instance[inst_pos].vplugin_instance_id == attach->vplugin_handle) { instance = &vplugin_ctx->vplugin_instance[inst_pos]; vplugin_release_instance_fd(attach, instance); break; } } if (inst_pos == PLUGIN_MAX_CNT) { soc_log_err("%s vplugin_handle %d not exist", __func__, attach->vplugin_handle); } // 释放帧信息的映射的fd drv_vplugin_close_frame_fd(); vplugin_osal_sem_up(); return TD_SUCCESS; } td_s32 vplugin_proccess_cmd_get_instance_state(td_u32 inst_id, ext_drv_vplugin_state *state) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; if (state == TD_NULL) { soc_log_err("%s get state is null", __func__); return TD_FAILURE; } drv_vplugin_get_ctx(&vplugin_ctx); vplugin_osal_sem_down(); for (id = 0; id < PLUGIN_MAX_CNT; id++) { if (vplugin_ctx->vplugin_instance[id].vplugin_instance_id == inst_id) { break; } } if (id == PLUGIN_MAX_CNT) { soc_log_err("%s vplugin_handle %d not exist", __func__, inst_id); vplugin_osal_sem_up(); return TD_FAILURE; } *state = vplugin_ctx->vplugin_instance[id].instance_state; vplugin_osal_sem_up(); return TD_SUCCESS; } static void vplugin_release_frame_fd_item(td_s64 dma_fd_matrix[][2], td_u32 idx) { td_s32 ret; if (dma_fd_matrix[idx][1] != -1) { ret = osal_mem_close_fd((long)dma_fd_matrix[idx][1]); if (ret != TD_SUCCESS) { soc_log_err("close fd[%ld] fail ret[%d]\n", (long)dma_fd_matrix[idx][1], ret); } soc_log_info("index %d dmahandle 0x%llx close fd %ld \n", idx, (long)dma_fd_matrix[idx][0], dma_fd_matrix[idx][1]); } return; } static void vplugin_release_frame_fd(td_s64 dma_fd_matrix[][2], td_u32 max_length) { td_u32 id; td_s32 ret = TD_SUCCESS; for (id = 0; id < max_length; id++) { if (dma_fd_matrix[id][1] != -1) { ret = osal_mem_close_fd((long)dma_fd_matrix[id][1]); if (ret != TD_SUCCESS) { soc_log_err("close fd[%ld] fail ret[%d]\n", (long)dma_fd_matrix[id][1], ret); } soc_log_info("index %d dmahandle 0x%llx close fd %ld \n", id, (long)dma_fd_matrix[id][0], dma_fd_matrix[id][1]); } } return; } td_s32 vplugin_get_buffer_fd(ext_drv_video_frame *video_frame_info, td_s64 dma_fd_matrix[][2], td_u32 *row, td_u32 column) { td_s32 i; td_handle vplugin_fd = -1; td_s64 dma_handle = TD_NULL; dma_handle = video_frame_info->buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle; if (dma_handle == TD_NULL) { soc_log_err(" %s dma_handle is invalid!\n", __func__); return TD_FAILURE; } for (i = 0; i < MAX_FD_MATRIX_LENGTH; i++) { if (dma_fd_matrix[i][0] == dma_handle) { vplugin_fd = dma_fd_matrix[i][1]; break; } } if (i == MAX_FD_MATRIX_LENGTH) { soc_log_warn("can not find fd, release node idx %d!\n", *row); // 释放帧信息的映射的fd vplugin_release_frame_fd_item(dma_fd_matrix, *row); drv_vplugin_clean_buffer_fd_item(dma_fd_matrix, *row); } if (vplugin_fd == -1) { vplugin_fd = drv_vplugin_get_buf_fd((td_void *)(uintptr_t)dma_handle); if (vplugin_fd <= 0) { soc_log_err(" get fd is invalid!\n"); return TD_FAILURE; } if (*row < MAX_FD_MATRIX_LENGTH) { dma_fd_matrix[*row][0] = dma_handle; dma_fd_matrix[*row][1] = vplugin_fd; *row = (*row + 1) % MAX_FD_MATRIX_LENGTH; } else { soc_log_err(" fd matrix is full!\n"); } } video_frame_info->buf_addr[EXT_DRV_3D_EYE_LEFT].start_addr = vplugin_fd; return TD_SUCCESS; } static td_bool vplugin_check_stream_dma_handle_valid(vplugin_stream_info *vstream_info) { drv_vplugin_ctx *vplugin_ctx = TD_NULL; td_u32 instance_idx = 0; td_u32 buffer_node_idx = 0; td_bool dma_handle_valid = TD_FALSE; td_u64 frountout_dma_handle = vstream_info->stream_info.frontout_stream_package. frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame.buf_addr[0].dma_handle; td_u64 backin_dma_handle = vstream_info->stream_info.backin_stream_package. backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].backin_frame.buf_addr[0].dma_handle; drv_vplugin_get_ctx(&vplugin_ctx); for (instance_idx = 0; instance_idx < PLUGIN_MAX_CNT; instance_idx++) { drv_vplugin_instance *instance = &vplugin_ctx->vplugin_instance[instance_idx]; ext_drv_vplugin_stream_package_node *buf_link_head = TD_NULL; if (instance->stream_status[EXT_DRV_VPLUGIN_STREAM_MAIN].stream_ready == TD_FALSE) { continue; } if (vplugin_ctx->vplugin_instance[instance_idx].buf_link_head == TD_NULL) { continue; } buf_link_head = vplugin_ctx->vplugin_instance[instance_idx].buf_link_head; for (buffer_node_idx = 0; buffer_node_idx < PLUGIN_STREAM_NODE_CNT; buffer_node_idx++) { if ((frountout_dma_handle == buf_link_head[buffer_node_idx].stream_package_info.frontout_stream_package. frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame.buf_addr[0].dma_handle) && (backin_dma_handle == buf_link_head[buffer_node_idx].stream_package_info.backin_stream_package. backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].backin_frame.buf_addr[0].dma_handle)) { dma_handle_valid = TD_TRUE; break; } } } if (dma_handle_valid == TD_FALSE) { soc_log_err("frount_out dma 0x%llx backin dma 0x%llx invalid \n", frountout_dma_handle, backin_dma_handle); } return dma_handle_valid; } td_s32 vplugin_proccess_cmd_catch_stream(vplugin_stream_info *vstream_info) { td_s32 get_frontout_fd_ret = TD_FAILURE; td_s32 get_backin_fd_ret = TD_FAILURE; drv_vplugin_ctx *vplugin_ctx = TD_NULL; td_bool dma_handle_valid = TD_FALSE; ext_drv_video_frame *frame; if (vstream_info == TD_NULL) { soc_log_err("%s catch stream is null", __func__); return TD_FAILURE; } drv_vplugin_get_ctx(&vplugin_ctx); vplugin_osal_sem_down(); vplugin_ctx->try_catch_cnt++; dma_handle_valid = vplugin_check_stream_dma_handle_valid(vstream_info); if (dma_handle_valid == TD_FALSE) { vplugin_osal_sem_up(); return TD_FAILURE; } frame = &vstream_info->stream_info.frontout_stream_package. frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame; get_frontout_fd_ret = vplugin_get_buffer_fd(&vstream_info->stream_info.frontout_stream_package. frontout_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].frontout_frame, g_frontout_fd, &g_frontout_index, g_digit_two); if (get_frontout_fd_ret != TD_SUCCESS) { soc_log_err(" vplugin_get_buffer_fd frontout failed\n"); } soc_log_info("front_out dmahandle 0x%llx fd %d width %d height %d bitwidth %d cnt %d\n", frame->buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle, frame->buf_addr[EXT_DRV_3D_EYE_LEFT].start_addr, frame->width, frame->height, frame->bit_width, g_frontout_index); get_backin_fd_ret = vplugin_get_buffer_fd(&vstream_info->stream_info.backin_stream_package. backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].backin_frame, g_backin_fd, &g_backin_index, g_digit_two); if (get_backin_fd_ret != TD_SUCCESS) { soc_log_err(" vplugin_get_buffer_fd backin failed\n"); } frame = &vstream_info->stream_info.backin_stream_package.backin_stream[EXT_DRV_VPLUGIN_STREAM_MAIN].backin_frame; soc_log_info("backin dmahandle 0x%llx fd %d width %d height %d bitwidth %d cnt %d\n", frame->buf_addr[EXT_DRV_3D_EYE_LEFT].dma_handle, frame->buf_addr[EXT_DRV_3D_EYE_LEFT].start_addr, frame->width, frame->height, frame->bit_width, g_backin_index); if (get_frontout_fd_ret == TD_SUCCESS) { vplugin_ctx->success_catch_frontout_cnt++; } if (get_backin_fd_ret == TD_SUCCESS) { vplugin_ctx->success_catch_backin_cnt++; } vplugin_ctx->frount_fd_cnt = g_frontout_index; vplugin_ctx->sendback_fd_cnt = g_backin_index; vplugin_osal_sem_up(); return TD_SUCCESS; } /******************************************************************************************* init/deinit *******************************************************************************************/ td_s32 drv_vplugin_init(void) { td_u32 id; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); if (memset_s(vplugin_ctx, sizeof(drv_vplugin_ctx), 0, sizeof(drv_vplugin_ctx)) != EOK) { soc_log_err("clean ctx failed\n"); return TD_FAILURE; } vplugin_ctx->is_init = TD_TRUE; for (id = 0; id < PLUGIN_MAX_CNT; id++) { drv_vplugin_instance_init(&vplugin_ctx->vplugin_instance[id], EXT_VPLUGIN_INVAL_ID, EXT_DRV_VPLUGIN_STATUS_NONE); } drv_vplugin_clean_buffer_fd(g_frontout_fd, &g_frontout_index, MAX_FD_MATRIX_LENGTH); drv_vplugin_clean_buffer_fd(g_backin_fd, &g_backin_index, MAX_FD_MATRIX_LENGTH); vplugin_osal_sem_init(); return TD_SUCCESS; } td_void drv_vplugin_deinit(void) { td_s32 ret; td_u32 id; td_u32 working_instance_cnt; drv_vplugin_ctx *vplugin_ctx = TD_NULL; drv_vplugin_get_ctx(&vplugin_ctx); working_instance_cnt = vplugin_ctx->working_instance_cnt; for (id = 0; id < working_instance_cnt; id++) { ret = drv_vplugin_stop_instance(vplugin_ctx->vplugin_instance[id].vplugin_instance_id); if (ret != TD_SUCCESS) { soc_log_err("vplugin instance%u stop failed!\n", vplugin_ctx->vplugin_instance[id].vplugin_instance_id); } ret = drv_vplugin_destroy_instance(vplugin_ctx->vplugin_instance[id].vplugin_instance_id); if (ret != TD_SUCCESS) { soc_log_err("vplugin instance%u destory failed!\n", vplugin_ctx->vplugin_instance[id].vplugin_instance_id); } } vplugin_ctx->is_init = TD_FALSE; vplugin_ctx->working_instance_cnt = 0; vplugin_osal_sem_destroy(); } #ifdef __cplusplus #if __cplusplus } #endif #endif