blob: 74ca63369b153ce26ac28256b85713fbe4fc6eb2 [file] [log] [blame]
Pengfei Liuc181a982020-01-07 19:27:13 +08001#include <stdio.h>
Pengfei Liub038b6a2020-01-14 15:57:01 +08002#include <unistd.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08003#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <string.h>
Pengfei Liub038b6a2020-01-14 15:57:01 +08007#include <stdlib.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08008#include <errno.h>
Pengfei Liu47ed6c92020-01-17 11:23:41 +08009#include "dvr_types.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080010#include "segment.h"
11
12#define MAX_SEGMENT_FD_COUNT (128)
13#define MAX_SEGMENT_PATH_SIZE (DVR_MAX_LOCATION_SIZE + 32)
Pengfei Liub038b6a2020-01-14 15:57:01 +080014#define MAX_PTS_THRESHOLD (10*1000)
pengfei.liu567d6d82020-04-17 16:48:59 +080015#define PCR_RECORD_INTERVAL_MS (400)
hualing chen2932d372020-04-29 13:44:00 +080016#define PTS_DISCONTINE_DEVIATION (40)
17#define PTS_HEAD_DEVIATION (40)
18
19
Pengfei Liub4734232020-01-17 18:25:10 +080020/**\brief Segment context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080021typedef struct {
Pengfei Liu3b1a8202020-02-12 23:04:21 +080022 int ts_fd; /**< Segment ts file fd*/
Pengfei Liub4734232020-01-17 18:25:10 +080023 FILE *index_fp; /**< Time index file fd*/
24 FILE *dat_fp; /**< Information file fd*/
pengfei.liu567d6d82020-04-17 16:48:59 +080025 FILE *ongoing_fp; /**< Ongoing file fd, used to verify timedhift mode*/
Pengfei Liub4734232020-01-17 18:25:10 +080026 uint64_t first_pts; /**< First pts value, use for write mode*/
pengfei.liu567d6d82020-04-17 16:48:59 +080027 uint64_t last_pts; /**< Last input pts value, use for write mode*/
28 uint64_t last_record_pts; /**< Last record pts value, use for write mode*/
pengfei.liuab5a2262020-02-14 17:33:40 +080029 uint64_t cur_time; /**< Current time save in index file */
pengfei.liu567d6d82020-04-17 16:48:59 +080030 uint64_t segment_id; /**< Current segment ID */
31 char location[MAX_SEGMENT_PATH_SIZE]; /**< Current time save in index file */
Pengfei Liuc181a982020-01-07 19:27:13 +080032} Segment_Context_t;
33
Pengfei Liub4734232020-01-17 18:25:10 +080034/**\brief Segment file type*/
Pengfei Liuc181a982020-01-07 19:27:13 +080035typedef enum {
Pengfei Liub4734232020-01-17 18:25:10 +080036 SEGMENT_FILE_TYPE_TS, /**< Used for store TS data*/
37 SEGMENT_FILE_TYPE_INDEX, /**< Used for store index data*/
38 SEGMENT_FILE_TYPE_DAT, /**< Used for store information data, such as duration etc*/
pengfei.liu567d6d82020-04-17 16:48:59 +080039 SEGMENT_FILE_TYPE_ONGOING, /**< Used for store information data, such as duration etc*/
Pengfei Liuc181a982020-01-07 19:27:13 +080040} Segment_FileType_t;
41
42static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
Pengfei Liub4734232020-01-17 18:25:10 +080043 const char location[DVR_MAX_LOCATION_SIZE],
Pengfei Liuc181a982020-01-07 19:27:13 +080044 uint64_t segment_id,
45 Segment_FileType_t type)
46{
47 int offset;
48
49 memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
50 strncpy(fname, location, strlen(location));
51 offset = strlen(location);
52 strncpy(fname + offset, "-", 1);
53 offset += 1;
54 sprintf(fname + offset, "%04llu", segment_id);
55 offset += 4;
56 if (type == SEGMENT_FILE_TYPE_TS)
57 strncpy(fname + offset, ".ts", 3);
58 else if (type == SEGMENT_FILE_TYPE_INDEX)
59 strncpy(fname + offset, ".idx", 4);
Pengfei Liub4734232020-01-17 18:25:10 +080060 else if (type == SEGMENT_FILE_TYPE_DAT)
61 strncpy(fname + offset, ".dat", 4);
hualing chen87072a82020-03-12 16:20:12 +080062 else if (type == SEGMENT_FILE_TYPE_ONGOING)
63 strncpy(fname + offset, ".going", 6);
Pengfei Liuc181a982020-01-07 19:27:13 +080064}
65
Pengfei Liu3b1a8202020-02-12 23:04:21 +080066static void segment_get_dirname(char dir_name[MAX_SEGMENT_PATH_SIZE],
67 const char location[DVR_MAX_LOCATION_SIZE])
68{
69 char *p;
70 int i;
71 int found = 0;
72
73 for (i = 0; i < (int)strlen(location); i++) {
74 if (location[i] == '/') {
75 p = (char *)location + i;
76 found = 1;
77 }
78 }
79 if (found)
80 memcpy(dir_name, location, p - location);
81}
82
Pengfei Liuc181a982020-01-07 19:27:13 +080083int segment_open(Segment_OpenParams_t *params, Segment_Handle_t *p_handle)
84{
85 Segment_Context_t *p_ctx;
86 char ts_fname[MAX_SEGMENT_PATH_SIZE];
87 char index_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liub4734232020-01-17 18:25:10 +080088 char dat_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liu3b1a8202020-02-12 23:04:21 +080089 char dir_name[MAX_SEGMENT_PATH_SIZE];
hualing chen87072a82020-03-12 16:20:12 +080090 char going_name[MAX_SEGMENT_PATH_SIZE];
Pengfei Liuc181a982020-01-07 19:27:13 +080091
Pengfei Liu3b1a8202020-02-12 23:04:21 +080092 DVR_RETURN_IF_FALSE(params);
93 DVR_RETURN_IF_FALSE(p_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +080094
hualing chena540a7e2020-03-27 16:44:05 +080095 //DVR_DEBUG(1, "%s, location:%s, id:%llu", __func__, params->location, params->segment_id);
Pengfei Liuc181a982020-01-07 19:27:13 +080096
Pengfei Liub038b6a2020-01-14 15:57:01 +080097 p_ctx = (void*)malloc(sizeof(Segment_Context_t));
Pengfei Liu3b1a8202020-02-12 23:04:21 +080098 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +080099 memset(p_ctx, 0, sizeof(Segment_Context_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800100
101 memset(ts_fname, 0, sizeof(ts_fname));
102 segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
103
104 memset(index_fname, 0, sizeof(index_fname));
105 segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
106
Pengfei Liub4734232020-01-17 18:25:10 +0800107 memset(dat_fname, 0, sizeof(dat_fname));
108 segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
109
hualing chen87072a82020-03-12 16:20:12 +0800110 memset(going_name, 0, sizeof(going_name));
111 segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
112
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800113 memset(dir_name, 0, sizeof(dir_name));
114 segment_get_dirname(dir_name, params->location);
115 if (access(dir_name, F_OK) == -1) {
116 DVR_DEBUG(1, "%s dir %s is not exist, create it", __func__, dir_name);
117 mkdir(dir_name, 0666);
118 }
119
Pengfei Liuc181a982020-01-07 19:27:13 +0800120 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800121 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800122 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800123 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800124 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800125 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800126 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800127 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800128 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chen87072a82020-03-12 16:20:12 +0800129 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800130 p_ctx->first_pts = ULLONG_MAX;
131 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800132 p_ctx->last_record_pts = ULLONG_MAX;
Pengfei Liuc181a982020-01-07 19:27:13 +0800133 } else {
134 DVR_DEBUG(1, "%s, unknow mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800135 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800136 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800137 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800138 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800139 }
140
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800141 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Pengfei Liub4734232020-01-17 18:25:10 +0800142 DVR_DEBUG(1, "%s open file failed [%s, %s, %s], reason:%s", __func__,
143 ts_fname, index_fname, dat_fname, strerror(errno));
Pengfei Liuc181a982020-01-07 19:27:13 +0800144 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800145 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800146 return DVR_FAILURE;
147 }
hualing chen87072a82020-03-12 16:20:12 +0800148 p_ctx->segment_id = params->segment_id;
149 strncpy(p_ctx->location, params->location, strlen(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800150
hualing chen7a56cba2020-04-14 14:09:27 +0800151 //DVR_DEBUG(1, "%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800152 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800153 return DVR_SUCCESS;
154}
155
156int segment_close(Segment_Handle_t handle)
157{
158 Segment_Context_t *p_ctx;
159
Pengfei Liub038b6a2020-01-14 15:57:01 +0800160 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800161 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800162
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800163 if (p_ctx->ts_fd != -1) {
164 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800165 }
166
167 if (p_ctx->index_fp) {
168 fclose(p_ctx->index_fp);
169 }
170
Pengfei Liub4734232020-01-17 18:25:10 +0800171 if (p_ctx->dat_fp) {
172 fclose(p_ctx->dat_fp);
173 }
174
hualing chen87072a82020-03-12 16:20:12 +0800175 if (p_ctx->ongoing_fp != NULL) {
176 fclose(p_ctx->ongoing_fp);
177 char going_name[MAX_SEGMENT_PATH_SIZE];
178 memset(going_name, 0, sizeof(going_name));
179 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
180 DVR_DEBUG(1, "segment close del [%s]", going_name);
181 unlink(going_name);
182 }
183
Pengfei Liuc181a982020-01-07 19:27:13 +0800184 free(p_ctx);
185 return 0;
186}
187
188ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
189{
190 Segment_Context_t *p_ctx;
191
192 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800193 DVR_RETURN_IF_FALSE(p_ctx);
194 DVR_RETURN_IF_FALSE(buf);
195 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800196
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800197 return read(p_ctx->ts_fd, buf, count);
Pengfei Liuc181a982020-01-07 19:27:13 +0800198}
199
200ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
201{
202 Segment_Context_t *p_ctx;
203
204 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800205 DVR_RETURN_IF_FALSE(p_ctx);
206 DVR_RETURN_IF_FALSE(buf);
207 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800208
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800209 return write(p_ctx->ts_fd, buf, count);
Pengfei Liuc181a982020-01-07 19:27:13 +0800210}
211
hualing chen2932d372020-04-29 13:44:00 +0800212int segment_update_pts_force(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800213{
214 Segment_Context_t *p_ctx;
215 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800216 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800217
218 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800219 DVR_RETURN_IF_FALSE(p_ctx);
220 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800221
Pengfei Liub038b6a2020-01-14 15:57:01 +0800222 if (p_ctx->first_pts == ULLONG_MAX) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800223 DVR_DEBUG(1, "%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800224 p_ctx->first_pts = pts;
225 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800226 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800227 if (p_ctx->last_pts == ULLONG_MAX) {
228 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800229 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800230 p_ctx->cur_time = pts - p_ctx->first_pts;
hualing chen2932d372020-04-29 13:44:00 +0800231 DVR_DEBUG(1, "%s force pcr:%llu -1", __func__, pts);
232 } else {
233 /*Last pts has valid value*/
234 int diff = pts - p_ctx->last_pts;
235 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
236 /*Current pts has a transition*/
237 DVR_DEBUG(1, "[%s]force update Current pts has a transition, [%llu, %llu, %llu]",__func__,
238 p_ctx->first_pts, p_ctx->last_pts, pts);
239 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
240 } else {
241 /*This is a normal pts, record it*/
242 p_ctx->cur_time += diff;
243 DVR_DEBUG(1, "%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
244 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
245 }
246 }
247
248 record_diff = pts - p_ctx->last_record_pts;
249 if (strlen(buf) > 0) {
250 DVR_DEBUG(1, "%s force pcr:%llu buf:%s", __func__, pts, buf);
251 fputs(buf, p_ctx->index_fp);
252 fflush(p_ctx->index_fp);
253 fsync(fileno(p_ctx->index_fp));
254 p_ctx->last_record_pts = pts;
255 }
256 p_ctx->last_pts = pts;
257
258 return DVR_SUCCESS;
259}
260
261int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
262{
263 Segment_Context_t *p_ctx;
264 char buf[256];
265 int record_diff = 0;
266
267 p_ctx = (Segment_Context_t *)handle;
268 DVR_RETURN_IF_FALSE(p_ctx);
269 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
270
271 if (p_ctx->first_pts == ULLONG_MAX) {
272 DVR_DEBUG(1, "%s first pcr:%llu", __func__, pts);
273 p_ctx->first_pts = pts;
274 //p_ctx->cur_time = p_ctx->cur_time + PTS_HEAD_DEVIATION;
275 }
276 memset(buf, 0, sizeof(buf));
277 if (p_ctx->last_pts == ULLONG_MAX) {
278 /*Last pts is init value*/
279 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
280 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800281 } else {
282 /*Last pts has valid value*/
pengfei.liu567d6d82020-04-17 16:48:59 +0800283 int diff = pts - p_ctx->last_pts;
hualing chen4b7c15d2020-04-07 16:13:48 +0800284 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
Pengfei Liub038b6a2020-01-14 15:57:01 +0800285 /*Current pts has a transition*/
pengfei.liuab5a2262020-02-14 17:33:40 +0800286 DVR_DEBUG(1, "Current pts has a transition, [%llu, %llu, %llu]",
287 p_ctx->first_pts, p_ctx->last_pts, pts);
pengfei.liu567d6d82020-04-17 16:48:59 +0800288 p_ctx->last_record_pts = pts;
hualing chen2932d372020-04-29 13:44:00 +0800289 //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINE_DEVIATION;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800290 } else {
291 /*This is a normal pts, record it*/
hualing chen4b7c15d2020-04-07 16:13:48 +0800292 p_ctx->cur_time += diff;
hualing chen2aba4022020-03-02 13:49:55 +0800293 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800294 }
295 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800296
297 record_diff = pts - p_ctx->last_record_pts;
298 if (strlen(buf) > 0 &&
299 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800300 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800301 fflush(p_ctx->index_fp);
hualing chen2932d372020-04-29 13:44:00 +0800302 //fsync(fileno(p_ctx->index_fp));
pengfei.liu567d6d82020-04-17 16:48:59 +0800303 p_ctx->last_record_pts = pts;
304 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800305 p_ctx->last_pts = pts;
Pengfei Liub4734232020-01-17 18:25:10 +0800306
Pengfei Liuc181a982020-01-07 19:27:13 +0800307 return DVR_SUCCESS;
308}
309
hualing chen266b9502020-04-04 17:39:39 +0800310loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800311{
312 Segment_Context_t *p_ctx;
313 char buf[256];
314 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800315 uint64_t pts = 0L;
316 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800317 char *p1, *p2;
318
319 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800320 DVR_RETURN_IF_FALSE(p_ctx);
321 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
322 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800323
hualing chen266b9502020-04-04 17:39:39 +0800324 if (time == 0) {
325 offset = 0;
326 DVR_DEBUG(1, "seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
327 DVR_RETURN_IF_FALSE(lseek64(p_ctx->ts_fd, offset, SEEK_SET) != -1);
328 return offset;
329 }
330
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800331 memset(buf, 0, sizeof(buf));
332 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800333 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800334 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800335 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800336 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800337 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800338 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800339 if ((p2 = strstr(buf, ","))) {
340 memcpy(value, p1, p2 - p1);
341 }
342 pts = strtoull(value, NULL, 10);
343 }
344
345 memset(value, 0, sizeof(value));
346 if ((p1 = strstr(buf, "offset="))) {
347 p1 += 7;
348 if ((p2 = strstr(buf, "}"))) {
349 memcpy(value, p1, p2 - p1);
350 }
351 offset = strtoull(value, NULL, 10);
352 }
hualing chen2aba4022020-03-02 13:49:55 +0800353 if (0)
354 {
355 DVR_DEBUG(1, "seek buf[%s]", buf);
356 DVR_DEBUG(1, "seek time=%llu, offset=%lld\n", pts, offset);
357 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800358 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800359 //DVR_DEBUG(1, "seek time=%llu, offset=%lld\n", pts, offset);
360 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800361 if (block_size > 0) {
362 offset = offset - offset%block_size;
363 }
hualing chen2aba4022020-03-02 13:49:55 +0800364 DVR_DEBUG(1, "seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800365 DVR_RETURN_IF_FALSE(lseek64(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800366 return offset;
367 }
hualing chen2aba4022020-03-02 13:49:55 +0800368 }
hualing chen2932d372020-04-29 13:44:00 +0800369 if (time > pts) {
370 if (block_size > 0) {
371 offset = offset - offset%block_size;
372 }
373 DVR_DEBUG(1, "seek time=%llu, offset=%lld time--%llu line %d end\n", pts, offset, time, line);
374 DVR_RETURN_IF_FALSE(lseek64(p_ctx->ts_fd, offset, SEEK_SET) != -1);
375 return offset;
376 }
hualing chen2aba4022020-03-02 13:49:55 +0800377 DVR_DEBUG(1, "seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800378 return DVR_FAILURE;
379}
380
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800381loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800382{
383 Segment_Context_t *p_ctx;
384
385 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800386 DVR_RETURN_IF_FALSE(p_ctx);
387 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800388
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800389 return lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
390}
391
pengfei.liu8b563292020-02-26 15:49:02 +0800392uint64_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800393{
394 Segment_Context_t *p_ctx;
395 char buf[256];
396 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800397 uint64_t pts = 0L;
398 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800399 char *p1, *p2;
400
401 p_ctx = (Segment_Context_t *)handle;
402 DVR_RETURN_IF_FALSE(p_ctx);
403 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
404 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
405
406 memset(buf, 0, sizeof(buf));
407 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
408 position = lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
409 DVR_RETURN_IF_FALSE(position != -1);
410
411 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
412 memset(value, 0, sizeof(value));
413 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800414 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800415 if ((p2 = strstr(buf, ","))) {
416 memcpy(value, p1, p2 - p1);
417 }
418 pts = strtoull(value, NULL, 10);
419 }
420
421 memset(value, 0, sizeof(value));
422 if ((p1 = strstr(buf, "offset="))) {
423 p1 += 7;
424 if ((p2 = strstr(buf, "}"))) {
425 memcpy(value, p1, p2 - p1);
426 }
427 offset = strtoull(value, NULL, 10);
428 }
429
430 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800431 //DVR_DEBUG(1, "tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800432 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800433 return pts;
434 }
435 }
hualing chena540a7e2020-03-27 16:44:05 +0800436 //DVR_DEBUG(1, "tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800437 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800438}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800439
pengfei.liu8b563292020-02-26 15:49:02 +0800440uint64_t segment_tell_total_time(Segment_Handle_t handle)
441{
442 Segment_Context_t *p_ctx;
443 char buf[256];
444 char last_buf[256];
445 char value[256];
446 uint64_t pts = ULLONG_MAX;
447 loff_t offset = 0, position = 0;
448 char *p1, *p2;
449 int line = 0;
450
451 p_ctx = (Segment_Context_t *)handle;
452 DVR_RETURN_IF_FALSE(p_ctx);
453 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
454 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
455
456 memset(buf, 0, sizeof(buf));
457 memset(last_buf, 0, sizeof(last_buf));
458 position = lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
459 DVR_RETURN_IF_FALSE(position != -1);
460
hualing chen041c4092020-04-05 15:11:50 +0800461 //DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, -1000L, SEEK_END) != -1);
462 //if seek error.we need seek 0 pos.
463 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
464 fseek(p_ctx->index_fp, 0L, SEEK_SET);
465 }
pengfei.liu8b563292020-02-26 15:49:02 +0800466 /* Save last line buffer */
467 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800468 if (strlen(buf) <= 0) {
hualing chen87072a82020-03-12 16:20:12 +0800469 DVR_DEBUG(1, "read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800470 continue;
471 }
pengfei.liu8b563292020-02-26 15:49:02 +0800472 memset(last_buf, 0, sizeof(last_buf));
473 memcpy(last_buf, buf, strlen(buf));
474 memset(buf, 0, sizeof(buf));
475 line++;
476 }
477
478 /* Extract time value */
479 memset(value, 0, sizeof(value));
480 if ((p1 = strstr(last_buf, "time="))) {
481 p1 += 5;
482 if ((p2 = strstr(last_buf, ","))) {
483 memcpy(value, p1, p2 - p1);
484 }
485 pts = strtoull(value, NULL, 10);
486 }
487
488 memset(value, 0, sizeof(value));
489 if ((p1 = strstr(last_buf, "offset="))) {
490 p1 += 7;
491 if ((p2 = strstr(last_buf, "}"))) {
492 memcpy(value, p1, p2 - p1);
493 }
494 offset = strtoull(value, NULL, 10);
495 }
hualing chen87072a82020-03-12 16:20:12 +0800496 //if (line < 2)
497 //DVR_DEBUG(1, "totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800498 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
499}
500
pengfei.liuab5a2262020-02-14 17:33:40 +0800501/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800502int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
503{
504 Segment_Context_t *p_ctx;
505 char buf[256];
506 uint32_t i;
507
508 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800509 DVR_RETURN_IF_FALSE(p_ctx);
510 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
511 DVR_RETURN_IF_FALSE(p_info);
hualing chen87072a82020-03-12 16:20:12 +0800512 //seek 0, rewrite info
513 DVR_RETURN_IF_FALSE(fseek(p_ctx->dat_fp, 0, SEEK_SET) != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800514
515 /*Save segment id*/
516 memset(buf, 0, sizeof(buf));
517 sprintf(buf, "id=%lld\n", p_info->id);
518 fputs(buf, p_ctx->dat_fp);
519
520 /*Save number of pids*/
521 memset(buf, 0, sizeof(buf));
522 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
523 fputs(buf, p_ctx->dat_fp);
524
525 /*Save pid information*/
526 for (i = 0; i < p_info->nb_pids; i++) {
527 memset(buf, 0, sizeof(buf));
528 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
529 fputs(buf, p_ctx->dat_fp);
530 }
531
532 /*Save segment duration*/
533 memset(buf, 0, sizeof(buf));
hualing chen87072a82020-03-12 16:20:12 +0800534 DVR_DEBUG(1, "duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800535 sprintf(buf, "duration=%ld\n", p_info->duration);
536 fputs(buf, p_ctx->dat_fp);
537
538 /*Save segment size*/
539 memset(buf, 0, sizeof(buf));
540 sprintf(buf, "size=%zu\n", p_info->size);
541 fputs(buf, p_ctx->dat_fp);
542
543 /*Save number of packets*/
544 memset(buf, 0, sizeof(buf));
545 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
546 fputs(buf, p_ctx->dat_fp);
547
548 fflush(p_ctx->dat_fp);
hualing chen2932d372020-04-29 13:44:00 +0800549 //fsync(fileno(p_ctx->dat_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800550 return DVR_SUCCESS;
551}
552
pengfei.liuab5a2262020-02-14 17:33:40 +0800553/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800554int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
555{
556 Segment_Context_t *p_ctx;
557 uint32_t i;
558 char buf[256];
559 char value[256];
560 char *p1, *p2;
561
562 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800563 DVR_RETURN_IF_FALSE(p_ctx);
564 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800565
566 /*Load segment id*/
567 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800568 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800569 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800570 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800571 p_info->id = strtoull(p1 + 3, NULL, 10);
572
573 /*Save number of pids*/
574 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800575 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800576 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800577 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800578 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
579
580 /*Save pid information*/
581 for (i = 0; i < p_info->nb_pids; i++) {
582 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800583 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800584 memset(value, 0, sizeof(value));
585 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800586 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800587 p1 += 4;
588 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800589 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800590 memcpy(value, p1, p2 - p1);
591 }
592 p_info->pids[i].pid = strtoull(value, NULL, 10);
593 }
594
595 memset(value, 0, sizeof(value));
596 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800597 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800598 p1 += 5;
599 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800600 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800601 memcpy(value, p1, p2 - p1);
602 }
603 p_info->pids[i].type = strtoull(value, NULL, 10);
604 }
605 }
606
607 /*Save segment duration*/
608 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800609 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800610 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800611 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800612 p_info->duration = strtoull(p1 + 9, NULL, 10);
hualing chena540a7e2020-03-27 16:44:05 +0800613 //DVR_DEBUG(1, "load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800614
615 /*Save segment size*/
616 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800617 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800618 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800619 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800620 p_info->size = strtoull(p1 + 5, NULL, 10);
621
622 /*Save number of packets*/
623 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800624 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800625 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800626 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800627 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
628
629 return DVR_SUCCESS;
630}
631
632int segment_delete(const char *location, uint64_t segment_id)
633{
634 char fname[MAX_SEGMENT_PATH_SIZE];
635 int ret;
636
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800637 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800638
639 /*delete ts file*/
640 memset(fname, 0, sizeof(fname));
641 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
642 ret = unlink(fname);
643 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800644 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800645
646 /*delete index file*/
647 memset(fname, 0, sizeof(fname));
648 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
649 unlink(fname);
650 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800651 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800652
653 /*delete store information file*/
654 memset(fname, 0, sizeof(fname));
655 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
656 unlink(fname);
657 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800658 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800659
660 return DVR_SUCCESS;
661}
662
hualing chen87072a82020-03-12 16:20:12 +0800663int segment_ongoing(Segment_Handle_t handle)
664{
665 Segment_Context_t *p_ctx;
666 p_ctx = (Segment_Context_t *)handle;
667 struct stat mstat;
668
669 char going_name[MAX_SEGMENT_PATH_SIZE];
670 memset(going_name, 0, sizeof(going_name));
671 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
672 int ret = stat(going_name, &mstat);
673 DVR_DEBUG(1, "segment check ongoing [%s] ret [%d]", going_name, ret);
674 if (ret != 0) {
675 return DVR_FAILURE;
676 }
677 return DVR_SUCCESS;
678}
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800679loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800680{
681 Segment_Context_t *p_ctx;
682 char buf[256];
683 char value[256];
684 uint64_t pts;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800685 loff_t offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800686 char *p1, *p2;
687
688 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800689 DVR_RETURN_IF_FALSE(p_ctx);
690 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
691 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800692
693 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800694 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800695 printf("start gets pts\n");
696 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
697 printf("buf[%s]\n", buf);
698 memset(value, 0, sizeof(value));
699 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800700 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800701 if ((p2 = strstr(buf, ","))) {
702 memcpy(value, p1, p2 - p1);
703 }
704 pts = strtoull(value, NULL, 10);
705 }
706
707 memset(value, 0, sizeof(value));
708 if ((p1 = strstr(buf, "offset="))) {
709 p1 += 7;
710 if ((p2 = strstr(buf, "}"))) {
711 memcpy(value, p1, p2 - p1);
712 }
713 offset = strtoull(value, NULL, 10);
714 }
715
716 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800717 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800718 }
719
720 return 0;
721}