blob: e0f096739aa1176831a3efec403b5e1fb2e42b53 [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>
Pengfei Liuc181a982020-01-07 19:27:13 +08009
Pengfei Liub4734232020-01-17 18:25:10 +080010/**\brief DVR segment file information*/
11typedef struct {
12 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
13 uint64_t id; /**< DVR Segment id*/
14} DVR_SegmentFile_t;
15
16void *dvr_segment_thread(void *arg)
17{
Pengfei Liub4734232020-01-17 18:25:10 +080018 int ret;
hualing chene83bf812020-04-23 13:42:37 +080019 DVR_SegmentFile_t *segment_file = (DVR_SegmentFile_t*)arg;
Wentao MA16f870e2022-09-09 11:00:22 +080020 if (segment_file == NULL) {
21 DVR_ERROR("Invalid segment_file pointer");
22 return NULL;
23 }
Pengfei Liub4734232020-01-17 18:25:10 +080024
hualing chen31140872020-03-25 12:29:26 +080025 pthread_detach(pthread_self());
Wentao MA96f68962022-06-15 19:45:35 +080026 DVR_INFO("%s try to delete [%s-%lld]", __func__, segment_file->location, segment_file->id);
hualing chene83bf812020-04-23 13:42:37 +080027 ret = segment_delete(segment_file->location, segment_file->id);
Wentao MA96f68962022-06-15 19:45:35 +080028 DVR_INFO("%s delete segment [%s-%lld] %s", __func__, segment_file->location, segment_file->id,
Pengfei Liub4734232020-01-17 18:25:10 +080029 ret == DVR_SUCCESS ? "success" : "failed");
hualing chene83bf812020-04-23 13:42:37 +080030 if (segment_file != NULL) {
31 //malloc at delete api.free at this
32 free(segment_file);
hualing chene83bf812020-04-23 13:42:37 +080033 }
Pengfei Liub4734232020-01-17 18:25:10 +080034 return NULL;
35}
Pengfei Liu3b1a8202020-02-12 23:04:21 +080036
Pengfei Liuc181a982020-01-07 19:27:13 +080037int dvr_segment_delete(const char *location, uint64_t segment_id)
38{
hualing chen6d24aa92020-03-23 18:43:47 +080039
Pengfei Liub4734232020-01-17 18:25:10 +080040 pthread_t thread;
hualing chene83bf812020-04-23 13:42:37 +080041 DVR_SegmentFile_t *segment;
Pengfei Liub4734232020-01-17 18:25:10 +080042
Pengfei Liu3b1a8202020-02-12 23:04:21 +080043 DVR_RETURN_IF_FALSE(location);
44 DVR_RETURN_IF_FALSE(strlen(location) < DVR_MAX_LOCATION_SIZE);
Wentao MA4b8d4752022-09-14 19:03:45 +080045 DVR_INFO("In function %s, segment %s's id is %lld", __func__, location, segment_id);
46
47 // Memory allocated here will be freed in segment deletion thread under normal conditions.
48 // In case of thread creation failure, it will be freed right away.
49 segment = (DVR_SegmentFile_t *)malloc(sizeof(DVR_SegmentFile_t));
50 DVR_RETURN_IF_FALSE(segment != NULL);
51
hualing chene83bf812020-04-23 13:42:37 +080052 memset(segment->location, 0, sizeof(segment->location));
53 memcpy(segment->location, location, strlen(location));
54 segment->id = segment_id;
Zhiqiang Han2d8cd822020-03-16 13:58:10 +080055
hualing chene83bf812020-04-23 13:42:37 +080056 int ret = pthread_create(&thread, NULL, dvr_segment_thread, segment);
57 if (ret != 0) {
hualing chene83bf812020-04-23 13:42:37 +080058 if (segment != NULL) {
59 free(segment);
hualing chene83bf812020-04-23 13:42:37 +080060 }
61 }
Pengfei Liub4734232020-01-17 18:25:10 +080062 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +080063}
64
hualing chen4b7c15d2020-04-07 16:13:48 +080065int dvr_segment_del_by_location(const char *location)
66{
67 FILE *fp;
Weiwei Wang2ca253d2022-11-01 15:49:10 +080068 char cmd[DVR_MAX_LOCATION_SIZE * 2 + 64];
hualing chen4b7c15d2020-04-07 16:13:48 +080069
70 DVR_RETURN_IF_FALSE(location);
71
Wentao MA96f68962022-06-15 19:45:35 +080072 DVR_INFO("%s location:%s", __func__, location);
hualing chen4b7c15d2020-04-07 16:13:48 +080073 {
74 /* del file */
75 memset(cmd, 0, sizeof(cmd));
hualing chen926a8ec2021-12-20 20:38:24 +080076 sprintf(cmd, "rm %s-* %s.list %s.stats %s.odb %s.dat", location, location, location, location, location);
hualing chen4b7c15d2020-04-07 16:13:48 +080077 fp = popen(cmd, "r");
78 DVR_RETURN_IF_FALSE(fp);
79 }
Zhiqiang Han5c805cf2020-05-09 16:51:08 +080080 pclose(fp);
Wentao MA96f68962022-06-15 19:45:35 +080081 DVR_INFO("%s location:%s end", __func__, location);
hualing chen4b7c15d2020-04-07 16:13:48 +080082 return DVR_SUCCESS;
83}
84
Pengfei Liuc181a982020-01-07 19:27:13 +080085int dvr_segment_get_list(const char *location, uint32_t *p_segment_nb, uint64_t **pp_segment_ids)
86{
Pengfei Liu3b1a8202020-02-12 23:04:21 +080087 FILE *fp;
88 char fpath[DVR_MAX_LOCATION_SIZE];
Zhiqiang Hanee5ac412020-05-07 20:54:32 +080089 uint32_t i = 0, j = 0, n = 0;
hualing chenb270cfa2020-08-19 15:04:35 +080090 char buf[DVR_MAX_LOCATION_SIZE + 10];
Pengfei Liu3b1a8202020-02-12 23:04:21 +080091 uint64_t *p = NULL;
hualing chenb270cfa2020-08-19 15:04:35 +080092 char cmd[DVR_MAX_LOCATION_SIZE + 64];
Pengfei Liu3b1a8202020-02-12 23:04:21 +080093
94 DVR_RETURN_IF_FALSE(location);
95 DVR_RETURN_IF_FALSE(p_segment_nb);
96 DVR_RETURN_IF_FALSE(pp_segment_ids);
97
Pengfei Liu3b1a8202020-02-12 23:04:21 +080098 memset(fpath, 0, sizeof(fpath));
99 sprintf(fpath, "%s.list", location);
100
Wentao MAb2070812022-09-02 13:10:03 +0800101 fp = fopen(fpath, "r");
102 if (fp != NULL) { /*the list file exists*/
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800103 /*get segment numbers*/
hualing chenb270cfa2020-08-19 15:04:35 +0800104 while (fgets(buf, sizeof(buf), fp) != NULL) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800105 i++;
106 }
107 *p_segment_nb = i;
108 rewind(fp);
109 /*malloc*/
110 p = malloc(i * sizeof(uint64_t));
111 i = 0;
112 /*set value*/
113 memset(buf, 0, sizeof(buf));
hualing chenb270cfa2020-08-19 15:04:35 +0800114 while (fgets(buf, sizeof(buf), fp) != NULL) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800115 p[i++] = strtoull(buf, NULL, 10);
116 memset(buf, 0, sizeof(buf));
117 }
118 *pp_segment_ids = p;
119 fclose(fp);
Wentao MA96f68962022-06-15 19:45:35 +0800120 DVR_INFO("%s location:%s segments:%d", __func__, location, i);
Wentao MAb2070812022-09-02 13:10:03 +0800121 } else { /*the list file does not exist*/
hualing chenb270cfa2020-08-19 15:04:35 +0800122 uint32_t id = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800123 memset(cmd, 0, sizeof(cmd));
Zhiqiang Hanade34ff2020-04-17 16:50:59 +0800124 sprintf(cmd, "ls -l %s-*.ts | wc -l", location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800125 fp = popen(cmd, "r");
126 DVR_RETURN_IF_FALSE(fp);
127 memset(buf, 0, sizeof(buf));
128 if (fgets(buf, sizeof(buf), fp) != NULL) {
Wentao MAb2070812022-09-02 13:10:03 +0800129 i = strtoul(buf, NULL, 10);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800130 pclose(fp);
wentao.maf57dd232022-10-08 16:07:29 +0800131 DVR_RETURN_IF_FALSE(i>0);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800132 } else {
133 pclose(fp);
wentao.maf57dd232022-10-08 16:07:29 +0800134 DVR_ERROR("%s location:%s get null", __func__, location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800135 return DVR_FAILURE;
136 }
Zhiqiang Hanee5ac412020-05-07 20:54:32 +0800137 n = i;
Wentao MA4b8d4752022-09-14 19:03:45 +0800138
Zhiqiang Han8dd08b32020-05-13 16:50:04 +0800139 /*try to get the 1st segment id*/
140 memset(cmd, 0, sizeof(cmd));
hualing chenb270cfa2020-08-19 15:04:35 +0800141 sprintf(cmd, "ls %s-*.ts", location);
Zhiqiang Han8dd08b32020-05-13 16:50:04 +0800142 fp = popen(cmd, "r");
143 DVR_RETURN_IF_FALSE(fp);
144 memset(buf, 0, sizeof(buf));
hualing chenb270cfa2020-08-19 15:04:35 +0800145 j = 0;
146 snprintf(fpath, sizeof(fpath), "%s-%%d.ts", location);
Wentao MA4b8d4752022-09-14 19:03:45 +0800147
wentao.maf57dd232022-10-08 16:07:29 +0800148 // Tainted data issue originating from fgets seem false positive, so we
149 // just suppress it here.
150 // coverity[tainted_data]
Wentao MA4b8d4752022-09-14 19:03:45 +0800151 p = malloc(n * sizeof(uint64_t));
Wentao MA4d85ff32022-09-23 11:36:18 +0800152 if (p == NULL) {
153 DVR_ERROR("%s, Failed to allocate memory with errno:%d (%s)",
154 __func__,errno,strerror(errno));
155 pclose(fp);
156 return DVR_FAILURE;
157 }
Wentao MA4b8d4752022-09-14 19:03:45 +0800158
hualing chenb270cfa2020-08-19 15:04:35 +0800159 while (fgets(buf, sizeof(buf), fp) != NULL) {
hualing chenb270cfa2020-08-19 15:04:35 +0800160 if (sscanf(buf, fpath, &id) != 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800161 DVR_INFO("%s location:%s buf:%s not get id", __func__, location, buf);
hualing chenb270cfa2020-08-19 15:04:35 +0800162 id = 0;
163 n = n -1;
164 } else {
hualing chenb270cfa2020-08-19 15:04:35 +0800165 p[j++] = id;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800166 }
hualing chenb270cfa2020-08-19 15:04:35 +0800167 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800168 }
Wentao MA96f68962022-06-15 19:45:35 +0800169 DVR_DEBUG("%s location:%s n=%d j=%d end", __func__, location, n, j);
hualing chenb270cfa2020-08-19 15:04:35 +0800170 pclose(fp);
171 *p_segment_nb = n;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800172 *pp_segment_ids = p;
173 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800174
Pengfei Liub4734232020-01-17 18:25:10 +0800175 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800176}
177
Pengfei Liub4734232020-01-17 18:25:10 +0800178int dvr_segment_get_info(const char *location, uint64_t segment_id, DVR_RecordSegmentInfo_t *p_info)
Pengfei Liuc181a982020-01-07 19:27:13 +0800179{
Pengfei Liub4734232020-01-17 18:25:10 +0800180 int ret;
181 Segment_OpenParams_t open_params;
182 Segment_Handle_t segment_handle;
183
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800184 DVR_RETURN_IF_FALSE(location);
185 DVR_RETURN_IF_FALSE(p_info);
186 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liub4734232020-01-17 18:25:10 +0800187
188 memset(&open_params, 0, sizeof(open_params));
189 memcpy(open_params.location, location, strlen(location));
190 open_params.segment_id = segment_id;
191 open_params.mode = SEGMENT_MODE_READ;
wentao.maf57dd232022-10-08 16:07:29 +0800192
193 // Previous location strlen checking againest DVR_MAX_LOCATION_SIZE and
wentao.mafd5283f2022-10-14 09:51:13 +0800194 // latter memset on open_params ensure that open_params.location is
wentao.maf57dd232022-10-08 16:07:29 +0800195 // null-terminated, so the Coverity STRING_NULL error is suppressed here.
196 // coverity[string_null]
Pengfei Liub4734232020-01-17 18:25:10 +0800197 ret = segment_open(&open_params, &segment_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800198 if (ret == DVR_SUCCESS) {
199 ret = segment_load_info(segment_handle, p_info);
Wentao MA07d3d742022-09-06 09:58:05 +0800200 if (ret != DVR_SUCCESS) {
201 DVR_ERROR("segment_load_info failed with return value %d",ret);
202 }
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800203 }
Wentao MA96f68962022-06-15 19:45:35 +0800204 DVR_DEBUG("%s, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
hualing chen926a8ec2021-12-20 20:38:24 +0800205 __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 +0800206 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800207 ret = segment_close(segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800208 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800209
210 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800211}
212
hualing chenb9a02922021-12-14 11:29:47 +0800213int dvr_segment_get_allInfo(const char *location, struct list_head *list)
214{
215 int ret;
216 Segment_OpenParams_t open_params;
217 Segment_Handle_t segment_handle;
218
219 DVR_RETURN_IF_FALSE(location);
220 DVR_RETURN_IF_FALSE(list);
221 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
222
223 memset(&open_params, 0, sizeof(open_params));
224 memcpy(open_params.location, location, strlen(location));
225 open_params.segment_id = 0;
226 open_params.mode = SEGMENT_MODE_READ;
wentao.maf57dd232022-10-08 16:07:29 +0800227
228 // Previous location strlen checking againest DVR_MAX_LOCATION_SIZE and
wentao.mafd5283f2022-10-14 09:51:13 +0800229 // latter memset on open_params ensure that open_params.location is
wentao.maf57dd232022-10-08 16:07:29 +0800230 // null-terminated, so the Coverity STRING_NULL error is suppressed here.
231 // coverity[string_null]
hualing chenb9a02922021-12-14 11:29:47 +0800232 ret = segment_open(&open_params, &segment_handle);
233 if (ret == DVR_SUCCESS) {
234 ret = segment_load_allInfo(segment_handle, list);
hualing chen926a8ec2021-12-20 20:38:24 +0800235 if (ret == DVR_FAILURE) {
236 segment_close(segment_handle);
237 return DVR_FAILURE;
238 }
hualing chenb9a02922021-12-14 11:29:47 +0800239 }
240 ret = segment_close(segment_handle);
241 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
242
243 return DVR_SUCCESS;
244}
245
246
Pengfei Liuc181a982020-01-07 19:27:13 +0800247int dvr_segment_link(const char *location, uint32_t nb_segments, uint64_t *p_segment_ids)
248{
Wentao MAe8ba5172022-08-09 11:18:17 +0800249 return dvr_segment_link_op(location, nb_segments, p_segment_ids, SEGMENT_OP_NEW);
Zhiqiang Hane0a1c382021-06-08 11:28:05 +0800250}
251
252int dvr_segment_link_op(const char *location, uint32_t nb_segments, uint64_t *p_segment_ids, int op)
253{
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800254 FILE *fp;
255 char fpath[DVR_MAX_LOCATION_SIZE];
256 uint32_t i;
hualing chenb270cfa2020-08-19 15:04:35 +0800257 char buf[DVR_MAX_LOCATION_SIZE + 64];
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800258
259 DVR_RETURN_IF_FALSE(location);
260 DVR_RETURN_IF_FALSE(p_segment_ids);
261 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
262
Wentao MA96f68962022-06-15 19:45:35 +0800263 DVR_INFO("%s op[%d] location:%s, nb_segments:%d", __func__, op, location, nb_segments);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800264 memset(fpath, 0, sizeof(fpath));
265 sprintf(fpath, "%s.list", location);
Wentao MAe8ba5172022-08-09 11:18:17 +0800266 fp = fopen(fpath, (op == SEGMENT_OP_ADD) ? "a+" : "w+");
Zhiqiang Hane0a1c382021-06-08 11:28:05 +0800267 if (!fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800268 DVR_INFO("failed to open list file, err:%d:%s", errno, strerror(errno));
Zhiqiang Hane0a1c382021-06-08 11:28:05 +0800269 return DVR_FAILURE;
270 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800271 for (i = 0; i< nb_segments; i++) {
272 memset(buf, 0, sizeof(buf));
Zhiqiang Hane0a1c382021-06-08 11:28:05 +0800273 sprintf(buf, "%lld\n", p_segment_ids[i]);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800274 fwrite(buf, 1, strlen(buf), fp);
275 }
276
277 fflush(fp);
278 fsync(fileno(fp));
279 fclose(fp);
Pengfei Liub4734232020-01-17 18:25:10 +0800280 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800281}