|
|
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
#include <pthread.h>
|
|
|
#include <time.h>
|
|
|
#include <unistd.h>
|
|
|
|
|
|
#include "JZsdkLib.h"
|
|
|
#include "BaseConfig.h"
|
|
|
#include "JZsdk_usb_bulk/JZsdk_usb_bulk.h"
|
|
|
|
|
|
#include "IRCUT/ircut.h"
|
|
|
|
|
|
|
|
|
#ifdef RTK_MPP_STATUS_ON
|
|
|
#include "MediaProc/MultProc/RTK_mmp/RTK_mmp.h"
|
|
|
#include "MediaProc/MultProc/RTK_mmp/Dec/RTK_mmp_dec.h"
|
|
|
#include "MediaProc/MultProc/RTK_mmp/Enc/RTK_mmp_enc.h"
|
|
|
#include "MediaProc/Camera/Camera.h"
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef RTK_RGA_STATUS_ON
|
|
|
|
|
|
#include "MediaProc/RgaProc/RK_Rga/RK_Rga.h"
|
|
|
|
|
|
//c1的rga结构体
|
|
|
typedef struct C1_RgaInfo
|
|
|
{
|
|
|
//源图像
|
|
|
RK_RgaImage *src_img;
|
|
|
|
|
|
//裁剪图像
|
|
|
RK_RgaImage *corp_img;
|
|
|
|
|
|
//目标图像
|
|
|
RK_RgaImage *dst_img;
|
|
|
|
|
|
//放大倍数
|
|
|
int scale;
|
|
|
|
|
|
}C1_RgaInfo;
|
|
|
|
|
|
static C1_RgaInfo *g_C1_RgaIrcInfo = NULL;
|
|
|
static C1_RgaInfo *g_C1_RgaOptInfo = NULL;
|
|
|
|
|
|
static unsigned char *g_MixedIrc_Buffer = NULL;
|
|
|
|
|
|
static unsigned char *g_MixedOpt_Buffer = NULL;
|
|
|
static unsigned int g_MixedOptBuffer_UseFlag = JZ_FLAGCODE_OFF;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef MEDIA_PROC_CONFIG_STATUS_ON
|
|
|
|
|
|
#include "MediaProc/Camera/Cam_FrameCatch/Cam_FrameCatch.h"
|
|
|
#include "MediaProc/MediaParm.h"
|
|
|
#include "MediaProc/VideoMgmt/VideoStreamPush/VideoStream_Push.h"
|
|
|
#include "MediaProc/VideoMgmt/VideoMgmt.h"
|
|
|
#include "MediaProc/IRC_funtion/IRC_Param.h"
|
|
|
#include "MediaProc/IRC_funtion/IRC_funtion.h"
|
|
|
#include "MediaProc/MediaProc_Param.h"
|
|
|
|
|
|
|
|
|
|
|
|
static void *g_usb_index = NULL;
|
|
|
|
|
|
// 定义 昆腾的 帧头长度和帧头内容
|
|
|
#define FRAME_HEADER_SIZE 4
|
|
|
static const unsigned char FRAME_HEADER[FRAME_HEADER_SIZE] = {0xaa, 0xbb, 0xcc, 0xdd};
|
|
|
#define NSEC_PER_SEC 1000000000L //1秒的纳秒数
|
|
|
#define TARGET_FPS 30
|
|
|
|
|
|
static unsigned char FrameBuffer[FIRST_HEIGHT * FIRST_WIDTH *2]; //用于存储帧数据的缓冲区
|
|
|
static unsigned int FrameBufferLen = 0; //用于存储帧数据的长度
|
|
|
static FrameBuffer_UseFlag = JZ_FLAGCODE_OFF;
|
|
|
|
|
|
#ifdef RTK_RGA_STATUS_ON
|
|
|
static T_JZsdkReturnCode JZC1_RgaDeal(C1_RgaInfo *rga_info, int resize, unsigned char *image, unsigned int *imgage_size);
|
|
|
static T_JZsdkReturnCode JZC1_RgaInit(C1_RgaInfo **rgaInfo, int dst_width, int dst_height, int dst_format);
|
|
|
#endif
|
|
|
|
|
|
//数据推送函数
|
|
|
static T_JZsdkReturnCode JZC1_PushFrame(int CameraIndex, unsigned char* data, unsigned int data_len)
|
|
|
{
|
|
|
int currentIndex = VideoMgmt_GetVideoStreamFlowIndexNum(); //获取当前视频流索引
|
|
|
//无视频流
|
|
|
if (currentIndex == 0)
|
|
|
{
|
|
|
//不推送视频
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
//红外相机
|
|
|
if (currentIndex == VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST && CameraIndex == VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST)
|
|
|
{
|
|
|
|
|
|
//推送数据到流转模块
|
|
|
VideoMgmt_Single_FrameIn(data, data_len);
|
|
|
}
|
|
|
|
|
|
//光学相机
|
|
|
if(CameraIndex == VIDEOMGMT_STREAMING_FLOW_INDEX_SECOND && currentIndex == VIDEOMGMT_STREAMING_FLOW_INDEX_SECOND)
|
|
|
{
|
|
|
//推送数据到流转模块
|
|
|
VideoMgmt_Single_FrameIn(data, data_len);
|
|
|
}
|
|
|
|
|
|
//组合视频流
|
|
|
if (currentIndex == VIDEOMGMT_STREAMING_FLOW_INDEX_THIRD && CameraIndex == VIDEOMGMT_STREAMING_FLOW_INDEX_THIRD)
|
|
|
{
|
|
|
//推送数据到流转模块
|
|
|
VideoMgmt_Single_FrameIn(data, data_len);
|
|
|
}
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static T_JZsdkReturnCode JZC1_OptDeal(unsigned char *data, unsigned int data_len)
|
|
|
{
|
|
|
|
|
|
|
|
|
#ifdef RTK_MPP_STATUS_ON
|
|
|
|
|
|
//JZSDK_LOG_INFO("JZC1_OptDeal");
|
|
|
|
|
|
MppFrame yuv_data = NULL; //用于传递yuv数据的地址
|
|
|
MppPacket Packet = NULL;
|
|
|
|
|
|
//输入数据进入解码器
|
|
|
RTK_mmp_dec_input(JZsdk_RtkMmpGetDecHandleAddr(1), data, data_len, &yuv_data);
|
|
|
|
|
|
// int width = mpp_frame_get_width(yuv_data);
|
|
|
// int height = mpp_frame_get_height(yuv_data);
|
|
|
// int h_stride = mpp_frame_get_hor_stride(yuv_data);
|
|
|
// int v_stride = mpp_frame_get_ver_stride(yuv_data);
|
|
|
|
|
|
// JZSDK_LOG_INFO("w:%d h:%d hor:%d ver:%d",width,height,h_stride,v_stride);
|
|
|
|
|
|
//光学数据缩放
|
|
|
int resize = JZ_FLAGCODE_OFF;
|
|
|
Camera_param(JZ_FLAGCODE_GET, CAMERA_RESIZE, &resize);
|
|
|
|
|
|
//将size转化为倍数
|
|
|
int ZoomRatio = 0;
|
|
|
switch (resize)
|
|
|
{
|
|
|
case 0:
|
|
|
ZoomRatio = JZ_FLAGCODE_OFF;
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
ZoomRatio = 2;
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
ZoomRatio = 4;
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
ZoomRatio = 8;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
ZoomRatio = JZ_FLAGCODE_OFF;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (ZoomRatio != JZ_FLAGCODE_OFF)
|
|
|
{
|
|
|
|
|
|
MppBuffer temp = mpp_frame_get_buffer(yuv_data);
|
|
|
RK_U32 h = mpp_frame_get_hor_stride(yuv_data);
|
|
|
RK_U32 w = mpp_frame_get_ver_stride(yuv_data);
|
|
|
|
|
|
int size = (h * w * 1.5);
|
|
|
|
|
|
unsigned char *temp_data = (unsigned char *)malloc(size);
|
|
|
memcpy(temp_data, mpp_buffer_get_ptr(temp), size);
|
|
|
|
|
|
JZC1_RgaDeal(g_C1_RgaOptInfo, ZoomRatio, temp_data, &size);
|
|
|
|
|
|
//重新将数据放回
|
|
|
memcpy(mpp_buffer_get_ptr(temp), temp_data, size);
|
|
|
|
|
|
free(temp_data);
|
|
|
}
|
|
|
|
|
|
|
|
|
//将数据放入混合缓冲区
|
|
|
MppBuffer temp = mpp_frame_get_buffer(yuv_data);
|
|
|
if (g_MixedOpt_Buffer != NULL && g_MixedOptBuffer_UseFlag == JZ_FLAGCODE_OFF)
|
|
|
{
|
|
|
g_MixedOptBuffer_UseFlag = JZ_FLAGCODE_ON;
|
|
|
memcpy(g_MixedOpt_Buffer, mpp_buffer_get_ptr(temp), (mpp_frame_get_hor_stride(yuv_data) * mpp_frame_get_ver_stride(yuv_data) * 1.5));
|
|
|
g_MixedOptBuffer_UseFlag = JZ_FLAGCODE_OFF;
|
|
|
}
|
|
|
|
|
|
|
|
|
//将返回的数据输入进编码器
|
|
|
RTK_mmp_enc_yuv_to_h264_byFrame(JZsdk_RtkMmpGetEncHandleAddr(1), yuv_data, &Packet);
|
|
|
|
|
|
//获取数据指针与长度
|
|
|
int packet_len = mpp_packet_get_length(Packet);
|
|
|
void *ptr = mpp_packet_get_pos(Packet);
|
|
|
|
|
|
//推送视频流
|
|
|
JZC1_PushFrame(2, (unsigned char *)ptr, packet_len);
|
|
|
|
|
|
//释放掉编码图像
|
|
|
mpp_packet_deinit(&Packet);
|
|
|
#endif
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
//红外数据纠正函数, 暂定全部替换
|
|
|
static T_JZsdkReturnCode JZC1_Irc_DataCorrect(unsigned char *data)
|
|
|
{
|
|
|
//像素修正
|
|
|
data[0] = data[5];
|
|
|
data[1] = data[6];
|
|
|
data[2] = data[5];
|
|
|
data[3] = data[6];
|
|
|
}
|
|
|
|
|
|
|
|
|
//在这里将灰度图数据转换成目标数据
|
|
|
static T_JZsdkReturnCode JZC1_IrcDeal(unsigned char *data, unsigned int data_len)
|
|
|
{
|
|
|
//JZSDK_LOG_DEBUG("irc数据处理");
|
|
|
if (data_len == 0)
|
|
|
{
|
|
|
JZSDK_LOG_ERROR("无数据错误");
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
|
|
|
//红外数据纠正处理
|
|
|
JZC1_Irc_DataCorrect(data);
|
|
|
|
|
|
//将 8位的raw数据 合并为16位数据
|
|
|
U16_t * u16Data = (U16_t *)malloc(sizeof(U16_t) * (data_len / 2));
|
|
|
int u16DataSize = data_len / 2;
|
|
|
|
|
|
//JZSDK_LOG_DEBUG("data_len:%d u16DataSize:%d", data_len / 2, FIRST_HEIGHT * FIRST_WIDTH);
|
|
|
|
|
|
//合成像素,u8转换合并成u16
|
|
|
JZsdk_Merge_U8_to_U16_byReverse(data, data_len, u16Data, &u16DataSize);
|
|
|
|
|
|
//将灰度图数据转换为原始码流数据
|
|
|
unsigned char *raw_data = NULL;
|
|
|
int raw_data_len = 0;
|
|
|
|
|
|
//将原始码流数据转换为rgb数据
|
|
|
IRC_FrameDeal(u16Data, u16DataSize, &raw_data, &raw_data_len);
|
|
|
|
|
|
//获取放大的倍数
|
|
|
//光学数据缩放
|
|
|
int resize = JZ_FLAGCODE_OFF;
|
|
|
Camera_param(JZ_FLAGCODE_GET, CAMERA_RESIZE, &resize);
|
|
|
|
|
|
//将size转化为倍数
|
|
|
int ZoomRatio = 0;
|
|
|
switch (resize)
|
|
|
{
|
|
|
case 0:
|
|
|
ZoomRatio = JZ_FLAGCODE_OFF;
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
ZoomRatio = 2;
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
ZoomRatio = 4;
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
//红外做不了8倍放大咧
|
|
|
ZoomRatio = 4;
|
|
|
//ZoomRatio = 8;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
ZoomRatio = 0;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if (ZoomRatio != JZ_FLAGCODE_OFF)
|
|
|
{
|
|
|
JZC1_RgaDeal(g_C1_RgaIrcInfo, ZoomRatio, raw_data, &raw_data_len);
|
|
|
}
|
|
|
|
|
|
//将数据放入混合缓冲区
|
|
|
if (g_MixedIrc_Buffer != NULL)
|
|
|
{
|
|
|
memcpy(g_MixedIrc_Buffer, raw_data, raw_data_len);
|
|
|
}
|
|
|
|
|
|
//将原始码流数据写入到编码器 并转换为h264
|
|
|
unsigned char *h264Data = NULL;
|
|
|
unsigned int h264DataLen = 0;
|
|
|
|
|
|
#ifdef RTK_MPP_STATUS_ON
|
|
|
MppPacket Packet = NULL;
|
|
|
|
|
|
RTK_mmp_enc_data_to_h264(JZsdk_RtkMmpGetEncHandleAddr(0), raw_data, raw_data_len, &Packet);
|
|
|
|
|
|
h264DataLen = mpp_packet_get_length(Packet);
|
|
|
h264Data = (unsigned char *)mpp_packet_get_pos(Packet);
|
|
|
//EncCfg->Packet_eos = mpp_packet_get_eos(packet);
|
|
|
// printf("获取到编码内容 len:%d\n",packet_len);
|
|
|
|
|
|
//释放掉packet
|
|
|
mpp_packet_deinit(&Packet);
|
|
|
#endif
|
|
|
|
|
|
//将h264数据推送
|
|
|
JZC1_PushFrame(1, h264Data, h264DataLen);
|
|
|
|
|
|
//释放内存
|
|
|
if (raw_data != NULL)
|
|
|
{
|
|
|
free(raw_data);
|
|
|
raw_data = NULL;
|
|
|
}
|
|
|
|
|
|
if (u16Data != NULL)
|
|
|
{
|
|
|
free(u16Data);
|
|
|
u16Data = NULL;
|
|
|
}
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static void *JZC1_IrcDataBuffer_Thread(void *args)
|
|
|
{
|
|
|
|
|
|
struct timespec now;
|
|
|
|
|
|
//获取起始时间
|
|
|
struct timespec start_time;
|
|
|
clock_gettime(CLOCK_MONOTONIC, &start_time);
|
|
|
long long prev_time = start_time.tv_sec * NSEC_PER_SEC + start_time.tv_nsec;
|
|
|
|
|
|
//设置间隔时间
|
|
|
long long period = NSEC_PER_SEC / TARGET_FPS;
|
|
|
|
|
|
unsigned char *TempBuffer = (unsigned char *)malloc(163840);
|
|
|
unsigned int TempBufferLen = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
{
|
|
|
//获取当前时间
|
|
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
|
long long current_time = now.tv_sec * NSEC_PER_SEC + now.tv_nsec;
|
|
|
|
|
|
//计算时间差
|
|
|
long long elapsed_time = current_time - prev_time;
|
|
|
|
|
|
//超过33ms
|
|
|
if (elapsed_time >= period)
|
|
|
{
|
|
|
while (FrameBuffer_UseFlag == JZ_FLAGCODE_ON)
|
|
|
{
|
|
|
delayUs(100);
|
|
|
}
|
|
|
|
|
|
FrameBuffer_UseFlag = JZ_FLAGCODE_ON;
|
|
|
|
|
|
memset(TempBuffer, 0, sizeof(TempBuffer));
|
|
|
memcpy(TempBuffer, FrameBuffer, FrameBufferLen);
|
|
|
TempBufferLen = FrameBufferLen;
|
|
|
|
|
|
FrameBuffer_UseFlag = JZ_FLAGCODE_OFF;
|
|
|
|
|
|
//红外数据缓冲线程
|
|
|
JZC1_IrcDeal(TempBuffer, TempBufferLen);
|
|
|
|
|
|
prev_time = current_time;
|
|
|
}
|
|
|
|
|
|
// 为了防止过于频繁地调用 clock_gettime,可以添加一个小的睡眠时间
|
|
|
// 例如,休眠1毫秒(100000000纳秒),以减少CPU占用
|
|
|
struct timespec req = { .tv_sec = 0, .tv_nsec = 1000000 };
|
|
|
nanosleep(&req, NULL);
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
static T_JZsdkReturnCode JZC1_IrcDataSave(unsigned char *data, unsigned int data_len)
|
|
|
{
|
|
|
//避免缓冲区被同时操作
|
|
|
while (FrameBuffer_UseFlag == JZ_FLAGCODE_ON)
|
|
|
{
|
|
|
delayUs(100);
|
|
|
}
|
|
|
|
|
|
FrameBuffer_UseFlag = JZ_FLAGCODE_ON;
|
|
|
|
|
|
memset(FrameBuffer, 0, sizeof(FrameBuffer));
|
|
|
memcpy(FrameBuffer, data, data_len);
|
|
|
FrameBufferLen = data_len;
|
|
|
|
|
|
FrameBuffer_UseFlag = JZ_FLAGCODE_OFF;
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
//红外数据接收线程
|
|
|
static void *JZC1_IrcDataRecv_Thread(void *args)
|
|
|
{
|
|
|
int frame_len = FIRST_WIDTH *2* FIRST_HEIGHT; //163840
|
|
|
unsigned char buf[frame_len]; //usb数据缓冲区需要为512的倍数
|
|
|
unsigned char frameData[frame_len]; // 存储整帧数据的画面缓冲区
|
|
|
unsigned int lineNum = 0;
|
|
|
int frame = 0;
|
|
|
int frameDataLen = 0;//缓冲区的数据长度
|
|
|
|
|
|
/*****
|
|
|
*
|
|
|
* 数据格式说明
|
|
|
*
|
|
|
* 帧头 0xaa 0xbb 0x02 0x80 0x01 0x00 + 行数 如第一行0x00 0x01
|
|
|
* 数据包长度为 0x0280
|
|
|
* 数据包 一包的行数为256 0x0100
|
|
|
* 当前数据为第x行 x= 0x0001
|
|
|
* 两位数据为一个点
|
|
|
* 接着把前4个点的数据 用第五个点替换掉
|
|
|
* *****/
|
|
|
|
|
|
while (1)
|
|
|
{
|
|
|
int realLen;
|
|
|
memset(buf,0,sizeof(buf));
|
|
|
T_JZsdkReturnCode ret = JZsdk_HalUsbBulk_ReadData(&g_usb_index, buf, sizeof(buf), &realLen);
|
|
|
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
|
|
|
{
|
|
|
// 处理读取错误
|
|
|
JZSDK_LOG_ERROR("读取错误");
|
|
|
continue;
|
|
|
//return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
if (realLen != 0)
|
|
|
{
|
|
|
//JZSDK_LOG_INFO("读取到%d 字节",realLen);
|
|
|
}
|
|
|
|
|
|
//寻找数据是否存在帧头
|
|
|
for (int i = 0; i < realLen; i++)
|
|
|
{
|
|
|
// 验证帧头
|
|
|
if (memcmp(buf+i, FRAME_HEADER, FRAME_HEADER_SIZE) != 0)
|
|
|
{
|
|
|
// 帧头不匹配,可能是噪声或错误的数据包
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/**********************
|
|
|
*
|
|
|
* 方法一,将usb缓冲区调整大小 到超过640*256, 然后直接输出整段画面,避免重复复制,节省处理时间
|
|
|
*
|
|
|
* ******************************/
|
|
|
//如果查找到帧头
|
|
|
|
|
|
//查看是否是第0帧
|
|
|
if (frame == 0)
|
|
|
{
|
|
|
//重置掉画面缓冲区
|
|
|
memset(frameData,0,sizeof(frameData));
|
|
|
|
|
|
//将数据置于缓冲区
|
|
|
frameDataLen = (realLen-i);
|
|
|
memcpy( &frameData[0], buf + i, frameDataLen);
|
|
|
|
|
|
//让画面帧强跳到第一帧
|
|
|
frame = 1;
|
|
|
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//如果是第一帧
|
|
|
if (frame == 1)
|
|
|
{
|
|
|
memcpy( &frameData[frameDataLen], buf, frame_len-frameDataLen );
|
|
|
|
|
|
JZC1_IrcDataSave(frameData, frame_len);
|
|
|
|
|
|
frame = 2;
|
|
|
frameDataLen = 0;
|
|
|
//memset(frameData,0,sizeof(frameData));
|
|
|
}
|
|
|
|
|
|
|
|
|
//如果不是第1帧,且上段数据小于一画面段,说明为数据被切割
|
|
|
if ( i<frame_len)
|
|
|
{
|
|
|
//则于前端残余数据拼接,并输出
|
|
|
if (frame%2==0 && (frame != 1) )
|
|
|
{
|
|
|
|
|
|
memcpy( &frameData[frame_len-i], buf, i);
|
|
|
//将未处理raw数据放入缓冲区
|
|
|
|
|
|
//JZSDK_LOG_INFO("写入1 %d %x", i, frameData[20]);
|
|
|
|
|
|
JZC1_IrcDataSave(frameData, frame_len);
|
|
|
//JZSDK_LOG_INFO("放入数据到缓冲区");
|
|
|
//memset(frameData,0,sizeof(frameData));
|
|
|
}
|
|
|
frame++;
|
|
|
}
|
|
|
|
|
|
//如果剩余长度超出一画数据,将画面数据整段输出
|
|
|
if ( (i + frame_len) < realLen)
|
|
|
{
|
|
|
if (frame%2==0)
|
|
|
{
|
|
|
//JZSDK_LOG_INFO("写入2");
|
|
|
|
|
|
memcpy( &frameData[0], buf, frame_len);
|
|
|
|
|
|
//将未处理raw数据放入缓冲区
|
|
|
JZC1_IrcDataSave(frameData, frame_len);
|
|
|
//JZSDK_LOG_INFO("放入数据到缓冲区");
|
|
|
}
|
|
|
frame++;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//JZSDK_LOG_INFO("i:%d, frame_len:%d realLen:%d frame:%d",i,frame_len,realLen,frame);
|
|
|
|
|
|
//如果剩余数据小于一画,存进画面缓冲区
|
|
|
//memset(frameData,0,sizeof(frameData));
|
|
|
memcpy(frameData, buf+i, (realLen-i));
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//C1 红外相机数据的初始化
|
|
|
static T_JZsdkReturnCode JZsdk_JZC1_Irc_Data_Init()
|
|
|
{
|
|
|
T_JZsdkReturnCode ret;
|
|
|
|
|
|
//初始化接收的usb口
|
|
|
ret = JZsdk_HalUsbBulk_Init(&g_usb_index, 0, 0, LINUX_USB_PID, LINUX_USB_VID, USB_IN_POINT, USB_OUT_POINT);
|
|
|
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
|
|
|
{
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
//初始化usb接收线程
|
|
|
pthread_t ReadDataTask;
|
|
|
pthread_attr_t task_attribute; //线程属性
|
|
|
pthread_attr_init(&task_attribute); //初始化线程属性
|
|
|
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
|
|
|
int Urcdata_Protection = pthread_create(&ReadDataTask,&task_attribute,JZC1_IrcDataRecv_Thread,NULL); //线程
|
|
|
if(Urcdata_Protection != 0)
|
|
|
{
|
|
|
JZSDK_LOG_ERROR("创建视频usb线程失败!");
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
|
|
|
//初始化送usb数据去处理的线程
|
|
|
pthread_t BufferDataTask;
|
|
|
pthread_attr_t BufferDataTask_attribute; //线程属性
|
|
|
pthread_attr_init(&BufferDataTask_attribute); //初始化线程属性
|
|
|
pthread_attr_setdetachstate(&BufferDataTask_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
|
|
|
int bufferdata_Protection = pthread_create(&BufferDataTask,&BufferDataTask_attribute,JZC1_IrcDataBuffer_Thread,NULL); //线程
|
|
|
if(bufferdata_Protection != 0)
|
|
|
{
|
|
|
JZSDK_LOG_ERROR("创建usb缓冲失败!");
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************
|
|
|
*
|
|
|
* 混合视频说明
|
|
|
*
|
|
|
* 1920*1088 做处理 并输出为 1920*1080
|
|
|
* __________________________________________________________________
|
|
|
* |_________________________________ |
|
|
|
* | |________________________________|
|
|
|
* | | |
|
|
|
* | | 1920*1088 /2 960* 544 |
|
|
|
* | | |
|
|
|
* | 320*256 拉伸4到 1280*1024 | |
|
|
|
* | 裁剪出 3/4 到 960 * 768 | |
|
|
|
* | | |
|
|
|
* | |________________________________|
|
|
|
* |_________________________________| |
|
|
|
* |__________________________________________________________________|
|
|
|
*
|
|
|
* ******************/
|
|
|
|
|
|
|
|
|
/******************
|
|
|
*
|
|
|
* 混合视频处理
|
|
|
*
|
|
|
*
|
|
|
* ********************/
|
|
|
static void JZC1_MixedVideo_Deal()
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
static void *MixedVideo_Thread(void *args)
|
|
|
{
|
|
|
#ifdef RTK_RGA_STATUS_ON
|
|
|
struct timespec now;
|
|
|
int d_ret = 0;
|
|
|
|
|
|
//获取起始时间
|
|
|
struct timespec start_time;
|
|
|
clock_gettime(CLOCK_MONOTONIC, &start_time);
|
|
|
long long prev_time = start_time.tv_sec * NSEC_PER_SEC + start_time.tv_nsec;
|
|
|
|
|
|
//设置间隔时间
|
|
|
long long period = NSEC_PER_SEC / TARGET_FPS;
|
|
|
|
|
|
/***** 红外图像参数 **********************************************************************************************************/
|
|
|
|
|
|
//红外源图像
|
|
|
im_rect Irc_Rect;
|
|
|
Irc_Rect.x = 0;
|
|
|
Irc_Rect.y = 0;
|
|
|
Irc_Rect.width = JZ_ALIGN(FIRST_WIDTH, 16);
|
|
|
Irc_Rect.height = JZ_ALIGN(FIRST_HEIGHT, 16);
|
|
|
int IRc_Format = RK_FORMAT_YCbCr_420_SP;
|
|
|
|
|
|
//红外放大图像
|
|
|
im_rect Irc_ResizeRect;
|
|
|
Irc_ResizeRect.x = 0;
|
|
|
Irc_ResizeRect.y = 0;
|
|
|
Irc_ResizeRect.width = JZ_ALIGN(FIRST_WIDTH, 16) * 4;
|
|
|
Irc_ResizeRect.height = JZ_ALIGN(FIRST_HEIGHT, 16) * 4;
|
|
|
|
|
|
//红外裁剪区域
|
|
|
im_rect Irc_CropRect;
|
|
|
Irc_CropRect.width = Irc_ResizeRect.width / 4 * 3;
|
|
|
Irc_CropRect.height = Irc_ResizeRect.height / 4 * 3;
|
|
|
Irc_CropRect.x = (Irc_ResizeRect.width - Irc_CropRect.width)/2;
|
|
|
Irc_CropRect.y = (Irc_ResizeRect.height - Irc_CropRect.height)/2;
|
|
|
|
|
|
//红外源图像
|
|
|
RK_RgaImage *Irc_SrcImg = NULL;
|
|
|
RK_Rga_ImageInit(&Irc_SrcImg, Irc_Rect.width, Irc_Rect.height, IRc_Format, Irc_Rect.x, Irc_Rect.y, Irc_Rect.width, Irc_Rect.height);
|
|
|
|
|
|
//红外放大图像
|
|
|
RK_RgaImage *Irc_ResizeImg = NULL;
|
|
|
RK_Rga_ImageInit(&Irc_ResizeImg, Irc_ResizeRect.width, Irc_ResizeRect.height, IRc_Format, Irc_ResizeRect.x, Irc_ResizeRect.y, Irc_ResizeRect.width, Irc_ResizeRect.height);
|
|
|
|
|
|
//红外裁剪图像
|
|
|
RK_RgaImage *Irc_CropImg = NULL;
|
|
|
RK_Rga_ImageInit(&Irc_CropImg, Irc_CropRect.width, Irc_CropRect.height, IRc_Format, 0, 0, Irc_CropRect.width, Irc_CropRect.height);
|
|
|
|
|
|
/***** 光学图像参数 **********************************************************************************************************/
|
|
|
|
|
|
//光学源图像
|
|
|
im_rect Opt_Rect;
|
|
|
Opt_Rect.x = 0;
|
|
|
Opt_Rect.y = 0;
|
|
|
Opt_Rect.width = JZ_ALIGN(SECOND_WIDTH, 16);
|
|
|
Opt_Rect.height = JZ_ALIGN(SECOND_HEIGHT, 16);
|
|
|
int Opt_Format = RK_FORMAT_YCbCr_420_SP;
|
|
|
|
|
|
//光学源缩小图像
|
|
|
im_rect Opt_ResizeRect;
|
|
|
Opt_ResizeRect.x = 0;
|
|
|
Opt_ResizeRect.y = 0;
|
|
|
Opt_ResizeRect.width = JZ_ALIGN(SECOND_WIDTH, 16) / 2;
|
|
|
Opt_ResizeRect.height = JZ_ALIGN(SECOND_HEIGHT, 16) / 2;
|
|
|
|
|
|
//光学源图像
|
|
|
RK_RgaImage *Opt_SrcImg = NULL;
|
|
|
RK_Rga_ImageInit(&Opt_SrcImg, Opt_Rect.width, Opt_Rect.height, Opt_Format, Opt_Rect.x, Opt_Rect.y, Opt_Rect.width, Opt_Rect.height);
|
|
|
|
|
|
//光学的缩小图像
|
|
|
RK_RgaImage *Opt_ResizeImg = NULL;
|
|
|
RK_Rga_ImageInit(&Opt_ResizeImg, Opt_ResizeRect.width, Opt_ResizeRect.height, Opt_Format, Opt_ResizeRect.x, Opt_ResizeRect.y, Opt_ResizeRect.width, Opt_ResizeRect.height);
|
|
|
|
|
|
|
|
|
/***** 目标图像参数 ***************************************************************************************************/
|
|
|
|
|
|
//目标图像的矩形
|
|
|
im_rect Dst_Rect;
|
|
|
Dst_Rect.x = 0;
|
|
|
Dst_Rect.y = 0;
|
|
|
Dst_Rect.width = JZ_ALIGN(SECOND_WIDTH, 16);
|
|
|
Dst_Rect.height = JZ_ALIGN(SECOND_HEIGHT, 16);
|
|
|
int Dst_Format = RK_FORMAT_YCbCr_420_SP;
|
|
|
|
|
|
//目标图像中光学图像的矩形
|
|
|
im_rect Dst_OptRect;
|
|
|
Dst_OptRect.x = Dst_Rect.width / 2;
|
|
|
Dst_OptRect.y = Dst_Rect.height / 4;
|
|
|
Dst_OptRect.width = Opt_ResizeRect.width;
|
|
|
Dst_OptRect.height = Opt_ResizeRect.height;
|
|
|
|
|
|
//目标图像中红外图像的矩形
|
|
|
im_rect Dst_IrcRect;
|
|
|
Dst_IrcRect.x = 0;
|
|
|
Dst_IrcRect.y = (Dst_Rect.height - Irc_CropRect.height) / 2;
|
|
|
Dst_IrcRect.width = Irc_CropRect.width;
|
|
|
Dst_IrcRect.height = Irc_CropRect.height;
|
|
|
|
|
|
//目标图像
|
|
|
RK_RgaImage *DstImg = NULL;
|
|
|
RK_Rga_ImageInit(&DstImg, Dst_Rect.width, Dst_Rect.height, Dst_Format, Dst_Rect.x, Dst_Rect.y, Dst_Rect.width, Dst_Rect.height);
|
|
|
JZSDK_LOG_DEBUG("Dstimg witdh :%d height:%d DstImg->buf_size:%d", DstImg->width, DstImg->height, DstImg->buf_size);
|
|
|
|
|
|
//空缓冲区
|
|
|
rga_buffer_t EmptyImg = {0};
|
|
|
im_rect EmptyRect = {0};
|
|
|
|
|
|
//开始绘制画面,待优化,如多步骤合成为一个步骤
|
|
|
while (1)
|
|
|
{
|
|
|
//获取当前时间
|
|
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
|
long long current_time = now.tv_sec * NSEC_PER_SEC + now.tv_nsec;
|
|
|
|
|
|
//计算时间差
|
|
|
long long elapsed_time = current_time - prev_time;
|
|
|
|
|
|
//超过33ms
|
|
|
if (elapsed_time >= period)
|
|
|
{
|
|
|
if (g_MixedIrc_Buffer == NULL || g_MixedOpt_Buffer == NULL)
|
|
|
{
|
|
|
delayMs(100);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
while (g_MixedOptBuffer_UseFlag == JZ_FLAGCODE_ON)
|
|
|
{
|
|
|
delayUs(100);
|
|
|
}
|
|
|
|
|
|
g_MixedOptBuffer_UseFlag = JZ_FLAGCODE_ON;
|
|
|
|
|
|
//填充输出图像
|
|
|
memset(DstImg->buf, 0x80, DstImg->buf_size);
|
|
|
|
|
|
//混合视频处理
|
|
|
memset(Irc_SrcImg->buf, 0, Irc_SrcImg->buf_size);
|
|
|
memset(Opt_SrcImg->buf, 0, Opt_SrcImg->buf_size);
|
|
|
|
|
|
//将数据放入缓冲区
|
|
|
memcpy(Irc_SrcImg->buf, g_MixedIrc_Buffer, (JZ_ALIGN(FIRST_WIDTH, 16)) * (JZ_ALIGN(FIRST_HEIGHT, 16)) * 3 / 2);
|
|
|
memcpy(Opt_SrcImg->buf, g_MixedOpt_Buffer, JZ_ALIGN(SECOND_WIDTH, 16) * JZ_ALIGN(SECOND_HEIGHT, 16) * 3 / 2);
|
|
|
|
|
|
g_MixedOptBuffer_UseFlag = JZ_FLAGCODE_OFF;
|
|
|
|
|
|
//光学数据处理
|
|
|
//缩小图像到1/2
|
|
|
d_ret = imresize(Opt_SrcImg->img, Opt_ResizeImg->img);
|
|
|
if (d_ret != IM_STATUS_SUCCESS)
|
|
|
{
|
|
|
printf("irc resize failed\n");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//红外数据处理
|
|
|
//放大图像到4倍
|
|
|
d_ret = imresize(Irc_SrcImg->img, Irc_ResizeImg->img);
|
|
|
if (d_ret != IM_STATUS_SUCCESS)
|
|
|
{
|
|
|
printf("opt resize failed\n");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//裁切红外图像
|
|
|
d_ret = imcrop(Irc_ResizeImg->img, Irc_CropImg->img, Irc_CropRect);
|
|
|
if (d_ret != IM_STATUS_SUCCESS)
|
|
|
{
|
|
|
printf("opt crop failed\n");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//将缩放好的光学画面放入目标画面
|
|
|
d_ret = improcess(Opt_ResizeImg->img, DstImg->img, EmptyImg, Opt_ResizeRect, Dst_OptRect, EmptyRect, IM_SYNC);
|
|
|
if (d_ret != IM_STATUS_SUCCESS)
|
|
|
{
|
|
|
printf("opt improcess failed\n");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//将裁切好的红外画面放入目标画面
|
|
|
d_ret = improcess(Irc_CropImg->img, DstImg->img, EmptyImg, Irc_CropImg->rect, Dst_IrcRect, EmptyRect, IM_SYNC);
|
|
|
if (d_ret != IM_STATUS_SUCCESS)
|
|
|
{
|
|
|
printf("irc improcess failed\n");
|
|
|
}
|
|
|
|
|
|
//将原始码流数据写入到编码器 并转换为h264
|
|
|
unsigned char *h264Data = NULL;
|
|
|
unsigned int h264DataLen = 0;
|
|
|
|
|
|
//JZSDK_LOG_DEBUG("DstImg->buf_size:%d", DstImg->buf_size);
|
|
|
|
|
|
#ifdef RTK_MPP_STATUS_ON
|
|
|
MppPacket Packet = NULL;
|
|
|
|
|
|
RTK_mmp_enc_data_to_h264(JZsdk_RtkMmpGetEncHandleAddr(2), DstImg->buf, DstImg->buf_size, &Packet);
|
|
|
|
|
|
h264DataLen = mpp_packet_get_length(Packet);
|
|
|
h264Data = (unsigned char *)mpp_packet_get_pos(Packet);
|
|
|
//EncCfg->Packet_eos = mpp_packet_get_eos(packet);
|
|
|
// printf("获取到编码内容 len:%d\n",packet_len);
|
|
|
|
|
|
//释放掉packet
|
|
|
mpp_packet_deinit(&Packet);
|
|
|
#endif
|
|
|
|
|
|
//推送视频流
|
|
|
JZC1_PushFrame(VIDEOMGMT_STREAMING_FLOW_INDEX_THIRD, h264Data, h264DataLen);
|
|
|
|
|
|
//JZSDK_LOG_DEBUG("混合一帧 :%d", h264DataLen);
|
|
|
|
|
|
//更新时间
|
|
|
prev_time = current_time;
|
|
|
}
|
|
|
|
|
|
// 为了防止过于频繁地调用 clock_gettime,可以添加一个小的睡眠时间
|
|
|
// 例如,休眠1毫秒(100000000纳秒),以减少CPU占用
|
|
|
struct timespec req = { .tv_sec = 0, .tv_nsec = 1000000 };
|
|
|
nanosleep(&req, NULL);
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
|
|
|
/******************
|
|
|
*
|
|
|
* 混合视频初始化
|
|
|
*
|
|
|
*
|
|
|
* ********************/
|
|
|
static JZC1_MixedVideo_Init()
|
|
|
{
|
|
|
g_MixedIrc_Buffer = (unsigned char *)malloc(JZ_ALIGN(FIRST_WIDTH, 16)*JZ_ALIGN(FIRST_HEIGHT, 16)*3/2);
|
|
|
g_MixedOpt_Buffer = (unsigned char *)malloc(JZ_ALIGN(SECOND_WIDTH, 16)*JZ_ALIGN(SECOND_HEIGHT, 16)*3/2);
|
|
|
|
|
|
//混合视频初始化
|
|
|
pthread_t Task;
|
|
|
pthread_attr_t attribute; //线程属性
|
|
|
pthread_attr_init(&attribute); //初始化线程属性
|
|
|
pthread_attr_setdetachstate(&attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
|
|
|
int bufferdata_Protection = pthread_create(&Task,&attribute,MixedVideo_Thread,NULL); //线程
|
|
|
if(bufferdata_Protection != 0)
|
|
|
{
|
|
|
JZSDK_LOG_ERROR("创建混合视频初始化失败!");
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
|
|
|
JZSDK_LOG_INFO("MixedVidoe_Init Success");
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
//JZ_C1 的媒体初始化
|
|
|
static T_JZsdkReturnCode JZC1_MediaInit()
|
|
|
{
|
|
|
T_JZsdkReturnCode ret = JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
|
|
|
|
|
|
//初始化媒体模块
|
|
|
#ifdef MEDIA_PROC_CONFIG_STATUS_ON
|
|
|
|
|
|
//初始化videoMgmt模块
|
|
|
VideoMgmt_Init();
|
|
|
|
|
|
//初始化Mulit模块
|
|
|
#ifdef RTK_MPP_STATUS_ON
|
|
|
//初始化红外的编解码器
|
|
|
RTK_mmp_enc_Init(JZsdk_RtkMmpGetEncHandleAddr(0), MPP_VIDEO_CodingAVC, MPP_FMT_YUV420SP, FIRST_WIDTH, FIRST_HEIGHT, 30, 5);
|
|
|
|
|
|
//初始化光学的编解码器
|
|
|
RTK_mmp_dec_Init(JZsdk_RtkMmpGetDecHandleAddr(1), MPP_VIDEO_CodingMJPEG, MPP_FMT_YUV420SP, SECOND_WIDTH, SECOND_HEIGHT);
|
|
|
RTK_mmp_enc_Init(JZsdk_RtkMmpGetEncHandleAddr(1), MPP_VIDEO_CodingAVC, MPP_FMT_YUV420SP, SECOND_WIDTH, SECOND_HEIGHT, 30, 15);
|
|
|
|
|
|
// RTK_mmp_dec_Init(JZsdk_RtkMmpGetDecHandleAddr(1), MPP_VIDEO_CodingMJPEG, MPP_FMT_YUV420SP, SECOND_WIDTH, SECOND_HEIGHT);
|
|
|
// RTK_mmp_enc_Init(JZsdk_RtkMmpGetEncHandleAddr(1), MPP_VIDEO_CodingAVC, MPP_FMT_YUV420SP, SECOND_WIDTH, SECOND_HEIGHT, 30, 15);
|
|
|
|
|
|
//初始化混合视频流的编码器
|
|
|
RTK_mmp_enc_Init(JZsdk_RtkMmpGetEncHandleAddr(2), MPP_VIDEO_CodingAVC, MPP_FMT_YUV420SP, SECOND_WIDTH, SECOND_HEIGHT, 30, 15);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
//初始化Camera模块
|
|
|
int CameraFd = -1;
|
|
|
ret = V4l2_Camarainit2(&CameraFd, SECOND_WIDTH, SECOND_HEIGHT, 30);
|
|
|
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
|
|
|
{
|
|
|
JZSDK_LOG_ERROR("光学相机启动失败");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
//光学相机的抓取
|
|
|
ret = JZsdk_FrameCatch_Single(JZC1_OptDeal);
|
|
|
}
|
|
|
|
|
|
//初始化IRC_funtion模块
|
|
|
ret = IRC_ParamInit(FIRST_HEIGHT, FIRST_WIDTH, 25);
|
|
|
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
|
|
|
{
|
|
|
JZSDK_LOG_ERROR("初始化红外的数据处理失败");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//初始化红外的数据输入
|
|
|
ret = JZsdk_JZC1_Irc_Data_Init();
|
|
|
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
|
|
|
{
|
|
|
JZSDK_LOG_ERROR("红外相机初始化失败");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//设置默认参数
|
|
|
|
|
|
//默认推送红外摄像头 后续改成 红外+光学 的组合画面
|
|
|
VideoMgmt_VideoStreamFlowIndex(VIDEOMGMT_STREAMING_FLOW_INDEX_THIRD);
|
|
|
|
|
|
//设置快门为开
|
|
|
JZsdk_Camera_ShutterSwitch(JZ_FLAGCODE_ON);
|
|
|
|
|
|
//设置伪彩颜色为hot
|
|
|
int value = 8;
|
|
|
Camera_param(JZ_FLAGCODE_SET, CAMERA_PSEUDO_COLOR, &value);
|
|
|
|
|
|
//设置为默认输出模式
|
|
|
value = 0;
|
|
|
Camera_param(JZ_FLAGCODE_SET, CAMERA_PIXEL_PSEUDO_COLOR_MODE, &value);
|
|
|
|
|
|
//设置默认打开自动校正
|
|
|
value = JZ_FLAGCODE_ON;
|
|
|
Proc_IRC_param(JZ_FLAGCODE_SET, JZSDK_WIDGET_BAD_PIXEL_CORRECT_MODE, &value);
|
|
|
|
|
|
//初始化变焦模块
|
|
|
Cam_Zoom_Init();
|
|
|
|
|
|
//初始化RGA模块
|
|
|
#ifdef RTK_RGA_STATUS_ON
|
|
|
ret = JZC1_RgaInit(&g_C1_RgaIrcInfo, JZ_ALIGN(FIRST_WIDTH, 16), JZ_ALIGN(FIRST_HEIGHT, 16), RK_FORMAT_YCbCr_420_SP);
|
|
|
ret = JZC1_RgaInit(&g_C1_RgaOptInfo, JZ_ALIGN(SECOND_WIDTH, 16), JZ_ALIGN(SECOND_HEIGHT, 16), RK_FORMAT_YCbCr_420_SP);
|
|
|
|
|
|
//混合视频初始化
|
|
|
JZC1_MixedVideo_Init();
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
#ifdef RTK_RGA_STATUS_ON
|
|
|
|
|
|
static T_JZsdkReturnCode JZC1_RgaInit(C1_RgaInfo **rgaInfo, int dst_width, int dst_height, int dst_format)
|
|
|
{
|
|
|
|
|
|
|
|
|
//初始化rga结构体
|
|
|
(*rgaInfo) = (C1_RgaInfo *)malloc(sizeof(C1_RgaInfo));
|
|
|
if ((*rgaInfo) == NULL)
|
|
|
{
|
|
|
JZSDK_LOG_ERROR("RGA初始化失败");
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
|
|
|
int width = dst_width;
|
|
|
int height = dst_height;
|
|
|
int rect_x = 0;
|
|
|
int rect_y = 0;
|
|
|
int rect_w = dst_width;
|
|
|
int rect_h = dst_height;
|
|
|
|
|
|
|
|
|
(*rgaInfo)->src_img = NULL;
|
|
|
RK_Rga_ImageInit(&(*rgaInfo)->src_img, width, height, dst_format, rect_x, rect_y, rect_w, rect_h); //初始化输入模块
|
|
|
|
|
|
(*rgaInfo)->corp_img = NULL;
|
|
|
RK_Rga_ImageInit(&(*rgaInfo)->corp_img, width, height, dst_format, rect_x, rect_y, rect_w, rect_h); //初始化裁剪模块
|
|
|
|
|
|
(*rgaInfo)->dst_img = NULL;
|
|
|
RK_Rga_ImageInit(&(*rgaInfo)->dst_img, width, height, dst_format, rect_x, rect_y, rect_w, rect_h); //初始化输出模块
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
//rga处理
|
|
|
#ifdef RTK_RGA_STATUS_ON
|
|
|
static T_JZsdkReturnCode JZC1_RgaDeal(C1_RgaInfo *rga_info, int resize, unsigned char *image, unsigned int *imgage_size)
|
|
|
{
|
|
|
int d_ret;
|
|
|
|
|
|
|
|
|
if (g_C1_RgaIrcInfo == NULL || *imgage_size != rga_info->src_img->buf_size)
|
|
|
{
|
|
|
printf("C1_Rga_Deal failed imagesize:%d bufsize:%d\n", *imgage_size, rga_info->src_img->buf_size);
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
|
|
|
//检查裁剪倍数是否改变
|
|
|
if (resize != rga_info->scale)
|
|
|
{
|
|
|
rga_info->scale = resize;
|
|
|
|
|
|
//释放裁剪区域, 并重新注册
|
|
|
if (rga_info->corp_img != NULL)
|
|
|
{
|
|
|
RK_Rga_ImageDeInit(&(rga_info->corp_img));
|
|
|
|
|
|
int width = rga_info->src_img->width / resize;
|
|
|
int height = rga_info->src_img->height / resize;
|
|
|
int rect_x = (rga_info->src_img->width) / 2 - width / 2;
|
|
|
int rect_y = (rga_info->src_img->height) / 2 - height / 2;
|
|
|
int rect_w = width;
|
|
|
int rect_h = height;
|
|
|
int dst_format = rga_info->src_img->format;
|
|
|
|
|
|
RK_Rga_ImageInit(&(rga_info->corp_img), width, height, dst_format, rect_x, rect_y, rect_w, rect_h); //初始化裁剪模块
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//将图像放入处理器
|
|
|
memcpy(rga_info->src_img->buf, image, *imgage_size);
|
|
|
|
|
|
//JZSDK_LOG_DEBUG("裁剪倍率%d",resize);
|
|
|
|
|
|
if (resize == 0)
|
|
|
{
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
//裁剪图像
|
|
|
d_ret = imcrop(rga_info->src_img->img, rga_info->corp_img->img, rga_info->corp_img->rect);
|
|
|
if (d_ret != IM_STATUS_SUCCESS)
|
|
|
{
|
|
|
printf("crop failed resize:%d\n",resize);
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
|
|
|
//缩放图像
|
|
|
d_ret = imresize(rga_info->corp_img->img, rga_info->dst_img->img);
|
|
|
if (d_ret != IM_STATUS_SUCCESS)
|
|
|
{
|
|
|
printf("resize failed\n");
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
}
|
|
|
|
|
|
//返回图像
|
|
|
memcpy(image, rga_info->dst_img->buf, rga_info->dst_img->buf_size);
|
|
|
//printf("image[0]:%d image[1]:%d\n", image[0], image[1]);
|
|
|
*imgage_size = rga_info->dst_img->buf_size;
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
|
|
|
|
|
|
|
|
|
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
T_JZsdkReturnCode JZC1_Init()
|
|
|
{
|
|
|
T_JZsdkReturnCode ret;
|
|
|
|
|
|
//初始化引脚
|
|
|
Ircut_Init();
|
|
|
|
|
|
//初始化媒体模块
|
|
|
ret = JZC1_MediaInit();
|
|
|
|
|
|
JZSDK_LOG_INFO("JZ_C1 INIT COMPLETED\n");
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
...
|
...
|
|