You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1446 lines
50 KiB
1446 lines
50 KiB
/*
|
|
* 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
|
|
|