blob: dca7bbdf5c798b50de34e07ba8ee1aec62f335d0 [file] [log] [blame]
Pengfei Liuc181a982020-01-07 19:27:13 +08001#include <stdio.h>
Pengfei Liu3b1a8202020-02-12 23:04:21 +08002#include <unistd.h>
3#include <stdlib.h>
Pengfei Liub4734232020-01-17 18:25:10 +08004#include <string.h>
Zhiqiang Hane0a1c382021-06-08 11:28:05 +08005#include <errno.h>
Pengfei Liub4734232020-01-17 18:25:10 +08006#include <pthread.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08007#include "dvr_segment.h"
Pengfei Liub4734232020-01-17 18:25:10 +08008#include <segment.h>
Zhiqiang Han02e890c2023-04-25 14:55:02 +08009#include <dirent.h>
Pengfei Liuc181a982020-01-07 19:27:13 +080010
Pengfei Liub4734232020-01-17 18:25:10 +080011/**\brief DVR segment file information*/
12typedef struct {
13 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
14 uint64_t id; /**< DVR Segment id*/
15} DVR_SegmentFile_t;
16
17void *dvr_segment_thread(void *arg)
18{
Pengfei Liub4734232020-01-17 18:25:10 +080019 int ret;
hualing chene83bf812020-04-23 13:42:37 +080020 DVR_SegmentFile_t *segment_file = (DVR_SegmentFile_t*)arg;
Wentao MA16f870e2022-09-09 11:00:22 +080021 if (segment_file == NULL) {
22 DVR_ERROR("Invalid segment_file pointer");
23 return NULL;
24 }
Pengfei Liub4734232020-01-17 18:25:10 +080025
hualing chen31140872020-03-25 12:29:26 +080026 pthread_detach(pthread_self());
Wentao MA96f68962022-06-15 19:45:35 +080027 DVR_INFO("%s try to delete [%s-%lld]", __func__, segment_file->location, segment_file->id);
hualing chene83bf812020-04-23 13:42:37 +080028 ret = segment_delete(segment_file->location, segment_file->id);
Wentao MA96f68962022-06-15 19:45:35 +080029 DVR_INFO("%s delete segment [%s-%lld] %s", __func__, segment_file->location, segment_file->id,
Pengfei Liub4734232020-01-17 18:25:10 +080030 ret == DVR_SUCCESS ? "success" : "failed");
hualing chene83bf812020-04-23 13:42:37 +080031 if (segment_file != NULL) {
32 //malloc at delete api.free at this
33 free(segment_file);
hualing chene83bf812020-04-23 13:42:37 +080034 }
Pengfei Liub4734232020-01-17 18:25:10 +080035 return NULL;
36}
Pengfei Liu3b1a8202020-02-12 23:04:21 +080037
Pengfei Liuc181a982020-01-07 19:27:13 +080038int dvr_segment_delete(const char *location, uint64_t segment_id)
39{
hualing chen6d24aa92020-03-23 18:43:47 +080040
Pengfei Liub4734232020-01-17 18:25:10 +080041 pthread_t thread;
hualing chene83bf812020-04-23 13:42:37 +080042 DVR_SegmentFile_t *segment;
Pengfei Liub4734232020-01-17 18:25:10 +080043
Pengfei Liu3b1a8202020-02-12 23:04:21 +080044 DVR_RETURN_IF_FALSE(location);
45 DVR_RETURN_IF_FALSE(strlen(location) < DVR_MAX_LOCATION_SIZE);
Wentao MA4b8d4752022-09-14 19:03:45 +080046 DVR_INFO("In function %s, segment %s's id is %lld", __func__, location, segment_id);
47
48 // Memory allocated here will be freed in segment deletion thread under normal conditions.
49 // In case of thread creation failure, it will be freed right away.
50 segment = (DVR_SegmentFile_t *)malloc(sizeof(DVR_SegmentFile_t));
51 DVR_RETURN_IF_FALSE(segment != NULL);
52
hualing chene83bf812020-04-23 13:42:37 +080053 memset(segment->location, 0, sizeof(segment->location));
54 memcpy(segment->location, location, strlen(location));
55 segment->id = segment_id;
Zhiqiang Han2d8cd822020-03-16 13:58:10 +080056
hualing chene83bf812020-04-23 13:42:37 +080057 int ret = pthread_create(&thread, NULL, dvr_segment_thread, segment);
58 if (ret != 0) {
hualing chene83bf812020-04-23 13:42:37 +080059 if (segment != NULL) {
60 free(segment);
hualing chene83bf812020-04-23 13:42:37 +080061 }
62 }
Pengfei Liub4734232020-01-17 18:25:10 +080063 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +080064}
65
hualing chen4b7c15d2020-04-07 16:13:48 +080066int dvr_segment_del_by_location(const char *location)
67{
Zhiqiang Han02e890c2023-04-25 14:55:02 +080068#if 0
hualing chen4b7c15d2020-04-07 16:13:48 +080069 FILE *fp;
Weiwei Wang2ca253d2022-11-01 15:49:10 +080070 char cmd[DVR_MAX_LOCATION_SIZE * 2 + 64];
hualing chen4b7c15d2020-04-07 16:13:48 +080071
72 DVR_RETURN_IF_FALSE(location);
73
Wentao MA96f68962022-06-15 19:45:35 +080074 DVR_INFO("%s location:%s", __func__, location);
hualing chen4b7c15d2020-04-07 16:13:48 +080075 {
76 /* del file */
77 memset(cmd, 0, sizeof(cmd));
Zhiqiang Hane4349002024-03-26 10:50:42 +080078 sprintf(cmd, "rm \"%s\"-* \"%s\".list \"%s\".stats \"%s\".odb \"%s\".dat", location, location, location, location, location);
hualing chen4b7c15d2020-04-07 16:13:48 +080079 fp = popen(cmd, "r");
80 DVR_RETURN_IF_FALSE(fp);
81 }
Zhiqiang Han5c805cf2020-05-09 16:51:08 +080082 pclose(fp);
Zhiqiang Han02e890c2023-04-25 14:55:02 +080083#else
84 DVR_RETURN_IF_FALSE(location);
85
86 DVR_INFO("%s location:%s", __func__, location);
87
88 DIR *dir; // pointer to directory
89 struct dirent *entry; // pointer to file entry
Zhiqiang Han2f019af2023-08-31 11:12:02 +080090 char *loc_dname = NULL;
91 int loc_dname_len = 0;
92 char *loc_fname = NULL;
93 int loc_fname_len = 0;
94 char *path = NULL;
95 int path_size = 0;
Zhiqiang Han02e890c2023-04-25 14:55:02 +080096
97 /*get the dirname and filename*/
98 loc_fname = strrchr(location, '/');// fine last slash
Zhiqiang Han02482362023-06-16 10:10:21 +000099 if (loc_fname) {// skip the slash
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800100 loc_fname_len = strlen(loc_fname);
Zhiqiang Han02482362023-06-16 10:10:21 +0000101 loc_fname += 1;
102 loc_fname_len -= 1;
103 }
Zhiqiang Han02e890c2023-04-25 14:55:02 +0800104 DVR_RETURN_IF_FALSE(loc_fname_len != 0);
105
106 loc_dname_len = loc_fname - location;
107 loc_dname = malloc(loc_dname_len + 1);
108 DVR_RETURN_IF_FALSE(loc_dname != NULL);
109 memcpy(loc_dname, location, loc_dname_len);
110 loc_dname[loc_dname_len] = '\0';
111
112 path_size = strlen(location) + 32;//assume the file ext is no more than 32 bytes
113 path = malloc(path_size);
114 if (path) {
115 dir = opendir(loc_dname); // open directory
116 if (dir != NULL) {
117 while ((entry = readdir(dir)) != NULL) { // read each file entry
118 if (entry->d_type == DT_REG) { // only regular files
119 if (strncmp(entry->d_name, loc_fname, loc_fname_len) == 0) {
120 snprintf(path, path_size, "%s/%s", loc_dname, entry->d_name);
121 if (remove(path) != 0) {
122 DVR_INFO("%s cannot delete file:%s", __func__, path);
Zhiqiang Han02482362023-06-16 10:10:21 +0000123 } else {
124 //DVR_INFO("rm [%s] ok", path);
Zhiqiang Han02e890c2023-04-25 14:55:02 +0800125 }
126 }
127 }
128 }
129 closedir(dir); // close directory
130 } else {
131 DVR_INFO("%s location:%s canot open", __func__, location);
132 }
133 free(path);
134
135 } else {
Zhiqiang Han02e890c2023-04-25 14:55:02 +0800136 DVR_INFO("%s mem fail", __func__);
137 }
138
139 free(loc_dname);
140#endif
Wentao MA96f68962022-06-15 19:45:35 +0800141 DVR_INFO("%s location:%s end", __func__, location);
hualing chen4b7c15d2020-04-07 16:13:48 +0800142 return DVR_SUCCESS;
143}
144
Pengfei Liuc181a982020-01-07 19:27:13 +0800145int dvr_segment_get_list(const char *location, uint32_t *p_segment_nb, uint64_t **pp_segment_ids)
146{
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800147 FILE *fp;
148 char fpath[DVR_MAX_LOCATION_SIZE];
Zhiqiang Hanee5ac412020-05-07 20:54:32 +0800149 uint32_t i = 0, j = 0, n = 0;
hualing chenb270cfa2020-08-19 15:04:35 +0800150 char buf[DVR_MAX_LOCATION_SIZE + 10];
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800151 uint64_t *p = NULL;
hualing chenb270cfa2020-08-19 15:04:35 +0800152 char cmd[DVR_MAX_LOCATION_SIZE + 64];
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800153
154 DVR_RETURN_IF_FALSE(location);
155 DVR_RETURN_IF_FALSE(p_segment_nb);
156 DVR_RETURN_IF_FALSE(pp_segment_ids);
157
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800158 memset(fpath, 0, sizeof(fpath));
Wentao MAe2a2db92024-08-26 16:21:41 +0800159 snprintf(fpath, DVR_MAX_LOCATION_SIZE-5, "%s.list", location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800160
Wentao MAb2070812022-09-02 13:10:03 +0800161 fp = fopen(fpath, "r");
162 if (fp != NULL) { /*the list file exists*/
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800163 /*get segment numbers*/
hualing chenb270cfa2020-08-19 15:04:35 +0800164 while (fgets(buf, sizeof(buf), fp) != NULL) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800165 i++;
166 }
167 *p_segment_nb = i;
168 rewind(fp);
169 /*malloc*/
170 p = malloc(i * sizeof(uint64_t));
171 i = 0;
172 /*set value*/
173 memset(buf, 0, sizeof(buf));
hualing chenb270cfa2020-08-19 15:04:35 +0800174 while (fgets(buf, sizeof(buf), fp) != NULL) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800175 p[i++] = strtoull(buf, NULL, 10);
176 memset(buf, 0, sizeof(buf));
177 }
178 *pp_segment_ids = p;
179 fclose(fp);
Wentao MA96f68962022-06-15 19:45:35 +0800180 DVR_INFO("%s location:%s segments:%d", __func__, location, i);
Wentao MAb2070812022-09-02 13:10:03 +0800181 } else { /*the list file does not exist*/
hualing chenb270cfa2020-08-19 15:04:35 +0800182 uint32_t id = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800183 memset(cmd, 0, sizeof(cmd));
Wentao MAe2a2db92024-08-26 16:21:41 +0800184 snprintf(cmd, DVR_MAX_LOCATION_SIZE+44, "ls -l \"%s\"-*.ts | wc -l", location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800185 fp = popen(cmd, "r");
186 DVR_RETURN_IF_FALSE(fp);
187 memset(buf, 0, sizeof(buf));
188 if (fgets(buf, sizeof(buf), fp) != NULL) {
Wentao MAb2070812022-09-02 13:10:03 +0800189 i = strtoul(buf, NULL, 10);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800190 pclose(fp);
wentao.maf57dd232022-10-08 16:07:29 +0800191 DVR_RETURN_IF_FALSE(i>0);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800192 } else {
193 pclose(fp);
wentao.maf57dd232022-10-08 16:07:29 +0800194 DVR_ERROR("%s location:%s get null", __func__, location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800195 return DVR_FAILURE;
196 }
Zhiqiang Hanee5ac412020-05-07 20:54:32 +0800197 n = i;
Wentao MA4b8d4752022-09-14 19:03:45 +0800198
Zhiqiang Han8dd08b32020-05-13 16:50:04 +0800199 /*try to get the 1st segment id*/
200 memset(cmd, 0, sizeof(cmd));
Wentao MAe2a2db92024-08-26 16:21:41 +0800201 snprintf(cmd, DVR_MAX_LOCATION_SIZE+55,"ls \"%s\"-*.ts", location);
Zhiqiang Han8dd08b32020-05-13 16:50:04 +0800202 fp = popen(cmd, "r");
203 DVR_RETURN_IF_FALSE(fp);
204 memset(buf, 0, sizeof(buf));
hualing chenb270cfa2020-08-19 15:04:35 +0800205 j = 0;
206 snprintf(fpath, sizeof(fpath), "%s-%%d.ts", location);
Wentao MA4b8d4752022-09-14 19:03:45 +0800207
wentao.maf57dd232022-10-08 16:07:29 +0800208 // Tainted data issue originating from fgets seem false positive, so we
209 // just suppress it here.
210 // coverity[tainted_data]
Wentao MA4b8d4752022-09-14 19:03:45 +0800211 p = malloc(n * sizeof(uint64_t));
Wentao MA4d85ff32022-09-23 11:36:18 +0800212 if (p == NULL) {
213 DVR_ERROR("%s, Failed to allocate memory with errno:%d (%s)",
214 __func__,errno,strerror(errno));
215 pclose(fp);
216 return DVR_FAILURE;
217 }
Wentao MA4b8d4752022-09-14 19:03:45 +0800218
hualing chenb270cfa2020-08-19 15:04:35 +0800219 while (fgets(buf, sizeof(buf), fp) != NULL) {
hualing chenb270cfa2020-08-19 15:04:35 +0800220 if (sscanf(buf, fpath, &id) != 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800221 DVR_INFO("%s location:%s buf:%s not get id", __func__, location, buf);
hualing chenb270cfa2020-08-19 15:04:35 +0800222 id = 0;
223 n = n -1;
224 } else {
hualing chenb270cfa2020-08-19 15:04:35 +0800225 p[j++] = id;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800226 }
hualing chenb270cfa2020-08-19 15:04:35 +0800227 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800228 }
Wentao MA96f68962022-06-15 19:45:35 +0800229 DVR_DEBUG("%s location:%s n=%d j=%d end", __func__, location, n, j);
hualing chenb270cfa2020-08-19 15:04:35 +0800230 pclose(fp);
231 *p_segment_nb = n;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800232 *pp_segment_ids = p;
233 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800234
Pengfei Liub4734232020-01-17 18:25:10 +0800235 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800236}
237
Pengfei Liub4734232020-01-17 18:25:10 +0800238int dvr_segment_get_info(const char *location, uint64_t segment_id, DVR_RecordSegmentInfo_t *p_info)
Pengfei Liuc181a982020-01-07 19:27:13 +0800239{
Pengfei Liub4734232020-01-17 18:25:10 +0800240 int ret;
241 Segment_OpenParams_t open_params;
Wentao MAe2a2db92024-08-26 16:21:41 +0800242 Segment_Handle_t segment_handle = NULL;
Pengfei Liub4734232020-01-17 18:25:10 +0800243
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800244 DVR_RETURN_IF_FALSE(location);
245 DVR_RETURN_IF_FALSE(p_info);
246 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liub4734232020-01-17 18:25:10 +0800247
248 memset(&open_params, 0, sizeof(open_params));
249 memcpy(open_params.location, location, strlen(location));
250 open_params.segment_id = segment_id;
251 open_params.mode = SEGMENT_MODE_READ;
wentao.maf57dd232022-10-08 16:07:29 +0800252
253 // Previous location strlen checking againest DVR_MAX_LOCATION_SIZE and
wentao.mafd5283f2022-10-14 09:51:13 +0800254 // latter memset on open_params ensure that open_params.location is
wentao.maf57dd232022-10-08 16:07:29 +0800255 // null-terminated, so the Coverity STRING_NULL error is suppressed here.
256 // coverity[string_null]
Pengfei Liub4734232020-01-17 18:25:10 +0800257 ret = segment_open(&open_params, &segment_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800258 if (ret == DVR_SUCCESS) {
259 ret = segment_load_info(segment_handle, p_info);
Wentao MA07d3d742022-09-06 09:58:05 +0800260 if (ret != DVR_SUCCESS) {
261 DVR_ERROR("segment_load_info failed with return value %d",ret);
262 }
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800263 }
Wentao MA96f68962022-06-15 19:45:35 +0800264 DVR_DEBUG("%s, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
hualing chen926a8ec2021-12-20 20:38:24 +0800265 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
hualing chenb2242352021-05-18 17:16:16 +0800266 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800267 ret = segment_close(segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800268 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800269
270 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800271}
272
hualing chenb9a02922021-12-14 11:29:47 +0800273int dvr_segment_get_allInfo(const char *location, struct list_head *list)
274{
275 int ret;
276 Segment_OpenParams_t open_params;
Wentao MAe2a2db92024-08-26 16:21:41 +0800277 Segment_Handle_t segment_handle = NULL;
hualing chenb9a02922021-12-14 11:29:47 +0800278
279 DVR_RETURN_IF_FALSE(location);
280 DVR_RETURN_IF_FALSE(list);
281 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
282
283 memset(&open_params, 0, sizeof(open_params));
284 memcpy(open_params.location, location, strlen(location));
285 open_params.segment_id = 0;
286 open_params.mode = SEGMENT_MODE_READ;
wentao.maf57dd232022-10-08 16:07:29 +0800287
288 // Previous location strlen checking againest DVR_MAX_LOCATION_SIZE and
wentao.mafd5283f2022-10-14 09:51:13 +0800289 // latter memset on open_params ensure that open_params.location is
wentao.maf57dd232022-10-08 16:07:29 +0800290 // null-terminated, so the Coverity STRING_NULL error is suppressed here.
291 // coverity[string_null]
hualing chenb9a02922021-12-14 11:29:47 +0800292 ret = segment_open(&open_params, &segment_handle);
293 if (ret == DVR_SUCCESS) {
294 ret = segment_load_allInfo(segment_handle, list);
hualing chen926a8ec2021-12-20 20:38:24 +0800295 if (ret == DVR_FAILURE) {
296 segment_close(segment_handle);
297 return DVR_FAILURE;
298 }
hualing chenb9a02922021-12-14 11:29:47 +0800299 }
300 ret = segment_close(segment_handle);
301 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
302
303 return DVR_SUCCESS;
304}
305
306
Pengfei Liuc181a982020-01-07 19:27:13 +0800307int dvr_segment_link(const char *location, uint32_t nb_segments, uint64_t *p_segment_ids)
308{
Wentao MAe8ba5172022-08-09 11:18:17 +0800309 return dvr_segment_link_op(location, nb_segments, p_segment_ids, SEGMENT_OP_NEW);
Zhiqiang Hane0a1c382021-06-08 11:28:05 +0800310}
311
312int dvr_segment_link_op(const char *location, uint32_t nb_segments, uint64_t *p_segment_ids, int op)
313{
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800314 FILE *fp;
315 char fpath[DVR_MAX_LOCATION_SIZE];
316 uint32_t i;
hualing chenb270cfa2020-08-19 15:04:35 +0800317 char buf[DVR_MAX_LOCATION_SIZE + 64];
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800318
319 DVR_RETURN_IF_FALSE(location);
320 DVR_RETURN_IF_FALSE(p_segment_ids);
321 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
322
Wentao MA96f68962022-06-15 19:45:35 +0800323 DVR_INFO("%s op[%d] location:%s, nb_segments:%d", __func__, op, location, nb_segments);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800324 memset(fpath, 0, sizeof(fpath));
Wentao MAe2a2db92024-08-26 16:21:41 +0800325 snprintf(fpath, DVR_MAX_LOCATION_SIZE-5, "%s.list", location);
Wentao MAe8ba5172022-08-09 11:18:17 +0800326 fp = fopen(fpath, (op == SEGMENT_OP_ADD) ? "a+" : "w+");
Zhiqiang Hane0a1c382021-06-08 11:28:05 +0800327 if (!fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800328 DVR_INFO("failed to open list file, err:%d:%s", errno, strerror(errno));
Zhiqiang Hane0a1c382021-06-08 11:28:05 +0800329 return DVR_FAILURE;
330 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800331 for (i = 0; i< nb_segments; i++) {
332 memset(buf, 0, sizeof(buf));
Zhiqiang Hane0a1c382021-06-08 11:28:05 +0800333 sprintf(buf, "%lld\n", p_segment_ids[i]);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800334 fwrite(buf, 1, strlen(buf), fp);
335 }
336
337 fflush(fp);
Zhiqiang Hanc43a4d22023-10-25 15:24:19 +0800338 //fsync(fileno(fp));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800339 fclose(fp);
Pengfei Liub4734232020-01-17 18:25:10 +0800340 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800341}