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.
790 lines
21 KiB
790 lines
21 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2019. All rights reserved.
|
|
* Description: encoder
|
|
* Author: sdk
|
|
* Create: 2019-08-13
|
|
*/
|
|
|
|
#include <math.h>
|
|
#include <limits.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <dlfcn.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
#include "uapi_ssm.h"
|
|
#include "mpi_venc_ext.h"
|
|
#include "soc_errno.h"
|
|
#include "td_type.h"
|
|
#include "mpi_memory_ext.h"
|
|
#include "drv_ioctl_venc.h"
|
|
#include "securec.h"
|
|
#include "soc_module.h"
|
|
#include "mpi_venc.h"
|
|
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
#endif /* end of #ifdef __cplusplus */
|
|
|
|
#define RC_LIB_NAME "libuapi_rc.so"
|
|
|
|
static td_void *g_handle = TD_NULL;
|
|
static td_s32 g_venc_dev_fd = -1;
|
|
static const td_char g_venc_dev_name[] = VENC_DEV;
|
|
static pthread_mutex_t g_venc_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static ext_ioctl_strm_buf_info g_asr_ve_chn_info[VENC_MAX_CHN_NUM];
|
|
static ext_ioctl_chan_virt_addr g_asr_ve_chn_vir_addr[VENC_MAX_CHN_NUM];
|
|
td_s32 g_dev_open_cnt;
|
|
|
|
#define ext_venc_lock() (void)pthread_mutex_lock(&g_venc_mutex)
|
|
#define ext_venc_unlock() (void)pthread_mutex_unlock(&g_venc_mutex)
|
|
|
|
#define check_venc_init_ret() \
|
|
do { \
|
|
ext_venc_lock(); \
|
|
if (g_venc_dev_fd < 0) { \
|
|
ext_err_venc("venc not init\n"); \
|
|
ext_venc_unlock(); \
|
|
return SOC_ERR_VENC_NO_INIT; \
|
|
} \
|
|
ext_venc_unlock(); \
|
|
} while (0)
|
|
|
|
#define check_channel_exist_ret(i, max, chn_handle) do { \
|
|
for ((i) = 0; (i) < (max); (i)++) { \
|
|
if (g_asr_ve_chn_info[(i)].handle == (chn_handle)) \
|
|
break; \
|
|
} \
|
|
if ((max) == (i)) { \
|
|
ext_err_venc("venc channel not exit\n"); \
|
|
return SOC_ERR_VENC_CHN_NOT_EXIST; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define venc_handle_invalid(handle) ((((handle) & 0xff000000) >> 24) != SOC_ID_VENC) /* 24 bit of handle */
|
|
|
|
static td_s32 init_function(td_void)
|
|
{
|
|
td_s32 (*rc_init_function)(td_void) = TD_NULL;
|
|
td_s32 ret;
|
|
|
|
g_handle = dlopen(RC_LIB_NAME, RTLD_LAZY);
|
|
if (g_handle == TD_NULL) {
|
|
close(g_venc_dev_fd);
|
|
g_venc_dev_fd = -1;
|
|
ext_fatal_venc("dynamic load the RC lib failed because %s!\n", dlerror());
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
rc_init_function = dlsym(g_handle, "venc_rc_init");
|
|
if (rc_init_function == TD_NULL) {
|
|
dlclose(g_handle);
|
|
g_handle = TD_NULL;
|
|
|
|
close(g_venc_dev_fd);
|
|
g_venc_dev_fd = -1;
|
|
ext_fatal_venc("can't find the RC initial function becasuse %s!\n", dlerror());
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = rc_init_function();
|
|
if (ret != TD_SUCCESS && ret != SOC_ERR_VENC_DEV_OPENED) {
|
|
dlclose(g_handle);
|
|
g_handle = TD_NULL;
|
|
|
|
close(g_venc_dev_fd);
|
|
g_venc_dev_fd = -1;
|
|
ext_fatal_venc("RC initial failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
td_s32 ext_mpi_venc_init(td_void)
|
|
{
|
|
struct stat st;
|
|
td_s32 i;
|
|
|
|
ext_venc_lock();
|
|
|
|
/* already opened in the process */
|
|
if (g_venc_dev_fd > 0) {
|
|
ext_venc_unlock();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
g_venc_dev_fd = open(g_venc_dev_name, O_RDWR | O_NONBLOCK, 0);
|
|
if (g_venc_dev_fd < 0) {
|
|
ext_fatal_venc("open VEDU err.\n");
|
|
ext_venc_unlock();
|
|
return SOC_ERR_VENC_NOT_SUPPORT;
|
|
}
|
|
|
|
if (fstat(g_venc_dev_fd, &st) == TD_FAILURE) {
|
|
ext_fatal_venc("VEDU is not exist.\n");
|
|
ext_venc_unlock();
|
|
return SOC_ERR_VENC_DEV_NOT_EXIST;
|
|
}
|
|
|
|
if (!S_ISCHR(st.st_mode)) {
|
|
ext_fatal_venc("VEDU is not device.\n");
|
|
ext_venc_unlock();
|
|
return SOC_ERR_VENC_NOT_DEV_FILE;
|
|
}
|
|
|
|
for (i = 0; i < VENC_MAX_CHN_NUM; i++) {
|
|
g_asr_ve_chn_vir_addr[i].strm_buf_virt_addr = TD_NULL;
|
|
g_asr_ve_chn_info[i].handle = TD_INVALID_HANDLE;
|
|
g_asr_ve_chn_info[i].strm_buf_phy_addr = TD_NULL;
|
|
g_asr_ve_chn_info[i].buf_size = 0;
|
|
g_asr_ve_chn_info[i].secure = TD_FALSE;
|
|
}
|
|
|
|
if (init_function() != TD_SUCCESS) {
|
|
ext_venc_unlock();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (g_dev_open_cnt < 0x7FFFFFFF) {
|
|
g_dev_open_cnt++;
|
|
ext_warn_venc("init count:g_dev_open_cnt = %d\n", g_dev_open_cnt);
|
|
} else {
|
|
ext_fatal_venc("init count:%d is overflow\n", g_dev_open_cnt);
|
|
}
|
|
|
|
ext_info_venc(" open librc success\n");
|
|
|
|
ext_venc_unlock();
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static void unmap_phy_addr_base(td_s32 i)
|
|
{
|
|
td_s32 ret;
|
|
td_u64 addr_temp;
|
|
td_void *virt_addr = TD_NULL;
|
|
td_mem_size_t buf_size;
|
|
|
|
addr_temp = ptr_u64(g_asr_ve_chn_vir_addr[i].strm_buf_virt_addr);
|
|
virt_addr = u64_ptr(addr_temp);
|
|
|
|
buf_size = g_asr_ve_chn_vir_addr[i].strm_buf_size;
|
|
ret = ext_mpi_mem_unmap(virt_addr, buf_size);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_err_venc("venc unmap failed!\n");
|
|
}
|
|
|
|
g_asr_ve_chn_vir_addr[i].strm_buf_virt_addr = NULL;
|
|
}
|
|
td_s32 ext_mpi_venc_deinit(td_void)
|
|
{
|
|
td_s32 i;
|
|
td_s32 (*rc_deinit_function)(td_void) = TD_NULL;
|
|
|
|
ext_venc_lock();
|
|
|
|
if (g_venc_dev_fd < 0) {
|
|
ext_venc_unlock();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
g_dev_open_cnt = (g_dev_open_cnt - 1) > 0 ? g_dev_open_cnt - 1 : 0;
|
|
if (g_dev_open_cnt > 0) {
|
|
ext_warn_venc("g_dev_open_cnt = %d venc is working in another channel, don't close!\n", g_dev_open_cnt);
|
|
ext_venc_unlock();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
for (i = 0; i < VENC_MAX_CHN_NUM; i++) {
|
|
if (g_asr_ve_chn_info[i].handle != TD_INVALID_HANDLE && g_asr_ve_chn_info[i].secure == TD_FALSE) {
|
|
unmap_phy_addr_base(i);
|
|
}
|
|
}
|
|
|
|
rc_deinit_function = dlsym(g_handle, "venc_rc_deinit");
|
|
if (rc_deinit_function == TD_NULL) {
|
|
ext_err_venc("can't find the RC de_init function becasuse %s!\n", dlerror());
|
|
} else {
|
|
td_s32 ret = rc_deinit_function();
|
|
if (ret != TD_SUCCESS && ret != SOC_ERR_VENC_DEV_OPENED) {
|
|
ext_err_venc("RC user deinit failed!\n");
|
|
}
|
|
}
|
|
|
|
dlclose(g_handle);
|
|
g_handle = TD_NULL;
|
|
|
|
close(g_venc_dev_fd);
|
|
|
|
g_venc_dev_fd = -1;
|
|
ext_venc_unlock();
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_set_config(td_handle venc_chan, venc_ioctl_chan_info *chan_info)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
if (chan_info == NULL) {
|
|
ext_err_venc("Channel config parameters is NULL\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
|
|
chan_info->chan_id = venc_chan;
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_SET_CHN_CFG, chan_info);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_err_venc("Set channel config failed(0x%x).\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_get_config(td_handle venc_chan, venc_ioctl_chan_info *chan_info)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
if (chan_info == NULL) {
|
|
ext_err_venc("Channel config parameters is NULL\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
|
|
chan_info->chan_id = venc_chan;
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_GET_CHN_CFG, chan_info);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_err_venc("Set channel config failed(0x%x).\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 get_venc_stream_addr_user(td_u32 chan_id)
|
|
{
|
|
td_u64 fd;
|
|
td_u32 buf_size;
|
|
td_void *start_vir_addr = TD_NULL;
|
|
td_void *strm_vir_addr = TD_NULL;
|
|
|
|
fd = g_asr_ve_chn_info[chan_id].strm_buf_fd;
|
|
buf_size = g_asr_ve_chn_info[chan_id].buf_size;
|
|
|
|
if (g_asr_ve_chn_info[chan_id].secure == TD_FALSE) {
|
|
start_vir_addr = ext_mpi_mem_map((td_mem_handle_t)fd, (td_mem_size_t)buf_size);
|
|
if (start_vir_addr == TD_NULL) {
|
|
ext_err_venc("memmap VENC's stream buffer failed.fd = %d\n", fd);
|
|
return SOC_ERR_VENC_CREATE_ERR;
|
|
}
|
|
|
|
strm_vir_addr = start_vir_addr;
|
|
}
|
|
|
|
g_asr_ve_chn_vir_addr[chan_id].strm_buf_virt_addr = strm_vir_addr;
|
|
g_asr_ve_chn_vir_addr[chan_id].strm_buf_size = buf_size;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 tee_support_init(td_handle *ssm_handle)
|
|
{
|
|
uapi_ssm_attr ssm_attr = {0};
|
|
|
|
if (uapi_ssm_init() != TD_SUCCESS) {
|
|
ext_err_venc("uapi_ssm_init() fail\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ssm_attr.intent = UAPI_SSM_INTENT_WATCH;
|
|
if (uapi_ssm_create(&ssm_attr, ssm_handle) != TD_SUCCESS) {
|
|
ext_err_venc("uapi_ssm_create() fail\n");
|
|
(td_void)uapi_ssm_deinit();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_create(td_handle *venc_chan, venc_ioctl_create *venc_chn_create)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
|
|
if (venc_chn_create == TD_NULL || venc_chan == TD_NULL) {
|
|
ext_err_venc("NULL para\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
check_venc_init_ret();
|
|
|
|
if (venc_chn_create->attr.secure) {
|
|
if (tee_support_init(&venc_chn_create->strm_buf_info.ssm_handle) != TD_SUCCESS) {
|
|
ext_err_venc("tee_support_init failed\n");
|
|
return SOC_ERR_VENC_CREATE_ERR;
|
|
}
|
|
} else {
|
|
venc_chn_create->strm_buf_info.ssm_handle = TD_INVALID_HANDLE;
|
|
}
|
|
|
|
ext_venc_lock();
|
|
|
|
for (i = 0; i < VENC_MAX_CHN_NUM; i++) {
|
|
if (g_asr_ve_chn_info[i].handle == TD_INVALID_HANDLE) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == VENC_MAX_CHN_NUM) {
|
|
ext_err_venc("mpi create err, \n");
|
|
ext_venc_unlock();
|
|
return SOC_ERR_VENC_CREATE_ERR;
|
|
}
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_CREATE_CHN, venc_chn_create);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_venc_unlock();
|
|
return ret;
|
|
}
|
|
|
|
(td_void)memcpy_s(&g_asr_ve_chn_info[i], sizeof(ext_ioctl_strm_buf_info),
|
|
&venc_chn_create->strm_buf_info, sizeof(venc_chn_create->strm_buf_info));
|
|
|
|
ret = get_venc_stream_addr_user(i);
|
|
if (ret != TD_SUCCESS) {
|
|
(void)ioctl(g_venc_dev_fd, CMD_VENC_DESTROY_CHN, &(venc_chn_create->chan_id));
|
|
ext_venc_unlock();
|
|
return ret;
|
|
}
|
|
|
|
*venc_chan = venc_chn_create->chan_id;
|
|
g_asr_ve_chn_info[i].handle = venc_chn_create->chan_id;
|
|
|
|
ext_info_venc("create_ok, chn%d, buf fd: %#x, len:%#x.\n", i, g_asr_ve_chn_info[i].strm_buf_fd,
|
|
g_asr_ve_chn_info[i].buf_size);
|
|
ext_venc_unlock();
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 destroy_venc_stream_addr(td_u32 chan_id)
|
|
{
|
|
td_s32 ret;
|
|
td_void *user_virt_addr = NULL;
|
|
td_u64 addr_temp;
|
|
|
|
if (g_asr_ve_chn_vir_addr[chan_id].strm_buf_virt_addr == TD_NULL) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
if (g_asr_ve_chn_info[chan_id].protocol == EXT_VENC_STD_JPEG) {
|
|
user_virt_addr = g_asr_ve_chn_vir_addr[chan_id].strm_buf_virt_addr;
|
|
} else {
|
|
addr_temp = ptr_u64(g_asr_ve_chn_vir_addr[chan_id].strm_buf_virt_addr);
|
|
user_virt_addr = u64_ptr(addr_temp);
|
|
}
|
|
|
|
ret = ext_mpi_mem_unmap(user_virt_addr, g_asr_ve_chn_info[chan_id].buf_size);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_err_venc("venc ext_mpi_media_mem_unmap failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
g_asr_ve_chn_vir_addr[chan_id].strm_buf_virt_addr = TD_NULL;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void tee_support_deinit(td_handle *ssm_handle)
|
|
{
|
|
if (*ssm_handle != TD_INVALID_HANDLE) {
|
|
(td_void)uapi_ssm_destroy(*ssm_handle);
|
|
(td_void)uapi_ssm_deinit();
|
|
*ssm_handle = TD_INVALID_HANDLE;
|
|
}
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_destroy(td_handle venc_chan)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
|
|
if (venc_chan == TD_INVALID_HANDLE) {
|
|
ext_err_venc("para venc_chan is invalid.\n");
|
|
return SOC_ERR_VENC_CHN_NOT_EXIST;
|
|
}
|
|
|
|
check_venc_init_ret();
|
|
ext_venc_lock();
|
|
for (i = 0; i < VENC_MAX_CHN_NUM; i++) {
|
|
if (g_asr_ve_chn_info[i].handle == venc_chan) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == VENC_MAX_CHN_NUM) {
|
|
ext_venc_unlock();
|
|
return SOC_ERR_VENC_CHN_NOT_EXIST;
|
|
}
|
|
|
|
ret = destroy_venc_stream_addr(i);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_venc_unlock();
|
|
return ret;
|
|
}
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_DESTROY_CHN, &venc_chan);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_venc_unlock();
|
|
return ret;
|
|
}
|
|
|
|
tee_support_deinit(&g_asr_ve_chn_info[i].ssm_handle);
|
|
|
|
g_asr_ve_chn_info[i].handle = TD_INVALID_HANDLE;
|
|
ext_venc_unlock();
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_u8 *get_video_stream_addr(td_u32 handle_id, venc_ioctl_buf_offset *buf_offset)
|
|
{
|
|
td_u8 *user_stream_addr = TD_NULL;
|
|
|
|
if (g_asr_ve_chn_info[handle_id].secure == TD_FALSE) {
|
|
user_stream_addr = (td_u8 *)(g_asr_ve_chn_vir_addr[handle_id].strm_buf_virt_addr) +
|
|
buf_offset->strm_buf_offset[0];
|
|
}
|
|
|
|
return user_stream_addr;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_acquire_stream(const td_handle venc_chan, venc_ioctl_acquire_stream *drv_stream,
|
|
const td_u32 timeout_ms)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 i = 0;
|
|
venc_ioctl_buf_offset *buf_off_set = TD_NULL;
|
|
|
|
if (venc_chan == TD_INVALID_HANDLE) {
|
|
ext_err_venc("para venc_chan is invalid.\n");
|
|
return SOC_ERR_VENC_CHN_NOT_EXIST;
|
|
}
|
|
|
|
if (drv_stream == TD_NULL) {
|
|
ext_err_venc("para stream is NULL.\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
|
|
drv_stream->chan_id = venc_chan;
|
|
drv_stream->block_flag = timeout_ms;
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_ACQUIRE_STREAM, drv_stream);
|
|
if (ret != TD_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
buf_off_set = &drv_stream->buf_offset;
|
|
|
|
if (drv_stream->stream.slc_len > 0) {
|
|
drv_stream->stream.virt_addr = ptr_u64(get_video_stream_addr(i, buf_off_set));
|
|
if ((drv_stream->stream.virt_addr == TD_NULL) && (g_asr_ve_chn_info[i].secure == TD_FALSE)) {
|
|
ext_err_venc("get_stream_addr failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
drv_stream->buf_handle.addr_offset = drv_stream->buf_offset.strm_buf_offset[0];
|
|
drv_stream->buf_handle.mem_handle = (td_mem_handle_t)g_asr_ve_chn_info[i].strm_buf_fd;
|
|
drv_stream->protocol = g_asr_ve_chn_info[i].protocol;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_release_stream(td_handle venc_chan, venc_ioctl_acquire_stream *acquire_stream)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (venc_chan == TD_INVALID_HANDLE) {
|
|
ext_err_venc("para venc_chan is invalid.\n");
|
|
return SOC_ERR_VENC_CHN_NOT_EXIST;
|
|
}
|
|
|
|
if (acquire_stream == TD_NULL) {
|
|
ext_err_venc("para stream is NULL.\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
check_venc_init_ret();
|
|
|
|
acquire_stream->chan_id = venc_chan;
|
|
acquire_stream->h264_stream_off = (td_u32)acquire_stream->buf_handle.addr_offset;
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_RELEASE_STREAM, acquire_stream);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_start(td_handle venc_chan)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
if (venc_handle_invalid(venc_chan)) {
|
|
ext_err_venc("para venc_chan is invalid.\n");
|
|
return SOC_ERR_VENC_INVALID_PARA;
|
|
}
|
|
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_START_RECV_PIC, &venc_chan);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_stop(td_handle venc_chan)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
if (venc_handle_invalid(venc_chan)) {
|
|
ext_err_venc("para venc_chan is invalid.\n");
|
|
return SOC_ERR_VENC_INVALID_PARA;
|
|
}
|
|
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_STOP_RECV_PIC, &venc_chan);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_request_i_frame(td_handle venc_chan)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
if (venc_handle_invalid(venc_chan)) {
|
|
ext_err_venc("para venc_chan is invalid.\n");
|
|
return SOC_ERR_VENC_INVALID_PARA;
|
|
}
|
|
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_REQUEST_I_FRAME, &venc_chan);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_queue_frame(td_handle venc_chan, venc_ioctl_queue_frame *venc_queue_frame)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
if (venc_chan == TD_INVALID_HANDLE) {
|
|
ext_err_venc("para venc_chan is invalid.\n");
|
|
return SOC_ERR_VENC_CHN_NOT_EXIST;
|
|
}
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
|
|
if (venc_queue_frame == TD_NULL) {
|
|
ext_err_venc("para _stream is NULL.\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
|
|
venc_queue_frame->chan_id = venc_chan;
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_QUEUE_FRAME, venc_queue_frame);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_dequeue_frame(td_handle venc_chan, venc_ioctl_queue_frame *venc_queue_frame)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
if (venc_chan == TD_INVALID_HANDLE) {
|
|
ext_err_venc("para venc_chan is invalid.\n");
|
|
return SOC_ERR_VENC_CHN_NOT_EXIST;
|
|
}
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
if (venc_queue_frame == TD_NULL) {
|
|
ext_err_venc("para _stream is NULL.\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
|
|
venc_queue_frame->chan_id = venc_chan;
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_DEQUEUE_FRAME, venc_queue_frame);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_get_cap_ability(venc_ioctl_cap *drv_cap)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (drv_cap == TD_NULL) {
|
|
ext_err_venc("para capability is NULL.\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
|
|
check_venc_init_ret();
|
|
|
|
venc_check_neq_ret(memset_s(drv_cap, sizeof(venc_ioctl_cap), 0, sizeof(venc_ioctl_cap)), TD_SUCCESS, TD_FAILURE);
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_GET_CAP, drv_cap);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_set_frame_drop_strategy(td_handle venc_id,
|
|
venc_ioctl_drop_frame_strategy *venc_frm_drop_strategy)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
check_venc_ptr_ret(venc_frm_drop_strategy);
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_id);
|
|
|
|
venc_frm_drop_strategy->chan_id = venc_id;
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_SET_DROP_FRM_STRATEGY, venc_frm_drop_strategy);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_err_venc("set_frame_drop_strategy failed! ret = %x\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_get_frame_drop_strategy(td_handle venc_id,
|
|
venc_ioctl_drop_frame_strategy *venc_frm_drop_strategy)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
check_venc_ptr_ret(venc_frm_drop_strategy);
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_id);
|
|
|
|
venc_frm_drop_strategy->chan_id = venc_id;
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_GET_DROP_FRM_STRATEGY, venc_frm_drop_strategy);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_err_venc("get_frame_drop_strategy failed! ret = %x\n", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_reset(td_handle venc_id)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_id);
|
|
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_RESET_CHN, &venc_id);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_err_venc("venc_reset chn %d failed! ret = %x\n", venc_id, ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_query_status(td_handle venc_id, venc_ioctl_status *query_status)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
check_venc_ptr_ret(query_status);
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_id);
|
|
|
|
query_status->chan_id = venc_id;
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_QUERY_STATUS, query_status);
|
|
if (ret != TD_SUCCESS) {
|
|
ext_err_venc("venc_reset failed! ret = %x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_get_attr(td_handle venc_chan, venc_ioctl_create *venc_chn_create)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
if (venc_chn_create == TD_NULL) {
|
|
ext_err_venc("para attr is NULL.\n");
|
|
return SOC_ERR_VENC_NULL_PTR;
|
|
}
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
venc_chn_create->chan_id = venc_chan;
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_GET_CHN_ATTR, venc_chn_create);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_set_rc_param(td_handle venc_chan, venc_ioctl_rc_param *ioctl_rc_param)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
check_venc_ptr_ret(ioctl_rc_param);
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
|
|
ioctl_rc_param->chan_id = venc_chan;
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_SET_RC_PARAM, ioctl_rc_param);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_s32 ext_mpi_venc_get_rc_param(td_handle venc_chan, venc_ioctl_rc_param *ioctl_rc_param)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
|
|
check_venc_ptr_ret(ioctl_rc_param);
|
|
check_venc_init_ret();
|
|
check_channel_exist_ret(i, VENC_MAX_CHN_NUM, venc_chan);
|
|
|
|
ioctl_rc_param->chan_id = venc_chan;
|
|
ret = ioctl(g_venc_dev_fd, CMD_VENC_GET_RC_PARAM, ioctl_rc_param);
|
|
|
|
return ret;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* end of #ifdef __cplusplus */
|
|
|