blob: ea797c576869fc10a1914eb59b5e5930044f9e85 [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*/
hualing chene83bf812020-04-23 13:42:37 +080013 pthread_mutex_t lock; /**< DVR segment lock*/
Pengfei Liub4734232020-01-17 18:25:10 +080014} 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;
Pengfei Liub4734232020-01-17 18:25:10 +080020
hualing chen31140872020-03-25 12:29:26 +080021 pthread_detach(pthread_self());
hualing chene83bf812020-04-23 13:42:37 +080022 DVR_DEBUG(1, "%s try to delete [%s-%lld]", __func__, segment_file->location, segment_file->id);
23 ret = segment_delete(segment_file->location, segment_file->id);
24 DVR_DEBUG(1, "%s delete segment [%s-%lld] %s", __func__, segment_file->location, segment_file->id,
Pengfei Liub4734232020-01-17 18:25:10 +080025 ret == DVR_SUCCESS ? "success" : "failed");
hualing chene83bf812020-04-23 13:42:37 +080026 if (segment_file != NULL) {
27 //malloc at delete api.free at this
28 free(segment_file);
29 segment_file = NULL;
30 }
Pengfei Liub4734232020-01-17 18:25:10 +080031 return NULL;
32}
Pengfei Liu3b1a8202020-02-12 23:04:21 +080033
Pengfei Liuc181a982020-01-07 19:27:13 +080034int dvr_segment_delete(const char *location, uint64_t segment_id)
35{
hualing chen6d24aa92020-03-23 18:43:47 +080036
Pengfei Liub4734232020-01-17 18:25:10 +080037 pthread_t thread;
hualing chene83bf812020-04-23 13:42:37 +080038 DVR_SegmentFile_t *segment;
39 //this segment will be free at del thread when used end.if thread
40 //creat error.will be free now.
41 segment = (DVR_SegmentFile_t *)malloc(sizeof(DVR_SegmentFile_t));
Pengfei Liub4734232020-01-17 18:25:10 +080042
43 DVR_DEBUG(1, "%s in, %s,id:%lld", __func__, location, segment_id);
hualing chene83bf812020-04-23 13:42:37 +080044 DVR_RETURN_IF_FALSE(segment);
Pengfei Liu3b1a8202020-02-12 23:04:21 +080045 DVR_RETURN_IF_FALSE(location);
46 DVR_RETURN_IF_FALSE(strlen(location) < DVR_MAX_LOCATION_SIZE);
hualing chene83bf812020-04-23 13:42:37 +080047 memset(segment->location, 0, sizeof(segment->location));
48 memcpy(segment->location, location, strlen(location));
49 segment->id = segment_id;
Zhiqiang Han2d8cd822020-03-16 13:58:10 +080050
hualing chene83bf812020-04-23 13:42:37 +080051 int ret = pthread_create(&thread, NULL, dvr_segment_thread, segment);
52 if (ret != 0) {
53 //creat thread error,need free segment
54 if (segment != NULL) {
55 free(segment);
56 segment = NULL;
57 }
58 }
Pengfei Liub4734232020-01-17 18:25:10 +080059 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +080060}
61
hualing chen4b7c15d2020-04-07 16:13:48 +080062int dvr_segment_del_by_location(const char *location)
63{
64 FILE *fp;
65 char fpath[DVR_MAX_LOCATION_SIZE];
66 char cmd[256];
67
68 DVR_RETURN_IF_FALSE(location);
69
70 DVR_DEBUG(1, "%s location:%s", __func__, location);
71 memset(fpath, 0, sizeof(fpath));
72 sprintf(fpath, "%s.del", location);
73 {
74 /* del file */
75 memset(cmd, 0, sizeof(cmd));
Zhiqiang Hanade34ff2020-04-17 16:50:59 +080076 sprintf(cmd, "rm %s-*", location);
hualing chen4b7c15d2020-04-07 16:13:48 +080077 fp = popen(cmd, "r");
78 DVR_RETURN_IF_FALSE(fp);
79 }
hualing chen7a56cba2020-04-14 14:09:27 +080080 DVR_DEBUG(1, "%s location:%s end", __func__, location);
81 fclose(fp);
hualing chen4b7c15d2020-04-07 16:13:48 +080082 return DVR_SUCCESS;
83}
84
85
Pengfei Liuc181a982020-01-07 19:27:13 +080086int dvr_segment_get_list(const char *location, uint32_t *p_segment_nb, uint64_t **pp_segment_ids)
87{
Pengfei Liu3b1a8202020-02-12 23:04:21 +080088 FILE *fp;
89 char fpath[DVR_MAX_LOCATION_SIZE];
90 uint32_t i = 0, j = 0;
91 char buf[64];
92 uint64_t *p = NULL;
93 char cmd[256];
94
95 DVR_RETURN_IF_FALSE(location);
96 DVR_RETURN_IF_FALSE(p_segment_nb);
97 DVR_RETURN_IF_FALSE(pp_segment_ids);
98
99 DVR_DEBUG(1, "%s location:%s", __func__, location);
100 memset(fpath, 0, sizeof(fpath));
101 sprintf(fpath, "%s.list", location);
102
103 if (access(fpath, 0) != -1) {
104 /*the list file is exist*/
105 fp = fopen(fpath, "r");
106 DVR_RETURN_IF_FALSE(fp);
107 /*get segment numbers*/
108 while (fgets(buf, sizeof(buf), fp) != NULL) {
109 i++;
110 }
111 *p_segment_nb = i;
112 rewind(fp);
113 /*malloc*/
114 p = malloc(i * sizeof(uint64_t));
115 i = 0;
116 /*set value*/
117 memset(buf, 0, sizeof(buf));
118 while (fgets(buf, sizeof(buf), fp) != NULL) {
119 p[i++] = strtoull(buf, NULL, 10);
120 memset(buf, 0, sizeof(buf));
121 }
122 *pp_segment_ids = p;
123 fclose(fp);
124 } else {
125 /*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
139 *p_segment_nb = i;
140 p = malloc(i * sizeof(uint64_t));
141 for (i = 0;;i++) {
142 memset(fpath, 0, sizeof(fpath));
143 sprintf(fpath, "%s-%04d.ts", location, i);
144 if (access(fpath, 0) != -1) {
145 p[j++] = i;
146 }
147 if (j >= *p_segment_nb) {
148 break;
149 }
150 }
151 *pp_segment_ids = p;
152 }
Pengfei Liub4734232020-01-17 18:25:10 +0800153 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800154}
155
Pengfei Liub4734232020-01-17 18:25:10 +0800156int dvr_segment_get_info(const char *location, uint64_t segment_id, DVR_RecordSegmentInfo_t *p_info)
Pengfei Liuc181a982020-01-07 19:27:13 +0800157{
Pengfei Liub4734232020-01-17 18:25:10 +0800158 int ret;
159 Segment_OpenParams_t open_params;
160 Segment_Handle_t segment_handle;
161
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800162 DVR_RETURN_IF_FALSE(location);
163 DVR_RETURN_IF_FALSE(p_info);
164 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liub4734232020-01-17 18:25:10 +0800165
166 memset(&open_params, 0, sizeof(open_params));
167 memcpy(open_params.location, location, strlen(location));
168 open_params.segment_id = segment_id;
169 open_params.mode = SEGMENT_MODE_READ;
170 ret = segment_open(&open_params, &segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800171 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800172
173 ret = segment_load_info(segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800174 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chena540a7e2020-03-27 16:44:05 +0800175 //DVR_DEBUG(1, "%s, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
176 // __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 +0800177
178 ret = segment_close(segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800179 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800180
181 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800182}
183
184int dvr_segment_link(const char *location, uint32_t nb_segments, uint64_t *p_segment_ids)
185{
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800186 FILE *fp;
187 char fpath[DVR_MAX_LOCATION_SIZE];
188 uint32_t i;
189 char buf[64];
190
191 DVR_RETURN_IF_FALSE(location);
192 DVR_RETURN_IF_FALSE(p_segment_ids);
193 DVR_RETURN_IF_FALSE(strlen((const char *)location) < DVR_MAX_LOCATION_SIZE);
194
195 DVR_DEBUG(1, "%s location:%s, nb_segments:%d", __func__, location, nb_segments);
196 memset(fpath, 0, sizeof(fpath));
197 sprintf(fpath, "%s.list", location);
198 fp = fopen(fpath, "w+");
199 for (i = 0; i< nb_segments; i++) {
200 memset(buf, 0, sizeof(buf));
201 sprintf(buf, "%lld", p_segment_ids[i]);
202 fwrite(buf, 1, strlen(buf), fp);
203 }
204
205 fflush(fp);
206 fsync(fileno(fp));
207 fclose(fp);
Pengfei Liub4734232020-01-17 18:25:10 +0800208 return DVR_SUCCESS;
Pengfei Liuc181a982020-01-07 19:27:13 +0800209}