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