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

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