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

/*
* 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