sdk-hwV1.3/external/fast-user-adapter/rt_media/api_adapter/AW_VideoInput_API.c

5020 lines
134 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/genetlink.h>
#define LOG_TAG "aw_video02"
#include "AW_VideoInput_API.h"
#include "aw_ion_alloc.h"
#include "aw_ion_util.h"
#include "aw_util.h"
//#include "uapi_rt_media.h"
#include "aw_message_queue.h"
#if RT_MEDIA_SUPPORT_VENC_PARAM_DEBUG
#include "aw_config_param_parser.h"
#endif
#define TMP_BUFFER_SIZE (4*256*1024)
#define RT_MEDIA_DEV_NAME ("/dev/rt-media")
#define MAX_SPS_PPS_SIZE (256)
typedef enum AWVideoInput_Cmd
{
VIDEO_INPUT_CMD_EXIT = 0,
VIDEO_INPUT_CMD_PAUSE = 1,
VIDEO_INPUT_CMD_EXCUTING = 2,
}AWVideoInput_Cmd;
#define SEM_WAIT_REPLY_NUM (VIDEO_INPUT_CMD_EXCUTING + 1)
typedef struct vbv_buffer_info
{
int share_fd;
int fd;
int bInit;
unsigned char* virBuf;
int size;
int handle;
}vbv_buffer_info;
typedef struct encoder_yuv_buf_info {
unsigned char* phy_addr;
unsigned char* vir_addr;
int buf_size;
int bInit_flag;
} encoder_yuv_buf_info;
typedef struct yuv_fd_info {
int bset;
int yuv_fd;
unsigned char* virBuf;
} yuv_fd_info;
typedef struct AWChannel_cxt
{
int id;
int dev_fd;
AWVideoInput_State state;
VideoInputConfig config;
Video_Input_cb callback;
Channel_Thread_exit thread_exit_cb;
AWVideoInputCallbackType mCallback;
void* mpAppData;
AWTdmBufferDoneCallback mTdmBufDoneCallback;
pthread_t thread;
int bThread_create_flag; ///< indicate if ChannelThread() has been created.
vbv_buffer_info vbv_buffer;
sps_pps_data_info sps_pps_data;
pthread_mutex_t mutex;
unsigned char* tmp_buf;
int tmp_buf_size;
catch_jpeg_config jpeg_config;
uint64_t pre_pts;
XmMessageQueue* mq;
sem_t reply_sem[SEM_WAIT_REPLY_NUM];
int mSockFd;
unsigned int mSrcNLPortId; //netlink port id of AWChannel_cxt self. we set it to differentiate it from other AWChannel_cxts.
encoder_yuv_buf_info enc_yuv_buf_info;
VideoInputOSD video_osd_info;
int video_osd_need_process_flag; //indicate when AWVideoInput_Start(), process osd setting.
RTVencVbrParam vbr_param;
int demo_wait_csi_ready;
WbYuvFuncInfo *p_wbyuv_info;
int b_insert_sps_pps;
yuv_fd_info s_yuv_fd[CONFIG_YUV_BUF_NUM];
pthread_t GENL_thread;
int bGENL_thread_create_flag;
int GENL_thread_exit_flag;
int enable_aiisp;
int start_process_tdm_buf;
pthread_t AIISP_thread;
int bAIISP_thread_create_flag;
int AIISP_thread_exit_flag;
}AWChannel_cxt;
typedef struct AWVideoInput_cxt
{
AWChannel_cxt channel_cxt[VIDEO_INPUT_CHANNEL_NUM];
int ion_fd;
unsigned short mGENLFamilyId; //generic netlink family id
}AWVideoInput_cxt;
/*******************isp to flash**************************/
#define ISP0_PARAM_OFFSET 104 /*104 ~ 110 sector 3.5k*/
#define ISP1_PARAM_OFFSET 112 /*112 ~ 118 sector 3.5k*/
struct write4k_op_t {
loff_t start;
unsigned char *buf;
loff_t len;
};
#define MEMWRITE_4K _IOWR('M', 29, struct write4k_op_t)
#define DAY_LIGNT_SENSOR_SIZE 96
#define NIGHT_LIGNT_SENSOR_SIZE 40
#pragma pack(1)
typedef struct taglight_sensor_attr_s {
unsigned short u16LightValue; /*adc value*/
unsigned short ae_table_idx;
unsigned int u32SnsExposure;
unsigned int u32SnsAgain;
} LIGHT_SENSOR_ATTR_S;
typedef struct tagsensor_isp_config_s {
int sign; //id0: 0xAA66AA66, id1: 0xBB66BB66
int crc; //checksum, crc32 check, if crc = 0, do check
int ver; //version, 0x01
int light_enable; //boot0 adc en
int adc_mode; //ADC mode, 0:the brighter the u16LightValue more, 1:the brighter the u16LightValue smaller
unsigned short light_def; //adc threshold: 1,adc_mode=0:smaller than it enter night mode, greater than it or equal enter day mode;
//2,adc_mode=1:greater than it enter night mode, smaller than it or equal enter day mode;
unsigned char ircut_state; //1:hold, 0:use ir_mode
unsigned short ir_mode; //IR mode 0:force day mode, 1:auto mode, 2:force night mode
unsigned short lv_liner_def; //lv threshold: smaller than it enter night mode, greater than it or equal enter day mode
unsigned short lv_hdr_def; //lv threshold: smaller than it enter night mode, greater than it or equal enter day mode
unsigned short width; //init size, 0:mean maximum size
unsigned short height;
unsigned short mirror;
unsigned short filp;
unsigned short fps;
unsigned short wdr_mode; //hdr or normal mode, wdr_mode = 0 mean normal, wdr_mode = 1 mean hdr
unsigned char flicker_mode; //0:disable,1:50HZ,2:60HZ, default 50HZ
unsigned char venc_format; //1:H264 2:H265
/* unsigned char reserv 256 */
unsigned char sensor_deinit; //sensor not init in melis
unsigned char get_yuv_en; //get melis yuv en
unsigned char light_sensor_en; //use LIGHT_SENSOR_ATTR_S en
unsigned char hdr_light_sensor_ratio; //LIGHT_SENSOR_ATTR_S hdr exposure ratio, default is 32
unsigned char lightadc_debug_en; //printf data about LIGHT_SENSOR_ATTR_S
unsigned char reserv[256 - 5];
LIGHT_SENSOR_ATTR_S linear[DAY_LIGNT_SENSOR_SIZE]; //day linear mode parameter, auto exp
LIGHT_SENSOR_ATTR_S linear_night[NIGHT_LIGNT_SENSOR_SIZE]; //night linear mode parameter
LIGHT_SENSOR_ATTR_S hdr[DAY_LIGNT_SENSOR_SIZE]; //day hdr mode paramete
LIGHT_SENSOR_ATTR_S hdr_night[NIGHT_LIGNT_SENSOR_SIZE]; //night hdr mode parameter
} SENSOR_ISP_CONFIG_S;
#pragma pack()
#define GENL_MSG_GET_WAIT_MAX_TIME_MS (200)
#define GENL_MSG_CHECK_MAX_INTERVAL_US (1*1000*1000)
#define GENL_MSG_CHECK_MAX_CNT (10)
static AWVideoInput_cxt* g_videoInput_cxt = NULL;
int AWVideoInput_DeInit(void);
void* ChannelThread(void* param);
void* GENLRecvThread(void *param);
void* AIISPThread(void *param);
int isp_config_to_flash(void);
static int callback_stream_data(AWChannel_cxt* channel_cxt, STREAM_DATA_INFO* stream_data)
{
AWVideoInput_StreamInfo s_stream_info;
memset(&s_stream_info, 0, sizeof(s_stream_info));
unsigned char* vbv_start_buf = channel_cxt->vbv_buffer.virBuf;
if(stream_data->keyframe_flag == 1)
{
aw_logd("stream: data = %p, %p, %p; size = %d, %d, %d; offset = %d, %d, %d, kf = %d, sizeof = %d",
stream_data->data0, stream_data->data1, stream_data->data2,
stream_data->size0, stream_data->size1, stream_data->size2,
stream_data->offset0, stream_data->offset1, stream_data->offset2,
stream_data->keyframe_flag, sizeof(STREAM_DATA_INFO));
}
//* keyframe and buf ring case
if(stream_data->keyframe_flag == 1
&& (channel_cxt->config.encodeType == 0 || channel_cxt->config.encodeType == 2)
&& channel_cxt->sps_pps_data.bInit == 1 && channel_cxt->b_insert_sps_pps)
s_stream_info.b_insert_sps_pps = 1;
else
s_stream_info.b_insert_sps_pps = 0;
//s_stream_info.pts = (uint64_t)stream_data->tv.tv_sec*1000000 + (uint64_t)stream_data->tv.tv_usec;
s_stream_info.pts = stream_data->pts;
if(stream_data->size0 > 0)
{
s_stream_info.data0 = vbv_start_buf + stream_data->offset0;
s_stream_info.size0 = stream_data->size0;
}
else
{
aw_loge("fatal error! why size0 is 0?");
}
if(stream_data->size1 > 0)
{
s_stream_info.data1 = vbv_start_buf + stream_data->offset1;
s_stream_info.size1 = stream_data->size1;
}
if(stream_data->size2 > 0)
{
s_stream_info.data2 = vbv_start_buf + stream_data->offset2;
s_stream_info.size2 = stream_data->size2;
}
s_stream_info.sps_pps_buf = channel_cxt->sps_pps_data.buf;
s_stream_info.sps_pps_size = channel_cxt->sps_pps_data.size;
s_stream_info.keyframe_flag = stream_data->keyframe_flag;
s_stream_info.stream_data = stream_data;
s_stream_info.channel_id = channel_cxt->id;
//* callback to caller
channel_cxt->callback(&s_stream_info);
return 0;
}
static int get_sps_pps_data(AWChannel_cxt* channel_cxt)
{
int size = 0;
int ret = ioctl(channel_cxt->dev_fd, IOCTL_GET_STREAM_HEADER_SIZE, &size);
aw_logd("get stream size = %d, ret = %d\n",size, ret);
if(ret != 0)
{
aw_logw("[%d]get sps pps size failed: ret = %d\n",channel_cxt->id, ret);
return -1;
}
if(size <= 0 || size > MAX_SPS_PPS_SIZE)
{
aw_loge("size of sps_pps_data is error: %d\n",size);
return -1;
}
if(channel_cxt->sps_pps_data.buf)
free(channel_cxt->sps_pps_data.buf);
channel_cxt->sps_pps_data.size = size;
channel_cxt->sps_pps_data.buf = (unsigned char*)malloc(size);
memset(channel_cxt->sps_pps_data.buf, 0, size);
ret = ioctl(channel_cxt->dev_fd, IOCTL_GET_STREAM_HEADER_DATA, channel_cxt->sps_pps_data.buf);
aw_logd("get stream ret = %d, data = %x %x %x %x %x %x\n",
ret,
channel_cxt->sps_pps_data.buf[0],
channel_cxt->sps_pps_data.buf[1],
channel_cxt->sps_pps_data.buf[2],
channel_cxt->sps_pps_data.buf[3],
channel_cxt->sps_pps_data.buf[4],
channel_cxt->sps_pps_data.buf[5]);
if(ret != 0)
{
aw_logw("[%d]get sps pps data failed: ret = %d\n",channel_cxt->id, ret);
return -1;
}
channel_cxt->sps_pps_data.bInit = 1;
return 0;
}
static int init_vbv_buffer(AWChannel_cxt* channel_cxt)
{
KERNEL_VBV_BUFFER_INFO kernel_vbv_buf;
memset(&kernel_vbv_buf, 0, sizeof(KERNEL_VBV_BUFFER_INFO));
int ret = ioctl(channel_cxt->dev_fd, IOCTL_GET_VBV_BUFFER_INFO, &kernel_vbv_buf);
if(ret != 0)
{
aw_loge("[%d]get vbv buf failed: ret = %d\n",channel_cxt->id, ret);
return -1;
}
channel_cxt->vbv_buffer.bInit = 1;
channel_cxt->vbv_buffer.size = kernel_vbv_buf.size;
channel_cxt->vbv_buffer.share_fd = kernel_vbv_buf.share_fd;
ret = aw_ion_mmap(channel_cxt->vbv_buffer.share_fd,
channel_cxt->vbv_buffer.size,
&channel_cxt->vbv_buffer.virBuf);
aw_logd("ret %d mmap: virBuf = %p, share_fd = %d",
ret, channel_cxt->vbv_buffer.virBuf,
channel_cxt->vbv_buffer.share_fd);
aw_logv("init_vbv_buffer: share_fd = %d, handle = %d, virBuf = %p, fd = %d\n",
channel_cxt->vbv_buffer.share_fd, channel_cxt->vbv_buffer.handle,
channel_cxt->vbv_buffer.virBuf, channel_cxt->vbv_buffer.fd);
return 0;
}
static void destroy_vbv_buffer(vbv_buffer_info* vbv_buf_info)
{
aw_ion_unmap(vbv_buf_info->size, vbv_buf_info->virBuf);
close(vbv_buf_info->share_fd);
aw_logd("close the share fd = %d, fd = %d", vbv_buf_info->share_fd, vbv_buf_info->fd);
vbv_buf_info->virBuf = NULL;
vbv_buf_info->bInit = 0;
}
static int delay_setup_osd_info(AWChannel_cxt* channel_cxt, VideoInputOSD *src_osd)
{
int i = 0;
VideoInputOSD* dst_osd = &channel_cxt->video_osd_info;
aw_logv("osd_num = %d", src_osd->osd_num);
for(i = 0; i < dst_osd->osd_num; i++)
{
if(dst_osd->item_info[i].data_buf)
{
free(dst_osd->item_info[i].data_buf);
dst_osd->item_info[i].data_buf = NULL;
}
}
for(i = 0; i < src_osd->osd_num; i++)
{
dst_osd->item_info[i].start_x = src_osd->item_info[i].start_x;
dst_osd->item_info[i].start_y = src_osd->item_info[i].start_y;
dst_osd->item_info[i].widht = src_osd->item_info[i].widht;
dst_osd->item_info[i].height = src_osd->item_info[i].height;
dst_osd->item_info[i].data_size = src_osd->item_info[i].data_size;
dst_osd->item_info[i].osd_type = src_osd->item_info[i].osd_type;
memcpy(&dst_osd->item_info[i].cover_yuv, &src_osd->item_info[i].cover_yuv, sizeof(VencCoverYuvS));
dst_osd->item_info[i].data_buf = malloc(dst_osd->item_info[i].data_size);
if(dst_osd->item_info[i].data_buf == NULL)
{
aw_loge("malloc failed, size = %d", dst_osd->item_info[i].data_size);
return -1;
}
memcpy(dst_osd->item_info[i].data_buf, src_osd->item_info[i].data_buf,
dst_osd->item_info[i].data_size);
}
dst_osd->osd_num = src_osd->osd_num;
dst_osd->argb_type = src_osd->argb_type;
channel_cxt->video_osd_need_process_flag = 1;
return 0;
}
#define INI_PATH "/tmp/"
static RTTunningSensorCfg SensorCfg[VIDEO_INPUT_CHANNEL_NUM];
static int save_ini_tuning_file(AWChannel_cxt* channel_cxt, char *path, int isp_id,int w, int h, int fps, int wdr)
{
char isp_cfg_path[128], command[128];
RTTunningCtlData TunningCtlData;
if (strcmp(path, "")) {
sprintf(isp_cfg_path, "%sisp%d_%d_%d_%d_%d/", path, isp_id, w, h, fps, wdr);
if (access(isp_cfg_path, F_OK) == 0) {
sprintf(command, "rm -rf %s", isp_cfg_path);
system(command);
}
sprintf(command, "mkdir %s", isp_cfg_path);
system(command);
TunningCtlData.cfg_id = RT_ISP_CTRL_GET_ISP_PARAM;
sprintf(TunningCtlData.path, "%sisp%d_%d_%d_%d_%d/", path, isp_id, w, h, fps, wdr);
pthread_mutex_lock(&channel_cxt->mutex);
ioctl(channel_cxt->dev_fd, IOCTL_GET_TUNNING_CTL_DATA, &TunningCtlData);
pthread_mutex_unlock(&channel_cxt->mutex);
//log
sprintf(isp_cfg_path, "%sisp%d_%d_%d_%d_%d/LOG/", path, isp_id, w, h, fps, wdr);
sprintf(command, "mkdir %s", isp_cfg_path);
system(command);
sprintf(command, "touch %sflag", isp_cfg_path);
system(command);
sprintf(command, "echo 0 > %sflag", isp_cfg_path);
system(command);
//3a stat
sprintf(isp_cfg_path, "%sisp%d_%d_%d_%d_%d/3a_stat/", path, isp_id, w, h, fps, wdr);
sprintf(command, "mkdir %s", isp_cfg_path);
system(command);
sprintf(command, "touch %sflag", isp_cfg_path);
system(command);
sprintf(command, "echo 0 > %sflag", isp_cfg_path);
system(command);
//creat isp_tuning file
sprintf(command, "touch %sisp_tuning_isp%d", path, isp_id);
system(command);
sprintf(command, "echo 1 > %sisp_tuning_isp%d", path, isp_id);
system(command);
} else {
printf("[ISP_TUNNING]: isp%d sensor path is invalid\n", isp_id);
return -1;
}
return 0;
}
static int load_ini_tuning_file(AWChannel_cxt* channel_cxt, char *path, int isp_id, int w, int h, int fps, int wdr)
{
int i, ret = 0, encoder_width, encoder_height;
char isp_cfg_path[128], buf[50], pic_path[128], rdval = 1;
RTTunningCtlData TunningCtlData;
static unsigned char delay_cnt = 0;
FILE *fd = NULL;
if (strcmp(path, "")) {
sprintf(isp_cfg_path, "%sisp_tuning_isp%d", path, isp_id);
fd = fopen(isp_cfg_path, "r");
if (fd) {
if (fgets(buf, 50, fd) != NULL) {
rdval = atoi(buf);
}
fclose(fd);
fd = NULL;
} else {
printf("[ISP_TUNNING]: %s open failed\n", isp_cfg_path);
return ret;
}
if (!rdval) {
//cfg ir colorspace
TunningCtlData.cfg_id = RT_ISP_CTRL_SET_ISP_PARAM;
sprintf(TunningCtlData.path, "%sisp%d_%d_%d_%d_%d/", path, isp_id, w, h, fps, wdr);
pthread_mutex_lock(&channel_cxt->mutex);
ioctl(channel_cxt->dev_fd, IOCTL_GET_TUNNING_CTL_DATA, &TunningCtlData);
pthread_mutex_unlock(&channel_cxt->mutex);
//update isp_tuning flag
sprintf(isp_cfg_path, "echo 1 > %sisp_tuning_isp%d", path, isp_id);
system(isp_cfg_path);
} else {
ret = 1;
}
//log
sprintf(isp_cfg_path, "%sisp%d_%d_%d_%d_%d/LOG/flag", path, isp_id, w, h, fps, wdr);
fd = fopen(isp_cfg_path, "r");
if (fd) {
if (fgets(buf, 50, fd) != NULL) {
rdval = atoi(buf);
}
fclose(fd);
fd = NULL;
} else {
printf("[ISP_TUNNING]: %s open failed\n", isp_cfg_path);
}
if (!rdval) {
TunningCtlData.cfg_id = RT_ISP_CTRL_GET_LOG;
sprintf(TunningCtlData.path, "%sisp%d_%d_%d_%d_%d/", path, isp_id, w, h, fps, wdr);
pthread_mutex_lock(&channel_cxt->mutex);
ioctl(channel_cxt->dev_fd, IOCTL_GET_TUNNING_CTL_DATA, &TunningCtlData);
pthread_mutex_unlock(&channel_cxt->mutex);
sprintf(isp_cfg_path, "echo 1 > %sisp%d_%d_%d_%d_%d/LOG/flag", path, isp_id, w, h, fps, wdr);
system(isp_cfg_path);
}
//3a_stat
sprintf(isp_cfg_path, "%sisp%d_%d_%d_%d_%d/3a_stat/flag", path, isp_id, w, h, fps, wdr);
fd = fopen(isp_cfg_path, "r");
if (fd) {
if (fgets(buf, 50, fd) != NULL) {
rdval = atoi(buf);
}
fclose(fd);
fd = NULL;
} else {
printf("[ISP_TUNNING]: %s open failed\n", isp_cfg_path);
}
if (!rdval) {
TunningCtlData.cfg_id = RT_ISP_CTRL_GET_3A_STAT;
sprintf(TunningCtlData.path, "%sisp%d_%d_%d_%d_%d/", path, isp_id, w, h, fps, wdr);
pthread_mutex_lock(&channel_cxt->mutex);
ioctl(channel_cxt->dev_fd, IOCTL_GET_TUNNING_CTL_DATA, &TunningCtlData);
pthread_mutex_unlock(&channel_cxt->mutex);
sprintf(isp_cfg_path, "echo 1 > %sisp%d_%d_%d_%d_%d/3a_stat/flag", path, isp_id, w, h, fps, wdr);
system(isp_cfg_path);
}
//encpp
sprintf(isp_cfg_path, "%sisp%d_%d_%d_%d_%d/encpp/encpp_flag", path, isp_id, w, h, fps, wdr);
if (access(isp_cfg_path, F_OK) == 0) {
RTsWbYuvParam WbYuvParam;
RTVencThumbInfo mThumbInfo;
memset(&WbYuvParam, 0, sizeof(RTsWbYuvParam));
memset(&mThumbInfo, 0, sizeof(RTVencThumbInfo));
fd = fopen(isp_cfg_path, "r");
if (fd) {
fgets(pic_path, 128, fd);
fclose(fd);
fd = NULL;
} else {
printf("[ISP_TUNNING]: %s open failed\n", isp_cfg_path);
return ret;
}
sprintf(isp_cfg_path, "%sisp%d_%d_%d_%d_%d/encpp/encpp_width", path, isp_id, w, h, fps, wdr);
fd = fopen(isp_cfg_path, "r");
if (fd) {
if (fgets(buf, 50, fd) != NULL) {
WbYuvParam.sWbYuvcrop.nWidth = atoi(buf);
}
fclose(fd);
fd = NULL;
} else {
printf("[ISP_TUNNING]: %s open failed\n", isp_cfg_path);
return ret;
}
sprintf(isp_cfg_path, "%sisp%d_%d_%d_%d_%d/encpp/encpp_height", path, isp_id, w, h, fps, wdr);
fd = fopen(isp_cfg_path, "r");
if (fd) {
if (fgets(buf, 50, fd) != NULL) {
WbYuvParam.sWbYuvcrop.nHeight = atoi(buf);
}
fclose(fd);
fd = NULL;
} else {
printf("[ISP_TUNNING]: %s open failed\n", isp_cfg_path);
return ret;
}
if (!channel_cxt->config.dst_width || !channel_cxt->config.dst_height) {
encoder_width = channel_cxt->config.width;
encoder_height = channel_cxt->config.height;
} else {
encoder_width = channel_cxt->config.dst_width;
encoder_height = channel_cxt->config.dst_height;
}
if (WbYuvParam.sWbYuvcrop.nWidth > encoder_width || WbYuvParam.sWbYuvcrop.nHeight > encoder_height) {
printf("[ISP_TUNNING]: resolution(%dx%d) > encoder_resolution(%dx%d)! \n", WbYuvParam.sWbYuvcrop.nWidth, WbYuvParam.sWbYuvcrop.nHeight,
encoder_width, encoder_height);
return ret;
}
WbYuvParam.bEnableWbYuv = 1;
WbYuvParam.nWbBufferNum = 1;
WbYuvParam.scalerRatio = RTVENC_ISP_SCALER_0;
if (WbYuvParam.sWbYuvcrop.nWidth == encoder_width && WbYuvParam.sWbYuvcrop.nHeight == encoder_height) {
WbYuvParam.bEnableCrop = 0;
} else {
WbYuvParam.bEnableCrop = 1;
WbYuvParam.sWbYuvcrop.nTop = (ALIGN_XXB(16, encoder_height)/2 - WbYuvParam.sWbYuvcrop.nHeight/2);
WbYuvParam.sWbYuvcrop.nLeft = (ALIGN_XXB(16, encoder_width)/2 - WbYuvParam.sWbYuvcrop.nWidth/2);
}
int nAlignW = ALIGN_XXB(16, WbYuvParam.sWbYuvcrop.nWidth);
int nAlignH = ALIGN_XXB(16, WbYuvParam.sWbYuvcrop.nHeight);
if (channel_cxt->p_wbyuv_info == NULL) {
channel_cxt->p_wbyuv_info = calloc(1, sizeof(WbYuvFuncInfo));
memset(channel_cxt->p_wbyuv_info, 0, sizeof(WbYuvFuncInfo));
}
if (delay_cnt-- > 0) {
if (!channel_cxt->p_wbyuv_info->enable_wbyuv || channel_cxt->p_wbyuv_info->yuvSize != nAlignW*nAlignH*3/2) {
printf("Init encpp cfg(Left=%d, Top=%d, Width=%d, Height=%d)\n", WbYuvParam.sWbYuvcrop.nLeft, WbYuvParam.sWbYuvcrop.nTop, WbYuvParam.sWbYuvcrop.nWidth, WbYuvParam.sWbYuvcrop.nHeight);
pthread_mutex_lock(&channel_cxt->mutex);
if (ioctl(channel_cxt->dev_fd, IOCTL_SET_WB_YUV, &WbYuvParam) != 0) {
pthread_mutex_unlock(&channel_cxt->mutex);
aw_loge("IOCTL_SET_WB_YUV failed");
return ret;
}
pthread_mutex_unlock(&channel_cxt->mutex);
channel_cxt->p_wbyuv_info->enable_wbyuv = 1;
channel_cxt->p_wbyuv_info->yuvSize = nAlignW*nAlignH*3/2;
if (channel_cxt->p_wbyuv_info->yuvBuf != NULL)
free(channel_cxt->p_wbyuv_info->yuvBuf);
channel_cxt->p_wbyuv_info->yuvBuf = calloc(1, channel_cxt->p_wbyuv_info->yuvSize);
delay_cnt = 3;//delay 3 frames
} else {
mThumbInfo.pThumbBuf = channel_cxt->p_wbyuv_info->yuvBuf;
mThumbInfo.nThumbSize = channel_cxt->p_wbyuv_info->yuvSize;
mThumbInfo.bWriteToFile = 0;
pthread_mutex_lock(&channel_cxt->mutex);
if (ioctl(channel_cxt->dev_fd, IOCTL_GET_WB_YUV, &mThumbInfo) != 0) {
aw_loge("IOCTL_GET_WB_YUV failed");
pthread_mutex_unlock(&channel_cxt->mutex);
return ret;
}
pthread_mutex_unlock(&channel_cxt->mutex);
sprintf(isp_cfg_path, "%s/encpp_frame", pic_path);
fd = fopen(isp_cfg_path, "w+");
if (fd) {
fwrite(channel_cxt->p_wbyuv_info->yuvBuf, 1, channel_cxt->p_wbyuv_info->yuvSize, fd);
fclose(fd);
fd = NULL;
} else {
printf("[ISP_TUNNING]: %s open failed\n", isp_cfg_path);
return ret;
}
sprintf(isp_cfg_path, "rm %sisp%d_%d_%d_%d_%d/encpp/encpp_flag", path, isp_id, w, h, fps, wdr);
system(isp_cfg_path);
}
}
}
} else {
printf("[ISP_TUNNING]: isp%d sensor path is invalid\n", isp_id);
return ret;
}
return ret;
}
static void isp_ini_tuning_run(AWChannel_cxt* channel_cxt)
{
static unsigned char ch_tuning_en = 0;
RTTunningCtlData TunningCtlData;
int i, ret = 0, channel_en;
if (!channel_cxt)
return;
channel_en = ch_tuning_en & (0x1 << channel_cxt->id);
if (!channel_en && access(INI_PATH"isp_tuning", F_OK) == 0) {
if (channel_cxt->id > 3)
return;
if (SensorCfg[channel_cxt->id].act_fps == 0xffff)
return;
TunningCtlData.cfg_id = RT_ISP_CTRL_GET_SENSOR_CFG;
pthread_mutex_lock(&channel_cxt->mutex);
ret = ioctl(channel_cxt->dev_fd, IOCTL_GET_TUNNING_CTL_DATA, &TunningCtlData);
pthread_mutex_unlock(&channel_cxt->mutex);
if(ret != 0) {
aw_loge("IOCTL_GET_TUNNING_CTL_DATA failed");
return;
}
for (i = 0; i < VIDEO_INPUT_CHANNEL_NUM; i++) {
if (!memcmp(&SensorCfg[i], &TunningCtlData.sensor_cfg, sizeof(RTTunningSensorCfg))) {
printf("[ISP_TUNNING]: ch%d->isp%d has been initialized.\n", channel_cxt->id, TunningCtlData.sensor_cfg.isp_id);
SensorCfg[channel_cxt->id].act_fps = 0xffff;
return;
}
}
TunningCtlData.cfg_id = RT_ISP_CTRL_RPBUF_INIT;
pthread_mutex_lock(&channel_cxt->mutex);
ret = ioctl(channel_cxt->dev_fd, IOCTL_GET_TUNNING_CTL_DATA, &TunningCtlData);
pthread_mutex_unlock(&channel_cxt->mutex);
ch_tuning_en |= (0x1 << channel_cxt->id);
SensorCfg[channel_cxt->id] = TunningCtlData.sensor_cfg;
save_ini_tuning_file(channel_cxt, INI_PATH, TunningCtlData.sensor_cfg.isp_id,TunningCtlData.sensor_cfg.sensor_width,
TunningCtlData.sensor_cfg.sensor_height, TunningCtlData.sensor_cfg.act_fps, TunningCtlData.sensor_cfg.wdr);
printf("[ISP_TUNNING]: ch%d->isp%d init ini tuning cfg OK!\n", channel_cxt->id, TunningCtlData.sensor_cfg.isp_id);
}
if (channel_en) {
ret = load_ini_tuning_file(channel_cxt, INI_PATH, TunningCtlData.sensor_cfg.isp_id, TunningCtlData.sensor_cfg.sensor_width,
TunningCtlData.sensor_cfg.sensor_height, TunningCtlData.sensor_cfg.act_fps, TunningCtlData.sensor_cfg.wdr);
if (!ret)
printf("[ISP_TUNNING]: ch%d->isp%d read ini tuning cfg OK!\n", channel_cxt->id, TunningCtlData.sensor_cfg.isp_id);
}
}
#define RT_MEDIA_SOCKET_MAX_SIZE (1024)
/**
send GEneric_NetLink_message to kernel. generic netlink family is defined upon NETLINK_GENERIC, user can define many
different families.
This function only accepts one NetLink Attribute. But in fact, one GENL message can contain many nla(NetLink Attribute)s.
@param nSockFd
client socket file descriptor, it must be created with NETLINK_GENERIC protocol.
@param genlFamilyId
generic netlink family id on generic netlink.
@param nlmsgFlags
NLM_F_REQUEST, NLM_F_ACK
@param nlmsgPortId
sending-client's port id.
@param genlCmd
command of generic netlink family
@param genlVersion
associated protocol version of the command, same to generic netlink family version.
@param nlaType,nlaData,nlaDataLen
netlink attribute of generic netlink family
@return:
0: success
-1: fail
*/
static int awVideoInput_SendGENLMessage(int nSockFd, unsigned short genlFamilyId, unsigned short nlmsgFlags,
unsigned int nlmsgPortId, unsigned char genlCmd, unsigned char genlVersion,
unsigned short nlaType, void *nlaData, unsigned short nlaDataLen)
{
struct sockaddr_nl skDstAddr;
int rc = 0;
int ret;
int nlaAttrSize = NLA_HDRLEN + nlaDataLen;
int nlaTotalSize = NLA_ALIGN(nlaAttrSize);
int genlmsg_MsgSize = GENL_HDRLEN + nlaTotalSize;
int genlmsg_TotalSize = NLMSG_ALIGN(genlmsg_MsgSize);
int nlmsg_MsgSize = NLMSG_HDRLEN + genlmsg_TotalSize;
int nlmsg_TotalSize = NLMSG_ALIGN(nlmsg_MsgSize);
//NLMSG_ALIGN(NLMSG_HDRLEN + NLMSG_ALIGN(GENL_HDRLEN + NLA_ALIGN(NLA_HDRLEN + nlaDataLen)))
char *buf = malloc(nlmsg_TotalSize);
if(NULL == buf)
{
aw_loge("fatal error! malloc %d bytes fail.", nlmsg_TotalSize);
return -1;
}
memset(buf, 0, nlmsg_TotalSize);
struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
struct genlmsghdr *gnlh = NLMSG_DATA(nlh);
nlh->nlmsg_len = nlmsg_TotalSize;
nlh->nlmsg_type = genlFamilyId;
nlh->nlmsg_flags = nlmsgFlags;
nlh->nlmsg_seq = 0;
nlh->nlmsg_pid = nlmsgPortId;
gnlh->cmd = genlCmd;
gnlh->version = genlVersion;
struct nlattr *nla = (struct nlattr *)((char *)gnlh + GENL_HDRLEN);
nla->nla_type = nlaType;
nla->nla_len = nlaAttrSize;
memcpy((char *)nla + NLA_HDRLEN, nlaData, nlaDataLen);
memset(&skDstAddr, 0, sizeof(skDstAddr));
skDstAddr.nl_family = AF_NETLINK;
skDstAddr.nl_pid = 0;
skDstAddr.nl_groups = 0;
ret = sendto(nSockFd, buf, nlmsg_TotalSize, 0, (struct sockaddr *)&skDstAddr, sizeof(skDstAddr));
if(ret < nlmsg_TotalSize)
{
aw_loge("fatal error! sendto() not send all data:%d<%d", ret, nlmsg_TotalSize);
rc = -1;
}
free(buf);
return rc;
}
/**
try to get generic netlink user-defined family id by family name.
@return
family id.
-1: failure
*/
static unsigned short awVideoInput_GetGENLFamilyId(int nSockFd, unsigned int nNLPortId, char *pFamilyName)
{
unsigned short genlFamilyId = -1;
int rc = awVideoInput_SendGENLMessage(nSockFd, GENL_ID_CTRL, NLM_F_REQUEST, nNLPortId, CTRL_CMD_GETFAMILY, 0,
CTRL_ATTR_FAMILY_NAME, (void *)pFamilyName, strlen(pFamilyName)+1);
if(rc != 0)
{
aw_loge("fatal error! send genl message to get family id fail");
return -1;
}
char *pBuf = (char *)malloc(RT_MEDIA_SOCKET_MAX_SIZE);
if(NULL == pBuf)
{
aw_loge("fatal error! malloc fail!");
return -1;
}
memset(pBuf, 0, RT_MEDIA_SOCKET_MAX_SIZE);
struct nlmsghdr *nlh;
struct genlmsghdr *gnlh;
struct nlattr *nla;
struct sockaddr_nl skSrcAddr;
socklen_t addrlen = sizeof(struct sockaddr_nl);
memset(&skSrcAddr, 0, addrlen);
int nRespLen = recvfrom(nSockFd, pBuf, RT_MEDIA_SOCKET_MAX_SIZE, 0, (struct sockaddr *)&skSrcAddr, &addrlen);
if (nRespLen >= 0)
{
//aw_logd("receive family info respLen:%d, sockaddr_nl:%d-%d-%d-%d,%d", nRespLen,
// skSrcAddr.nl_family, skSrcAddr.nl_pad, skSrcAddr.nl_pid, skSrcAddr.nl_groups, addrlen);
nlh = (struct nlmsghdr *)pBuf;
if (nlh->nlmsg_type == NLMSG_ERROR || !NLMSG_OK(nlh, nRespLen))
{
aw_loge("fatal error! nlmsg wrong:[%d,%d-%d]", nlh->nlmsg_type, nlh->nlmsg_len, nRespLen);
if(nlh->nlmsg_type == NLMSG_ERROR)
{
struct nlmsgerr *errmsg = NLMSG_DATA(nlh);
aw_loge("fatal error! nlmsg err:[%d]", errmsg->error);
}
genlFamilyId = -1;
}
else
{
if(GENL_ID_CTRL == nlh->nlmsg_type)
{
//ref to ctrl_fill_info() in lichee/linux-4.9/net/netlink/genetlink.c
unsigned char genlCtrlCmd;
unsigned char genlCtrlVersion;
char genlFamilyName[GENL_NAMSIZ];
unsigned int genlFamilyVersion = 0;
unsigned int genlFamilyHdrSize = 0;
unsigned int genlFamilyMaxAttr = 0;
gnlh = NLMSG_DATA(nlh);
genlCtrlCmd = gnlh->cmd;
genlCtrlVersion = gnlh->version;
nla = (struct nlattr *)((char *)gnlh + GENL_HDRLEN);
if(CTRL_ATTR_FAMILY_NAME == nla->nla_type)
{
if(nla->nla_len - NLA_HDRLEN > GENL_NAMSIZ)
{
aw_loge("fatal error! nla wrong:[%d-%d]", nla->nla_type, nla->nla_len);
}
memcpy(genlFamilyName, (char *)nla + NLA_HDRLEN, nla->nla_len - NLA_HDRLEN);
}
else
{
aw_loge("fatal error! nla is not our respect:[%d-%d]", nla->nla_type, nla->nla_len);
}
nla = (struct nlattr *)((char *)nla + NLA_ALIGN(nla->nla_len));
if(CTRL_ATTR_FAMILY_ID == nla->nla_type)
{
if(nla->nla_len - NLA_HDRLEN != 2)
{
aw_loge("fatal error! nla wrong:[%d-%d]", nla->nla_type, nla->nla_len);
}
genlFamilyId = *(unsigned short*)((char *)nla + NLA_HDRLEN);
}
else
{
aw_loge("fatal error! nla is not our respect:[%d-%d]", nla->nla_type, nla->nla_len);
}
nla = (struct nlattr *)((char *)nla + NLA_ALIGN(nla->nla_len));
if(CTRL_ATTR_VERSION == nla->nla_type)
{
if(nla->nla_len - NLA_HDRLEN != 4)
{
aw_loge("fatal error! nla wrong:[%d-%d]", nla->nla_type, nla->nla_len);
}
genlFamilyVersion = *(unsigned int*)((char *)nla + NLA_HDRLEN);
}
else
{
aw_loge("fatal error! nla is not our respect:[%d-%d]", nla->nla_type, nla->nla_len);
}
nla = (struct nlattr *)((char *)nla + NLA_ALIGN(nla->nla_len));
if(CTRL_ATTR_HDRSIZE == nla->nla_type)
{
if(nla->nla_len - NLA_HDRLEN != 4)
{
aw_loge("fatal error! nla wrong:[%d-%d]", nla->nla_type, nla->nla_len);
}
genlFamilyHdrSize = *(unsigned int*)((char *)nla + NLA_HDRLEN);
}
else
{
aw_loge("fatal error! nla is not our respect:[%d-%d]", nla->nla_type, nla->nla_len);
}
nla = (struct nlattr *)((char *)nla + NLA_ALIGN(nla->nla_len));
if(CTRL_ATTR_MAXATTR == nla->nla_type)
{
if(nla->nla_len - NLA_HDRLEN != 4)
{
aw_loge("fatal error! nla wrong:[%d-%d]", nla->nla_type, nla->nla_len);
}
genlFamilyMaxAttr = *(unsigned int*)((char *)nla + NLA_HDRLEN);
}
else
{
aw_loge("fatal error! nla is not our respect:[%d-%d]", nla->nla_type, nla->nla_len);
}
aw_logd("receive ctrl family cmd-version:[%d-%d], parse genlmsg family info:[%s-%d-%d-%d-%d]", genlCtrlCmd, genlCtrlVersion,
genlFamilyName, genlFamilyId, genlFamilyVersion, genlFamilyHdrSize, genlFamilyMaxAttr);
}
else
{
aw_loge("fatal error! nlmsg type wrong:[%d]", nlh->nlmsg_type);
genlFamilyId = -1;
}
}
}
else
{
aw_loge("fatal error! receive response message fail:[%d,%s]", nRespLen, strerror(errno));
genlFamilyId = -1;
}
free(pBuf);
return genlFamilyId;
}
/**
every AWChannel_cxt need set its NLPortId to rt_media in kernel, so send channelId to rt_media, rt_media will receive
channelId and sending socket's portId.
@return
0: success
-1: failure
*/
static int awVideoInput_GENLSocketConnectRtMedia(AWChannel_cxt *pChannel)
{
int rc = 0;
int nChannelId = pChannel->id;
rc = awVideoInput_SendGENLMessage(pChannel->mSockFd, g_videoInput_cxt->mGENLFamilyId, NLM_F_REQUEST | NLM_F_ACK,
pChannel->mSrcNLPortId, RT_MEDIA_CMD_SEND, RT_MEDIA_GENL_VERSION,
RT_MEDIA_CMD_ATTR_CHNID, (void *)&nChannelId, sizeof(nChannelId));
if(rc != 0)
{
aw_loge("fatal error! send genl message to trasport channel id fail");
return -1;
}
char *pBuf = (char *)malloc(RT_MEDIA_SOCKET_MAX_SIZE);
if(NULL == pBuf)
{
aw_loge("fatal error! malloc fail!");
return -1;
}
memset(pBuf, 0, RT_MEDIA_SOCKET_MAX_SIZE);
struct nlmsghdr *nlh;
struct genlmsghdr *gnlh;
struct nlattr *nla;
struct sockaddr_nl skSrcAddr;
socklen_t addrlen = sizeof(struct sockaddr_nl);
memset(&skSrcAddr, 0, addrlen);
int nRespLen = recvfrom(pChannel->mSockFd, pBuf, RT_MEDIA_SOCKET_MAX_SIZE, 0, (struct sockaddr *)&skSrcAddr, &addrlen);
if (nRespLen >= 0)
{
//aw_logd("receive rt_media respLen:%d, sockaddr_nl:%d-%d-%d-%d,%d", nRespLen,
// skSrcAddr.nl_family, skSrcAddr.nl_pad, skSrcAddr.nl_pid, skSrcAddr.nl_groups, addrlen);
nlh = (struct nlmsghdr *)pBuf;
if (NLMSG_ERROR == nlh->nlmsg_type || !NLMSG_OK(nlh, nRespLen))
{
if(NLMSG_ERROR == nlh->nlmsg_type)
{
struct nlmsgerr *errmsg = NLMSG_DATA(nlh);
if(0 == errmsg->error)
{
//aw_logd("we receive rt_media_cmd successful ack!");
rc = 0;
}
else
{
aw_loge("fatal error! nlmsg err:[%d]", errmsg->error);
rc = -1;
}
}
else
{
aw_loge("fatal error! nlmsg wrong:[%d,%d-%d]", nlh->nlmsg_type, nlh->nlmsg_len, nRespLen);
rc = -1;
}
}
else
{
aw_loge("fatal error! check code! nlmsg type[%d] is not what we want.", nlh->nlmsg_type);
rc = -1;
}
}
else
{
aw_loge("fatal error! receive response message fail:[%d,%s]", nRespLen, strerror(errno));
rc = -1;
}
free(pBuf);
return rc;
}
/**
receive generic netlink message from kernel, we use rt_media genl family.
@return
0: success
-1: fail
*/
static int awVideoInput_ReceiveGENLRTCbEvent(AWChannel_cxt *pChannel, RTCbEvent *pEvent)
{
int ret = 0;
if(NULL == pEvent)
{
return -1;
}
int nlaDataLen = sizeof(RTCbEvent);
int nlaAttrSize = NLA_HDRLEN + nlaDataLen;
int nlaTotalSize = NLA_ALIGN(nlaAttrSize);
int genlmsg_MsgSize = GENL_HDRLEN + nlaTotalSize;
int genlmsg_TotalSize = NLMSG_ALIGN(genlmsg_MsgSize);
int nlmsg_MsgSize = NLMSG_HDRLEN + genlmsg_TotalSize;
int nlmsg_TotalSize = NLMSG_ALIGN(nlmsg_MsgSize);
//create message
struct nlmsghdr *nlh = (struct nlmsghdr *)malloc(nlmsg_TotalSize);
if(!nlh)
{
aw_loge("fatal error! nlmsg malloc fail");
return -1;
}
struct genlmsghdr *gnlh;
struct nlattr *nla;
struct sockaddr_nl skSrcAddr;
socklen_t addrlen = sizeof(struct sockaddr_nl);
memset(&skSrcAddr, 0, addrlen);
int nRespLen = recvfrom(pChannel->mSockFd, (void*)nlh, nlmsg_TotalSize, 0, (struct sockaddr *)&skSrcAddr, (socklen_t *)&addrlen);
if(nRespLen >= 0)
{
//aw_logd("recorder[%d] receive generic netlink message from kernel! respLen:%d, sockaddr_nl:[%d-%d-%d-%d,%d]",
// pChannel->id, pChannel->config.channelId nRespLen, skSrcAddr.nl_family, skSrcAddr.nl_pad, skSrcAddr.nl_pid, skSrcAddr.nl_groups, addrlen);
if (nlh->nlmsg_type == NLMSG_ERROR || !NLMSG_OK(nlh, nRespLen))
{
aw_loge("fatal error! nlmsg wrong:[%d,%d-%d]", nlh->nlmsg_type, nlh->nlmsg_len, nRespLen);
if(nlh->nlmsg_type == NLMSG_ERROR)
{
struct nlmsgerr *errmsg = NLMSG_DATA(nlh);
aw_loge("fatal error! nlmsg err:[%d]", errmsg->error);
}
ret = -1;
}
else
{
if(g_videoInput_cxt->mGENLFamilyId == nlh->nlmsg_type)
{
//ref to rt_media_send_genl_RTCbEvent() in lichee/linux-4.9/driver/media/rt-media/rt_media.c
gnlh = NLMSG_DATA(nlh);
if(RT_MEDIA_CMD_CB_EVENT == gnlh->cmd)
{
nla = (struct nlattr *)((char *)gnlh + GENL_HDRLEN);
if(RT_MEDIA_CMD_ATTR_RTCBEVENT == nla->nla_type)
{
if(nla->nla_len - NLA_HDRLEN != nlaDataLen)
{
aw_loge("fatal error! nla wrong:[%d-%d,%d]", nla->nla_type, nla->nla_len, nlaDataLen);
}
memcpy((void *)pEvent, (char *)nla + NLA_HDRLEN, nlaDataLen);
//aw_logd("recorder[%d] event info:type:%d, data1:%d", pChannel->id, pEvent->eEventType, pEvent->nData1);
ret = 0;
}
else
{
aw_loge("fatal error! nla is not our respect:[%d-%d]", nla->nla_type, nla->nla_len);
ret = -1;
}
}
else
{
aw_loge("fatal error! unknown rt_media genl family command:%d,%d, ignore", gnlh->cmd, gnlh->version);
ret = -1;
}
}
else
{
aw_loge("fatal error! nlmsg type wrong:[%d!=%d]", nlh->nlmsg_type, g_videoInput_cxt->mGENLFamilyId);
ret = -1;
}
}
}
else
{
aw_loge("fatal error! receive rt media genlmsg fail:[%d,%s]", nRespLen, strerror(errno));
ret = -1;
}
free(nlh);
return ret;
}
int AWVideoInput_Init(void)
{
int ret;
int i = 0;
AWChannel_cxt* channel_cxt = NULL;
if(g_videoInput_cxt != NULL)
{
aw_logw("the g_videoInput_cxt had inited");
return -1;
}
g_videoInput_cxt = (AWVideoInput_cxt*)malloc(sizeof(AWVideoInput_cxt));
memset(g_videoInput_cxt, 0, sizeof(AWVideoInput_cxt));
g_videoInput_cxt->ion_fd = -1;
aw_rt_ion_alloc_open();
g_videoInput_cxt->ion_fd = aw_ion_open();
if(g_videoInput_cxt->ion_fd < 0)
{
aw_loge("open ion failed: %d",g_videoInput_cxt->ion_fd);
goto error_exit;
}
for(i = 0; i < VIDEO_INPUT_CHANNEL_NUM; i++)
{
channel_cxt = &g_videoInput_cxt->channel_cxt[i];
channel_cxt->id = i;
channel_cxt->dev_fd = -1;
channel_cxt->state = VIDEO_INPUT_STATE_IDLE;
pthread_mutex_init(&channel_cxt->mutex, NULL);
channel_cxt->mq = aw_message_queue_create(16, "aw_video_in");
int j = 0;
for(j = 0; j < SEM_WAIT_REPLY_NUM; j++)
{
sem_init(&channel_cxt->reply_sem[j], 0, 0);
}
channel_cxt->mSockFd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
if(channel_cxt->mSockFd >= 0)
{
//aw_logd("create socket success:[%d]", channel_cxt->mSockFd);
channel_cxt->mSrcNLPortId = getpid() | channel_cxt->id<<16;
struct sockaddr_nl stSrcAddr;
memset(&stSrcAddr, 0, sizeof(struct sockaddr_nl));
stSrcAddr.nl_family = AF_NETLINK;
stSrcAddr.nl_pid = channel_cxt->mSrcNLPortId;
ret = bind(channel_cxt->mSockFd, (struct sockaddr*)&stSrcAddr, sizeof(struct sockaddr_nl));
if(ret != 0)
{
aw_loge("fatal error! bind sockaddr to socket fd fail:[%d,%s]", ret, strerror(errno));
}
if(0 == g_videoInput_cxt->mGENLFamilyId)
{
if(strlen(RT_MEDIA_GENL_NAME) + 1 > GENL_NAMSIZ)
{
aw_loge("fatal error! genl rt_media family name[%s] too long, must reduce it!", RT_MEDIA_GENL_NAME);
}
g_videoInput_cxt->mGENLFamilyId = awVideoInput_GetGENLFamilyId(channel_cxt->mSockFd, channel_cxt->mSrcNLPortId, RT_MEDIA_GENL_NAME);
}
}
else
{
aw_loge("fatal error! create socket fail:[%d,%s]", channel_cxt->mSockFd, strerror(errno));
}
}
return 0;
error_exit:
AWVideoInput_DeInit();
return -1;
}
int AWVideoInput_Configure(int channel, VideoInputConfig *pCfg)
{
int i = 0;
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call configure\n");
return -1;
}
aw_logd("configure: channel = %d, pixelformat = %d\n",channel, pCfg->pixelformat);
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("configure: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel_cxt = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel_cxt->mutex);
if(cur_channel_cxt->dev_fd == -1)
{
cur_channel_cxt->dev_fd = open(RT_MEDIA_DEV_NAME, O_RDWR);
if(cur_channel_cxt->dev_fd < 0)
{
aw_loge("open rt-media failed: %d\n",cur_channel_cxt->dev_fd);
pthread_mutex_unlock(&cur_channel_cxt->mutex);
return -1;
}
}
VideoInputConfig* cur_config = &cur_channel_cxt->config;
cur_config->demo_start = 1;
memcpy(cur_config, pCfg, sizeof(VideoInputConfig));
#if RT_MEDIA_SUPPORT_VENC_PARAM_DEBUG
check_ve_param_file(VE_PARAM_STATIC, cur_config, cur_config->channelId);
#endif
aw_logd("wdr_enable = %d, enable_aiisp = %d", cur_config->enable_wdr, cur_config->enable_aiisp);
cur_channel_cxt->enable_aiisp = cur_config->enable_aiisp;
if (ioctl(cur_channel_cxt->dev_fd, IOCTL_CONFIG, cur_config))
{
aw_loge("IOCTL_CONFIG failed");
return -1;
}
ret = awVideoInput_GENLSocketConnectRtMedia(cur_channel_cxt);
if(ret != 0)
{
aw_loge("fatal error! recorder[%d=%d] genl socket connect rt_media fail, portId:%d", channel, cur_channel_cxt->id, cur_channel_cxt->mSrcNLPortId);
}
if (cur_config->output_mode == OUTPUT_MODE_ENCODE_FILE_YUV || OUTPUT_MODE_ENCODE_OUTSIDE_YUV == cur_config->output_mode)
{
unsigned char* vir_addr = NULL;
int buf_size = rt_cal_input_buffer_size(cur_config->width, cur_config->height, cur_config->pixelformat, 0);
cur_channel_cxt->enc_yuv_buf_info.buf_size = buf_size;
if(cur_channel_cxt->enc_yuv_buf_info.vir_addr)
aw_rt_ion_alloc_pfree(cur_channel_cxt->enc_yuv_buf_info.vir_addr);
vir_addr = aw_rt_ion_alloc_palloc(buf_size);
cur_channel_cxt->enc_yuv_buf_info.phy_addr = aw_rt_ion_alloc_vir2phy(vir_addr);
cur_channel_cxt->enc_yuv_buf_info.vir_addr = vir_addr;
cur_channel_cxt->enc_yuv_buf_info.bInit_flag = 1;
}
cur_channel_cxt->state = VIDEO_INPUT_STATE_CONFIGED;
pthread_mutex_unlock(&cur_channel_cxt->mutex);
return ret;
}
int AWVideoInput_CallBack(int channel, Video_Input_cb cb, int bAppendSpspps)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call set callback");
return -1;
}
//aw_logd("set callback: channel = %d\n",channel);
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("callback: the channel[%d] overflow", channel);
return -1;
}
AWChannel_cxt* channel_cxt = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&channel_cxt->mutex);
channel_cxt->callback = cb;
channel_cxt->b_insert_sps_pps = bAppendSpspps;
pthread_mutex_unlock(&channel_cxt->mutex);
//* todo
return 0;
}
int AWVideoInput_SetChannelThreadExitCb(int channel, Channel_Thread_exit cb)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call set callback");
return -1;
}
//aw_logd("set callback: channel = %d\n",channel);
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("callback: the channel[%d] overflow", channel);
return -1;
}
AWChannel_cxt* channel_cxt = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&channel_cxt->mutex);
channel_cxt->thread_exit_cb = cb;
aw_logd("thread_exit_cb %p %p", cb, channel_cxt->thread_exit_cb);
pthread_mutex_unlock(&channel_cxt->mutex);
return 0;
}
/**
set callback to AWVideoInput channel, used to notify app some events.
It can replace AWVideoInput_CallBack() and AWVideoInput_SetChannelThreadExitCb().
@param cb
cb's params contain event type, so it can implement many different functions.
@param pAppData
app set, cb use it as param. When callback happen, app can use pAppData's content.
*/
int AWVideoInput_SetChannelCallback(int channel, AWVideoInputCallbackType cb, void* pAppData)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("fatal error! g_videoInput_cxt is null");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("fatal error! the channel[%d] overflow", channel);
return -1;
}
AWChannel_cxt* channel_cxt = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&channel_cxt->mutex);
channel_cxt->mCallback = cb;
channel_cxt->mpAppData = pAppData;
pthread_mutex_unlock(&channel_cxt->mutex);
return 0;
}
/**
set to channel if appending spspps when send video stream.
@return
0:success;
-1: fail
*/
int AWVideoInput_AppendSpspps(int channel, int bAppendSpspps)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("fatal error! g_videoInput_cxt is null");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("fatal error! the channel[%d] overflow", channel);
return -1;
}
AWChannel_cxt* channel_cxt = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&channel_cxt->mutex);
channel_cxt->b_insert_sps_pps = bAppendSpspps;
pthread_mutex_unlock(&channel_cxt->mutex);
return 0;
}
static int post_messgae_and_wait(AWChannel_cxt* channel_cxt, int cmd)
{
XmMessage msg;
memset(&msg, 0, sizeof(XmMessage));
msg.messageId = cmd;
msg.psem_reply = &channel_cxt->reply_sem[cmd];
aw_message_queue_postMessage(channel_cxt->mq, &msg);
aw_logv("********* cmd = %d, wait reply start", cmd);
aw_rt_SemTimedWait(msg.psem_reply, -1);
aw_logv("********* cmd = %d, wait reply finish", cmd);
return 0;
}
AWVideoInput_State AWVideoInput_Get_channel_state(int channel)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("start: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
AWVideoInput_State eState = cur_channel->state;
pthread_mutex_unlock(&cur_channel->mutex);
return eState;
}
int AWVideoInput_Get_csi_status(int channel)
{
int csi_status[VIDEO_INPUT_CHANNEL_NUM];
memset(csi_status, 0, sizeof(int) * VIDEO_INPUT_CHANNEL_NUM);
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("start: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
ioctl(cur_channel->dev_fd, IOCTL_GET_CSI_STATUS, csi_status);
return csi_status[channel];
}
int AWVideoInput_Check_Wait_Start(int channel)
{
int csi_status[VIDEO_INPUT_CHANNEL_NUM];
memset(csi_status, 0, sizeof(int) * VIDEO_INPUT_CHANNEL_NUM);
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("start: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
ioctl(cur_channel->dev_fd, IOCTL_GET_CSI_STATUS, csi_status);
if (csi_status[channel] == 0) {
return -1;
}
if (cur_channel->demo_wait_csi_ready && csi_status[channel]) {
aw_logd("re IOCTL_START");
cur_channel->demo_wait_csi_ready = 0;
AWVideoInput_Start(channel, 1);
}
return 0;
}
int AWVideoInput_Start(int channel,int bStart)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("start: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
AWVideoInput_State state = cur_channel->state;
//aw_logd("start: channel = %d, flag = %d, state = %d\n",channel, bStart, state);
if(bStart == 0 && state == VIDEO_INPUT_STATE_EXCUTING)
{
ret = ioctl(cur_channel->dev_fd, IOCTL_PAUSE, channel);
if(cur_channel->bThread_create_flag == 1)
{
pthread_mutex_unlock(&cur_channel->mutex);
post_messgae_and_wait(cur_channel, VIDEO_INPUT_CMD_PAUSE);
pthread_mutex_lock(&cur_channel->mutex);
}
else
cur_channel->state = VIDEO_INPUT_STATE_PAUSE;
}
else if(bStart == 1 && (state == VIDEO_INPUT_STATE_CONFIGED || state == VIDEO_INPUT_STATE_PAUSE))
{
ret = ioctl(cur_channel->dev_fd, IOCTL_START, channel);
if (ret) {
aw_logw("channel %d kernel rt not ready, pause it and start later.", channel);
cur_channel->demo_wait_csi_ready = 1;
}
if(state == VIDEO_INPUT_STATE_CONFIGED
&& cur_channel->bThread_create_flag == 0
&& (cur_channel->config.output_mode == OUTPUT_MODE_STREAM
|| cur_channel->config.output_mode == OUTPUT_MODE_ENCODE_FILE_YUV
|| cur_channel->config.output_mode == OUTPUT_MODE_ENCODE_OUTSIDE_YUV)
)
{
pthread_create(&cur_channel->thread, NULL, ChannelThread, (void*)cur_channel);
cur_channel->bThread_create_flag = 1;
cur_channel->GENL_thread_exit_flag = 0;
pthread_create(&cur_channel->GENL_thread, NULL, GENLRecvThread, (void *)cur_channel);
cur_channel->bGENL_thread_create_flag = 1;
if (cur_channel->enable_aiisp) {
cur_channel->AIISP_thread_exit_flag = 0;
pthread_create(&cur_channel->AIISP_thread, NULL, AIISPThread, (void *)cur_channel);
cur_channel->bAIISP_thread_create_flag = 1;
}
}
if(cur_channel->bThread_create_flag == 1)
{
pthread_mutex_unlock(&cur_channel->mutex);
if (ret) {
//kernel rt not ready, pause
post_messgae_and_wait(cur_channel, VIDEO_INPUT_CMD_PAUSE);
} else {
post_messgae_and_wait(cur_channel, VIDEO_INPUT_CMD_EXCUTING);
}
pthread_mutex_lock(&cur_channel->mutex);
}
else {
if (!ret) {
cur_channel->state = VIDEO_INPUT_STATE_EXCUTING;
}
}
}
else
{
aw_logw("channel %d start(%d): state is not right(%d)\n", channel, bStart, state);
pthread_mutex_unlock(&cur_channel->mutex);
return -1;
}
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_StartProcessTdmBuf(int channel)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("fatal error! g_videoInput_cxt is null!\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("fatal error! the channel id %d is invalid value!\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
if (0 == cur_channel->enable_aiisp)
{
aw_logw("channel[%d] not enable aiisp, please check code!\n", channel);
pthread_mutex_unlock(&cur_channel->mutex);
return -1;
}
cur_channel->start_process_tdm_buf = 1;
aw_logd("start process_tdm_buf\n");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_DeInit(void)
{
if(g_videoInput_cxt)
{
int ret = 0;
int i = 0;
int j = 0;
AWChannel_cxt* channel_cxt = NULL;
VideoInputOSD* video_osd = NULL;
for(i = 0; i < VIDEO_INPUT_CHANNEL_NUM; i++)
{
channel_cxt = &g_videoInput_cxt->channel_cxt[i];
if(channel_cxt->sps_pps_data.buf)
free(channel_cxt->sps_pps_data.buf);
if (channel_cxt->p_wbyuv_info && channel_cxt->p_wbyuv_info->enable_wbyuv) {
AWVideoInput_DeInitWbYuv(i, channel_cxt->p_wbyuv_info);
}
if(channel_cxt->bThread_create_flag == 1)
{
post_messgae_and_wait(channel_cxt, VIDEO_INPUT_CMD_EXIT);
pthread_join(channel_cxt->thread, (void**)&ret);
}
if (channel_cxt->bGENL_thread_create_flag)
{
channel_cxt->GENL_thread_exit_flag = 1;
pthread_join(channel_cxt->GENL_thread, NULL);
}
if (channel_cxt->bAIISP_thread_create_flag)
{
channel_cxt->AIISP_thread_exit_flag = 1;
pthread_join(channel_cxt->AIISP_thread, NULL);
}
channel_cxt->enable_aiisp = 0;
channel_cxt->start_process_tdm_buf = 0;
if(channel_cxt->dev_fd >= 0)
{
ret = ioctl(channel_cxt->dev_fd, IOCTL_DESTROY, 0);
close(channel_cxt->dev_fd);
}
pthread_mutex_destroy(&channel_cxt->mutex);
video_osd = &channel_cxt->video_osd_info;
for(j = 0; j < video_osd->osd_num; j++)
{
if(video_osd->item_info[j].data_buf)
free(video_osd->item_info[j].data_buf);
video_osd->item_info[j].data_buf = NULL;
}
if(channel_cxt->enc_yuv_buf_info.vir_addr)
aw_rt_ion_alloc_pfree(channel_cxt->enc_yuv_buf_info.vir_addr);
if(channel_cxt->vbv_buffer.bInit == 1)
{
destroy_vbv_buffer(&channel_cxt->vbv_buffer);
}
if(channel_cxt->mq)
aw_message_queue_destroy(channel_cxt->mq);
for(j = 0; j < SEM_WAIT_REPLY_NUM; j++)
{
sem_destroy(&channel_cxt->reply_sem[j]);
}
if(channel_cxt->mSockFd >= 0)
{
close(channel_cxt->mSockFd);
channel_cxt->mSockFd = -1;
}
}
if(g_videoInput_cxt->ion_fd >= 0)
aw_ion_close(g_videoInput_cxt->ion_fd);
aw_rt_ion_alloc_close();
free(g_videoInput_cxt);
g_videoInput_cxt = NULL;
}
return 0;
}
int AWVideoInput_SetIFrame(int channel)
{
//* todo
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetForceKeyFrame\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetForceKeyFrame: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
if((VIDEO_INPUT_STATE_EXCUTING == cur_channel->state) || (VIDEO_INPUT_STATE_PAUSE == cur_channel->state))
{
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_FORCE_KEYFRAME, NULL);
if(ret != 0)
{
aw_loge("IOCTL_SET_FORCE_KEYFRAME failed:%s", strerror(errno));
}
}
else
{
aw_loge("fatal error! called in wrong state[%d]", cur_channel->state);
ret = -1;
}
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetOSD(int channel, VideoInputOSD *pOsdInfo)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call set osd\n");
return -1;
}
aw_logv("set osd: channel = %d\n",channel);
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("set osd: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel_cxt = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel_cxt->mutex);
int ret = 0;
if(cur_channel_cxt->state == VIDEO_INPUT_STATE_EXCUTING)
ret = ioctl(cur_channel_cxt->dev_fd, IOCTL_SET_OSD, pOsdInfo);
else
delay_setup_osd_info(cur_channel_cxt, pOsdInfo);
cur_channel_cxt->config.enable_overlay = 1;
pthread_mutex_unlock(&cur_channel_cxt->mutex);
return ret;
}
//* catch jpeg from channel 0
int AWVideoInput_CatchJpegConfig(catch_jpeg_config *p_jpg_config)
{
if(!g_videoInput_cxt)
{
aw_loge("error: g_videoInput_cxt is null");
return -1;
}
AWChannel_cxt* channel_cxt = &g_videoInput_cxt->channel_cxt[p_jpg_config->channel_id];
if(channel_cxt->state != VIDEO_INPUT_STATE_EXCUTING)
{
aw_loge("error: the state[%d] is not right", channel_cxt->state);
return -1;
}
channel_cxt->jpeg_config.width = p_jpg_config->width;
channel_cxt->jpeg_config.height = p_jpg_config->height;
channel_cxt->jpeg_config.qp = p_jpg_config->qp;
channel_cxt->jpeg_config.rotate_angle = p_jpg_config->rotate_angle;
return 0;
}
//* catch jpeg from channel 0
int AWVideoInput_CatchJpeg(char *buf, int *bufLen, int channel_id)
{
int ret = 0;
int max_buf_size = *bufLen;
catch_jpeg_buf_info buf_info;
*bufLen = 0;
memset(&buf_info, 0, sizeof(catch_jpeg_buf_info));
if(!g_videoInput_cxt)
{
aw_loge("error: g_videoInput_cxt is null");
return -1;
}
AWChannel_cxt* channel_cxt = &g_videoInput_cxt->channel_cxt[channel_id];
if(channel_cxt->state != VIDEO_INPUT_STATE_EXCUTING)
{
aw_loge("error: the state[%d] is not right", channel_cxt->state);
return -1;
}
pthread_mutex_lock(&channel_cxt->mutex);
ret = ioctl(channel_cxt->dev_fd, IOCTL_CATCH_JPEG_START, &channel_cxt->jpeg_config);
if(ret != 0)
{
aw_loge("call IOCTL_CATCH_JPEG_START error: %d",ret);
goto catch_jpeg_exit;
}
//* set the max_size, return valid_size
buf_info.buf = (unsigned char*)buf;
buf_info.buf_size = max_buf_size;
ret = ioctl(channel_cxt->dev_fd, IOCTL_CATCH_JPEG_GET_DATA, &buf_info);
if(ret != 0)
{
aw_loge("call IOCTL_CATCH_JPEG_GET_DATA error: %d", ret);
goto catch_jpeg_exit;
}
*bufLen = buf_info.buf_size;
catch_jpeg_exit:
ioctl(channel_cxt->dev_fd, IOCTL_CATCH_JPEG_STOP, NULL);
pthread_mutex_unlock(&channel_cxt->mutex);
return ret;
}
int AWVideoInput_GetYuvFrame(int channel, VideoYuvFrame* pYuvFrame)
{
int i = 0;
int j = 0;
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetYuvFrame: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
unsigned char* phy_addr = NULL;
rt_yuv_info s_yuv_info;
memset(&s_yuv_info, 0, sizeof(rt_yuv_info));
ret = ioctl(cur_channel->dev_fd, IOCTL_REQUEST_YUV_FRAME, &s_yuv_info);
if(ret != 0)
{
aw_loge("GetYuvFrame failed, ret = %d\n", ret);
pthread_mutex_unlock(&cur_channel->mutex);
return -1;
}
aw_logd("fd %d phy_addr %p", s_yuv_info.fd, s_yuv_info.phy_addr);
int align_w = ALIGN_XXB(16, cur_channel->config.width);
int align_h = ALIGN_XXB(16, cur_channel->config.height);
int y_size = align_w*align_h;
int c_size = align_w*align_h/4;
int yuv_size = align_w * align_h * 3 / 2;
unsigned char* vir_addr = NULL;
for (j = 0; j < CONFIG_YUV_BUF_NUM; j++) {
if (cur_channel->s_yuv_fd[j].yuv_fd == s_yuv_info.fd && cur_channel->s_yuv_fd[j].bset) {
vir_addr = cur_channel->s_yuv_fd[j].virBuf;
break;
}
}
if (j >= CONFIG_YUV_BUF_NUM) {
for (i = 0; i < CONFIG_YUV_BUF_NUM; i++) {
if (!cur_channel->s_yuv_fd[i].bset) {
cur_channel->s_yuv_fd[i].bset = 1;
cur_channel->s_yuv_fd[i].yuv_fd = s_yuv_info.fd;
ret = aw_ion_mmap(s_yuv_info.fd, yuv_size, &vir_addr);
aw_logd("ret %d mmap: virBuf = %p, share_fd = %d", ret, vir_addr, s_yuv_info.fd);
cur_channel->s_yuv_fd[i].virBuf = vir_addr;
break;
}
}
if (i >= CONFIG_YUV_BUF_NUM)
aw_loge("yuv fd init err.");
}
if (vir_addr == NULL) {
aw_loge("vir_addr == NULL.");
return -1;
}
pYuvFrame->widht = align_w;
pYuvFrame->height = align_h;
pYuvFrame->phyAddr[0] = s_yuv_info.phy_addr;
pYuvFrame->phyAddr[1] = s_yuv_info.phy_addr + y_size;
pYuvFrame->phyAddr[2] = s_yuv_info.phy_addr + y_size + c_size;
pYuvFrame->virAddr[0] = vir_addr;
pYuvFrame->virAddr[1] = vir_addr + y_size;
pYuvFrame->virAddr[2] = vir_addr + y_size + c_size;
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_ReleaseYuvFrame(int channel, VideoYuvFrame* pYuvFrame)
{
int i = 0;
int ret = 0;
unsigned char* phy_addr = pYuvFrame->phyAddr[0];
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("ReleaseYuvFrame: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
ioctl(cur_channel->dev_fd, IOCTL_RETURN_YUV_FRAME, &phy_addr);
return 0;
}
//* for debug
int AWVideoInput_RequestEmptyYuvFrame(int channel, VideoYuvFrame* pYuvFrame)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetYuvFrame: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
unsigned char* phy_addr = NULL;
unsigned char* vir_addr = NULL;
if(cur_channel->enc_yuv_buf_info.bInit_flag == 1)
{
cur_channel->enc_yuv_buf_info.bInit_flag = 0;
phy_addr = cur_channel->enc_yuv_buf_info.phy_addr;
vir_addr = cur_channel->enc_yuv_buf_info.vir_addr;
}
else
{
ret = ioctl(cur_channel->dev_fd, IOCTL_REQUEST_ENC_YUV_FRAME, &phy_addr);
if(ret != 0 || phy_addr != cur_channel->enc_yuv_buf_info.phy_addr)
{
aw_logv(" reqeust enc yuv frame failed");
pthread_mutex_unlock(&cur_channel->mutex);
return -1;
}
vir_addr = cur_channel->enc_yuv_buf_info.vir_addr;
}
int align_w = ALIGN_XXB(16, cur_channel->config.width);
int align_h = ALIGN_XXB(16, cur_channel->config.height);
int y_size = align_w*align_h;
int c_size = align_w*align_h/4;
pYuvFrame->widht = align_w;
pYuvFrame->height = align_h;
pYuvFrame->phyAddr[0] = phy_addr;
pYuvFrame->phyAddr[1] = phy_addr + y_size;
pYuvFrame->phyAddr[2] = phy_addr + y_size + c_size;
pYuvFrame->virAddr[0] = vir_addr;
pYuvFrame->virAddr[1] = vir_addr + y_size;
pYuvFrame->virAddr[2] = vir_addr + y_size + c_size;
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
//* for debug
int AWVideoInput_SubmitFilledYuvFrame(int channel, VideoYuvFrame* pYuvFrame, int yuv_size)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetYuvFrame: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
aw_rt_ion_alloc_flush_cache(pYuvFrame->virAddr[0], yuv_size);
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SUBMIT_ENC_YUV_FRAME, &pYuvFrame->phyAddr[0]);
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
//int AWVideoInput_GetBinImageData(int channel, char *buf, int bufLen)
//{
// int ret = 0;
// if(g_videoInput_cxt == NULL)
// {
// aw_loge("g_videoInput_cxt is null when call start\n");
// return -1;
// }
//
// if(channel >= VIDEO_INPUT_CHANNEL_NUM)
// {
// aw_loge("GetBinImageData: the channel[%d] overflow\n", channel);
// return -1;
// }
//
// AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
// VideoGetBinImageBufInfo buf_info;
// buf_info.buf = (unsigned char*)buf;
// buf_info.max_size = bufLen;
//
// if(cur_channel->config.enable_bin_image == 0)
// {
// aw_loge("GetBinImageData: the functions of GetBinImageData is disable");
// return -1;
// }
//
// pthread_mutex_lock(&cur_channel->mutex);
//
// ret = ioctl(cur_channel->dev_fd, IOCTL_GET_BIN_IMAGE_DATA, &buf_info);
//
// pthread_mutex_unlock(&cur_channel->mutex);
//
// return ret;
//}
//
//int AWVideoInput_GetMvInfoData(int channel, char *buf, int bufLen)
//{
// int ret = 0;
// if(g_videoInput_cxt == NULL)
// {
// aw_loge("g_videoInput_cxt is null when call start\n");
// return -1;
// }
//
// if(channel >= VIDEO_INPUT_CHANNEL_NUM)
// {
// aw_loge("GetMvInfoData: the channel[%d] overflow\n", channel);
// return -1;
// }
//
// AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
// VideoGetMvInfoBufInfo buf_info;
// buf_info.buf = (unsigned char*)buf;
// buf_info.max_size = bufLen;
//
// if(cur_channel->config.enable_mv_info == 0)
// {
// aw_loge("GetMvInfoData: the functions of GetMvInfoData is disable");
// return -1;
// }
//
// pthread_mutex_lock(&cur_channel->mutex);
//
// ret = ioctl(cur_channel->dev_fd, IOCTL_GET_MV_INFO_DATA, &buf_info);
//
// pthread_mutex_unlock(&cur_channel->mutex);
//
// return ret;
//}
int AWVideoInput_GetLuminance(int channel)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetLuminance: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int lv = ioctl(cur_channel->dev_fd, IOCTL_GET_ISP_LV, NULL);
pthread_mutex_unlock(&cur_channel->mutex);
return lv;
}
int AWVideoInput_GetHist(int channel, unsigned int *hist)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call GetHist\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetHist: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_ISP_HIST, hist);
if(ret != 0)
aw_loge("IOCTL_GET_ISP_HIST failed");
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_GetExpGain(int channel, RTIspExpGain *expgain)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call GetExpGain\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetExpGain: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_ISP_EXP_GAIN, expgain);
if(ret != 0)
aw_loge("IOCTL_GET_ISP_EXP_GAIN failed");
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_GetConfigure(int channel, VideoInputConfig *pCfg)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetLuminance: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
memcpy(pCfg, &cur_channel->config, sizeof(VideoInputConfig));
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_SetIrParam(int channel, RTIrParam* pIrParam)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call start\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("IR_SetISPColor2Grey: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_IR_PARAM, pIrParam);
if(ret != 0)
aw_loge("IOCTL_SET_IR_COLOR2GREY failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetHFlip(int channel, int bflip)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetHFlip\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetHFlip: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
if((VIDEO_INPUT_STATE_EXCUTING == cur_channel->state) || (VIDEO_INPUT_STATE_PAUSE == cur_channel->state))
{
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_HORIZONTAL_FLIP, bflip);
if(ret != 0)
aw_loge("IOCTL_SET_HORIZONTAL_FLIP failed:%s", strerror(errno));
}
else
{
aw_loge("fatal error! called in wrong state[%d]", cur_channel->state);
ret = -1;
}
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetSharp(int channel, int bsharp)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetHFlip\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetHFlip: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_SHARP, bsharp);
if(ret != 0)
aw_loge("IOCTL_SET_SHARP failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetVFlip(int channel, int bflip)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetVFlip\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetVFlip: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
if((VIDEO_INPUT_STATE_EXCUTING == cur_channel->state) || (VIDEO_INPUT_STATE_PAUSE == cur_channel->state))
{
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_VERTICAL_FLIP, bflip);
if(ret != 0)
aw_loge("IOCTL_SET_VERTICAL_FLIP failed:%s", strerror(errno));
}
else
{
aw_loge("fatal error! called in wrong state[%d]", cur_channel->state);
ret = -1;
}
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetPowerLineFreq(int channel, RT_POWER_LINE_FREQUENCY power_line_freq)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetPowerLineFreq\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetPowerLineFreq: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_POWER_LINE_FREQ, power_line_freq);
if(ret != 0)
aw_loge("IOCTL_SET_POWER_LINE_FREQ failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetBrightness(int channel, int brightness_level)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetBrightness\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetBrightness: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_BRIGHTNESS, brightness_level);
if(ret != 0)
aw_loge("IOCTL_SET_BRIGHTNESS failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetContrast(int channel, int contrast_level)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetContrast\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetContrast: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_CONTRAST, contrast_level);
if(ret != 0)
aw_loge("IOCTL_SET_CONTRAST failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetSaturation(int channel, int saturation_level)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetSaturation\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetSaturation: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_SATURATION, saturation_level);
if(ret != 0)
aw_loge("IOCTL_SET_SATURATION failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetHue(int channel, int hue_level)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetHue\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetHue: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_HUE, hue_level);
if(ret != 0)
aw_loge("IOCTL_SET_HUE failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetSharpness(int channel, int sharpness_level)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetSharpness\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetSharpness: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_SHARPNESS, sharpness_level);
if(ret != 0)
aw_loge("IOCTL_SET_SHARPNESS failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_GetSensorName(int channel, char *name)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call GetSensorName\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetSensorName: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_GET_SENSOR_NAME, name);
if(ret != 0)
aw_loge("IOCTL_GET_SENSOR_NAME failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_GetSensorResolution(int channel, RTSensorResolution *sensor_resolution)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call GetSensorResolution\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetSensorResolution: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_GET_SENSOR_RESOLUTION, sensor_resolution);
if(ret != 0)
aw_loge("IOCTL_GET_SENSOR_RESOLUTION failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetSensorExp(int channel, int exp_time)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetAeMeteringMode\n");
return -1;
}
if (exp_time < 0) {
aw_loge("Invaild exp_time!!!\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetSensorExp: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_SENSOR_EXP, exp_time);
if(ret != 0)
aw_loge("IOCTL_SET_SENSOR_EXP failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetSensorGain(int channel, int gain)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetAeMeteringMode\n");
return -1;
}
if (gain < 16) {
aw_loge("Invaild gain, gain must >= 16!!!\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetSensorGain: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_SENSOR_GAIN, gain);
if(ret != 0)
aw_loge("IOCTL_SET_SENSOR_GAIN failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetAeMeteringMode(int channel, RT_AE_METERING_MODE ae_metering_mode)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetAeMeteringMode\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetAeMeteringMode: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_GET_ISP_AE_METERING_MODE, ae_metering_mode);
if(ret != 0)
aw_loge("IOCTL_GET_ISP_AE_METERING_MODE failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetAeMode(int channel, int ae_mode)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetAeMeteringMode\n");
return -1;
}
if (ae_mode < 0 || ae_mode > 1) {
aw_loge("Invaild ae_mode, please check it\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetAeMode: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ISP_AE_MODE, ae_mode);
if(ret != 0)
aw_loge("IOCTL_SET_ISP_AE_MODE failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetIspAttrCfg(int channel, RTIspCtrlAttr *isp_ctrl_attr)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetIspAttrCfg\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetIspAttrCfg: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ISP_ATTR_CFG, isp_ctrl_attr);
if(ret != 0)
aw_loge("IOCTL_SET_ISP_ATTR_CFG failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_GetIspAttrCfg(int channel, RTIspCtrlAttr *isp_ctrl_attr)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetIspAttrCfg\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetIspAttrCfg: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_GET_ISP_ATTR_CFG, isp_ctrl_attr);
if(ret != 0)
aw_loge("IOCTL_SET_ISP_ATTR_CFG failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetIspOrl(int channel, RTIspOrl *isp_orl)
{
int ret = 0;
if (g_videoInput_cxt == NULL) {
aw_loge("g_videoInput_cxt is null when call SetIspAttrCfg\n");
return -1;
}
if (channel >= VIDEO_INPUT_CHANNEL_NUM) {
aw_loge("SetIspAttrCfg: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ISP_ORL, isp_orl);
if(ret != 0)
aw_loge("IOCTL_SET_ISP_ORL failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_ResetEncoderType(int channel, int encoderType)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call ResetEncoderType\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("ResetEncoderType: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
if(cur_channel->config.encodeType == encoderType)
{
aw_logw("the encoder type is the some, no need reset: %d, %d",
cur_channel->config.encodeType, encoderType);
pthread_mutex_unlock(&cur_channel->mutex);
return -1;
}
if(cur_channel->state != VIDEO_INPUT_STATE_PAUSE)
{
aw_logw("the state[%d] is not pause[%d]", cur_channel->state, VIDEO_INPUT_STATE_PAUSE);
pthread_mutex_unlock(&cur_channel->mutex);
return -1;
}
aw_logd("ori_type = %d, new_type = %d",
cur_channel->config.encodeType, encoderType);
//post_messgae_and_wait(cur_channel, VIDEO_INPUT_CMD_PAUSE);
ret = ioctl(cur_channel->dev_fd, IOCTL_RESET_ENCODER_TYPE, encoderType);
if(cur_channel->vbv_buffer.bInit == 1)
{
destroy_vbv_buffer(&cur_channel->vbv_buffer);
}
cur_channel->sps_pps_data.bInit = 0;
//post_messgae_and_wait(cur_channel, VIDEO_INPUT_CMD_EXCUTING);
if(ret == 0)
cur_channel->config.encodeType = encoderType;
else
aw_loge("reset encoder type failed, ret = %d", ret);
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetKernelRtMediaPause(int channel)
{
//* todo
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_PAUSE, NULL);
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_ReturnStreamData(int channel, STREAM_DATA_INFO *p_stream_data)
{
//* todo
int ret = 0;
if(g_videoInput_cxt == NULL || !p_stream_data)
{
aw_loge("g_videoInput_cxt or p_stream_data is null %p\n", p_stream_data);
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_RETURN_STREAM_DATA, p_stream_data);
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetKernelRtMediaStart(int channel)
{
//* todo
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_START, NULL);
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_ResetInOutBuffer(int channel)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
ret = ioctl(cur_channel->dev_fd, IOCTL_RESET_IN_OUT_BUFFER, 0);
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_ResetSize(int channel, int width, int height)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call ResetSize\n");
return -1;
}
int64_t time_begin = get_cur_time_us();
aw_logv("begin time = %lld", time_begin);
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("ResetSize: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
if(width == cur_channel->config.width && height == cur_channel->config.height)
{
aw_loge("the wdith[%d] and height[%d] are not change", width, height);
return 0;
}
pthread_mutex_lock(&cur_channel->mutex);
if(cur_channel->state != VIDEO_INPUT_STATE_PAUSE)
{
aw_logw("the state[%d] is not pause[%d]", cur_channel->state, VIDEO_INPUT_STATE_PAUSE);
pthread_mutex_unlock(&cur_channel->mutex);
return -1;
}
#if 0
ret = ioctl(cur_channel->dev_fd, IOCTL_PAUSE, channel);
int64_t time_pause = get_cur_time_us();
aw_logv("ioctl pause, ret = %d, time = %lld",
ret, time_pause - time_begin);
#endif
if(cur_channel->bThread_create_flag == 1)
{
pthread_mutex_unlock(&cur_channel->mutex);
post_messgae_and_wait(cur_channel, VIDEO_INPUT_CMD_EXIT);
pthread_join(cur_channel->thread, (void**)&ret);
cur_channel->bThread_create_flag = 0;
pthread_mutex_lock(&cur_channel->mutex);
}
int64_t time_thread = get_cur_time_us();
aw_logv("exit thread, time = %lld", time_thread - time_pause);
ret = ioctl(cur_channel->dev_fd, IOCTL_DESTROY, 0);
if(cur_channel->vbv_buffer.bInit == 1)
{
destroy_vbv_buffer(&cur_channel->vbv_buffer);
}
cur_channel->sps_pps_data.bInit = 0;
int64_t time_destroy = get_cur_time_us();
cur_channel->config.width = width;
cur_channel->config.height = height;
cur_channel->config.dst_width = width;
cur_channel->config.dst_height = height;
if (cur_channel->config.output_mode == OUTPUT_MODE_YUV) {
int i = 0;
for (; i < CONFIG_YUV_BUF_NUM; i++)
memset(&cur_channel->s_yuv_fd[i], 0, sizeof(yuv_fd_info));
}
aw_logv("ioctl destroy, ret = %d, time = %lld", ret, time_destroy - time_thread);
ret = ioctl(cur_channel->dev_fd, IOCTL_CONFIG, &cur_channel->config);
int64_t time_config = get_cur_time_us();
aw_logv("ioctl config, ret = %d, time = %lld", ret, time_config - time_destroy);
ret = awVideoInput_GENLSocketConnectRtMedia(cur_channel);
if(ret != 0)
{
aw_loge("fatal error! recorder[%d=%d] genl socket connect rt_media fail, portId:%d", channel, cur_channel->id, cur_channel->mSrcNLPortId);
}
cur_channel->state = VIDEO_INPUT_STATE_CONFIGED;
pthread_mutex_unlock(&cur_channel->mutex);
int64_t time_create_thread = get_cur_time_us();
aw_logv("finish, diff_time = %lld, create_time = %lld, time = %lld",
get_cur_time_us() - time_begin, time_create_thread - time_config,
get_cur_time_us());
return 0;
}
int AWVideoInput_GetChannelInfo(int channel, VideoChannelInfo *pChannelInfo)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetPowerLineFreq\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetChannelInfo: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
memcpy(&pChannelInfo->mConfig, &cur_channel->config, sizeof(VideoInputConfig));
pChannelInfo->state = cur_channel->state;
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_SetH264VideoTiming(int channel, RTVencH264VideoTiming* H264VideoTiming)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_H264_VIDEO_TIMING, H264VideoTiming);
if(ret != 0)
aw_loge("failed!");
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_SetH265VideoTiming(int channel, RTVencH265TimingS* H265VideoTiming)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_H265_VIDEO_TIMING, H265VideoTiming);
if(ret != 0)
aw_loge("failed!");
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_SetFixQp(int channel, RTVencFixQP* fix_qp)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_FIX_QP, fix_qp);
if(ret != 0)
aw_loge("failed!");
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_RegisterTdmBufDoneCallback(int channel, void *cb)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
cur_channel->mTdmBufDoneCallback = cb;
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_ReturnTdmBuf(int channel, struct vin_isp_tdm_event_status* p_tdm_status)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_RETURN_TDM_BUF, p_tdm_status);
if(ret != 0)
aw_loge("failed!");
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_GetTdmData(int channel, struct vin_isp_tdm_data* p_tdm_data)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_TDM_DATA, p_tdm_data);
if(ret != 0)
aw_loge("failed!");
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_SetQpRange(int channel, video_qp_range* qp_range)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetQpRange\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetQpRange: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_QP_RANGE, qp_range);
if(ret != 0)
{
aw_loge("IOCTL_SET_QP_RANGE failed, i_qp = %d ~ %d, p_qp = %d ~ %d",
qp_range->i_min_qp, qp_range->i_max_qp, qp_range->p_min_qp, qp_range->p_max_qp);
}
else
memcpy(&cur_channel->config.qp_range, qp_range, sizeof(video_qp_range));
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_GetQpRange(int channel, video_qp_range* qp_range)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
memcpy(qp_range, &cur_channel->config.qp_range, sizeof(video_qp_range));
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
//Unit:kbps
int AWVideoInput_SetBitrate(int channel, int bitrate)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetBitrate\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetBitrate: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_BITRATE, bitrate);
if(ret != 0)
aw_loge("IOCTL_SET_BITRATE failed, bitrate = %d", bitrate);
else
cur_channel->config.bitrate = bitrate;
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_SetEnIFrmMbRcMoveStatus(int channel, int nMbRcMoveStatus)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_MB_RC_MOVE_STATUS, nMbRcMoveStatus);
if(ret != 0)
aw_loge("failed, nMbRcMoveStatus = %d", nMbRcMoveStatus);
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_SetJpgQuality(int channel, int nQuality)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_JPEG_QUALITY, nQuality);
if(ret != 0)
aw_loge("failed, nQuality = %d", nQuality);
else
cur_channel->config.jpg_quality = nQuality;
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
//Unit:kbps
int AWVideoInput_GetBitrate(int channel)
{
int cur_bitrate = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
cur_bitrate = cur_channel->config.bitrate;
pthread_mutex_unlock(&cur_channel->mutex);
return cur_bitrate;
}
//* set the frameRate, such as 1 ~ 15 fps;
int AWVideoInput_SetFps(int channel, int fps)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetBitrate\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetFps: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_FPS, fps);
if(ret != 0)
aw_loge("IOCTL_SET_BITRATE failed, bitrate = %d", fps);
else
cur_channel->config.fps = fps;
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_GetFps(int channel)
{
int cur_fps = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
cur_fps = cur_channel->config.fps;
pthread_mutex_unlock(&cur_channel->mutex);
return cur_fps;
}
int AWVideoInput_SetVbrParam(int channel, RTVencVbrParam *pvbr_param)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetVbrParam\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetVbrParam: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_VBR_PARAM, pvbr_param);
if(ret != 0)
aw_loge("IOCTL_SET_VBR_PARAM failed, pvbr_param = %p", pvbr_param);
else
memcpy(&cur_channel->vbr_param, pvbr_param, sizeof(RTVencVbrParam));
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_GetVbrParam(int channel, RTVencVbrParam *pvbr_param)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
memcpy(pvbr_param, &cur_channel->vbr_param, sizeof(RTVencVbrParam));
pthread_mutex_unlock(&cur_channel->mutex);
return 0;
}
int AWVideoInput_GetSumMad(int channel)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call GetSumMbInfo\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("GetSumMbInfo: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
RTVencMBSumInfo mMbSumInfo;
memset(&mMbSumInfo, 0, sizeof(RTVencMBSumInfo));
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_SUM_MB_INFO, &mMbSumInfo);
if(ret != 0)
aw_loge("IOCTL_GET_SUM_MB_INFO failed");
pthread_mutex_unlock(&cur_channel->mutex);
return mMbSumInfo.sum_mad;
}
int AWVideoInput_GetMotionSearchResult(int channel, RTVencMotionSearchResult* pMotionSearchResult)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_ENC_MOTION_SEARCH_RESULT, pMotionSearchResult);
if(ret != 0)
aw_loge("IOCTL_GET_ENC_MOTION_SEARCH_RESULT failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetSuperFrameParam(int channel, RTVencSuperFrameConfig* pSuperFrameConfig)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_VENC_SUPER_FRAME_PARAM, pSuperFrameConfig);
if(ret != 0)
aw_loge("IOCTL_SET_VENC_SUPER_FRAME_PARAM failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetMotionSearchParam(int channel, RTVencMotionSearchParam* pMotionSearchParam)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ENC_MOTION_SEARCH_PARAM, pMotionSearchParam);
if(ret != 0)
aw_loge("IOCTL_SET_ENC_MOTION_SEARCH_PARAM failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetRoi(int channel, RTVencROIConfig* pRoiConfig)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ROI, pRoiConfig);
if(ret != 0)
aw_loge("IOCTL_SET_ROI failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetGdc(int channel, RTsGdcParam* pGdcConfig)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_GDC, pGdcConfig);
if(ret != 0)
aw_loge("IOCTL_SET_GDC failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetRotate(int channel, int rotate_angle)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ROTATE, rotate_angle);
if(ret != 0)
aw_loge("IOCTL_SET_ROTATE failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
/**
获取h264或h265码流的spspps信息.
必须在AWVideoInput_Start()之后调用内核视频编码库是在AWVideoInput_Start()内初始化在AWVideoInput_Configure()内被创建。
@param channel
vipp的通道号这里也用来代表编码通道号。
@param pSpsPpsInfo
caller传入不重新分配内存buf指针指向AWChannel_cxt->sps_pps_data->buffer
@return
0:success
-1:fail
*/
int AWVideoInput_GetSpsPpsInfo(int channel, sps_pps_data_info *pSpsPpsInfo)
{
int ret = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
if(cur_channel->config.encodeType == 0 || cur_channel->config.encodeType == 2)
{
if(cur_channel->sps_pps_data.bInit == 0)
{
ret = get_sps_pps_data(cur_channel);
if(ret != 0)
{
aw_loge("fatal error! get spspps fail:%d", ret);
}
}
if(cur_channel->sps_pps_data.bInit)
{
pSpsPpsInfo->bInit = cur_channel->sps_pps_data.bInit;
pSpsPpsInfo->buf = cur_channel->sps_pps_data.buf;
pSpsPpsInfo->size = cur_channel->sps_pps_data.size;
ret = 0;
}
else
{
aw_loge("fatal error! spspps is got fail");
ret = -1;
}
}
else
{
aw_loge("fatal error! encodeType[%d] not support get spspps!", cur_channel->config.encodeType);
ret = -1;
}
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetRecRefLbcMode(int channel, RTeVeLbcMode rec_lbc_mode)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_REC_REF_LBC_MODE, rec_lbc_mode);
if(ret != 0)
aw_loge("IOCTL_SET_REC_REF_LBC_MODE failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetWeakTextTh(int channel, RTVenWeakTextTh *pWeakTextureTh)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_WEAK_TEXT_TH, pWeakTextureTh);
if(ret != 0)
aw_loge("IOCTL_SET_WEAK_TEXT_TH failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetRegionD3DParam(int channel, RTVencRegionD3DParam *pRegionD3DParam)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_REGION_D3D_PARAM, pRegionD3DParam);
if(ret != 0)
aw_loge("IOCTL_SET_REGION_D3D_PARAM failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_GetRegionD3DResult(int channel, RTVencRegionD3DResult *pRegionD3DResult)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_REGION_D3D_RESULT, pRegionD3DResult);
if(ret != 0)
aw_loge("IOCTL_GET_REGION_D3D_RESULT failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetChromaQPOffset(int channel, int nChromaQpOffset)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_CHROMA_QP_OFFSET, nChromaQpOffset);
if(ret != 0)
aw_loge("IOCTL_SET_ROTATE failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
/**
set decoding flag to vencLib. It is recommended to call it before AWVideoInput_Start(), after AWVideoInput_Configure().
When vencLib knows decoder is running, it will do not start to encode when in blanking interval. To avoid v853 ve
online encoding bug.
@param channel
venc channel in AWVideoInput.
@param bEncAndDecCase
1: decoder is exist.
0: no decoder.
@return
0: success
-1: fail
*/
int AWVideoInput_SetEncAndDecCase(int channel, int bEncAndDecCase)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ENC_AND_DEC_CASE, bEncAndDecCase);
if(ret != 0)
aw_loge("ioctl failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetH264ConstraintFlag(int channel, RTVencH264ConstraintFlag *pConstraintFlag)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_H264_CONSTRAINT_FLAG, pConstraintFlag);
if(ret != 0)
aw_loge("IOCTL_SET_H264_CONSTRAINT_FLAG failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetVe2IspD2DLimit(int channel, RTVencVe2IspD2DLimit *pD2DLimit)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_VE2ISP_D2D_LIMIT, pD2DLimit);
if(ret != 0)
aw_loge("IOCTL_SET_VE2ISP_D2D_LIMIT failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_EnableSmallSearchRange(int channel, int enable)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_EN_SMALL_SEARCH_RANGE, enable);
if(ret != 0)
aw_loge("IOCTL_SET_EN_SMALL_SEARCH_RANGE failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetForceConfWin(int channel, RTVencForceConfWin *pConfWin)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_FORCE_CONF_WIN, pConfWin);
if(ret != 0)
aw_loge("IOCTL_SET_FORCE_CONF_WIN failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetRotVe2Isp(int channel, RTVencRotVe2Isp *pRotVe2Isp)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ROT_VE2ISP, pRotVe2Isp);
if(ret != 0)
aw_loge("IOCTL_SET_ROT_VE2ISP failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetInsertData(int channel, RTVencInsertData *pInsertData)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_INSERT_DATA, pInsertData);
if(ret != 0)
aw_loge("IOCTL_SET_INSERT_DATA failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_GetInsertDataBufStatus(int channel, RT_VENC_BUF_STATUS *pStatus)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_INSERT_DATA_BUF_STATUS, pStatus);
if(ret != 0)
aw_loge("IOCTL_GET_INSERT_DATA_BUF_STATUS failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetChmoraGray(int channel, int enable_gray)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_GRAY, enable_gray);
if(ret != 0)
aw_loge("IOCTL_SET_GRAY failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_Set2dNR(int channel, RTs2DfilterParam* p_2dnr_param)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_2DNR, p_2dnr_param);
if(ret != 0)
aw_loge("IOCTL_SET_2DNR failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_Set3dNR(int channel, RTs3DfilterParam* p_3dnr_param)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_3DNR, p_3dnr_param);
if(ret != 0)
aw_loge("IOCTL_SET_3DNR failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetWbYuv(int channel, WbYuvFuncInfo *pWbYuvFuncInfo, RTsWbYuvParam *pWbYuvParam, int dst_w, int dst_h)
{
//center point alignment
pWbYuvParam->sWbYuvcrop.nTop = (ALIGN_XXB(16, dst_h)/2 - pWbYuvParam->sWbYuvcrop.nHeight/2);
pWbYuvParam->sWbYuvcrop.nLeft = (ALIGN_XXB(16, dst_w)/2 - pWbYuvParam->sWbYuvcrop.nWidth/2);
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
cur_channel->p_wbyuv_info = pWbYuvFuncInfo;
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_WB_YUV, pWbYuvParam);
if(ret != 0) {
pthread_mutex_unlock(&cur_channel->mutex);
aw_loge("IOCTL_SET_WB_YUV failed");
return ret;
}
pthread_mutex_unlock(&cur_channel->mutex);
unsigned int ThumbScale = 0;
if(pWbYuvParam->scalerRatio == RTVENC_ISP_SCALER_0)
ThumbScale = 0;
else if(pWbYuvParam->scalerRatio == RTVENC_ISP_SCALER_HALF)
ThumbScale = 1;
else if(pWbYuvParam->scalerRatio == RTVENC_ISP_SCALER_QUARTER)
ThumbScale = 2;
else if(pWbYuvParam->scalerRatio == RTVENC_ISP_SCALER_EIGHTH)
ThumbScale = 3;
unsigned int nAlignW = ALIGN_XXB(16, dst_w) >> ThumbScale;
unsigned int nAlignH = ALIGN_XXB(16, dst_h) >> ThumbScale;
if(pWbYuvParam->bEnableCrop)
{
nAlignW = ALIGN_XXB(16, pWbYuvParam->sWbYuvcrop.nWidth);
nAlignH = ALIGN_XXB(16, pWbYuvParam->sWbYuvcrop.nHeight);
}
pWbYuvFuncInfo->yuvSize = nAlignW*nAlignH*3/2;
aw_logd("%d %d %d", nAlignW, nAlignH, pWbYuvFuncInfo->yuvSize);
pWbYuvFuncInfo->yuvBuf = calloc(1, pWbYuvFuncInfo->yuvSize);
if(pWbYuvFuncInfo->yuvBuf == NULL)
{
aw_loge("malloc failed, size = %d", pWbYuvFuncInfo->yuvSize);
return -1;
}
if(pWbYuvFuncInfo->wbyuv_file)
{
return 0;
}
char wb_yuv_name[128];
sprintf(wb_yuv_name, "/mnt/extsd/wb_%dx%d.yuv",nAlignW, nAlignH);
pWbYuvFuncInfo->wbyuv_file = fopen(wb_yuv_name, "wb");
if(pWbYuvFuncInfo->wbyuv_file == NULL)
{
aw_logw("open file failed : %s", wb_yuv_name);
}
return ret;
}
int AWVideoInput_SaveWbYuv(int channel, WbYuvFuncInfo *pWbYuvFuncInfo)
{
int result;
RTVencThumbInfo mThumbInfo;
memset(&mThumbInfo, 0, sizeof(RTVencThumbInfo));
mThumbInfo.pThumbBuf = pWbYuvFuncInfo->yuvBuf;
mThumbInfo.nThumbSize = pWbYuvFuncInfo->yuvSize;
mThumbInfo.bWriteToFile = 0;
aw_logd("yuvBuf = %p, yuvSize = %d, file = %p",
pWbYuvFuncInfo->yuvBuf, pWbYuvFuncInfo->yuvSize, pWbYuvFuncInfo->wbyuv_file);
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_WB_YUV, &mThumbInfo);
pthread_mutex_unlock(&cur_channel->mutex);
if(ret == 0) {
if(pWbYuvFuncInfo->wbyuv_file)
fwrite(pWbYuvFuncInfo->yuvBuf, 1, pWbYuvFuncInfo->yuvSize, pWbYuvFuncInfo->wbyuv_file);
else
aw_logd("wbyuv_file[%p] is null", pWbYuvFuncInfo->wbyuv_file);
} else {
aw_logw("wb yuv not ready.");
}
return ret;
}
int AWVideoInput_DeInitWbYuv(int channel, WbYuvFuncInfo *pWbYuvFuncInfo)
{
RTsWbYuvParam mWbYuvParam;
memset(&mWbYuvParam, 0, sizeof(RTsWbYuvParam));
mWbYuvParam.bEnableWbYuv = 0;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_WB_YUV, &mWbYuvParam);
if(ret != 0) {
pthread_mutex_unlock(&cur_channel->mutex);
aw_loge("IOCTL_SET_WB_YUV failed");
return ret;
}
pthread_mutex_unlock(&cur_channel->mutex);
if(pWbYuvFuncInfo->wbyuv_file)
fclose(pWbYuvFuncInfo->wbyuv_file);
if(pWbYuvFuncInfo->yuvBuf)
{
free(pWbYuvFuncInfo->yuvBuf);
}
free(pWbYuvFuncInfo);
return 0;
}
int AWVideoInput_SetPIntraRefresh(int channel, RTVencCyclicIntraRefresh* pIntraRefresh)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_CYCLIC_INTRA_REFRESH, pIntraRefresh);
if(ret != 0)
aw_loge("IOCTL_SET_CYCLIC_INTRA_REFRESH failed");
if (pIntraRefresh->bEnable) {
int en_pIntraRefresh = pIntraRefresh->bEnable;
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_P_FRAME_INTRA, en_pIntraRefresh);
if(ret != 0)
aw_loge("IOCTL_SET_P_FRAME_INTRA failed");
}
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
/**
call rtmedia to drop <n> frames actively.
when rtmedia receives this command, it will record dropNum, then drop frames not to encode.
*/
int AWVideoInput_DropFrame(int channel, int nDropNum)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("fatal error! g_videoInput_cxt is null");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("fatal error! the channel[%d] overflow", channel);
return -1;
}
AWChannel_cxt* channel_cxt = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&channel_cxt->mutex);
int ret = ioctl(channel_cxt->dev_fd, IOCTL_DROP_FRAME, nDropNum);
if(ret != 0)
{
aw_loge("fatal error! chn[%d] drop [%d] frames fail[0x%x]", channel, nDropNum, ret);
}
pthread_mutex_unlock(&channel_cxt->mutex);
return ret;
}
int AWVideoInput_SetCameraMoveStatus(int channel, RT_VENC_CAMERA_MOVE_STATUS camera_move_status)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_CAMERA_MOVE_STATUS, camera_move_status);
if(ret != 0)
aw_loge("IOCTL_SET_CAMERA_MOVE_STATUS failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetCrop(int channel, RTCropInfo *crop_info)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_CROP, crop_info);
if(ret != 0)
aw_loge("IOCTL_SET_CROP failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetVencTargetBitsClipParam(int channel, RT_VENC_TARGET_BITS_CLIP_PARAM *target_bits_clop_param)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_SET_VENC_TARTGET_BITS_CLIP_PARAM, target_bits_clop_param);
if(ret != 0)
aw_loge("IOCTL_SET_VENC_TARTGET_BITS_CLIP_PARAM failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_SetIspFaceAeCfg(int channel, AWVideoInput_FaceAeInfo FaceAeInfo, AWVideoInput_VideoSrcRes Res)
{
int ret = 0, real_vaild_cnt, i;
RTIspCtrlAttr isp_ctrl_attr;
AWVideoInput_VideoPoint PtRightBottom[RT_AE_FACE_MAX_NUM];
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetIspAttrCfg\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetIspAttrCfg: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
if (FaceAeInfo.enable == true) {
if (FaceAeInfo.vaild_face_num < 0) {
aw_loge("face_num = %d is < 0, please check it!\n", FaceAeInfo.vaild_face_num);
return -1;
} else if (FaceAeInfo.vaild_face_num > RT_AE_FACE_MAX_NUM) {
aw_logw("vaild_face_num:%d > RT_AE_FACE_MAX_NUM:%d, it will only use %d face_roi!",
FaceAeInfo.vaild_face_num, RT_AE_FACE_MAX_NUM, RT_AE_FACE_MAX_NUM);
FaceAeInfo.vaild_face_num = RT_AE_FACE_MAX_NUM;
}
/* reset face_ae_cfg_load for detect */
memset(&isp_ctrl_attr, 0, sizeof(RTIspCtrlAttr));
/* parser face_roi */
for (i = 0, real_vaild_cnt = 0; i < FaceAeInfo.vaild_face_num; i++) {
/* calc PtRightBottom */
PtRightBottom[i].x = FaceAeInfo.face_roi_rgn[i].nLeft + FaceAeInfo.face_roi_rgn[i].nWidth;
PtRightBottom[i].y = FaceAeInfo.face_roi_rgn[i].nTop + FaceAeInfo.face_roi_rgn[i].nHeight;
/* check area */
if ((FaceAeInfo.face_roi_rgn[i].nLeft > Res.src_width) || (FaceAeInfo.face_roi_rgn[i].nTop > Res.src_height) ||
(PtRightBottom[i].x > Res.src_width) || (PtRightBottom[i].y > Res.src_height) ||
(FaceAeInfo.face_roi_rgn[i].nLeft == PtRightBottom[i].x && FaceAeInfo.face_roi_rgn[i].nTop == PtRightBottom[i].y)) {
aw_loge("face_ae_cfg_load.face_ae_coor[%d]: (%d, %d) (%d, %d), it is invalid coordinate from src:%d*%d, will lost it\n",
FaceAeInfo.face_roi_rgn[i].nLeft, FaceAeInfo.face_roi_rgn[i].nTop,
PtRightBottom[i].x, PtRightBottom[i].y, Res.src_width, Res.src_height);
/* reset this face_ae_coor */
memset(&isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[i], 0, sizeof(struct isp_h3a_coor_win));
} else {
/* calc vaild face_roi */
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[real_vaild_cnt].x1 = (int)(FaceAeInfo.face_roi_rgn[i].nLeft * 2000 / Res.src_width - 1000 );
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[real_vaild_cnt].y1 = (int)(FaceAeInfo.face_roi_rgn[i].nTop * 2000 / Res.src_height - 1000 );
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[real_vaild_cnt].x2 = (int)(PtRightBottom[i].x * 2000 / Res.src_width - 1000 );
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[real_vaild_cnt].y2 = (int)(PtRightBottom[i].y * 2000 / Res.src_height - 1000 );
//#define PRINT_INFO
#ifdef PRINT_INFO
aw_logd("face_ae_cfg_load.face_ae_coor[%d]: (%d, %d) & (%d, %d) -> (%d, %d) (%d, %d)\n", i,
FaceAeInfo.face_roi_rgn[i].nLeft, FaceAeInfo.face_roi_rgn[i].nTop,
PtRightBottom[i].x, PtRightBottom[i].y,
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[real_vaild_cnt].x1, isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[real_vaild_cnt].y1,
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[real_vaild_cnt].x2, isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_coor[real_vaild_cnt].y2);
#endif
real_vaild_cnt++;
}
}
if (real_vaild_cnt > RT_AE_FACE_MAX_NUM || real_vaild_cnt < 0) {
aw_loge("real_vaild_num = %d, it will not do faceAE, please check face_roi!\n", real_vaild_cnt);
return -1;
} else if (real_vaild_cnt == 0) {
aw_logd("real_vaild_num = %d, it will recover AE\n", real_vaild_cnt);
}
isp_ctrl_attr.isp_attr_cfg.ae_face_info.vaild_face_cnt = real_vaild_cnt;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_tolerance = FaceAeInfo.face_ae_tolerance;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_speed = FaceAeInfo.face_ae_speed;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_target = FaceAeInfo.face_ae_target;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_delay_cnt = FaceAeInfo.face_ae_delay_cnt;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_up_percent = FaceAeInfo.face_up_percent;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_down_percent = FaceAeInfo.face_down_percent;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_face_block_num_thrd = FaceAeInfo.ae_face_block_num_thrd;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_face_block_weight = FaceAeInfo.ae_face_block_weight;
isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_over_face_max_exp_control = FaceAeInfo.ae_over_face_max_exp_control;
if (real_vaild_cnt != 0) {
memcpy(&isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_face_win_weight, &FaceAeInfo.ae_face_win_weight, RT_AE_FACE_WIN_WEIGHT_LENGTH * sizeof(unsigned short));
memcpy(&isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_face_pos_weight, &FaceAeInfo.ae_face_pos_weight, RT_AE_FACE_POS_WEIGHT_LENGTH * sizeof(int));
}
isp_ctrl_attr.isp_attr_cfg.ae_face_info.enable = true;
} else {
aw_logd("It will disable faceAE!\n");
isp_ctrl_attr.isp_attr_cfg.ae_face_info.enable = false;
}
pthread_mutex_lock(&cur_channel->mutex);
isp_ctrl_attr.isp_attr_cfg.cfg_id = RT_ISP_CTRL_AE_FACE_CFG;
ret = ioctl(cur_channel->dev_fd, IOCTL_SET_ISP_ATTR_CFG, &isp_ctrl_attr);
if(ret != 0)
aw_loge("Set RT_ISP_CTRL_AE_FACE_CFG failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
int AWVideoInput_GetIspFaceAeCfg(int channel, AWVideoInput_FaceAeInfo *FaceAeInfo)
{
int ret = 0;
RTIspCtrlAttr isp_ctrl_attr;
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null when call SetIspAttrCfg\n");
return -1;
}
if (!FaceAeInfo) {
aw_loge("FaceAeInfo is NULL!\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("SetIspAttrCfg: the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
memset(&isp_ctrl_attr, 0, sizeof(RTIspCtrlAttr));
isp_ctrl_attr.isp_attr_cfg.cfg_id = RT_ISP_CTRL_AE_FACE_CFG;
ret = ioctl(cur_channel->dev_fd, IOCTL_GET_ISP_ATTR_CFG, &isp_ctrl_attr);
if(ret != 0) {
aw_loge("Get RT_ISP_CTRL_AE_FACE_CFG failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
pthread_mutex_unlock(&cur_channel->mutex);
FaceAeInfo->enable = isp_ctrl_attr.isp_attr_cfg.ae_face_info.enable;
FaceAeInfo->vaild_face_num = isp_ctrl_attr.isp_attr_cfg.ae_face_info.vaild_face_cnt;
FaceAeInfo->face_ae_tolerance = isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_tolerance;
FaceAeInfo->face_ae_speed = isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_speed;
FaceAeInfo->face_ae_target = isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_target;
FaceAeInfo->face_ae_delay_cnt = isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_ae_delay_cnt;
FaceAeInfo->face_up_percent = isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_up_percent;
FaceAeInfo->face_down_percent = isp_ctrl_attr.isp_attr_cfg.ae_face_info.face_down_percent;
FaceAeInfo->ae_face_block_num_thrd = isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_face_block_num_thrd;
FaceAeInfo->ae_face_block_weight = isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_face_block_weight;
FaceAeInfo->ae_over_face_max_exp_control = isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_over_face_max_exp_control;
memcpy(&FaceAeInfo->ae_face_win_weight, &isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_face_win_weight, RT_AE_FACE_WIN_WEIGHT_LENGTH * sizeof(unsigned short));
memcpy(&FaceAeInfo->ae_face_pos_weight, &isp_ctrl_attr.isp_attr_cfg.ae_face_info.ae_face_pos_weight, RT_AE_FACE_POS_WEIGHT_LENGTH * sizeof(int));
return ret;
}
int AWVideoInput_GetISPReg(int channel, VIN_ISP_REG_GET_CFG *cfg_ptr)
{
if(g_videoInput_cxt == NULL)
{
aw_loge("g_videoInput_cxt is null\n");
return -1;
}
if(channel >= VIDEO_INPUT_CHANNEL_NUM)
{
aw_loge("the channel[%d] overflow\n", channel);
return -1;
}
AWChannel_cxt* cur_channel = &g_videoInput_cxt->channel_cxt[channel];
pthread_mutex_lock(&cur_channel->mutex);
int ret = ioctl(cur_channel->dev_fd, IOCTL_GET_ISP_REG, cfg_ptr);
if(ret != 0)
aw_loge("IOCTL_GET_ISP_REG failed");
pthread_mutex_unlock(&cur_channel->mutex);
return ret;
}
void* ChannelThread(void* param)
{
AWChannel_cxt* channel_cxt = (AWChannel_cxt*)param;
STREAM_DATA_INFO stream_data;
int csi_status[VIDEO_INPUT_CHANNEL_NUM];
int ret = 0;
int try_get_vbv_buf_cnt = 0;
XmMessage msg;
int bget_stream_data_succ = 0;
int err_cnt = 0;
int64_t err_start_time = 0;
int64_t wait_start_time = 0;
int haved_exit = 0;
fd_set socketFds;
FD_ZERO(&socketFds);
FD_SET(channel_cxt->mSockFd, &socketFds);
memset(&msg, 0, sizeof(XmMessage));
memset(csi_status, 0, sizeof(int) * VIDEO_INPUT_CHANNEL_NUM);
char strThreadName[32];
sprintf(strThreadName, "AWVideoInput%d", channel_cxt->id);
prctl(PR_SET_NAME, strThreadName);
while(1)
{
if(aw_message_queue_tryGetMessage(channel_cxt->mq, &msg, 0) == 0)
{
if(msg.messageId == VIDEO_INPUT_CMD_PAUSE)
channel_cxt->state = VIDEO_INPUT_STATE_PAUSE;
else if(msg.messageId == VIDEO_INPUT_CMD_EXCUTING) {
channel_cxt->state = VIDEO_INPUT_STATE_EXCUTING;
}
else if(msg.messageId == VIDEO_INPUT_CMD_EXIT)
channel_cxt->state = VIDEO_INPUT_STATE_IDLE;
sem_post(msg.psem_reply);
}
//try to receive event from kernel rt_media.
/*if(channel_cxt->mSockFd >= 0)
{
fd_set tmpRdFds = socketFds;
struct timeval timeout = {0, 0};
int nReadyCnt = select(channel_cxt->mSockFd+1, &tmpRdFds, NULL, NULL, &timeout);
if(nReadyCnt > 0)
{
if(FD_ISSET(channel_cxt->mSockFd, &tmpRdFds))
{
RTCbEvent stEvent;
ret = awVideoInput_ReceiveGENLRTCbEvent(channel_cxt, &stEvent);
if(0 == ret)
{
switch(stEvent.eEventType)
{
case RTCB_EVENT_VENC_DROP_FRAME:
{
if(channel_cxt->mCallback)
{
channel_cxt->mCallback(channel_cxt->mpAppData, channel_cxt->id, AWVideoInput_Event_DropFrame, stEvent.nData1, 0, NULL);
}
break;
}
default:
{
aw_loge("fatal error! chn[%d] receive unknown event type:%d", channel_cxt->id, stEvent.eEventType);
break;
}
}
}
}
}
else if(nReadyCnt < 0)
{
aw_loge("fatal error! chn[%d] select fail[%d]", channel_cxt->id, nReadyCnt);
}
}*/
if(channel_cxt->state == VIDEO_INPUT_STATE_IDLE)
{
aw_logd("the state is idle, exit the thread\n");
break;
}
else if(channel_cxt->state == VIDEO_INPUT_STATE_PAUSE)
{
if (channel_cxt->demo_wait_csi_ready) {
ioctl(channel_cxt->dev_fd, IOCTL_GET_CSI_STATUS, csi_status);
if (csi_status[channel_cxt->id]) {
channel_cxt->demo_wait_csi_ready = 0;
ret = ioctl(channel_cxt->dev_fd, IOCTL_START, channel_cxt->id);
channel_cxt->state = VIDEO_INPUT_STATE_EXCUTING;
} else if (channel_cxt->thread_exit_cb) {
if (!wait_start_time)
wait_start_time = get_cur_time_us();
if (get_cur_time_us() - wait_start_time > WAIT_CSI_TIMEOUT_TIME && !haved_exit) {
aw_loge("channel %d wait csi more than 5 seconds, will exit!", channel_cxt->id);
channel_cxt->thread_exit_cb();
haved_exit = 1;
}
}
}
aw_message_queue_waitMessage(channel_cxt->mq, 200);
continue;
}
else if(channel_cxt->state == VIDEO_INPUT_STATE_EXCUTING)
{
//* get share_fd of vbv buf from kernel;
if(channel_cxt->vbv_buffer.bInit == 0)
{
if(init_vbv_buffer(channel_cxt) != 0)
{
aw_logv("init_vbv_buffer failed\n");
usleep(10*1000);
try_get_vbv_buf_cnt++;
if (try_get_vbv_buf_cnt % 50 == 0)
aw_logd("init_vbv_buffer failed, cnt = %d\n", try_get_vbv_buf_cnt);
continue;
}
else
{
aw_logd("try_get_vbv_buf_cnt = %d ", try_get_vbv_buf_cnt );
try_get_vbv_buf_cnt = 0;
}
}
//* h264 and h265 encoder need get header data
if(channel_cxt->sps_pps_data.bInit == 0
&& (channel_cxt->config.encodeType == 0 || channel_cxt->config.encodeType == 2))
{
get_sps_pps_data(channel_cxt);
}
pthread_mutex_lock(&channel_cxt->mutex);
if(channel_cxt->video_osd_need_process_flag == 1)
{
aw_logv("*** setup the osd ***");
ret = ioctl(channel_cxt->dev_fd, IOCTL_SET_OSD, &channel_cxt->video_osd_info);
channel_cxt->video_osd_need_process_flag = 0;
}
pthread_mutex_unlock(&channel_cxt->mutex);
memset(&stream_data, 0, sizeof(STREAM_DATA_INFO));
ret = ioctl(channel_cxt->dev_fd, IOCTL_GET_STREAM_DATA, &stream_data);
if(ret != 0)
{
err_cnt++;
if (bget_stream_data_succ || err_cnt == 1)
err_start_time = get_cur_time_us();
bget_stream_data_succ = 0;
if (get_cur_time_us() - err_start_time > WAIT_CSI_TIMEOUT_TIME) {
aw_loge("channel %d get stream data more than 5 seconds, will exit!", channel_cxt->id);
if (channel_cxt->thread_exit_cb) {
aw_logd("%d thread_exit_cb %p", channel_cxt->id, channel_cxt->thread_exit_cb);
channel_cxt->thread_exit_cb();
}
channel_cxt->state = VIDEO_INPUT_STATE_PAUSE;
}
continue;
}
isp_ini_tuning_run(channel_cxt);
#if RT_MEDIA_SUPPORT_VENC_PARAM_DEBUG
check_ve_param_file(VE_PARAM_DYNAMIC, &channel_cxt->config, channel_cxt->id);
#endif
bget_stream_data_succ = 1;
if (channel_cxt->p_wbyuv_info) {
if (channel_cxt->p_wbyuv_info->enable_wbyuv && channel_cxt->p_wbyuv_info->get_num > 0) {
if (AWVideoInput_SaveWbYuv(channel_cxt->id, channel_cxt->p_wbyuv_info) == 0)
channel_cxt->p_wbyuv_info->get_num--;
}
}
if(channel_cxt->id == 0)
aw_logv("stream info: size0 = %d, offset = %d", stream_data.size0, stream_data.offset0);
#if 0
aw_logd("stream data: %x, %x, %x, %x, %x, %x, %x, %x\n",
stream_data.buf[0], stream_data.buf[1],
stream_data.buf[2], stream_data.buf[3],
stream_data.buf[4], stream_data.buf[5],
stream_data.buf[6], stream_data.buf[7]);
#endif
#if 1
stream_data.tv.tv_sec = stream_data.pts/1000000;
stream_data.tv.tv_usec = stream_data.pts%1000000;
if(channel_cxt->id == 0)
{
uint64_t cur_time = get_cur_time_us();
aw_logv("id = %d, tv_sec = %lu, tv_usec = %lu, pts = %llu us; pre_diff = %llu ms, cur_time = %llu us, diff = %llu ms\n",
channel_cxt->id, stream_data.tv.tv_sec, stream_data.tv.tv_usec,
stream_data.pts, (stream_data.pts - channel_cxt->pre_pts)/1000,
cur_time, (cur_time - stream_data.pts)/1000);
}
channel_cxt->pre_pts = stream_data.pts;
callback_stream_data(channel_cxt, &stream_data);
ret = ioctl(channel_cxt->dev_fd, IOCTL_RETURN_STREAM_DATA, &stream_data);
#endif
}
}
aw_logd("exit the thread, channel = %d\n", channel_cxt->id);
return 0;
}
void *GENLRecvThread(void * param)
{
AWChannel_cxt* channel_cxt = (AWChannel_cxt*)param;
fd_set socketFds;
FD_ZERO(&socketFds);
FD_SET(channel_cxt->mSockFd, &socketFds);
char thread_name[32] = {0};
uint64_t cur_time_us = 0, time_us = 0;
int GENL_msg_cnt = 0;
sprintf(thread_name, "AWVideoGENL%d", channel_cxt->id);
prctl(PR_SET_NAME, (unsigned long)thread_name, 0, 0, 0);
if (channel_cxt->mSockFd < 0)
{
aw_loge("GENL socket invalid!");
return (void *)NULL;
}
while (1)
{
if (channel_cxt->GENL_thread_exit_flag)
break;
if (time_us == 0)
time_us = get_cur_time_us();
cur_time_us = get_cur_time_us();
if (((cur_time_us - time_us) >= GENL_MSG_CHECK_MAX_INTERVAL_US))
{
if (GENL_msg_cnt >= GENL_MSG_CHECK_MAX_CNT)
aw_loge("Be careful! channel %d get GENL msg %d times at %llu us!",
channel_cxt->id, GENL_MSG_CHECK_MAX_CNT, (cur_time_us - time_us));
time_us = 0;
GENL_msg_cnt = 0;
}
fd_set tmpRdFds = socketFds;
struct timeval timeout =
{GENL_MSG_GET_WAIT_MAX_TIME_MS / 1000, (GENL_MSG_GET_WAIT_MAX_TIME_MS % 1000) * 1000};
int nReadyCnt = select(channel_cxt->mSockFd+1, &tmpRdFds, NULL, NULL, &timeout);
if(nReadyCnt > 0)
{
if(FD_ISSET(channel_cxt->mSockFd, &tmpRdFds))
{
RTCbEvent stEvent;
int ret = awVideoInput_ReceiveGENLRTCbEvent(channel_cxt, &stEvent);
if(0 == ret)
{
GENL_msg_cnt++;
switch(stEvent.eEventType)
{
case RTCB_EVENT_VENC_DROP_FRAME:
{
if(channel_cxt->mCallback)
{
channel_cxt->mCallback(channel_cxt->mpAppData,
channel_cxt->id, AWVideoInput_Event_DropFrame,
stEvent.nData1, 0, NULL);
}
break;
}
default:
{
aw_loge("fatal error! chn[%d] receive unknown event type:%d",
channel_cxt->id, stEvent.eEventType);
break;
}
}
}
}
}
else if(nReadyCnt < 0)
{
aw_loge("fatal error! chn[%d] select fail[%d]", channel_cxt->id, nReadyCnt);
}
}
aw_logv("channel %d GENL recv thread exit!", channel_cxt->id);
return (void *)NULL;
}
void *AIISPThread(void * param)
{
AWChannel_cxt* channel_cxt = (AWChannel_cxt*)param;
char thread_name[32] = {0};
int ret = 0;
sprintf(thread_name, "AWAIISP%d", channel_cxt->id);
prctl(PR_SET_NAME, (unsigned long)thread_name, 0, 0, 0);
aw_logd("channel %d AIISP Thread enter\n", channel_cxt->id);
while (1)
{
if (channel_cxt->AIISP_thread_exit_flag)
break;
if (channel_cxt->enable_aiisp && channel_cxt->start_process_tdm_buf)
{
struct vin_isp_tdm_event_status tdm_status;
memset(&tdm_status, 0, sizeof(struct vin_isp_tdm_event_status));
ret = ioctl(channel_cxt->dev_fd, IOCTL_GET_TDM_BUF, &tdm_status);
if(ret == 0)
{
if (tdm_status.iommu_buf)
{
aw_logv("ch%d dev_id[%d] buf[%d] %p size:%d, fill_len:%d, head_len:%d, cb:%p", channel_cxt->id, tdm_status.dev_id,
tdm_status.buf_id, tdm_status.iommu_buf, tdm_status.buf_size, tdm_status.fill_len, tdm_status.head_len, channel_cxt->mTdmBufDoneCallback);
if (channel_cxt->mTdmBufDoneCallback)
{
channel_cxt->mTdmBufDoneCallback(&tdm_status);
}
else
{
ret = ioctl(channel_cxt->dev_fd, IOCTL_RETURN_TDM_BUF, &tdm_status);
if(ret != 0)
aw_loge("ch%d ioctl IOCTL_RETURN_TDM_BUF failed! ret=%d", channel_cxt->id, ret);
}
}
}
else
aw_loge("ch%d ioctl IOCTL_GET_TDM_BUF failed! ret=%d", channel_cxt->id, ret);
}
usleep(10*1000);
}
aw_logd("channel %d AIISP thread exit!", channel_cxt->id);
return (void *)NULL;
}
LIGHT_SENSOR_ATTR_S linear_lightadc[] = {
{275, 249, 21600, 256},
{475, 249, 17984, 304},
//{675, 230, 12000, 272},
{1374, 211, 6000, 320},
{1600, 197, 5248, 256},
{1615, 187, 3968, 256},
{1631, 175, 2848, 256},
{1638, 164, 2096, 256},
{1644, 156, 1680, 256},
{1648, 150, 1424, 256},
{1651, 144, 1200, 256},
{1655, 140, 1072, 256},
{1659, 132, 864, 256},
{1663, 126, 720, 256},
{1668, 118, 576, 256},
};
int isp_config_to_flash(void)
{
SENSOR_ISP_CONFIG_S *sensor_isp_cfg0, *sensor_isp_cfg1;
int fd = 0;
struct write4k_op_t write_4k;
fd = open("/dev/mtd0", O_RDWR);
if (fd < 0) {
aw_loge("open mtd error");
return -1;
}
sensor_isp_cfg0 = malloc(sizeof(SENSOR_ISP_CONFIG_S));
memset(sensor_isp_cfg0, 0, sizeof(SENSOR_ISP_CONFIG_S));
sensor_isp_cfg0->sign = SENSOR_0_SIGN;
sensor_isp_cfg0->crc = 0;
sensor_isp_cfg0->ver = 0;
sensor_isp_cfg0->light_enable = 0;
sensor_isp_cfg0->adc_mode = 0;
sensor_isp_cfg0->light_def = 900;
sensor_isp_cfg0->ircut_state = 0;
sensor_isp_cfg0->ir_mode = 0;
sensor_isp_cfg0->lv_liner_def = 200;
sensor_isp_cfg0->lv_hdr_def = 0;
sensor_isp_cfg0->width = 0;
sensor_isp_cfg0->height = 0;
sensor_isp_cfg0->mirror = 0;
sensor_isp_cfg0->filp = 0;
sensor_isp_cfg0->fps = 15;
sensor_isp_cfg0->wdr_mode = 0;
sensor_isp_cfg0->flicker_mode = 0;
sensor_isp_cfg0->venc_format = 0;
sensor_isp_cfg0->sensor_deinit = 0;
sensor_isp_cfg0->get_yuv_en = 0;
sensor_isp_cfg0->lightadc_debug_en = 0;
sensor_isp_cfg0->light_sensor_en = 1;
memcpy(sensor_isp_cfg0->linear, linear_lightadc, sizeof(linear_lightadc));
write_4k.start = ISP0_PARAM_OFFSET*512;
write_4k.buf = malloc(sizeof(SENSOR_ISP_CONFIG_S));
memset(write_4k.buf, 0, sizeof(SENSOR_ISP_CONFIG_S));
memcpy((void *)write_4k.buf, (void *)sensor_isp_cfg0, sizeof(SENSOR_ISP_CONFIG_S));
write_4k.len = sizeof(SENSOR_ISP_CONFIG_S);
ioctl(fd, MEMWRITE_4K, &write_4k);
free(sensor_isp_cfg0);
sensor_isp_cfg1 = malloc(sizeof(SENSOR_ISP_CONFIG_S));
memset(sensor_isp_cfg1, 0, sizeof(SENSOR_ISP_CONFIG_S));
sensor_isp_cfg1->sign = SENSOR_1_SIGN;
sensor_isp_cfg1->crc = 0;
sensor_isp_cfg1->ver = 0;
sensor_isp_cfg1->light_enable = 0;
sensor_isp_cfg1->adc_mode = 0;
sensor_isp_cfg1->light_def = 0;
sensor_isp_cfg1->ircut_state = 0;
sensor_isp_cfg1->ir_mode = 0;
sensor_isp_cfg1->lv_liner_def = 0;
sensor_isp_cfg1->lv_hdr_def = 0;
sensor_isp_cfg1->width = 0;
sensor_isp_cfg1->height = 0;
sensor_isp_cfg1->mirror = 0;
sensor_isp_cfg1->filp = 1;
sensor_isp_cfg1->fps = 20;
sensor_isp_cfg1->wdr_mode = 0;
sensor_isp_cfg1->flicker_mode = 0;
sensor_isp_cfg1->venc_format = 0;
sensor_isp_cfg1->sensor_deinit = 0;
write_4k.start = ISP1_PARAM_OFFSET*512;
memset(write_4k.buf, 0, sizeof(SENSOR_ISP_CONFIG_S));
memcpy((void *)write_4k.buf, (void *)sensor_isp_cfg1, sizeof(SENSOR_ISP_CONFIG_S));
write_4k.len = sizeof(SENSOR_ISP_CONFIG_S);
ioctl(fd, MEMWRITE_4K, &write_4k);
free(sensor_isp_cfg1);
free(write_4k.buf);
close(fd);
return 0;
}