Files
2026-08-24 10:03:24 +08:00

285 lines
8.9 KiB
C++

//#define LOG_NDEBUG 0
#define LOG_TAG "AMLVENC_API"
#ifdef __ANDROID__
#include <utils/Log.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include "enc_api.h"
//#include <cutils/properties.h>
//#if !defined(__aarch64__)
//#include "enc/m8_enc_fast/m8venclib_fast.h"
//#include "enc/m8_enc_fast/rate_control_m8_fast.h"
//#include "enc/m8_enc/m8venclib.h"
//#include "enc/m8_enc/rate_control_m8.h"
//#endif
#include "enc/gx_enc_fast/gxvenclib_fast.h"
#include "enc/gx_enc_fast/rate_control_gx_fast.h"
#define ENCODER_PATH "/dev/amvenc_avc"
#define AMVENC_DEVINFO_M8 "AML-M8"
#define AMVENC_DEVINFO_G9 "AML-G9"
#define AMVENC_DEVINFO_GXBB "AML-GXBB"
#define AMVENC_DEVINFO_GXTVBB "AML-GXTVBB"
#define AMVENC_AVC_IOC_MAGIC 'E'
#define AMVENC_AVC_IOC_GET_DEVINFO _IOW(AMVENC_AVC_IOC_MAGIC, 0xf0, unsigned int)
const AMVencHWFuncPtr gx_fast_dev = {
GxInitFastEncode,
GxFastEncodeInitFrame,
GxFastEncodeSPS_PPS,
GxFastEncodeSlice,
GxFastEncodeCommit,
GxUnInitFastEncode,
};
const AMVencRCFuncPtr gx_fast_rc = {
GxFastInitRateControlModule,
GxFastRCUpdateBuffer,
GxFastRCUpdateFrame,
GxFastRCInitFrameQP,
GxFastCleanupRateControlModule,
};
const AMVencHWFuncPtr *gdev[] = {
NULL,
NULL,
&gx_fast_dev,
NULL,
};
const AMVencRCFuncPtr *grc[] = {
NULL,
NULL,
&gx_fast_rc,
NULL,
};
AMVEnc_Status AMInitRateControlModule(amvenc_hw_t *hw_info)
{
if (!hw_info)
return AMVENC_MEMORY_FAIL;
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV) || (hw_info->dev_fd < 0) || (!hw_info->dev_data))
return AMVENC_FAIL;
if (grc[hw_info->dev_id]->Initialize != NULL) {
if (!(&(hw_info->init_para))) {
LOGAPI("AMInitRateControlModule: init_para NULL!");
return AMVENC_MEMORY_FAIL;
}
hw_info->rc_data = grc[hw_info->dev_id]->Initialize(&(hw_info->init_para));
}
if (!hw_info->rc_data) {
LOGAPI("AMInitRateControlModule Fail, dev type:%d. fd:%d",hw_info->dev_id, hw_info->dev_fd);
return AMVENC_FAIL;
}
return AMVENC_SUCCESS;
}
AMVEnc_Status AMPreRateControl(amvenc_hw_t *hw_info, int frameInc, bool force_IDR)
{
AMVEnc_Status ret = AMVENC_FAIL;
if (!hw_info)
return AMVENC_MEMORY_FAIL;
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV) || (!hw_info->rc_data))
return AMVENC_FAIL;
if (grc[hw_info->dev_id]->PreControl != NULL)
ret = grc[hw_info->dev_id]->PreControl(hw_info->dev_data, hw_info->rc_data, frameInc, force_IDR);
return ret;
}
AMVEnc_Status AMPostRateControl(amvenc_hw_t *hw_info, bool IDR, int *skip_num, int numFrameBits)
{
AMVEnc_Status ret = AMVENC_FAIL;
if (!hw_info)
return AMVENC_MEMORY_FAIL;
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV) || (!hw_info->rc_data))
return AMVENC_FAIL;
if (grc[hw_info->dev_id]->PostControl != NULL)
ret = grc[hw_info->dev_id]->PostControl(hw_info->dev_data, hw_info->rc_data, IDR, skip_num, numFrameBits);
return ret;
}
AMVEnc_Status AMRCInitFrameQP(amvenc_hw_t *hw_info, bool IDR, int bitrate, float frame_rate)
{
AMVEnc_Status ret = AMVENC_FAIL;
if (!hw_info)
return AMVENC_MEMORY_FAIL;
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV) || (!hw_info->rc_data))
return AMVENC_FAIL;
if (grc[hw_info->dev_id]->InitFrameQP != NULL)
ret = grc[hw_info->dev_id]->InitFrameQP(hw_info->dev_data, hw_info->rc_data, IDR, bitrate, frame_rate);
return ret;
}
void AMCleanupRateControlModule(amvenc_hw_t *hw_info)
{
if (!hw_info)
return;
if ((hw_info->rc_data) && (hw_info->dev_id > NO_DEFINE) && (hw_info->dev_id < MAX_DEV))
grc[hw_info->dev_id]->Release(hw_info->rc_data);
hw_info->rc_data = NULL;
return;
}
AMVEnc_Status InitAMVEncode(amvenc_hw_t *hw_info, int force_mode)
{
char dev_info[16];
int iret = -1, fd = -1;
if (!hw_info)
return AMVENC_MEMORY_FAIL;
hw_info->dev_fd = -1;
hw_info->dev_data = NULL;
hw_info->init_para.cbr_hw = false;
fd = open(ENCODER_PATH, O_RDWR);
if (fd<0) {
return AMVENC_FAIL;
}
memset(dev_info,0,sizeof(dev_info));
iret = ioctl(fd, AMVENC_AVC_IOC_GET_DEVINFO, &dev_info[0]);
LOGAPI("AMVENC_AVC_IOC_GET_DEVINFO: dev_info=%s", dev_info);
if((iret<0)||(dev_info[0] == 0)){
LOGAPI("The old encoder driver, not support query the dev info. set as M8 type!");
hw_info->dev_id = M8_FAST;
}else if((strcmp(dev_info, (char *)AMVENC_DEVINFO_M8) == 0)
||(strcmp(dev_info, (char *)AMVENC_DEVINFO_G9) == 0)){
LOGAPI("shitty m8");
hw_info->dev_id = M8_FAST;
}else if(strcmp(dev_info, (char *)AMVENC_DEVINFO_GXBB) == 0){
LOGAPI("gxbb");
hw_info->dev_id = GXBB;
}else if (strcmp(dev_info, (char *)AMVENC_DEVINFO_GXTVBB) == 0){
LOGAPI("gxtvbb");
hw_info->dev_id = GXBB;
hw_info->init_para.cbr_hw = true;
}else{
hw_info->dev_id = NO_DEFINE;
}
if (hw_info->dev_id == M8_FAST) {
if((hw_info->init_para.enc_width >= 1280) && (hw_info->init_para.enc_height >= 720))
hw_info->dev_id = M8_FAST;
else
hw_info->dev_id = M8;
if(1 == force_mode){
hw_info->dev_id = M8_FAST;
} else if(2 == force_mode){
hw_info->dev_id = M8;
}
int value = 0;
// memset(prop,0,sizeof(prop));
//#ifdef SUPPORT_STANDARD_PROP
// if (property_get("vendor.hw.encoder.forcemode", prop, NULL) > 0) {
//#else
// if (property_get("hw.encoder.forcemode", prop, NULL) > 0) {
//#endif
// sscanf(prop,"%d", &value);
// }else{
// value = 0;
// }
if(1 == value){
hw_info->dev_id = M8_FAST;
} else if(2 == value){
hw_info->dev_id = M8;
}
LOGAPI("hw.encoder.forcemode = %d, dev_id=%d. fd:%d", value, hw_info->dev_id, fd);
}
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV)) {
LOGAPI("Not found available hw encoder device, fd:%d", fd);
close(fd);
return AMVENC_FAIL;
}
if (gdev[hw_info->dev_id]->Initialize != NULL)
hw_info->dev_data = gdev[hw_info->dev_id]->Initialize(fd, &hw_info->init_para);
if (!hw_info->dev_data)
{
LOGAPI("InitAMVEncode Fail, dev type:%d. fd:%d", hw_info->dev_id, fd);
hw_info->dev_id = NO_DEFINE;
close(fd);
return AMVENC_FAIL;
}
hw_info->dev_fd = fd;
return AMVENC_SUCCESS;
}
AMVEnc_Status AMVEncodeInitFrame(amvenc_hw_t *hw_info, ulong *yuv, AMVEncBufferType type, AMVEncFrameFmt fmt, bool IDRframe)
{
AMVEnc_Status ret = AMVENC_FAIL;
if (!hw_info)
return AMVENC_MEMORY_FAIL;
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV) || (hw_info->dev_fd < 0) || (!hw_info->dev_data))
return AMVENC_FAIL;
if (gdev[hw_info->dev_id]->InitFrame != NULL)
ret = gdev[hw_info->dev_id]->InitFrame(hw_info->dev_data, yuv, type, fmt, IDRframe);
return ret;
}
AMVEnc_Status AMVEncodeSPS_PPS(amvenc_hw_t *hw_info, unsigned char *outptr, int *datalen)
{
AMVEnc_Status ret = AMVENC_FAIL;
if (!hw_info)
return AMVENC_MEMORY_FAIL;
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV) || (hw_info->dev_fd < 0) || (!hw_info->dev_data))
return AMVENC_FAIL;
if (gdev[hw_info->dev_id]->EncodeSPS_PPS != NULL)
ret = gdev[hw_info->dev_id]->EncodeSPS_PPS(hw_info->dev_data, outptr, datalen);
return ret;
}
AMVEnc_Status AMVEncodeSlice(amvenc_hw_t *hw_info, unsigned char *outptr, int *datalen)
{
AMVEnc_Status ret = AMVENC_FAIL;
if (!hw_info)
return AMVENC_MEMORY_FAIL;
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV) || (hw_info->dev_fd < 0) || (!hw_info->dev_data))
return AMVENC_FAIL;
if (gdev[hw_info->dev_id]->EncodeSlice != NULL)
ret = gdev[hw_info->dev_id]->EncodeSlice(hw_info->dev_data, outptr, datalen);
return ret;
}
AMVEnc_Status AMVEncodeCommit(amvenc_hw_t *hw_info, bool IDR)
{
AMVEnc_Status ret = AMVENC_FAIL;
if (!hw_info)
return AMVENC_MEMORY_FAIL;
if ((hw_info->dev_id <= NO_DEFINE) || (hw_info->dev_id >= MAX_DEV) || (hw_info->dev_fd < 0) || (!hw_info->dev_data))
return AMVENC_FAIL;
if (gdev[hw_info->dev_id]->Commit != NULL)
ret = gdev[hw_info->dev_id]->Commit(hw_info->dev_data, IDR);
return ret;
}
void UnInitAMVEncode(amvenc_hw_t *hw_info)
{
if (!hw_info)
return;
if ((hw_info->dev_data) && (hw_info->dev_id > NO_DEFINE) && (hw_info->dev_id < MAX_DEV))
gdev[hw_info->dev_id]->Release(hw_info->dev_data);
hw_info->dev_data = NULL;
if (hw_info->dev_fd >= 0)
{
close(hw_info->dev_fd);
}
hw_info->dev_fd = -1;
hw_info->dev_id = NO_DEFINE;
return;
}