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.

335 lines
9.2 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
* Description: encoder
* Author: sdk
* Create: 2019-07-18
*/
#include <stdio.h>
#include "mpi_venc_ext.h"
#include "uapi_venc.h"
#include "venc_convert.h"
#include "mpi_venc.h"
td_s32 uapi_venc_init(td_void)
{
return ext_mpi_venc_init();
}
td_s32 uapi_venc_deinit(td_void)
{
return ext_mpi_venc_deinit();
}
td_s32 uapi_venc_create(td_handle *venc_chan, const uapi_venc_attr *attr)
{
venc_ioctl_create venc_chn_create = {0};
check_venc_ptr_ret(attr);
check_venc_ptr_ret(venc_chan);
venc_get_drv_chn_create_attr(&venc_chn_create, attr);
return ext_mpi_venc_create(venc_chan, &venc_chn_create);
}
td_s32 uapi_venc_destroy(td_handle venc_chan)
{
return ext_mpi_venc_destroy(venc_chan);
}
td_s32 uapi_venc_attach_input(td_handle venc_chan, td_handle src)
{
venc_unused(venc_chan);
venc_unused(src);
ext_err_venc("this func not support!\n");
return SOC_ERR_VENC_NOT_SUPPORT;
}
td_s32 uapi_venc_detach_input(td_handle venc_chan)
{
venc_unused(venc_chan);
ext_err_venc("this func not support!\n");
return SOC_ERR_VENC_NOT_SUPPORT;
}
td_s32 uapi_venc_acquire_stream(td_handle venc_chan, uapi_venc_stream *stream, td_u32 timeout_ms)
{
td_s32 ret;
venc_ioctl_acquire_stream acquire_stream = {0};
check_venc_ptr_ret(stream);
ret = ext_mpi_venc_acquire_stream(venc_chan, &acquire_stream, timeout_ms);
if (ret != TD_SUCCESS) {
return ret;
}
ret = venc_convert_stream_drv_to_user(stream, &acquire_stream);
return ret;
}
td_s32 uapi_venc_release_stream(td_handle venc_chan, const uapi_venc_stream *stream)
{
venc_ioctl_acquire_stream acquire_stream = {0};
check_venc_ptr_ret(stream);
if (venc_convert_stream_user_to_drv(&acquire_stream, stream) != TD_SUCCESS) {
ext_err_venc("venc_convert_stream_user_to_drv failed\n");
return SOC_ERR_VENC_INVALID_PARA;
}
return ext_mpi_venc_release_stream(venc_chan, &acquire_stream);
}
td_s32 uapi_venc_start(td_handle venc_chan)
{
return ext_mpi_venc_start(venc_chan);
}
td_s32 uapi_venc_stop(td_handle venc_chan)
{
return ext_mpi_venc_stop(venc_chan);
}
td_s32 uapi_venc_set_config(td_handle venc_chan, const uapi_venc_config *config)
{
venc_ioctl_chan_info chan_info = {0};
td_s32 ret;
check_venc_ptr_ret(config);
ret = ext_mpi_venc_get_config(venc_chan, &chan_info);
if (ret != TD_SUCCESS) {
ext_err_venc("Get kernel config failed\n");
return ret;
}
venc_convert_config_user_to_drv(&chan_info.config, config);
return ext_mpi_venc_set_config(venc_chan, &chan_info);
}
td_s32 uapi_venc_get_config(td_handle venc_chan, uapi_venc_config *config)
{
td_s32 ret;
venc_ioctl_chan_info chan_info = {0};
check_venc_ptr_ret(config);
ret = ext_mpi_venc_get_config(venc_chan, &chan_info);
if (ret == TD_SUCCESS) {
venc_convert_config_drv_to_user(config, &chan_info.config);
}
return ret;
}
td_s32 uapi_venc_request_i_frame(td_handle venc_chan)
{
return ext_mpi_venc_request_i_frame(venc_chan);
}
td_s32 uapi_venc_queue_frame(td_handle venc_chan, uapi_video_frame_info *frame_info)
{
td_s32 ret;
venc_ioctl_queue_frame venc_queue_frame = {0};
check_venc_ptr_ret(frame_info);
ret = venc_convert_frame_user_to_drv(&venc_queue_frame.venc_frame, frame_info);
if (ret != TD_SUCCESS) {
ext_err_venc("frame_convert_user_to_drv failed\n");
return SOC_ERR_VENC_INVALID_PARA;
}
return ext_mpi_venc_queue_frame(venc_chan, &venc_queue_frame);
}
td_s32 uapi_venc_dequeue_frame(td_handle venc_chan, uapi_video_frame_info *frame_info)
{
td_s32 ret;
venc_ioctl_queue_frame venc_queue_frame;
check_venc_ptr_ret(frame_info);
ret = ext_mpi_venc_dequeue_frame(venc_chan, &venc_queue_frame);
if (ret != TD_SUCCESS) {
return ret;
}
ret = venc_convert_frame_drv_to_user(frame_info, &venc_queue_frame.venc_frame);
if (ret != TD_SUCCESS) {
ext_err_venc("frame_convert_user_to_drv failed\n");
return SOC_ERR_VENC_INVALID_PARA;
}
return ret;
}
td_s32 uapi_venc_get_default_attr(uapi_venc_attr *attr)
{
if (attr == NULL) {
return SOC_ERR_VENC_NULL_PTR;
}
attr->venc_type = UAPI_VCODEC_TYPE_H264;
attr->max_width = 1280; /* 1280: max picture width */
attr->max_height = 720; /* 720: max picture height */
attr->profile.h264_profile = UAPI_H264_PROFILE_HIGH;
attr->slice_split.enable = TD_FALSE;
attr->slice_split.mode = UAPI_VENC_SPLIT_MAX;
attr->slice_split.size = 0;
attr->stream_buf_size = 1280 * 720 * 2; /* set default StrmBuf Size 1280 * 720 * 2 */
attr->gop_mode = UAPI_VENC_GOP_MODE_NORMALP;
attr->secure = TD_FALSE;
attr->config.width = 1280; /* set default Width 1280 */
attr->config.height = 720; /* set default Height 720 */
attr->config.target_bitrate = 4 * 1024 * 1024; /* set default Target BitRate 4 * 1024 * 1024 */
attr->config.input_frame_rate = 25 * 1000; /* 1000: set default Input FrmRate 25 */
attr->config.target_frame_rate = 25 * 1000; /* 1000: set default Target FrmRate 25 */
attr->config.gop = 100; /* set default Gop 100 */
attr->config.quick_encode = TD_FALSE;
attr->config.priority = 0;
attr->config.qfactor = 0;
attr->config.input_frame_rate_type = UAPI_VENC_FRAME_RATE_TYPE_USER;
attr->config.sp_interval = 0;
return TD_SUCCESS;
}
td_s32 uapi_venc_get_cap_ability(uapi_venc_cap *capability)
{
td_s32 ret;
venc_ioctl_cap drv_cap = {0};
check_venc_ptr_ret(capability);
ret = ext_mpi_venc_get_cap_ability(&drv_cap);
if (ret == TD_SUCCESS) {
venc_convert_cap_drv_to_user(capability, &drv_cap);
}
return ret;
}
td_s32 uapi_venc_set_frame_drop_strategy(td_handle venc_id, const uapi_venc_frame_drop_strategy *frm_drop_param)
{
venc_ioctl_drop_frame_strategy venc_frm_drop_strategy = {0};
check_venc_ptr_ret(frm_drop_param);
venc_convert_strategy_user_to_drv(&venc_frm_drop_strategy, frm_drop_param);
return ext_mpi_venc_set_frame_drop_strategy(venc_id, &venc_frm_drop_strategy);
}
td_s32 uapi_venc_get_frame_drop_strategy(td_handle venc_id, uapi_venc_frame_drop_strategy *frm_drop_param)
{
td_s32 ret;
venc_ioctl_drop_frame_strategy venc_frm_drop_strategy = {0};
check_venc_ptr_ret(frm_drop_param);
ret = ext_mpi_venc_get_frame_drop_strategy(venc_id, &venc_frm_drop_strategy);
if (ret == TD_SUCCESS) {
venc_convert_strategy_drv_to_user(frm_drop_param, &venc_frm_drop_strategy);
}
return ret;
}
static td_s32 process_cmd_set_rc_param(td_handle venc_id, td_void *param, td_u32 param_len)
{
uapi_venc_rc_param *iapi_rc_param = TD_NULL;
venc_ioctl_rc_param drv_rc_param = {};
check_venc_ptr_ret(param);
if (param_len != sizeof(uapi_venc_rc_param)) {
ext_err_venc("param length error, expect param type is uapi_venc_rc_param\n");
return SOC_ERR_VENC_INVALID_PARA;
}
iapi_rc_param = (uapi_venc_rc_param *)param;
venc_convert_rc_param_iapi_to_drv(&drv_rc_param.rc_param, iapi_rc_param);
return ext_mpi_venc_set_rc_param(venc_id, &drv_rc_param);
}
static td_s32 process_cmd_get_rc_param(td_handle venc_id, td_void *param, td_u32 param_len)
{
uapi_venc_rc_param *iapi_rc_param = TD_NULL;
venc_ioctl_rc_param drv_rc_param = {};
td_s32 ret;
check_venc_ptr_ret(param);
if (param_len != sizeof(uapi_venc_rc_param)) {
ext_err_venc("param length error, expect param type is uapi_venc_rc_param\n");
return SOC_ERR_VENC_INVALID_PARA;
}
iapi_rc_param = (uapi_venc_rc_param *)param;
ret = ext_mpi_venc_get_rc_param(venc_id, &drv_rc_param);
if (ret == TD_SUCCESS) {
venc_convert_rc_param_drv_to_unf(iapi_rc_param, &drv_rc_param.rc_param);
}
return ret;
}
td_s32 uapi_venc_invoke(td_handle venc_id, uapi_venc_invoke_cmd invoke_cmd, td_void *param, td_u32 param_len)
{
td_s32 ret = SOC_ERR_VENC_NOT_SUPPORT;
switch (invoke_cmd) {
case UAPI_VENC_INVOKE_SET_RC_PARAM:
ret = process_cmd_set_rc_param(venc_id, param, param_len);
break;
case UAPI_VENC_INVOKE_GET_RC_PARAM:
ret = process_cmd_get_rc_param(venc_id, param, param_len);
break;
default:
printf("Unsupported command\n");
break;
}
return ret;
}
td_s32 uapi_venc_reset(td_handle venc_id)
{
return ext_mpi_venc_reset(venc_id);
}
td_s32 uapi_venc_query_status(td_handle venc_id, uapi_venc_chan_status *status)
{
td_s32 ret;
venc_ioctl_status query_status = {0};
check_venc_ptr_ret(status);
ret = ext_mpi_venc_query_status(venc_id, &query_status);
if (ret == TD_SUCCESS) {
venc_convert_status_drv_to_user(status, &query_status);
}
return ret;
}
/* Don't get input frame type */
td_s32 uapi_venc_get_attr(td_handle chan_id, uapi_venc_attr *attr)
{
td_s32 ret;
venc_ioctl_create venc_chn_create;
check_venc_ptr_ret(attr);
ret = ext_mpi_venc_get_attr(chan_id, &venc_chn_create);
if (ret == TD_SUCCESS) {
venc_convert_attr_drv_to_user(attr, &venc_chn_create.attr);
}
return ret;
}