作者 ookk303

210更新

... ... @@ -57,7 +57,13 @@
"videostream_push.h": "c",
"v4l2_record.h": "c",
"deviceinfo.h": "c",
"mediaproc.h": "c"
"mediaproc.h": "c",
"jzsdk_network.h": "c",
"kt_irc.h": "c",
"rtk_mmp_dec.h": "c",
"rtk_mmp_enc.h": "c",
"videostreamtranscode.h": "c",
"time.h": "c"
},
"Codegeex.GenerationPreference": "automatic",
"C_Cpp.dimInactiveRegions": false
... ...
# 编译链的配置
#1、编译链与设备类型的选择
set(DEVICE_NAME JZ_H150S)
set(DEVICE_NAME JZ_C1)
#上一行为禁止修改行
message("**************************JZSDK构建编译开始***************************\n")
... ...
... ... @@ -40,6 +40,13 @@ if(${DEVICE_INFO_MODULE} STREQUAL "VERSION_SWITCH_ON")
endif()
#如果要加载设备配置
if(${DEVICE_CONFIG_MODULE} STREQUAL "VERSION_SWITCH_ON")
message("\n设备配置源码加载中")
file(GLOB_RECURSE DEVICE_CONFOG_SRC ${ROOT_DIRS}Module/DeviceConfig/*.c)
list(APPEND ALL_SRC_FILES ${DEVICE_CONFOG_SRC})
endif()
#如果要加载云台模块,需要加载以下附属内容
if(${GIMBAL_MODULE} STREQUAL "VERSION_SWITCH_ON")
message("\n云台模块源码加载中")
... ...
... ... @@ -9,6 +9,9 @@ set(AUDIODEAL_MODULE VERSION_SWITCH_OFF)
# 信息模块
set(DEVICE_INFO_MODULE VERSION_SWITCH_OFF)
# 设备配置模块
set(DEVICE_CONFIG_MODULE VERSION_SWITCH_OFF)
# Gimbal 云台处理模块
set(GIMBAL_MODULE VERSION_SWITCH_OFF)
... ... @@ -57,12 +60,16 @@ set(IMAGEPROCESSING_MODULE VERSION_SWITCH_OFF)
# 添加信息模块
set(DEVICE_INFO_MODULE VERSION_SWITCH_ON)
# 添加设备配置模块
set(DEVICE_CONFIG_MODULE VERSION_SWITCH_ON)
# 添加UI管理模块
set(UI_CONTROL_MODULE VERSION_SWITCH_ON)
# 添加电源管理模块
set(POWER_MANAGER_MODULE VERSION_SWITCH_ON)
message("通用库加载完成")
########################### 独立库加载 ##########################################
... ...
... ... @@ -22,6 +22,7 @@
#include "JZsdk_haldata_deal/JZsdk_data_transmisson.h"
#include "MediaProc/MediaProc.h"
#include "UI_control/WidegMgmt/JZsdk_Widget.h"
#include "DeviceConfig/DeviceConfig.h"
#if APP_VERSION == APP_PSDK
#include "fc_subscription/test_fc_subscription.h"
... ... @@ -347,11 +348,8 @@ T_JZsdkReturnCode Main_APP_Psdk()
else if (DEVICE_VERSION == JZ_C1)
{
//引脚初始化
Ircut_Init();
//视频流模块初始化
MediaProc_Init();
//初始化C1
JZC1_Init();
}
... ...
... ... @@ -7,19 +7,19 @@
#define VERSION_CHOOSE_H
#include "./ConfigParams.h"
//1~10行 除了D可以修改版本选择 禁止动任何东西
#define DEVICE_VERSION JZ_H150S
#define DEVICE_VERSION JZ_C1
//禁止修改行 选择是串口程序 还是 psdk程序
#define APP_VERSION APP_PSDK
//禁止修改行 板子型号
#define PLATFORM_VERSION PLATFORM_H3
#define PLATFORM_VERSION PLATFORM_V3S
//禁止修改行 串口连接程序的软件版本号
#define MAJOR_VERSION 0x01
#define MINOR_VERSION 0x03
#define MODIFY_VERSION 0x09
#define DEBUG_VERSION 0x02
#define DEBUG_VERSION 0x05
//禁止修改行 滤波方式
#define FILTERING_TYPE HIGH_PASS_FILTERING
... ... @@ -48,6 +48,7 @@
//是否开启媒体功能
#ifdef MACRO_MEDIA_PROC_MODULE
#define MEDIA_PROC_CONFIG_STATUS VERSION_SWITCH_ON
#define MEDIA_PROC_CONFIG_STATUS_ON
#else
#define MEDIA_PROC_CONFIG_STATUS VERSION_SWITCH_OFF
#endif
... ... @@ -103,6 +104,7 @@
//是否开启媒体管理功能
#define MEDIA_PROC_CONFIG_STATUS VERSION_SWITCH_ON
#define MEDIA_PROC_CONFIG_STATUS_ON
//是否开启红外相机功能
#define IRC_CONFIG_STATUS VERSION_SWITCH_ON
... ...
/**
********************************************************************
* @file Kt_Irc.h
* Kt_Irc的头文件
* @file DeviceConfig.h
* DeviceConfig.h的头文件
*
*********************************************************************
*/
/* Define to prevent recursive inclusion 避免重定义 -------------------------------------*/
#ifndef KT_IRC_H
#define KT_IRC_H
#ifndef DEVICE_CONFIG_H
#define DEVICE_CONFIG_H
/* Includes ------------------------------------------------------------------*/
#include "JZsdk_Base/JZsdk_Code/JZsdk_Code.h"
#include "DeviceConfig/JZC1/JZC1.h"
/* Includes ------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
/* Exported constants --------------------------------------------------------*/
/* 常亮定义*/
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
T_JZsdkReturnCode JZsdk_Kt_Irc_Camera_Init();
T_JZsdkReturnCode JZsdk_Kt_Irc_ShutterSwitch(int value);
#ifdef __cplusplus
}
... ...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.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/Camera/Cam_FrameCatch/Cam_FrameCatch.h"
#include "MediaProc/MediaParm.h"
#include "MediaProc/MultProc/RTK_mmp/Dec/RTK_mmp_dec.h"
#include "MediaProc/MultProc/RTK_mmp/Enc/RTK_mmp_enc.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"
#endif
static void *g_usb_index = NULL;
// 定义 昆腾的 帧头长度和帧头内容
#define FRAME_HEADER_SIZE 4
static const unsigned char FRAME_HEADER[FRAME_HEADER_SIZE] = {0xaa, 0xbb, 0xcc, 0xdd};
//数据推送函数
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 == 1 && CameraIndex == 1)
{
//推送数据到流转模块
VideoMgmt_Single_FrameIn(data, data_len);
}
//光学相机
if(CameraIndex == 2 && currentIndex == 2)
{
//推送数据到流转模块
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)
{
//JZSDK_LOG_INFO("JZC1_OptDeal");
#ifdef RTK_MPP_STATUS_ON
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);
//将返回的数据输入进编码器
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数据处理");
//红外数据纠正处理
JZC1_Irc_DataCorrect(data);
//将灰度图数据转换为原始码流数据
unsigned char *raw_data = NULL;
int raw_data_len = 0;
IRC_FrameDeal(data, data_len, &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;
}
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_IrcDeal(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_IrcDeal(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_IrcDeal(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 opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZC1_IrcDataRecv_Thread,NULL); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建视频usb线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//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_YUV420P, FIRST_WIDTH, FIRST_HEIGHT, 25, 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);
#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_FIRST);
//设置快门为开
JZsdk_Camera_ShutterSwitch(JZ_FLAGCODE_ON);
//设置伪彩颜色
int value = 8;
Camera_param(JZ_FLAGCODE_SET, CAMERA_PSEUDO_COLOR, &value);
//设置伪彩模式
value = 1;
Camera_param(JZ_FLAGCODE_SET, CAMERA_PIXEL_PSEUDO_COLOR_MODE, &value);
#endif
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_JZsdkReturnCode JZC1_Init()
{
T_JZsdkReturnCode ret;
//初始化引脚
Ircut_Init();
//初始化媒体模块
ret = JZC1_MediaInit();
JZSDK_LOG_INFO("JZ_C1 INIT COMPLETED\n");
return ret;
}
... ...
/**
********************************************************************
* @file JZC1.h
* JZC1.h的头文件
*
*********************************************************************
*/
/* Define to prevent recursive inclusion 避免重定义 -------------------------------------*/
#ifndef JZC1_H
#define JZC1_H
#include "JZsdk_Base/JZsdk_Code/JZsdk_Code.h"
/* Includes ------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
/* Exported constants --------------------------------------------------------*/
/* 常亮定义*/
/* Exported types ------------------------------------------------------------*/
T_JZsdkReturnCode JZC1_Init();
#ifdef __cplusplus
}
#endif
#endif
... ...
... ... @@ -20,8 +20,8 @@ static int CameraFd = 0;
//临时方案 后续会改写法合并到t_JZsdk_TaskFuntionInput(搞起来有点麻烦)
typedef struct t_FrameCatch_TaskFuntionInput
{
void (*task_function)(void*); //任务函数指针,用于指定 执行的任务
void* data; //数据指针
void (*task_function)(unsigned char*, unsigned int); //任务函数指针,用于指定 执行的任务
unsigned* data; //数据指针
unsigned int data_size; //数据大小
} t_FrameCatch_TaskFuntionInput;
... ... @@ -71,12 +71,12 @@ T_JZsdkReturnCode JZsdk_FrameCatch_Init(int ThreadMode)
if (ThreadMode == 0)
{
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Catch_SingleThread,NULL); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建相机抓取并处理初始化线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
// int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Catch_SingleThread,NULL); //线程
// if(opus_Protection != 0)
// {
// JZSDK_LOG_ERROR("创建相机抓取并处理初始化线程失败!");
// return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
// }
}
else if (ThreadMode == 1)
{
... ... @@ -92,23 +92,51 @@ T_JZsdkReturnCode JZsdk_FrameCatch_Init(int ThreadMode)
}
/*******************************************************************************************************************************************/
//多线程抓取数据线程
static void *JZsdk_Catch_MultiThread2(void *args)
{
while (1)
{
unsigned int buf_size = 0;
unsigned char *buf = NULL;
//从相机中读取一张照片
V4L2_CameraFrameRecord_OnlyGetFrame(&buf, &buf_size);
//printf("read: len:%d data[3]:%x data[4]:%x\n", buf_size, buf[3], buf[4]);
if (buf == NULL)
{
JZSDK_LOG_ERROR("相机数据读取失败");
continue;
}
//放入缓冲池 //将数据放入缓冲池,从而被其他线程使用
VideoMgmt_write_data(&args, buf, buf_size);
//归还图片
V4L2_CameraFrameRecord_OnlyReturnFrame();
}
}
//单线程抓取数据线程
static void *JZsdk_Catch_SingleThread2(void *args)
{
t_FrameCatch_TaskFuntionInput *task = (t_FrameCatch_TaskFuntionInput *)args;
while (1)
{
task->task_function();
unsigned int buf_size = 0;
unsigned char *buf = NULL;
//从相机中读取一张照片
V4L2_CameraFrameRecord_OnlyGetFrame(&buf, &buf_size);
//printf("read: len:%d data[3]:%x data[4]:%x\n", buf_size, buf[3], buf[4]);
//JZSDK_LOG_INFO("read: len:%d data[3]:%x data[4]:%x\n", buf_size, buf[3], buf[4]);
if (buf == NULL)
{
... ... @@ -117,9 +145,7 @@ static void *JZsdk_Catch_SingleThread2(void *args)
}
//进行数据处理
VideoMgmt_Single_FrameIn(buf, buf_size);
task->task_function();
task->task_function(buf, buf_size);
//归还图片
V4L2_CameraFrameRecord_OnlyReturnFrame();
... ... @@ -130,13 +156,12 @@ static void *JZsdk_Catch_SingleThread2(void *args)
/********************************************
*
*
* 相机抓取初始化
* 相机抓取多线程单线程
*
* 传入线程的抓取模式 ThreadMode: 0为单线程 1为多线程
* 传入线程的处理函数 task_function
*
* *****************************************/
T_JZsdkReturnCode JZsdk_FrameCatch_Init2(int ThreadMode, T_JZsdkReturnCode (*task_function)(void*))
T_JZsdkReturnCode JZsdk_FrameCatch_Single(T_JZsdkReturnCode (*task_function)(unsigned char*, unsigned int))
{
T_JZsdkReturnCode ret;
... ... @@ -146,34 +171,61 @@ T_JZsdkReturnCode JZsdk_FrameCatch_Init2(int ThreadMode, T_JZsdkReturnCode (*tas
pthread_attr_init(&task_attribute); //初始化线程属性
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
//单线程模式
if (task_function == NULL)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
t_FrameCatch_TaskFuntionInput *task = (t_FrameCatch_TaskFuntionInput*)malloc(sizeof(t_FrameCatch_TaskFuntionInput));
if (task == NULL)
{
// 处理内存分配失败的情况
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
task->task_function = task_function;
task->args = NULL;
if (ThreadMode == 0)
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Catch_SingleThread2,(void *)task); //线程
if(opus_Protection != 0)
{
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Catch_SingleThread,(void *)task); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建相机抓取并处理初始化线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
JZSDK_LOG_ERROR("创建相机抓取并处理初始化线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
else if (ThreadMode == 1)
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/*************************
*
*
* 相机抓取多线程
*
*
* ******************/
T_JZsdkReturnCode JZsdk_FrameCatch_Multi(void *FrameIndex)
{
T_JZsdkReturnCode ret;
//初始化数据接收线程
pthread_t ReadDataTask;
pthread_attr_t task_attribute; //线程属性
pthread_attr_init(&task_attribute); //初始化线程属性
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
if (FrameIndex == NULL)
{
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Catch_MultiThread,(void *)task); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建相机抓取并处理初始化线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Catch_MultiThread2, FrameIndex); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建相机抓取并处理初始化线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
\ No newline at end of file
... ...
... ... @@ -25,7 +25,8 @@ extern "C" {
/* Exported functions --------------------------------------------------------*/
T_JZsdkReturnCode JZsdk_FrameCatch_Init(int ThreadMode);
T_JZsdkReturnCode JZsdk_FrameCatch_Single(T_JZsdkReturnCode (*task_function)(unsigned char*, unsigned int));
T_JZsdkReturnCode JZsdk_FrameCatch_Multi(void *FrameIndex);
#ifdef __cplusplus
... ...
... ... @@ -8,9 +8,9 @@
#include "./Camera.h"
#include "version_choose.h"
#include "BaseConfig.h"
#include "./Kt_Irc/Kt_Irc.h"
#include "../ImageProc/PseudoColor/PseudoColor.h"
#include "MediaProc/MediaProc_Param.h"
#include "Ircut/ircut.h"
#include "MediaProc/IRC_funtion/IRC_funtion.h"
... ... @@ -68,6 +68,8 @@ T_JZsdkReturnCode Camera_Init(int ThreadMode, int width, int height, int frame_n
}
//快门开关
/***********************************
*
... ... @@ -79,7 +81,20 @@ T_JZsdkReturnCode JZsdk_Camera_ShutterSwitch(int value)
{
T_JZsdkReturnCode ret;
#if DEVICE_VERSION == JZ_C1
ret = JZsdk_Kt_Irc_ShutterSwitch(value);
if (value == JZ_FLAGCODE_ON)
{
ret = SysfsGPIO_Set_ircut(KT_IRC_SHUTTER_GPIO_NUM, 1);
}
else if (value == JZ_FLAGCODE_OFF)
{
ret = SysfsGPIO_Set_ircut(KT_IRC_SHUTTER_GPIO_NUM, 0);
}
else
{
ret = JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
#else
ret = JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
#endif
... ...
#include <stdio.h>
#include "MediaProc.h"
#include "IrcC1.h"
#include "MediaParm.h"
#include "JZsdkLib.h"
#include "BaseConfig.h"
#ifdef RTK_MPP_STATUS_ON
#include "MediaProc/MultProc/RTK_mmp/RTK_mmp.h"
//c1的红外编码权柄
void *JZC1_Irc_enc_handle = NULL;
//c1的光学相机编码权柄
void *JZC1_Opt_enc_handle = NULL;
void *JZC1_Opt_dec_handle = NULL;
#endif
T_JZsdkReturnCode JZC1_Init()
{
T_JZsdkReturnCode ret = JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
#ifdef RTK_MPP_STATUS_ON
//1、初始化编解码模块
//初始化红外的编解码器
RTK_mmp_enc_Init(&JZC1_Irc_enc_handle, MPP_VIDEO_CodingAVC, MPP_FMT_YUV420P, FIRST_WIDTH, FIRST_HEIGHT, 25, 5);
//初始化光学的编解码器
RTK_mmp_enc_Init(&JZC1_Opt_enc_handle, MPP_VIDEO_CodingAVC, MPP_FMT_YUV420P, SECOND_WIDTH, SECOND_HEIGHT, 25, 5);
RTK_mmp_dec_Init(&JZC1_Opt_dec_handle, MPP_VIDEO_CodingAVC, MPP_FMT_YUV420P, SECOND_WIDTH, SECOND_HEIGHT, 30, 15);
//2、相机初始化
Camera_Init();
//初始化光学相机
ret = JZsdk_Kt_Camera_Init();
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("光学相机初始化失败");
}
else
{
//初始化数据转换模块
JZsdk_Kt_Cam_DataDeal_Init();
}
#endif
}
\ No newline at end of file
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "JZsdkLib.h"
#include "version_choose.h"
#include "BaseConfig.h"
#include "JZsdk_usb_bulk/JZsdk_usb_bulk.h"
#include "../V4L2_camera/V4L2_Record.h"
#include "../../MultProc/MultProc.h"
#include "../../MediaParm.h"
#include "../../VideoMgmt/VideoMgmt.h"
#include "Ircut/ircut.h"
#include "../Camera.h"
#include "UI_control/UI_control.h"
#include "../../IRC_funtion/IRC_Param.h"
#include "../../IRC_funtion/IRC_funtion.h"
#define IRC_WIDTH FIRST_WIDTH
#define IRC_HEIGHT FIRST_HEIGHT
#define CAMERA_WIDTH SECOND_WIDTH
#define CAMERA_HEIGHT SECOND_HEIGHT
static int Kt_Camera_fd;
extern IRC_param *g_IRC_Param;
#define IRC_WIDTH FIRST_WIDTH
#define IRC_HEIGHT FIRST_HEIGHT
// 定义帧头长度和帧头内容
#define FRAME_HEADER_SIZE 4
static const unsigned char FRAME_HEADER[FRAME_HEADER_SIZE] = {0xaa, 0xbb, 0xcc, 0xdd};
static void *Irc_usb_index = NULL;
//红外数据纠正函数, 暂定全部替换
T_JZsdkReturnCode Kt_Irc_DataCorrect(unsigned char *data)
{
//像素修正
data[0] = data[5];
data[1] = data[6];
data[2] = data[5];
data[3] = data[6];
}
//红外数据接收线程
static void *JZsdk_Kt_Irc_DataRecv_Thread(void *args)
{
int frame_len = IRC_WIDTH*2*IRC_HEIGHT; //163840
unsigned char buf[163840]; //usb数据缓冲区需要为512的倍数 4194304 后续考虑为 262144
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(&Irc_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 );
VideoMgmt_write_data(&VideoMgmt_FirstRaw_index, 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]);
VideoMgmt_write_data(&VideoMgmt_FirstRaw_index, 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数据放入缓冲区
VideoMgmt_write_data(&VideoMgmt_FirstRaw_index, 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;
}
}
}
//红外相机数据的初始化
T_JZsdkReturnCode JZsdk_Kt_Irc_Data_Init()
{
T_JZsdkReturnCode ret;
//初始化接收的usb口
ret = JZsdk_HalUsbBulk_Init(&Irc_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 opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Kt_Irc_DataRecv_Thread,NULL); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建视频usb线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//红外数据的处理
static void *JZsdk_Kt_Irc_DataDeal_Thread(void *args)
{
int DealFrameNum = 0;
unsigned char BaseBuffer[IRC_WIDTH*2*IRC_HEIGHT];
while (1)
{
unsigned char *gary_data = NULL;
unsigned int gary_data_len;
//1、从原始流缓冲区中取出raw数据
VideoMgmt_read_data(&VideoMgmt_FirstRaw_index, &gary_data, &gary_data_len,JZ_FLAGCODE_OFF ,JZ_FLAGCODE_OFF);
//2、红外数据纠正处理
Kt_Irc_DataCorrect(gary_data);
//3、将灰度图数据转换为原始码流数据
unsigned char *raw_data = NULL;
int raw_data_len = 0;
IRC_FrameDeal(gary_data, gary_data_len, &raw_data, &raw_data_len);
//4、将原始码流数据转换成h264流,为避免多次复制,这里的h264会直接放入视频流管理的缓冲区
JZsdk_RTKMMP_RawData_to_h264(raw_data, raw_data_len);
//5、释放内存
if (raw_data != NULL)
{
if (raw_data != NULL)
{
free(raw_data);
raw_data = NULL;
}
if (gary_data != NULL)
{
}
if (gary_data != NULL)
{
free(gary_data);
gary_data = NULL;
}
}
//JZSDK_LOG_DEBUG("得到了一帧红外h264");
}
}
//红外相机数据的处理线程
static T_JZsdkReturnCode JZsdk_Kt_Irc_DataDeal_Init()
{
pthread_t ReadDataTask;
pthread_attr_t task_attribute; //线程属性
pthread_attr_init(&task_attribute); //初始化线程属性
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Kt_Irc_DataDeal_Thread,NULL); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建红外相机数据的处理线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//光学相机数据的处理线程
static void *JZsdk_Kt_Cam_DataDeal_Thread(void *args)
{
int DealFrameNum = 0;
while (1)
{
unsigned char *raw_data = NULL;
unsigned int raw_data_len;
//1、从原始流缓冲区中取出raw数据
VideoMgmt_read_data(&VideoMgmt_SecondRaw_index, &raw_data, &raw_data_len,JZ_FLAGCODE_OFF ,JZ_FLAGCODE_OFF);
//2、将raw数据流转换成h264流,并放置到视频流缓冲区
JZsdk_Kt_CamMMP_Mjpeg_to_h264(raw_data, raw_data_len);
free(raw_data);
raw_data = NULL;
//DealFrameNum++;
//printf("get Cam Frame%d\n",DealFrameNum);
}
}
//光学相机数据的处理线程
static T_JZsdkReturnCode JZsdk_Kt_Cam_DataDeal_Init()
{
pthread_t ReadDataTask;
pthread_attr_t task_attribute; //线程属性
pthread_attr_init(&task_attribute); //初始化线程属性
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Kt_Cam_DataDeal_Thread,NULL); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建红外相机数据的处理线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//光学相机数据读取线程
static void *JZsdk_Kt_Cam_Data_Thread(void *args)
{
while (1)
{
unsigned int buf_size = 0;
unsigned char *buf = NULL;
//从相机中读取一张照片
V4L2_CameraFrameRecord_OnlyGetFrame(&buf, &buf_size);
if (buf == NULL)
{
JZSDK_LOG_ERROR("相机数据读取失败");
continue;
}
//放入缓冲池
VideoMgmt_write_data(&VideoMgmt_SecondRaw_index, buf, buf_size);
//归还图片
V4L2_CameraFrameRecord_OnlyReturnFrame();
}
}
//光学相机初始化
static T_JZsdkReturnCode JZsdk_Kt_Camera_Init()
{
T_JZsdkReturnCode ret;
//初始化摄像头
ret = V4l2_Camarainit2(&Kt_Camera_fd,CAMERA_WIDTH,CAMERA_HEIGHT,30);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
return ret;
}
//初始化数据接收线程
pthread_t ReadDataTask;
pthread_attr_t task_attribute; //线程属性
pthread_attr_init(&task_attribute); //初始化线程属性
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Kt_Cam_Data_Thread,NULL); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建v4l2线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//昆腾相机初始化
T_JZsdkReturnCode JZsdk_Kt_Irc_Camera_Init()
{
T_JZsdkReturnCode ret;
//1、初始化光学相机
ret = JZsdk_Kt_Camera_Init();
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("光学相机初始化失败");
}
else
{
//初始化数据转换模块
JZsdk_Kt_Cam_DataDeal_Init();
}
//2、初始化红外的数据处理
ret = IRC_ParamInit(&g_IRC_Param, IRC_HEIGHT, IRC_WIDTH, 25);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("初始化红外的数据处理失败");
}
//3、初始化红外的数据输入
ret = JZsdk_Kt_Irc_Data_Init();
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("红外相机初始化失败");
}
else
{
//初始化数据转换模块
JZsdk_Kt_Irc_DataDeal_Init();
}
JZSDK_LOG_INFO("KT_Irc init complete");
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//昆腾的红外相机的快门开关
/***********************************
*
* value on为开 off为关
*
*
* ***************************************/
T_JZsdkReturnCode JZsdk_Kt_Irc_ShutterSwitch(int value)
{
T_JZsdkReturnCode ret;
if (value == JZ_FLAGCODE_ON)
{
ret = SysfsGPIO_Set_ircut(KT_IRC_SHUTTER_GPIO_NUM, 1);
}
else if (value == JZ_FLAGCODE_OFF)
{
ret = SysfsGPIO_Set_ircut(KT_IRC_SHUTTER_GPIO_NUM, 0);
}
else
{
ret = JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return ret;
}
... ... @@ -30,11 +30,11 @@ static T_JZsdkReturnCode IRC_param_Init(struct IRC_param **index, int height, in
备注:
*/
T_JZsdkReturnCode IRC_ParamInit(struct IRC_param **index, int height, int width, int frameRate)
T_JZsdkReturnCode IRC_ParamInit(int height, int width, int frameRate)
{
T_JZsdkReturnCode ret;
IRC_param_Init(index, height, width, frameRate);
ret = IRC_param_Init(&g_IRC_Param, height, width, frameRate);
if (g_IRC_Param->DealWay ==IRC_DEALMODE_KTLIB)
{
... ... @@ -66,7 +66,7 @@ static T_JZsdkReturnCode IRC_data_PreliminaryDeal(U8_t *rawData , int dataSize,
ret = JZsdk_Merge_U8_to_U16_byReverse(rawData, dataSize, returnData, returnDataSize);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS || *returnDataSize != dealInfo->PixelNum)
{
JZSDK_LOG_ERROR("像素合成失败");
JZSDK_LOG_ERROR("像素合成失败, ret:0x%x dataSize:%d returnDataSize:%d PixelNum:%d", ret, dataSize,*returnDataSize, dealInfo->PixelNum);
return ret;
}
... ...
... ... @@ -26,7 +26,7 @@ extern "C" {
/* Exported functions --------------------------------------------------------*/
T_JZsdkReturnCode IRC_ParamInit(struct IRC_param **index, int height, int width, int frameRate);
T_JZsdkReturnCode IRC_ParamInit(int height, int width, int frameRate);
T_JZsdkReturnCode IRC_FrameDeal(unsigned char *rawData ,unsigned int dataSize, unsigned char **outData, unsigned int *outDataSize);
T_JZsdkReturnCode IRC_SetRawPixel_ResetFlag();
... ...
... ... @@ -116,6 +116,7 @@ T_JZsdkReturnCode PseudoColor_Gray2Rgb(U8_t *in_str, U8_t **out_str, unsigned in
{
if (P_Color_FinishFlag != JZ_FLAGCODE_ON)
{
JZSDK_LOG_ERROR("伪彩配置文件未初始化");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
... ... @@ -123,6 +124,7 @@ T_JZsdkReturnCode PseudoColor_Gray2Rgb(U8_t *in_str, U8_t **out_str, unsigned in
*out_str = (unsigned char*)malloc(*out_str_len * sizeof(unsigned char));
if (out_str == NULL)
{
JZSDK_LOG_ERROR("内存分配失败");
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
... ...
... ... @@ -12,7 +12,6 @@
#include "./MultProc/MultProc.h"
#include "./MediaParm.h"
#include "./Camera/Camera.h"
#include "./Camera/Kt_Irc/Kt_Irc.h"
//单线程方案
static T_JZsdkReturnCode MediaProc_SingleThreading()
... ... @@ -26,13 +25,6 @@ static T_JZsdkReturnCode MediaProc_SingleThreading()
//2、转码模块初始化
VideoStreamTransCode_Init();
}
//如果是昆腾相机 红外+光学 则红外为1号,光学为2号
if (DEVICE_VERSION == JZ_C1)
{
//1、初始化编解码处理模块
JZsdk_Kt_IrcMMP_Init(FIRST_WIDTH ,FIRST_HEIGHT, 25, 5 ,SECOND_WIDTH ,SECOND_HEIGHT, 30, 15);
}
}
//多线程方案
... ... @@ -55,41 +47,6 @@ static T_JZsdkReturnCode MediaProc_MultiThreading()
VideoMgmt_VideoStreamFlowIndex(VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST); //默认推送光学摄像头
}
//如果是昆腾相机 红外+光学 则红外为1号,光学为2号
if (DEVICE_VERSION == JZ_C1)
{
//1、启动视频流缓冲区模块
VideoMgmt_init_buffer(&VideoMgmt_FirstVideo_index);
VideoMgmt_init_buffer(&VideoMgmt_FirstRaw_index);
VideoMgmt_init_buffer(&VideoMgmt_SecondVideo_index);
VideoMgmt_init_buffer(&VideoMgmt_SecondRaw_index);
//2、初始化编解码处理模块
JZsdk_Kt_IrcMMP_Init(FIRST_WIDTH ,FIRST_HEIGHT, 25, 5 ,SECOND_WIDTH ,SECOND_HEIGHT, 30, 15);
//3、相机初始化
JZsdk_Kt_Irc_Camera_Init();
//4、启用推流模块
VideoMgmt_VideoStreamFlow_Init(25, &VideoMgmt_FirstVideo_index, VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST);
VideoMgmt_VideoStreamFlow_Init(30, &VideoMgmt_SecondVideo_index, VIDEOMGMT_STREAMING_FLOW_INDEX_SECOND);
//转码模块
VideoStreamTransCode_Init();
//5、打开默认选项
VideoMgmt_VideoStreamFlowIndex(VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST); //默认推送红外摄像头 后续改成 红外+光学 的组合画面
JZsdk_Kt_Irc_ShutterSwitch(JZ_FLAGCODE_ON);
//6、修改部分参数
int value = 8;
Camera_param(JZ_FLAGCODE_SET, CAMERA_PSEUDO_COLOR, &value);
value = 1;
Camera_param(JZ_FLAGCODE_SET, CAMERA_PIXEL_PSEUDO_COLOR_MODE, &value);
}
}
//视频流模块初始化
... ... @@ -98,8 +55,6 @@ T_JZsdkReturnCode MediaProc_Init()
#if DEVICE_VERSION == JZ_H150S || DEVICE_VERSION == JZ_H150T
MediaProc_SingleThreading();
# elif DEVICE_VERSION == JZ_C1
MediaProc_MultiThreading();
#endif
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
... ...
... ... @@ -7,75 +7,52 @@
#include "version_choose.h"
#include "MediaProc/VideoMgmt/VideoMgmt.h"
void *Kt_Irc_enc_index = NULL; //昆腾红外编码器的索引值
void *Kt_Cam_enc_index = NULL; //昆腾光学编码器的索引值
void *Kt_Cam_dec_index = NULL; //昆腾光学解码器的索引值
//c1 0是红外权柄 1是光学权柄 2为空权柄
static void *RtkMmpEncHandle[3] = { NULL }; // 所有元素都被初始化为NULL
static void *RtkMmpDecHandle[3] = { NULL }; // 所有元素都被初始化为NULL
//昆腾红外相机的mmp初始化部分
T_JZsdkReturnCode JZsdk_Kt_IrcMMP_Init(int Irc_width, int Irc_height, int Irc_frame, int Irc_gop, int Cam_width, int Cam_height, int Cam_frame,int Cam_gop)
{
#if RTK_MPP_STATUS == VERSION_SWITCH_ON
//初始化红外数据的编码器
RTK_mmp_enc_Init(&Kt_Irc_enc_index, MPP_VIDEO_CodingAVC, MPP_FMT_YUV420P, Irc_width, Irc_height, Irc_frame, Irc_gop);
//RTK_mmp_enc_Init(&Kt_Irc_enc_index, MPP_VIDEO_CodingAVC, MPP_FMT_RGB888, Irc_width, Irc_height, Irc_frame);
/*
rtk模块获取编码权柄
属于参数即可权柄
//初始化光学数据的编解码器
RTK_mmp_dec_Init(&Kt_Cam_dec_index, MPP_VIDEO_CodingMJPEG, MPP_FMT_YUV420SP, Cam_width, Cam_height);
RTK_mmp_enc_Init(&Kt_Cam_enc_index, MPP_VIDEO_CodingAVC, MPP_FMT_YUV420SP, Cam_width, Cam_height, Cam_frame, Cam_gop);
#endif
*/
void *JZsdk_RtkMmpGetEncHandle(int CameraIndex)
{
return RtkMmpEncHandle[CameraIndex];
}
//原始视频流通过rtkmmp转为h264
T_JZsdkReturnCode JZsdk_RTKMMP_RawData_to_h264(unsigned char *RawData, int data_len)
{
#if RTK_MPP_STATUS == VERSION_SWITCH_ON
MppPacket Packet = NULL;
RTK_mmp_enc_data_to_h264(&Kt_Irc_enc_index, RawData, data_len, &Packet);
int packet_len = mpp_packet_get_length(Packet);
void *ptr = mpp_packet_get_pos(Packet);
//EncCfg->Packet_eos = mpp_packet_get_eos(packet);
// printf("获取到编码内容 len:%d\n",packet_len);
//3、将h264流输出到视频流缓冲区
VideoMgmt_write_data(&VideoMgmt_FirstVideo_index, ptr, packet_len);
/*
rtk模块获取解码权柄
属于参数即可权柄
//释放掉packet
mpp_packet_deinit(&Packet);
#endif
*/
void *JZsdk_RtkMmpGetDecHandle(int CameraIndex)
{
return RtkMmpDecHandle[CameraIndex];
}
//昆腾光学相机数据输入部分
T_JZsdkReturnCode JZsdk_Kt_CamMMP_Mjpeg_to_h264(unsigned char *data, int data_len)
/*********
*
* 返回dec权柄地址
*
*
* ***/
void **JZsdk_RtkMmpGetDecHandleAddr(int CameraIndex)
{
#if RTK_MPP_STATUS == VERSION_SWITCH_ON
MppFrame yuv_data = NULL; //用于传递yuv数据的地址
MppPacket Packet = NULL;
//输入数据进入解码器
RTK_mmp_dec_input(&Kt_Cam_dec_index, 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);
//将返回的数据输入进编码器
RTK_mmp_enc_yuv_to_h264_byFrame(&Kt_Cam_enc_index, yuv_data, &Packet);
//获取数据指针与长度
int packet_len = mpp_packet_get_length(Packet);
void *ptr = mpp_packet_get_pos(Packet);
//置入视频缓冲区
VideoMgmt_write_data(&VideoMgmt_SecondVideo_index, (unsigned char *)ptr, (unsigned int)packet_len);
return &(RtkMmpDecHandle[CameraIndex]);
}
//释放掉编码图像
mpp_packet_deinit(&Packet);
#endif
/*********
*
* 返回enc权柄地址
*
*
* ***/
void **JZsdk_RtkMmpGetEncHandleAddr(int CameraIndex)
{
return &(RtkMmpEncHandle[CameraIndex]);
}
//昆腾相机设置下一帧为I帧
... ... @@ -84,11 +61,11 @@ T_JZsdkReturnCode JZsdk_Kt_CamMMPenc_SetNextFrame_IDR(int CameraIndex)
#if RTK_MPP_STATUS == VERSION_SWITCH_ON
if (CameraIndex == 0)
{
RTK_mmp_enc_SetNextFrame_IDR(&Kt_Irc_enc_index);
RTK_mmp_enc_SetNextFrame_IDR(JZsdk_RtkMmpGetEncHandleAddr(0));
}
else if(CameraIndex == 1)
{
RTK_mmp_enc_SetNextFrame_IDR(&Kt_Cam_enc_index);
RTK_mmp_enc_SetNextFrame_IDR(JZsdk_RtkMmpGetEncHandleAddr(1));
}
else
{
... ...
... ... @@ -35,9 +35,17 @@ extern "C" {
/* Exported functions --------------------------------------------------------*/
T_JZsdkReturnCode JZsdk_Kt_CamMMP_Mjpeg_to_h264(unsigned char *data, int data_len);
T_JZsdkReturnCode JZsdk_RTKMMP_RawData_to_h264(unsigned char *RawData, int data_len);
T_JZsdkReturnCode JZsdk_RTKMMP_RawData_to_h264_Return(void **index, unsigned char *RawData, int *data_len);
T_JZsdkReturnCode JZsdk_Kt_IrcMMP_Init(int Irc_width, int Irc_height, int Irc_frame, int Irc_gop, int Cam_width, int Cam_height, int Cam_frame,int Cam_gop);
T_JZsdkReturnCode JZsdk_Kt_CamMMPenc_SetNextFrame_IDR(int CameraIndex);
void *JZsdk_RtkMmpGetEncHandle(int CameraIndex);
void *JZsdk_RtkMmpGetDecHandle(int CameraIndex);
void **JZsdk_RtkMmpGetDecHandleAddr(int CameraIndex);
void **JZsdk_RtkMmpGetEncHandleAddr(int CameraIndex);
#ifdef __cplusplus
... ...
... ... @@ -32,6 +32,11 @@
JZ_VideoStreamUseStatus g_VideoStreamDealStatus = VIDEO_STREAM_IDLE; //视频流的处理状态
static int g_VideoFreezeFlag = JZ_FLAGCODE_OFF; //视频流冻结功能
static int g_VideoFreeze_PlayFlag = JZ_FLAGCODE_OFF; //视频流冻结功能的传输flag
//视频流冻结的缓存区
static unsigned char *g_FreezeData = NULL; //当前使用的缓存区
static unsigned int FreezeDataLen = 0;
/*********************************************************************************************************************************************
*
... ... @@ -44,6 +49,8 @@ static int g_VideoFreezeFlag = JZ_FLAGCODE_OFF; //视频流冻结功能
static int g_VideoStreamFlowIndexNum = JZ_FLAGCODE_OFF; //视频流转的索引值
//获取视频索引
int VideoMgmt_GetVideoStreamFlowIndexNum()
{
return g_VideoStreamFlowIndexNum;
... ... @@ -149,6 +156,18 @@ T_JZsdkReturnCode VideoStramPhoto_DevelopH264FlowGenerateIDR()
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static void *Pthread_FreezeTime(void *arg)
{
//每500ms 恢复一次冻结画面
while (1)
{
delayMs(500);
g_VideoFreeze_PlayFlag = JZ_FLAGCODE_ON;
}
}
/**************
*
* 视频流流转的线程
... ... @@ -157,18 +176,72 @@ T_JZsdkReturnCode VideoStramPhoto_DevelopH264FlowGenerateIDR()
* ************/
T_JZsdkReturnCode VideoMgmt_VideoStreamToDeal(unsigned char *data, unsigned int data_len)
{
//拍照数据
VideoStramPhoto_PhotoDataIn(data, data_len);
//出错
if (data == NULL)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//冻结数据处理
int VideoFreezeFlag = g_VideoFreezeFlag;
//如果冻结功能未打开
if (VideoFreezeFlag == JZ_FLAGCODE_OFF)
{
if (g_FreezeData != NULL)
{
free(g_FreezeData);
g_FreezeData = NULL;
}
}
//冻结功能打开
else if (VideoFreezeFlag == JZ_FLAGCODE_ON)
{
//如果冻结数据为空,且 当前为i帧
if (g_FreezeData == NULL && data[4] == 0x67)
{
FreezeDataLen = data_len;
JZsdk_Malloc((void **)&g_FreezeData, data_len);
memcpy(g_FreezeData, data , data_len);
}
}
//没有冻结数据的情况下
if (g_FreezeData == NULL)
{
//拍照数据
VideoStramPhoto_PhotoDataIn(data, data_len);
//录像处理函数
VideoStramRecord_RecordDataIn(data, data_len);
//连拍处理函数
//FrameDeal_ShootPhotoBurstDeal(FrameDealBuffer, FrameLength);
//推流
VideoStream_PushFrame(data, data_len);
}
else
{
//拍照数据
VideoStramPhoto_PhotoDataIn(g_FreezeData, FreezeDataLen);
//录像处理函数
VideoStramRecord_RecordDataIn(g_FreezeData, FreezeDataLen);
//录像处理函数
VideoStramRecord_RecordDataIn(data, data_len);
//连拍处理函数
//FrameDeal_ShootPhotoBurstDeal(g_FreezeData, FreezeDataLen);
//连拍处理函数
//FrameDeal_ShootPhotoBurstDeal(FrameDealBuffer, FrameLength);
//推流
if (g_VideoFreeze_PlayFlag == JZ_FLAGCODE_ON)
{
VideoStream_PushFrame(g_FreezeData, FreezeDataLen);
g_VideoFreeze_PlayFlag = JZ_FLAGCODE_OFF;
}
}
//推流
VideoStream_PushFrame(data, data_len);
//JZSDK_LOG_INFO("推送一帧%d,数据大小%d\n",VideoPush->VideoStreamFlowIndex,data_len);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
... ... @@ -329,4 +402,34 @@ T_JZsdkReturnCode VideoMgmt_Get_StreamWidthAndHeight(int *width, int *height)
#endif
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/*******************
*
*
* videoMgmt初始化
*
*
*
* ***********************/
T_JZsdkReturnCode VideoMgmt_Init(void)
{
T_JZsdkReturnCode ret;
//初始化转码模块
VideoStreamTransCode_Init();
//冻结计时模块
//创建视频流流转线程
pthread_t FreezeTask;
pthread_attr_t task_attribute; //线程属性
pthread_attr_init(&task_attribute); //初始化线程属性
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
int p_ret = pthread_create(&FreezeTask,&task_attribute,(void *)Pthread_FreezeTime,NULL); //线程
if(p_ret != 0)
{
JZSDK_LOG_ERROR("创建冻结计时线程失败!");
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
\ No newline at end of file
... ...
... ... @@ -25,6 +25,7 @@ extern "C" {
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
T_JZsdkReturnCode VideoMgmt_Init(void);
T_JZsdkReturnCode VideoMgmt_init_buffer(void **index);
T_JZsdkReturnCode VideoMgmt_VideoBuffer_Deinit(void **index);
T_JZsdkReturnCode VideoMgmt_write_data(void **index, unsigned char *data, unsigned int data_len);
... ...
... ... @@ -202,16 +202,8 @@ static int Video_TransCode_Thread_Init()
* ********/
T_JZsdkReturnCode VideoStreamTransCode_Init()
{
if (DEVICE_VERSION == JZ_H150S
|| DEVICE_VERSION == JZ_H150T
|| DEVICE_VERSION == JZ_C1)
{
Video_TransCode_Thread_Init();
}
else
{
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
Video_TransCode_Thread_Init();
JZSDK_LOG_INFO("transcode module init success");
... ...
... ... @@ -187,7 +187,7 @@ T_JZsdkReturnCode AttentionVoice_IndependencePlay()
if (language == 0x11)
{
Megaphone_TTS_Play("Upgrade defeat, restarting Megaphone.", strlen("Upgrade defeat, restarting Megaphone."), JZ_FLAGCODE_ON);
Megaphone_TTS_Play("Megaphone starting.", strlen("Megaphone starting."), JZ_FLAGCODE_ON);
}
else
{
... ...
# cmake 最低版本要求 第三行名字不能动
cmake_minimum_required(VERSION 2.8)
project(JZ_H150S)
project(JZ_C1)
set(CMAKE_C_FLAGS "-pthread -std=gnu99 -lm -ldl -lstdc++")
#"-pthread":指定在编译时链接POSIX线程库,以支持多线程程序。
... ...