作者 ookk303

.9保存

... ... @@ -43,7 +43,11 @@
"espeak_tts.h": "c",
"buffersrc.h": "c",
"audiodeal.h": "c",
"wiringpi.h": "c"
"wiringpi.h": "c",
"v4l2_cameraparametersetting.h": "c",
"rtk_mmp.h": "c",
"videostream_shootphoto.h": "c",
"videostream_record.h": "c"
},
"Codegeex.GenerationPreference": "automatic"
}
\ No newline at end of file
... ...
... ... @@ -15,16 +15,12 @@
#include "../../MediaParm.h"
#include "../../VideoMgmt/VideoMgmt.h"
#include "../../StreamProc/StreamProc.h"
#include "Ircut/ircut.h"
#include "../Camera.h"
#include "UI_control/UI_control.h"
static int CameraFd = 0;
//光学相机数据读取线程
static void *JZsdk_Cam_Data_Thread(void *args)
//多线程抓取数据线程
static void *JZsdk_Catch_MultiThread(void *args)
{
while (1)
{
... ... @@ -42,7 +38,7 @@ static void *JZsdk_Cam_Data_Thread(void *args)
continue;
}
//放入缓冲池
//放入缓冲池 //将数据放入缓冲池,从而被其他线程使用
VideoMgmt_write_data(&VideoMgmt_FirstVideo_index, buf, buf_size);
//归还图片
... ... @@ -50,38 +46,68 @@ static void *JZsdk_Cam_Data_Thread(void *args)
}
}
//150st相机初始化
T_JZsdkReturnCode JZsdk_H150ST_CameraInit(int width, int height, int frame_num)
//单线程抓取数据线程
static void *JZsdk_Catch_SingleThread(void *args)
{
T_JZsdkReturnCode ret;
while (1)
{
unsigned int buf_size = 0;
unsigned char *buf = NULL;
//从相机中读取一张照片
V4L2_CameraFrameRecord_OnlyGetFrame(&buf, &buf_size);
//初始化摄像头
ret = V4l2_Camarainit2(&CameraFd,width,height,frame_num);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
return ret;
}
//printf("read: len:%d data[3]:%x data[4]:%x\n", buf_size, buf[3], buf[4]);
//初始化摄像头参数
ret = V4L2_Parameter_Setting(CameraFd);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("摄像头参数调整失败");
return ret;
if (buf == NULL)
{
JZSDK_LOG_ERROR("相机数据读取失败");
continue;
}
//进行数据处理
//归还图片
V4L2_CameraFrameRecord_OnlyReturnFrame();
}
}
/******************************
*
* 相机抓取初始化
* ThreadMode: 0为单线程 1为多线程
*
* ******************************/
T_JZsdkReturnCode JZsdk_FrameCatch_Init(int ThreadMode)
{
T_JZsdkReturnCode 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_Cam_Data_Thread,NULL); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建v4l2线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
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;
}
}
else if (ThreadMode == 1)
{
int opus_Protection = pthread_create(&ReadDataTask,&task_attribute,JZsdk_Catch_MultiThread,NULL); //线程
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
... ...
/**
********************************************************************
* @file H150ST_Cam.h
* H150ST_Cam.h 的头文件
* @file Cam_FrameCatch.h
* Cam_FrameCatch.c 的头文件
*
*********************************************************************
*/
/* Define to prevent recursive inclusion 避免重定义 -------------------------------------*/
#ifndef H150ST_CAM_H
#define H150ST_CAM_H
#ifndef CAM_FRAMECATCH_H
#define CAM_FRAMECATCH_H
/* Includes ------------------------------------------------------------------*/
#include "JZsdk_Base/JZsdk_Code/JZsdk_Code.h"
... ... @@ -24,7 +24,7 @@ extern "C" {
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
T_JZsdkReturnCode JZsdk_H150ST_CameraInit(int width, int height, int frame_num);
T_JZsdkReturnCode JZsdk_FrameCatch_Init(int ThreadMode);
... ...
... ... @@ -14,6 +14,12 @@
#include "MediaProc/IRC_funtion/IRC_funtion.h"
#include "./V4L2_camera/V4L2_CameraParameterSetting.h"
#include "./V4L2_camera/V4L2_Record.h"
#include "./Cam_FrameCatch/Cam_FrameCatch.h"
static int g_CameraFd = 0; //摄像头文件描述符
static int PseudoColor = JZ_FLAGCODE_OFF; //伪彩颜色
static int PixelColorMode = JZ_FLAGCODE_OFF; //像素颜色模式
... ... @@ -25,6 +31,42 @@ int g_CameraRegionBox_FirstPixel[2] = {0, 0}; // 初始化第一点坐标(x, y)
int g_CameraRegionBox_SecondPixel[2] = {0, 0}; // 初始化第二点坐标(x, y)为(0, 0)
int g_CameraRegionBox_ClickTime = 0;
/******************************
*
* 相机初始化
* ThreadMode: 0为单线程 1为多线程
* width: 宽
* height: 高
* frame_num: 帧数
*
* ******************************/
T_JZsdkReturnCode Camera_Init(int ThreadMode, int width, int height, int frame_num)
{
T_JZsdkReturnCode ret;
//初始化摄像头
ret = V4l2_Camarainit2(&g_CameraFd,width,height,frame_num);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
return ret;
}
#if DEVICE_VERSION == JZ_H150S || DEVICE_VERSION == JZ_H150T
//初始化摄像头参数
ret = V4L2_Parameter_Setting(g_CameraFd);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("摄像头参数调整失败");
return ret;
}
#endif
//根据线程模式初始化抓取和初步处理的线程
JZsdk_FrameCatch_Init(ThreadMode);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//快门开关
/***********************************
... ...
... ... @@ -32,7 +32,8 @@ T_JZsdkReturnCode JZsdk_Camera_BadPixelSwitch();
T_JZsdkReturnCode JZsdk_CameraSPC_ResetSwitch();
T_JZsdkReturnCode JZsdk_Camera_GasEnhancementCorrectSwitch();
T_JZsdkReturnCode JZsdk_H150ST_CameraInit(int width, int height, int frame_num);
T_JZsdkReturnCode Camera_Init(int ThreadMode, int width, int height, int frame_num);
#ifdef __cplusplus
}
... ...
... ... @@ -14,9 +14,41 @@
#include "./Camera/Camera.h"
#include "./Camera/Kt_Irc/Kt_Irc.h"
//视频流模块初始化
T_JZsdkReturnCode MediaProc_Init()
//单线程方案
static T_JZsdkReturnCode MediaProc_SingleThreading()
{
//如果是150S相机 150T相机
if (DEVICE_VERSION == JZ_H150S || DEVICE_VERSION == JZ_H150T)
{
//1、相机初始化
Camera_Init(0,FIRST_WIDTH, FIRST_HEIGHT, FIRST_FRAME_NUM);
//2、转码模块初始化
VideoStreamTransCode_Init();
}
}
//多线程方案
static T_JZsdkReturnCode MediaProc_MultiThreading()
{
//如果是150S相机 150T相机
if (DEVICE_VERSION == JZ_H150S || DEVICE_VERSION == JZ_H150T)
{
//1、启动视频流缓冲区模块
VideoMgmt_init_buffer(&VideoMgmt_FirstVideo_index);
//2、相机初始化
Camera_Init(1,FIRST_WIDTH, FIRST_HEIGHT, FIRST_FRAME_NUM);
//3、启用推流模块
VideoMgmt_VideoStreamFlow_Init(FIRST_FRAME_NUM, &VideoMgmt_FirstVideo_index, VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST);
//转码模块
VideoStreamTransCode_Init();
VideoMgmt_VideoStreamFlowIndex(VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST); //默认推送光学摄像头
}
//如果是昆腾相机 红外+光学 则红外为1号,光学为2号
if (DEVICE_VERSION == JZ_C1)
{
... ... @@ -51,23 +83,17 @@ T_JZsdkReturnCode MediaProc_Init()
Camera_param(JZ_FLAGCODE_SET, CAMERA_PIXEL_PSEUDO_COLOR_MODE, &value);
}
//如果是150S相机 150T相机
if (DEVICE_VERSION == JZ_H150S || DEVICE_VERSION == JZ_H150T)
{
//1、启动视频流缓冲区模块
VideoMgmt_init_buffer(&VideoMgmt_FirstVideo_index);
//2、相机初始化
JZsdk_H150ST_CameraInit(FIRST_WIDTH, FIRST_HEIGHT, FIRST_FRAME_NUM);
}
//3、启用推流模块
VideoMgmt_VideoStreamFlow_Init(FIRST_FRAME_NUM, &VideoMgmt_FirstVideo_index, VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST);
//视频流模块初始化
T_JZsdkReturnCode MediaProc_Init()
{
//转码模块
VideoStreamTransCode_Init();
VideoMgmt_VideoStreamFlowIndex(VIDEOMGMT_STREAMING_FLOW_INDEX_FIRST); //默认推送光学摄像头
}
#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;
}
\ No newline at end of file
... ...
/**************************************************
*
* 文件名:VideoMgmt.c
* 视频流模块
* 版本:V1.0
* 作用:
* 在视频流完成处理之后
* 1、将视频流数据发送到视频流推送模块
* 2、将视频流数据发送到视频流录制块
* 3、将视频流数据发送到视频流拍照模块
*
* **********************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
... ... @@ -19,241 +31,26 @@
//额外头文件声明
#define DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN 60000
#define VIDEO_FRAME_AUD_LEN 6
static const unsigned char s_frameAudInfo[VIDEO_FRAME_AUD_LEN] = {0x00, 0x00, 0x00, 0x01, 0x09, 0x10};
JZ_VideoStreamUseStatus g_VideoStreamDealStatus = VIDEO_STREAM_IDLE; //视频流的处理状态
/*视频流缓冲区地址说明
留有三对缓冲区,一队中的数据分别为成型数据,以及原始数据
如果设备只有一个摄像头,则使用一号视频流
如果设备为 红外+光学 则红外为1号,光学为2号
*/
void *VideoMgmt_FirstVideo_index = NULL; //一号视频流的缓冲地址
void *VideoMgmt_SecondVideo_index = NULL; //二号视频流的缓冲地址
void *VideoMgmt_ThirdVideo_index = NULL; //三号视频流的缓冲地址
void *VideoMgmt_FirstRaw_index = NULL; //一号原始流的缓冲地址
void *VideoMgmt_SecondRaw_index = NULL; //二号原始流的缓冲地址
void *VideoMgmt_ThirdRaw_index = NULL; //三号原始流的缓冲地址
static int VideoFreezeFlag = JZ_FLAGCODE_OFF; //视频流冻结功能
//视频流缓冲区结构
typedef struct JZsdk_VideoBuffer{
unsigned char *data; //缓冲区数据
unsigned int data_len;
int is_ready; // 标志位,表示数据是否准备好被读取
pthread_mutex_t lock; // 互斥锁,用于线程同步
pthread_cond_t cond; // 条件变量,用于通知读取线程数据已准备好
} JZsdk_VideoBuffer;
// 初始化缓冲区
T_JZsdkReturnCode VideoMgmt_init_buffer(void **index)
{
//从索引值获取对应的缓冲区
//创建一个缓冲区
struct JZsdk_VideoBuffer *VideoBuffer = NULL;
//为编码器参数注册内存
VideoBuffer = (struct JZsdk_VideoBuffer *)malloc(sizeof(struct JZsdk_VideoBuffer));
if (VideoBuffer == NULL) {
JZSDK_LOG_ERROR("视频流缓冲区注册失败");
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
VideoBuffer->data = NULL;
VideoBuffer->data_len = 0;
VideoBuffer->is_ready = 0;
pthread_mutex_init(&VideoBuffer->lock, NULL);
pthread_cond_init(&VideoBuffer->cond, NULL);
if (*index != NULL)
{
free(*index);
}
*index = (void *)VideoBuffer;
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//缓冲区清理
T_JZsdkReturnCode VideoMgmt_VideoBuffer_Deinit(void **index)
{
if (index == NULL || *index == NULL) {
// 如果索引或缓冲区指针为空,则直接返回
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
//从索引值获取对应的缓冲区
struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
if (VideoBuffer->data != NULL)
{
free(VideoBuffer->data);
VideoBuffer->data = NULL;
}
VideoBuffer->data_len = 0;
VideoBuffer->is_ready = 0;
pthread_mutex_destroy(&VideoBuffer->lock);
pthread_cond_destroy(&VideoBuffer->cond);
free(VideoBuffer);
index = NULL; // 防止悬挂指针
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//缓冲区写入
T_JZsdkReturnCode VideoMgmt_write_data(void **index, unsigned char *data, unsigned int data_len)
{
//从索引值获取对应的缓冲区
struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
pthread_mutex_lock(&VideoBuffer->lock);
// 释放旧数据
if (VideoBuffer->data)
{
free(VideoBuffer->data);
VideoBuffer->data = NULL;
}
// 分配新内存并复制数据
VideoBuffer->data = (unsigned char *)malloc(data_len);
memcpy(VideoBuffer->data, data, data_len);
VideoBuffer->data_len = data_len;
VideoBuffer->is_ready = 1; // 标记数据已准备好
// 通知读取线程数据已准备好
pthread_cond_signal(&VideoBuffer->cond);
pthread_mutex_unlock(&VideoBuffer->lock);
}
//缓冲区读取
//输入的参数,缓冲区索引地址 回复的数据地址 回复的数据长度 帧头帧尾模式 帧头帧尾长度
T_JZsdkReturnCode VideoMgmt_read_data(void **index, unsigned char **data, unsigned int *data_len, unsigned int mode, unsigned int extra_len)
{
//从索引值获取对应的缓冲区
struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
// 检查缓冲区指针是否有效
if (VideoBuffer == NULL)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示参数无效
}
pthread_mutex_lock(&VideoBuffer->lock);
// 等待数据准备好
while (!VideoBuffer->is_ready)
{
pthread_cond_wait(&VideoBuffer->cond, &VideoBuffer->lock);
}
// 检查数据指针是否有效
if (VideoBuffer->data == NULL)
{
pthread_mutex_unlock(&VideoBuffer->lock);
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示没有数据可供读取
}
// 返回数据和长度
*data_len = VideoBuffer->data_len;
if (mode == JZ_FLAGCODE_OFF)
{
*data = (unsigned char *)malloc(*data_len);
memcpy(*data, VideoBuffer->data, *data_len);
}
else if (mode == VIDEOMGMT_USE_FRAMEHEAD)
{
*data = (unsigned char *)malloc(*data_len + extra_len);
memcpy(*data+extra_len, VideoBuffer->data, VideoBuffer->data_len);
}
else if (mode == VIDEOMGMT_USE_FRAMEEND)
{
*data = (unsigned char *)malloc(*data_len + extra_len);
memcpy(*data, VideoBuffer->data, VideoBuffer->data_len);
}
else
{
*data = (unsigned char *)malloc(*data_len);
memcpy(*data, VideoBuffer->data, *data_len);
}
VideoBuffer->is_ready = 0;
pthread_mutex_unlock(&VideoBuffer->lock);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/**********
/****************************
*
* 直接返回地址略有风险,暂时不考虑使用这个以下注释的方法
* videoMgmt的初始化
*
*
* ************/
// //缓冲区读取
// T_JZsdkReturnCode VideoMgmt_read_data(void **index, unsigned char **data, unsigned int *data_len)
// {
// //从索引值获取对应的缓冲区
// struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
// // 检查缓冲区指针是否有效
// if (VideoBuffer == NULL)
// {
// return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示参数无效
// }
// pthread_mutex_lock(&VideoBuffer->lock);
// // 等待数据准备好
// while (!VideoBuffer->is_ready)
// {
// pthread_cond_wait(&VideoBuffer->cond, &VideoBuffer->lock);
// }
// // 检查数据指针是否有效
// if (VideoBuffer->data == NULL)
// {
// pthread_mutex_unlock(&VideoBuffer->lock);
// return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示没有数据可供读取
// }
// // 返回数据和长度
// *data = (VideoBuffer->data);
// *data_len = VideoBuffer->data_len;
// return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
// }
// //回复已经读取完成,在read函数,且数据处理完成后调用
// T_JZsdkReturnCode VideoMgmt_ReplyRead(void **index)
// {
// //从索引值获取对应的缓冲区
// struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
// // 检查缓冲区指针是否有效
// if (VideoBuffer == NULL)
// {
// return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示参数无效
// }
// VideoBuffer->is_ready = 0;
// pthread_mutex_unlock(&VideoBuffer->lock);
// return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
// }
*
* **************************/
T_JZsdkReturnCode VideoMgmt_Init()
{
//1
VideoMgmt_VideoStreamFlow_Init(int FrameNumber, void **index, int VideoStreamFlowIndex);
}
/*********************************************************************************************************************************************
*
... ... @@ -375,10 +172,10 @@ T_JZsdkReturnCode VideoStramPhoto_DevelopH264FlowGenerateIDR()
/**************
*
* 视频流流转的线程
*
* 视频流处理完成后,可以通过此函数完成拍照记录 录像记录 以及推送
*
* ************/
static T_JZsdkReturnCode VideoStreamToDeal(unsigned char *data, unsigned int data_len)
T_JZsdkReturnCode VideoMgmt_VideoStreamToDeal(unsigned char *data, unsigned int data_len)
{
//拍照数据
VideoStramPhoto_PhotoDataIn(data, data_len);
... ... @@ -394,6 +191,16 @@ static T_JZsdkReturnCode VideoStreamToDeal(unsigned char *data, unsigned int dat
//JZSDK_LOG_INFO("推送一帧%d,数据大小%d\n",VideoPush->VideoStreamFlowIndex,data_len);
}
/******************************************************************************
*
* 多线程下的处理
*
*
*
* ***********************************************************/
static void *VideoMgmt_VideoStreamFlow_Thread(void *args)
{
struct VideoMgmt_VideoStreamFlow *VideoPush = (struct VideoMgmt_VideoStreamFlow *)args;
... ... @@ -442,13 +249,15 @@ static void *VideoMgmt_VideoStreamFlow_Thread(void *args)
}
}
//冻结开了就推送冻结画面
if (VideoFreezeFlag == JZ_FLAGCODE_ON && FreezeDataLen != 0)
{
VideoStreamToDeal(FreezeData, FreezeDataLen);
VideoMgmt_VideoStreamToDeal(FreezeData, FreezeDataLen);
}
//否则推送正常画面
else
{
VideoStreamToDeal(data, data_len);
VideoMgmt_VideoStreamToDeal(data, data_len);
}
// 释放数据(如果有必要的话)
... ... @@ -472,6 +281,7 @@ static void *VideoMgmt_VideoStreamFlow_Thread(void *args)
return NULL;
}
//视频流流转模块的初始化
T_JZsdkReturnCode VideoMgmt_VideoStreamFlow_Init(int FrameNumber, void **index, int VideoStreamFlowIndex)
{
... ...
... ... @@ -93,6 +93,15 @@ T_JZsdkReturnCode VideoStramPhoto_DevelopH264FlowGenerateIDR();
* *********/
T_JZsdkReturnCode VideoRecord_TransMode(int status);
/*********
*
* 内部交互函数
*
* *****************/
T_JZsdkReturnCode VideoMgmt_VideoStreamToDeal(unsigned char *data, unsigned int data_len);
#ifdef __cplusplus
}
#endif
... ...
/**************************************************
*
* 文件名:缓冲区管理文件
*
* **********************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "JZsdkLib.h"
#include "./VideoMgmt.h"
#include "version_choose.h"
#include "BaseConfig.h"
#include "./VideoStreamPush/VideoStream_Push.h"
#include "./VideoStreamRecord/VideoStream_Record.h"
#include "./VideoStreamPhoto/VideoStream_ShootPhoto.h"
#include "UI_control/UI_control.h"
#include "../MediaParm.h"
#include "../StreamProc/RTK_mmp/RTK_mmp.h"
/*视频流缓冲区地址说明
留有三对缓冲区,一队中的数据分别为成型数据,以及原始数据
如果设备只有一个摄像头,则使用一号视频流
如果设备为 红外+光学 则红外为1号,光学为2号
*/
void *VideoMgmt_FirstVideo_index = NULL; //一号视频流的缓冲地址
void *VideoMgmt_SecondVideo_index = NULL; //二号视频流的缓冲地址
void *VideoMgmt_ThirdVideo_index = NULL; //三号视频流的缓冲地址
void *VideoMgmt_FirstRaw_index = NULL; //一号原始流的缓冲地址
void *VideoMgmt_SecondRaw_index = NULL; //二号原始流的缓冲地址
void *VideoMgmt_ThirdRaw_index = NULL; //三号原始流的缓冲地址
//视频流缓冲区结构
typedef struct JZsdk_VideoBuffer{
unsigned char *data; //缓冲区数据
unsigned int data_len;
int is_ready; // 标志位,表示数据是否准备好被读取
pthread_mutex_t lock; // 互斥锁,用于线程同步
pthread_cond_t cond; // 条件变量,用于通知读取线程数据已准备好
} JZsdk_VideoBuffer;
// 初始化缓冲区
T_JZsdkReturnCode VideoMgmt_init_buffer(void **index)
{
//从索引值获取对应的缓冲区
//创建一个缓冲区
struct JZsdk_VideoBuffer *VideoBuffer = NULL;
//为编码器参数注册内存
VideoBuffer = (struct JZsdk_VideoBuffer *)malloc(sizeof(struct JZsdk_VideoBuffer));
if (VideoBuffer == NULL) {
JZSDK_LOG_ERROR("视频流缓冲区注册失败");
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
VideoBuffer->data = NULL;
VideoBuffer->data_len = 0;
VideoBuffer->is_ready = 0;
pthread_mutex_init(&VideoBuffer->lock, NULL);
pthread_cond_init(&VideoBuffer->cond, NULL);
if (*index != NULL)
{
free(*index);
}
*index = (void *)VideoBuffer;
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//缓冲区清理
T_JZsdkReturnCode VideoMgmt_VideoBuffer_Deinit(void **index)
{
if (index == NULL || *index == NULL) {
// 如果索引或缓冲区指针为空,则直接返回
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
//从索引值获取对应的缓冲区
struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
if (VideoBuffer->data != NULL)
{
free(VideoBuffer->data);
VideoBuffer->data = NULL;
}
VideoBuffer->data_len = 0;
VideoBuffer->is_ready = 0;
pthread_mutex_destroy(&VideoBuffer->lock);
pthread_cond_destroy(&VideoBuffer->cond);
free(VideoBuffer);
index = NULL; // 防止悬挂指针
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//缓冲区写入
T_JZsdkReturnCode VideoMgmt_write_data(void **index, unsigned char *data, unsigned int data_len)
{
//从索引值获取对应的缓冲区
struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
pthread_mutex_lock(&VideoBuffer->lock);
// 释放旧数据
if (VideoBuffer->data)
{
free(VideoBuffer->data);
VideoBuffer->data = NULL;
}
// 分配新内存并复制数据
VideoBuffer->data = (unsigned char *)malloc(data_len);
memcpy(VideoBuffer->data, data, data_len);
VideoBuffer->data_len = data_len;
VideoBuffer->is_ready = 1; // 标记数据已准备好
// 通知读取线程数据已准备好
pthread_cond_signal(&VideoBuffer->cond);
pthread_mutex_unlock(&VideoBuffer->lock);
}
//缓冲区读取
//输入的参数,缓冲区索引地址 回复的数据地址 回复的数据长度 帧头帧尾模式 帧头帧尾长度
T_JZsdkReturnCode VideoMgmt_read_data(void **index, unsigned char **data, unsigned int *data_len, unsigned int mode, unsigned int extra_len)
{
//从索引值获取对应的缓冲区
struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
// 检查缓冲区指针是否有效
if (VideoBuffer == NULL)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示参数无效
}
pthread_mutex_lock(&VideoBuffer->lock);
// 等待数据准备好
while (!VideoBuffer->is_ready)
{
pthread_cond_wait(&VideoBuffer->cond, &VideoBuffer->lock);
}
// 检查数据指针是否有效
if (VideoBuffer->data == NULL)
{
pthread_mutex_unlock(&VideoBuffer->lock);
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示没有数据可供读取
}
// 返回数据和长度
*data_len = VideoBuffer->data_len;
if (mode == JZ_FLAGCODE_OFF)
{
*data = (unsigned char *)malloc(*data_len);
memcpy(*data, VideoBuffer->data, *data_len);
}
else if (mode == VIDEOMGMT_USE_FRAMEHEAD)
{
*data = (unsigned char *)malloc(*data_len + extra_len);
memcpy(*data+extra_len, VideoBuffer->data, VideoBuffer->data_len);
}
else if (mode == VIDEOMGMT_USE_FRAMEEND)
{
*data = (unsigned char *)malloc(*data_len + extra_len);
memcpy(*data, VideoBuffer->data, VideoBuffer->data_len);
}
else
{
*data = (unsigned char *)malloc(*data_len);
memcpy(*data, VideoBuffer->data, *data_len);
}
VideoBuffer->is_ready = 0;
pthread_mutex_unlock(&VideoBuffer->lock);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/**********
*
* 直接返回地址略有风险,暂时不考虑使用这个以下注释的方法
*
* ************/
// //缓冲区读取
// T_JZsdkReturnCode VideoMgmt_read_data(void **index, unsigned char **data, unsigned int *data_len)
// {
// //从索引值获取对应的缓冲区
// struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
// // 检查缓冲区指针是否有效
// if (VideoBuffer == NULL)
// {
// return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示参数无效
// }
// pthread_mutex_lock(&VideoBuffer->lock);
// // 等待数据准备好
// while (!VideoBuffer->is_ready)
// {
// pthread_cond_wait(&VideoBuffer->cond, &VideoBuffer->lock);
// }
// // 检查数据指针是否有效
// if (VideoBuffer->data == NULL)
// {
// pthread_mutex_unlock(&VideoBuffer->lock);
// return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示没有数据可供读取
// }
// // 返回数据和长度
// *data = (VideoBuffer->data);
// *data_len = VideoBuffer->data_len;
// return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
// }
// //回复已经读取完成,在read函数,且数据处理完成后调用
// T_JZsdkReturnCode VideoMgmt_ReplyRead(void **index)
// {
// //从索引值获取对应的缓冲区
// struct JZsdk_VideoBuffer *VideoBuffer = (struct JZsdk_VideoBuffer *)*index;
// // 检查缓冲区指针是否有效
// if (VideoBuffer == NULL)
// {
// return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 假设的错误码,表示参数无效
// }
// VideoBuffer->is_ready = 0;
// pthread_mutex_unlock(&VideoBuffer->lock);
// return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
// }
\ No newline at end of file
... ...
/**************************************************
*
* 文件名:VideoMgmt的多线程处理模式
*
* **********************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "JZsdkLib.h"
#include "./VideoMgmt.h"
#include "version_choose.h"
#include "BaseConfig.h"
#include "./VideoStreamPush/VideoStream_Push.h"
#include "./VideoStreamRecord/VideoStream_Record.h"
#include "./VideoStreamPhoto/VideoStream_ShootPhoto.h"
#include "UI_control/UI_control.h"
#include "../MediaParm.h"
#include "../StreamProc/RTK_mmp/RTK_mmp.h"
... ...
/**************************************************
*
* 文件名:VideoMgmt的单线程处理模式
*
* **********************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "JZsdkLib.h"
#include "./VideoMgmt.h"
#include "version_choose.h"
#include "BaseConfig.h"
#include "./VideoStreamPush/VideoStream_Push.h"
#include "./VideoStreamRecord/VideoStream_Record.h"
#include "./VideoStreamPhoto/VideoStream_ShootPhoto.h"
#include "UI_control/UI_control.h"
#include "../MediaParm.h"
#include "../StreamProc/RTK_mmp/RTK_mmp.h"
/************************
*
* 视频管理模块
* 单线程模式下的数据输入接口
*
* *************************/
T_JZsdkReturnCode VideoMgmt_Single_FrameIn(unsigned char *FrmaeData,unsigned int FrmaeDataLen)
{
//判断数据是否为空
if(FrmaeData == NULL)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
//判断数据长度是否为空
if(FrmaeDataLen == 0)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//进行数据后处理,即加入帧头,帧尾等
//将数据输入到流转函数中
VideoMgmt_VideoStreamToDeal(FrmaeData,FrmaeDataLen);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
\ No newline at end of file
... ...