VideoMgmt_Buffer.c
7.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/**************************************************
*
* 文件名:缓冲区管理文件
*
* **********************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "JZsdkLib.h"
#include "BaseConfig.h"
#include "./VideoMgmt.h"
#include "../MediaParm.h"
#include "./VideoMgmt_Parm.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;
// }