ffmpeg_VideoTranscode.c
7.8 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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/* Includes ------------------------------------------------------------------*/
#include <fcntl.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
// 自建库
#include "../VideoTranscode.h"
#include "JZsdkLib.h"
/* Private constants ---------------------------------------------------------*/
#define FFMPEG_CMD_BUF_SIZE (256 + 256)
//转码模式
#define H264_TRANSCODETO_JPG (1)
#define H264_TRAMSCODETO_MP4 (2)
#define H264_TRAMSCODETO_JPG_BURST (3)
/* Private types -------------------------------------------------------------*/
static void *ffmpeg_VideoTranscodeTask(void *arg);
static int tanscodemode = 0;
static int GPS_Receive_Date = 0;
static int GPS_Receive_Time = 0;
extern int VideoTranscode_Flag ; //视频转码标志位,off为转码完毕,on为转码完成
extern int PhotoTranscode_Flag ; //图片转码标志位,off为转码完毕,on为转码完成
FILE *NUMBER_SET_fp;
char number_set[6];
//互斥锁
static pthread_mutex_t TranscodeLock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t TransCond = PTHREAD_COND_INITIALIZER;
//转码服务函数
// 服务初始化函数
T_JZsdkReturnCode ffmpeg_VideoTranscode_Sever(void)
{
pthread_t WriteDataTask;
pthread_attr_t task_attribute; //线程属性
pthread_attr_init(&task_attribute); //初始化线程属性
pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED); //设置线程分离属性
int opus_Protection = pthread_create(&WriteDataTask,&task_attribute,ffmpeg_VideoTranscodeTask,NULL); //线程
if(opus_Protection != 0)
{
JZSDK_LOG_ERROR("创建视频转码线程失败!");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/*
转码函数部分
*/
// 拍照转码函数
static T_JZsdkReturnCode ffmpeg_ShootPhoto_transcode()
{
//打开转码标志位
if (PhotoTranscode_Flag == JZ_FLAGCODE_ON)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
PhotoTranscode_Flag = JZ_FLAGCODE_ON;
//ffmpeg指令
char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];
int ret;
//地址拼接
char str1[40] = "/root/sdcard/DCIM/Photos/PSDK_PHOTO";
int str2 ;
char str3[6] = ".jpg";
char *ffmpeg_ShootPhoto_CallBack_InPath = "/root/sdcard/DCIM/Photos/temp.h264";
char ffmpeg_ShootPhoto_CallBack_OutPath[FFMPEG_CMD_BUF_SIZE];
//输出名字修改
NUMBER_SET_fp = fopen("/root/sdcard/DCIM/Photos/pthoto_number.txt","r+");
if(NUMBER_SET_fp == NULL)
{
NUMBER_SET_fp = fopen("/root/sdcard/DCIM/Photos/pthoto_number.txt","w+");
fwrite("00000", 1, 5, NUMBER_SET_fp);
fseek(NUMBER_SET_fp, 0, SEEK_SET);
}
fread(number_set, 1, 5, NUMBER_SET_fp);
str2 = atoi(number_set) + 1;
snprintf(number_set, 6, "%05d", str2);
fseek(NUMBER_SET_fp, 0, SEEK_SET);
fwrite(number_set, 1, 5, NUMBER_SET_fp);
//snprintf(ffmpeg_ShootPhoto_CallBack_OutPath, 256, "%s_%d_%d%s", str1,GPS_Receive_Date,GPS_Receive_Time,str2);
snprintf(ffmpeg_ShootPhoto_CallBack_OutPath, 256, "%s_%s%s", str1, number_set, str3);
fclose(NUMBER_SET_fp);
NUMBER_SET_fp = NULL;
JZSDK_LOG_INFO("ffmpeg_ShootPhoto_CallBack_OutPath:%s",ffmpeg_ShootPhoto_CallBack_OutPath);
//JZSDK_LOG_INFO("%s",ffmpeg_ShootPhoto_CallBack_OutPath);
//将h264照片转换为jpg格式
snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE,
"echo \"y\" | ffmpeg -i \"%s\" -y -f image2 -t 0.001 -s 1980*1080 \"%s\" >/dev/null 2>&1",
ffmpeg_ShootPhoto_CallBack_InPath,
ffmpeg_ShootPhoto_CallBack_OutPath);
//JZSDK_LOG_INFO("ffmpegCmdStr:%s",ffmpegCmdStr);
JZSDK_LOG_INFO("录像保存位置:%s",ffmpeg_ShootPhoto_CallBack_OutPath);
JZsdk_RunSystemCmd(ffmpegCmdStr);
PhotoTranscode_Flag = JZ_FLAGCODE_OFF;
}
// 录像转码函数
static void ffmpeg_RecordVideo_transcode()
{
//打开转码标志位
if (VideoTranscode_Flag == JZ_FLAGCODE_ON)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
VideoTranscode_Flag = JZ_FLAGCODE_ON;
//ffmpeg指令
char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];
char *ffmpeg_RecordVideo_InPath = "/root/sdcard/DCIM/Videos/temp.h264";
char ffmpeg_RecordVideo_OutPath[FFMPEG_CMD_BUF_SIZE];
//转码
char str1[40] = "/root/sdcard/DCIM/Videos/PSDK_VIDEO";
int str2;
char str3[10] = ".mp4";
//输出名字修改
NUMBER_SET_fp = fopen("/root/sdcard/DCIM/Videos/video_number.txt","r+");
if(NUMBER_SET_fp == NULL)
{
NUMBER_SET_fp = fopen("/root/sdcard/DCIM/Videos/video_number.txt","w+");
fwrite("00000", 1, 5, NUMBER_SET_fp);
fseek(NUMBER_SET_fp, 0, SEEK_SET);
}
fread(number_set, 1, 5, NUMBER_SET_fp);
str2 = atoi(number_set) + 1;
snprintf(number_set, 6, "%05d", str2);
fseek(NUMBER_SET_fp, 0, SEEK_SET);
fwrite(number_set, 1, 5, NUMBER_SET_fp);
//snprintf(ffmpeg_RecordVideo_OutPath, 256, "%s_%d_%d%s", str1,GPS_Receive_Date,GPS_Receive_Time,str2);
snprintf(ffmpeg_RecordVideo_OutPath, 256, "%s_%s%s", str1, number_set, str3);
fclose(NUMBER_SET_fp);
NUMBER_SET_fp = NULL;
//将h264视频转换为mp4格式
snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE,
"echo \"y\" | ffmpeg -i \"%s\" -y -vcodec copy \"%s\" >/dev/null 2>&1",
ffmpeg_RecordVideo_InPath,
ffmpeg_RecordVideo_OutPath);
//ffmpeg -f h264 -i xxx.264 -vcodec copy xxx.mp4
//JZSDK_LOG_INFO("ffmpegCmdStr:%s",ffmpegCmdStr);
JZSDK_LOG_INFO("录像保存位置:%s",ffmpeg_RecordVideo_OutPath);
JZsdk_RunSystemCmd(ffmpegCmdStr);
VideoTranscode_Flag = JZ_FLAGCODE_OFF;
}
// 连拍转码函数
static void ffmpeg_ShootPhoroBurst_transcode()
{
//ffmpeg指令
char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];
char *ffmpeg_ShootPhoroBurst_InPath = "/root/sdcard/DCIM/Videos/temp.h264";
char ffmpeg_ShootPhoroBurst_OutPath[FFMPEG_CMD_BUF_SIZE];
//转码
char str1[40] = "/root/sdcard/DCIM/Photos/video_";
char str2[10] = ".mp4";
//根据时间写名字
snprintf(ffmpeg_ShootPhoroBurst_OutPath, 256, "%s_%d_%d%s", str1,GPS_Receive_Date,GPS_Receive_Time,str2);
//将h264照片转换为jpg格式
snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE,
"echo \"y\" | ffmpeg -i \"%s\" -r 25 -f image2 -t 0.001 -s 1280*720 \"%s\" >/dev/null 2>&1",
ffmpeg_ShootPhoroBurst_InPath,
ffmpeg_ShootPhoroBurst_OutPath);
//ffmpeg -i output.mp4 -r 30 -f image2 foo-%05d.jpeg
JZSDK_LOG_INFO("录像保存位置:%s",ffmpeg_ShootPhoroBurst_OutPath);
JZsdk_RunSystemCmd(ffmpegCmdStr);
}
/*
转码解锁函数
*/
//拍照转码解锁函数
void ffmpeg_H264_tanscodeto(int mode)
{
tanscodemode = mode;
pthread_mutex_unlock(&TranscodeLock);
}
/*
gps时间接受函数
*/
void ffmpeg_tanscode_DateAndTime_Receive(int date,int time)
{
GPS_Receive_Date = date;
GPS_Receive_Time = time;
}
//转码线程
static void *ffmpeg_VideoTranscodeTask(void *arg)
{
while (1) {
pthread_mutex_lock(&TranscodeLock);
JZSDK_LOG_INFO("s_VideoTranscode_Mutex解锁线程");
//如果为拍照转码
if(tanscodemode == H264_TRANSCODETO_JPG)
{
// //ffmpeg_CameraTransLock(true);
ffmpeg_ShootPhoto_transcode();
//ffmpeg_CameraTransLock(false);
}
//如果为录像转码
if(tanscodemode == H264_TRAMSCODETO_MP4)
{
//ffmpeg_CameraTransLock(true);
ffmpeg_RecordVideo_transcode();
//ffmpeg_CameraTransLock(false);
}
// //如果为连拍转码
// if(tanscodemode == H264_TRAMSCODETO_JPG_BURST)
// {
// ffmpeg_ShootPhoroBurst_transcode();
// }
tanscodemode = JZ_FLAGCODE_OFF;
}
}