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
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;
|
|
}
|