blob: ced1d202b558195f0928c7181b0acd39225a01c3 [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>
5#include <pthread.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08006#include "dvr_segment.h"
Pengfei Liub4734232020-01-17 18:25:10 +08007#include <segment.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08008
Pengfei Liub4734232020-01-17 18:25:10 +08009/**\brief DVR segment file information*/
10typedef struct {
11 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
12 uint64_t id; /**< DVR Segment id*/
13} DVR_SegmentFile_t;
14
15void *dvr_segment_thread(void *arg)
16{
Pengfei Liub4734232020-01-17 18:25:10 +080017 int ret;
hualing chene83bf812020-04-23 13:42:37 +080018 DVR_SegmentFile_t *segment_file = (DVR_SegmentFile_t*)arg;
Pengfei Liub4734232020-01-17 18:25:10 +080019
hualing chen31140872020-03-25 12:29:26 +080020 pthread_detach(pthread_self());
hualing chene83bf812020-04-23 13:42:37 +080021 DVR_DEBUG(1, "%s try to delete [%s-%lld]", __func__, segment_file->location, segment_file->id);
22 ret = segment_delete(segment_file->location, segment_file->id);
23 DVR_DEBUG(1, "%s delete segment [%s-%lld] %s", __func__, segment_file->location, segment_file->id,
Pengfei Liub4734232020-01-17 18:25:10 +080024 ret == DVR_SUCCESS ? "success" : "failed");
hualing chene83bf812020-04-23 13:42:37 +080025 if (segment_file != NULL) {
26 //malloc at delete api.free at this
27 free(segment_file);
28 segment_file = NULL;
29 }
Pengfei Liub4734232020-01-17 18:25:10 +080030 return NULL;
31}
Pengfei Liu3b1a8202020-02-12 23:04:21 +080032
Pengfei Liuc181a982020-01-07 19:27:13 +080033int dvr_segment_delete(const char *location, uint64_t segment_id)
34{
hualing chen6d24aa92020-03-23 18:43:47 +080035
Pengfei Liub4734232020-01-17 18:25:10 +080036 pthread_t thread;
hualing chene83bf812020-04-23 13:42:37 +080037 DVR_SegmentFile_t *segment;
38 //this segment will be free at del thread when used end.if thread
39 //creat error.will be free now.
40 segment = (DVR_SegmentFile_t *)malloc(sizeof(DVR_SegmentFile_t));
Pengfei Liub4734232020-01-17 18:25:10 +080041
42 DVR_DEBUG(1, "%s in, %s,id:%lld", __func__, location, segment_id);
hualing chene83bf812020-04-23 13:42:37 +080043 DVR_RETURN_IF_FALSE(segment);
Pengfei Liu3b1a8202020-02-12 23:04:21 +080044 DVR_RETURN_IF_FALSE(location);
45 DVR_RETURN_IF_FALSE(strlen(location) < DVR_MAX_LOCATION_SIZE);
hualing chene83bf812020-04-23 13:42:37 +080046 memset(segment->location, 0, sizeof(segment->location));
47 memcpy(segment->location, location, strlen(location));
48 segment->id = segment_id;
Zhiqiang Han2d8cd822020-03-16 13:58:10 +080049
hualing chene83bf812020-04-23 13:42:37 +080050 int ret = pthread_create(&thread, NULL, dvr_segment_thread, segment);
51 if (ret != 0) {
52 //creat thread error,need free segment
53 if (segment != NULL) {
54 free(segment);
55 segment = NULL;
56 }
57 }
Pengfei Liub4734232020-01-17 18:25:10 +080058 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +080059}
60
hualing chen4b7c15d2020-04-07 16:13:48 +080061int dvr_segment_del_by_location(const char *location)
62{
63 FILE *fp;
64 char fpath[DVR_MAX_LOCATION_SIZE];
65 char cmd[256];
66
67 DVR_RETURN_IF_FALSE(location);
68
69 DVR_DEBUG(1, "%s location:%s", __func__, location);
70 memset(fpath, 0, sizeof(fpath));
71 sprintf(fpath, "%s.del", location);
72 {
73 /* del file */
74 memset(cmd, 0, sizeof(cmd));
Zhiqiang Hanade34ff2020-04-17 16:50:59 +080075 sprintf(cmd, "rm %s-*", location);
hualing chen4b7c15d2020-04-07 16:13:48 +080076 fp = popen(cmd, "r");
77 DVR_RETURN_IF_FALSE(fp);
78 }
hualing chen7a56cba2020-04-14 14:09:27 +080079 DVR_DEBUG(1, "%s location:%s end", __func__, location);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +080080 pclose(fp);
hualing chen4b7c15d2020-04-07 16:13:48 +080081 return DVR_SUCCESS;
82}
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;
Pengfei Liu3b1a8202020-02-12 23:04:21 +080090 char buf[64];
91 uint64_t *p = NULL;
92 char cmd[256];
93
94 DVR_RETURN_IF_FALSE(location);
95 DVR_RETURN_IF_FALSE(p_segment_nb);
96 DVR_RETURN_IF_FALSE(pp_segment_ids);
97
98 DVR_DEBUG(1, "%s location:%s", __func__, location);
99 memset(fpath, 0, sizeof(fpath));
100 sprintf(fpath, "%s.list", location);
101
102 if (access(fpath, 0) != -1) {
103 /*the list file is exist*/
104 fp = fopen(fpath, "r");
105 DVR_RETURN_IF_FALSE(fp);
106 /*get segment numbers*/
107 while (fgets(buf, sizeof(buf), fp) != NULL) {
108 i++;
109 }
110 *p_segment_nb = i;
111 rewind(fp);
112 /*malloc*/
113 p = malloc(i * sizeof(uint64_t));
114 i = 0;
115 /*set value*/
116 memset(buf, 0, sizeof(buf));
117 while (fgets(buf, sizeof(buf), fp) != NULL) {
118 p[i++] = strtoull(buf, NULL, 10);
119 memset(buf, 0, sizeof(buf));
120 }
121 *pp_segment_ids = p;
122 fclose(fp);
123 } else {
Zhiqiang Han8dd08b32020-05-13 16:50:04 +0800124 uint32_t start = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800125 /*the list file does not exist*/
126 memset(cmd, 0, sizeof(cmd));
Zhiqiang Hanade34ff2020-04-17 16:50:59 +0800127 sprintf(cmd, "ls -l %s-*.ts | wc -l", location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800128 fp = popen(cmd, "r");
129 DVR_RETURN_IF_FALSE(fp);
130 memset(buf, 0, sizeof(buf));
131 if (fgets(buf, sizeof(buf), fp) != NULL) {
132 i = strtoull(buf, NULL, 10);
133 pclose(fp);
134 } else {
135 pclose(fp);
136 return DVR_FAILURE;
137 }
138
Zhiqiang Hanee5ac412020-05-07 20:54:32 +0800139 n = i;
140 p = malloc(n * sizeof(uint64_t));
Zhiqiang Han8dd08b32020-05-13 16:50:04 +0800141
142 /*try to get the 1st segment id*/
143 memset(cmd, 0, sizeof(cmd));
144 sprintf(cmd, "ls %s-*.ts | head -n 1", location);
145 fp = popen(cmd, "r");
146 DVR_RETURN_IF_FALSE(fp);
147 memset(buf, 0, sizeof(buf));
148 if (fgets(buf, sizeof(buf), fp) != NULL) {
149 snprintf(fpath, sizeof(fpath), "%s-%%d.ts", location);
150 if (sscanf(buf, fpath, &start) != 1)
151 start = 0;
152 }
153 pclose(fp);
154
155 for (i = start; i < (start + n); i++) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800156 memset(fpath, 0, sizeof(fpath));
157 sprintf(fpath, "%s-%04d.ts", location, i);
158 if (access(fpath, 0) != -1) {
159 p[j++] = i;
160 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800161 }
Zhiqiang Hanee5ac412020-05-07 20:54:32 +0800162 *p_segment_nb = j;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800163 *pp_segment_ids = p;
164 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800165
Pengfei Liub4734232020-01-17 18:25:10 +0800166 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800167}
168
Pengfei Liub4734232020-01-17 18:25:10 +0800169int dvr_segment_get_info(const char *location, uint64_t segment_id, DVR_RecordSegmentInfo_t *p_info)
Pengfei Liuc181a982020-01-07 19:27:13 +0800170{
Pengfei Liub4734232020-01-17 18:25:10 +0800171 int ret;
172 Segment_OpenParams_t open_params;
173 Segment_Handle_t segment_handle;
174
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800175 DVR_RETURN_IF_FALSE(location);
176 DVR_RETURN_IF_FALSE(p_info);
177 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liub4734232020-01-17 18:25:10 +0800178
179 memset(&open_params, 0, sizeof(open_params));
180 memcpy(open_params.location, location, strlen(location));
181 open_params.segment_id = segment_id;
182 open_params.mode = SEGMENT_MODE_READ;
183 ret = segment_open(&open_params, &segment_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800184 if (ret == DVR_SUCCESS) {
185 ret = segment_load_info(segment_handle, p_info);
186 }
hualing chena540a7e2020-03-27 16:44:05 +0800187 //DVR_DEBUG(1, "%s, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
188 // __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
Pengfei Liub4734232020-01-17 18:25:10 +0800189
190 ret = segment_close(segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800191 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800192
193 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800194}
195
196int dvr_segment_link(const char *location, uint32_t nb_segments, uint64_t *p_segment_ids)
197{
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800198 FILE *fp;
199 char fpath[DVR_MAX_LOCATION_SIZE];
200 uint32_t i;
201 char buf[64];
202
203 DVR_RETURN_IF_FALSE(location);
204 DVR_RETURN_IF_FALSE(p_segment_ids);
205 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
206
207 DVR_DEBUG(1, "%s location:%s, nb_segments:%d", __func__, location, nb_segments);
208 memset(fpath, 0, sizeof(fpath));
209 sprintf(fpath, "%s.list", location);
210 fp = fopen(fpath, "w+");
211 for (i = 0; i< nb_segments; i++) {
212 memset(buf, 0, sizeof(buf));
213 sprintf(buf, "%lld", p_segment_ids[i]);
214 fwrite(buf, 1, strlen(buf), fp);
215 }
216
217 fflush(fp);
218 fsync(fileno(fp));
219 fclose(fp);
Pengfei Liub4734232020-01-17 18:25:10 +0800220 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800221}