blob: c6dc8b88ec4fe35a03be4222a6a51c97d9360540 [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 Liub4734232020-01-17 18:25:10 +080015/**\brief Segment context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080016typedef struct {
Pengfei Liu3b1a8202020-02-12 23:04:21 +080017 int ts_fd; /**< Segment ts file fd*/
Pengfei Liub4734232020-01-17 18:25:10 +080018 FILE *index_fp; /**< Time index file fd*/
19 FILE *dat_fp; /**< Information file fd*/
hualing chen87072a82020-03-12 16:20:12 +080020 FILE *ongoing_fp; /**< Ongoing file fd, used to verify timedhift mode*/
Pengfei Liub4734232020-01-17 18:25:10 +080021 uint64_t first_pts; /**< First pts value, use for write mode*/
22 uint64_t last_pts; /**< Last pts value, use for write mode*/
pengfei.liuab5a2262020-02-14 17:33:40 +080023 uint64_t cur_time; /**< Current time save in index file */
hualing chen87072a82020-03-12 16:20:12 +080024 uint64_t segment_id;
25 char location[MAX_SEGMENT_PATH_SIZE];/**< Current time save in index file */
Pengfei Liuc181a982020-01-07 19:27:13 +080026} Segment_Context_t;
27
Pengfei Liub4734232020-01-17 18:25:10 +080028/**\brief Segment file type*/
Pengfei Liuc181a982020-01-07 19:27:13 +080029typedef enum {
Pengfei Liub4734232020-01-17 18:25:10 +080030 SEGMENT_FILE_TYPE_TS, /**< Used for store TS data*/
31 SEGMENT_FILE_TYPE_INDEX, /**< Used for store index data*/
32 SEGMENT_FILE_TYPE_DAT, /**< Used for store information data, such as duration etc*/
hualing chen87072a82020-03-12 16:20:12 +080033 SEGMENT_FILE_TYPE_ONGOING, /**< Used for store information data, such as duration etc*/
Pengfei Liuc181a982020-01-07 19:27:13 +080034} Segment_FileType_t;
35
36static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
Pengfei Liub4734232020-01-17 18:25:10 +080037 const char location[DVR_MAX_LOCATION_SIZE],
Pengfei Liuc181a982020-01-07 19:27:13 +080038 uint64_t segment_id,
39 Segment_FileType_t type)
40{
41 int offset;
42
43 memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
44 strncpy(fname, location, strlen(location));
45 offset = strlen(location);
46 strncpy(fname + offset, "-", 1);
47 offset += 1;
48 sprintf(fname + offset, "%04llu", segment_id);
49 offset += 4;
50 if (type == SEGMENT_FILE_TYPE_TS)
51 strncpy(fname + offset, ".ts", 3);
52 else if (type == SEGMENT_FILE_TYPE_INDEX)
53 strncpy(fname + offset, ".idx", 4);
Pengfei Liub4734232020-01-17 18:25:10 +080054 else if (type == SEGMENT_FILE_TYPE_DAT)
55 strncpy(fname + offset, ".dat", 4);
hualing chen87072a82020-03-12 16:20:12 +080056 else if (type == SEGMENT_FILE_TYPE_ONGOING)
57 strncpy(fname + offset, ".going", 6);
Pengfei Liuc181a982020-01-07 19:27:13 +080058}
59
Pengfei Liu3b1a8202020-02-12 23:04:21 +080060static void segment_get_dirname(char dir_name[MAX_SEGMENT_PATH_SIZE],
61 const char location[DVR_MAX_LOCATION_SIZE])
62{
63 char *p;
64 int i;
65 int found = 0;
66
67 for (i = 0; i < (int)strlen(location); i++) {
68 if (location[i] == '/') {
69 p = (char *)location + i;
70 found = 1;
71 }
72 }
73 if (found)
74 memcpy(dir_name, location, p - location);
75}
76
Pengfei Liuc181a982020-01-07 19:27:13 +080077int segment_open(Segment_OpenParams_t *params, Segment_Handle_t *p_handle)
78{
79 Segment_Context_t *p_ctx;
80 char ts_fname[MAX_SEGMENT_PATH_SIZE];
81 char index_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liub4734232020-01-17 18:25:10 +080082 char dat_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liu3b1a8202020-02-12 23:04:21 +080083 char dir_name[MAX_SEGMENT_PATH_SIZE];
hualing chen87072a82020-03-12 16:20:12 +080084 char going_name[MAX_SEGMENT_PATH_SIZE];
Pengfei Liuc181a982020-01-07 19:27:13 +080085
Pengfei Liu3b1a8202020-02-12 23:04:21 +080086 DVR_RETURN_IF_FALSE(params);
87 DVR_RETURN_IF_FALSE(p_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +080088
hualing chena540a7e2020-03-27 16:44:05 +080089 //DVR_DEBUG(1, "%s, location:%s, id:%llu", __func__, params->location, params->segment_id);
Pengfei Liuc181a982020-01-07 19:27:13 +080090
Pengfei Liub038b6a2020-01-14 15:57:01 +080091 p_ctx = (void*)malloc(sizeof(Segment_Context_t));
Pengfei Liu3b1a8202020-02-12 23:04:21 +080092 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +080093 memset(p_ctx, 0, sizeof(Segment_Context_t));
Pengfei Liuc181a982020-01-07 19:27:13 +080094
95 memset(ts_fname, 0, sizeof(ts_fname));
96 segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
97
98 memset(index_fname, 0, sizeof(index_fname));
99 segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
100
Pengfei Liub4734232020-01-17 18:25:10 +0800101 memset(dat_fname, 0, sizeof(dat_fname));
102 segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
103
hualing chen87072a82020-03-12 16:20:12 +0800104 memset(going_name, 0, sizeof(going_name));
105 segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
106
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800107 memset(dir_name, 0, sizeof(dir_name));
108 segment_get_dirname(dir_name, params->location);
109 if (access(dir_name, F_OK) == -1) {
110 DVR_DEBUG(1, "%s dir %s is not exist, create it", __func__, dir_name);
111 mkdir(dir_name, 0666);
112 }
113
Pengfei Liuc181a982020-01-07 19:27:13 +0800114 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800115 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800116 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800117 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800118 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800119 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800120 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800121 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800122 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chen87072a82020-03-12 16:20:12 +0800123 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800124 p_ctx->first_pts = ULLONG_MAX;
125 p_ctx->last_pts = ULLONG_MAX;
Pengfei Liuc181a982020-01-07 19:27:13 +0800126 } else {
127 DVR_DEBUG(1, "%s, unknow mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800128 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800129 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800130 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800131 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800132 }
133
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800134 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Pengfei Liub4734232020-01-17 18:25:10 +0800135 DVR_DEBUG(1, "%s open file failed [%s, %s, %s], reason:%s", __func__,
136 ts_fname, index_fname, dat_fname, strerror(errno));
Pengfei Liuc181a982020-01-07 19:27:13 +0800137 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800138 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800139 return DVR_FAILURE;
140 }
hualing chen87072a82020-03-12 16:20:12 +0800141 p_ctx->segment_id = params->segment_id;
142 strncpy(p_ctx->location, params->location, strlen(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800143
hualing chen7a56cba2020-04-14 14:09:27 +0800144 //DVR_DEBUG(1, "%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800145 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800146 return DVR_SUCCESS;
147}
148
149int segment_close(Segment_Handle_t handle)
150{
151 Segment_Context_t *p_ctx;
152
Pengfei Liub038b6a2020-01-14 15:57:01 +0800153 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800154 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800155
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800156 if (p_ctx->ts_fd != -1) {
157 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800158 }
159
160 if (p_ctx->index_fp) {
161 fclose(p_ctx->index_fp);
162 }
163
Pengfei Liub4734232020-01-17 18:25:10 +0800164 if (p_ctx->dat_fp) {
165 fclose(p_ctx->dat_fp);
166 }
167
hualing chen87072a82020-03-12 16:20:12 +0800168 if (p_ctx->ongoing_fp != NULL) {
169 fclose(p_ctx->ongoing_fp);
170 char going_name[MAX_SEGMENT_PATH_SIZE];
171 memset(going_name, 0, sizeof(going_name));
172 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
173 DVR_DEBUG(1, "segment close del [%s]", going_name);
174 unlink(going_name);
175 }
176
Pengfei Liuc181a982020-01-07 19:27:13 +0800177 free(p_ctx);
178 return 0;
179}
180
181ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
182{
183 Segment_Context_t *p_ctx;
184
185 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800186 DVR_RETURN_IF_FALSE(p_ctx);
187 DVR_RETURN_IF_FALSE(buf);
188 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800189
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800190 return read(p_ctx->ts_fd, buf, count);
Pengfei Liuc181a982020-01-07 19:27:13 +0800191}
192
193ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
194{
195 Segment_Context_t *p_ctx;
196
197 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800198 DVR_RETURN_IF_FALSE(p_ctx);
199 DVR_RETURN_IF_FALSE(buf);
200 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800201
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800202 return write(p_ctx->ts_fd, buf, count);
Pengfei Liuc181a982020-01-07 19:27:13 +0800203}
204
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800205int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800206{
207 Segment_Context_t *p_ctx;
208 char buf[256];
209
210 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800211 DVR_RETURN_IF_FALSE(p_ctx);
212 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800213
Pengfei Liub038b6a2020-01-14 15:57:01 +0800214 if (p_ctx->first_pts == ULLONG_MAX) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800215 DVR_DEBUG(1, "%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800216 p_ctx->first_pts = pts;
217 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800218 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800219 if (p_ctx->last_pts == ULLONG_MAX) {
220 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800221 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800222 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800223 } else {
224 /*Last pts has valid value*/
hualing chen4b7c15d2020-04-07 16:13:48 +0800225 int diff = pts - p_ctx->last_pts;
226 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
Pengfei Liub038b6a2020-01-14 15:57:01 +0800227 /*Current pts has a transition*/
pengfei.liuab5a2262020-02-14 17:33:40 +0800228 DVR_DEBUG(1, "Current pts has a transition, [%llu, %llu, %llu]",
229 p_ctx->first_pts, p_ctx->last_pts, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800230 } else {
231 /*This is a normal pts, record it*/
hualing chen4b7c15d2020-04-07 16:13:48 +0800232 p_ctx->cur_time += diff;
hualing chen2aba4022020-03-02 13:49:55 +0800233 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800234 }
235 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800236 if (strlen(buf) > 0)
237 fputs(buf, p_ctx->index_fp);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800238 p_ctx->last_pts = pts;
239 fflush(p_ctx->index_fp);
240 fsync(fileno(p_ctx->index_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800241
Pengfei Liuc181a982020-01-07 19:27:13 +0800242 return DVR_SUCCESS;
243}
244
hualing chen266b9502020-04-04 17:39:39 +0800245loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800246{
247 Segment_Context_t *p_ctx;
248 char buf[256];
249 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800250 uint64_t pts = 0L;
251 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800252 char *p1, *p2;
253
254 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800255 DVR_RETURN_IF_FALSE(p_ctx);
256 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
257 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800258
hualing chen266b9502020-04-04 17:39:39 +0800259 if (time == 0) {
260 offset = 0;
261 DVR_DEBUG(1, "seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
262 DVR_RETURN_IF_FALSE(lseek64(p_ctx->ts_fd, offset, SEEK_SET) != -1);
263 return offset;
264 }
265
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800266 memset(buf, 0, sizeof(buf));
267 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800268 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800269 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800270 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800271 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800272 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800273 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800274 if ((p2 = strstr(buf, ","))) {
275 memcpy(value, p1, p2 - p1);
276 }
277 pts = strtoull(value, NULL, 10);
278 }
279
280 memset(value, 0, sizeof(value));
281 if ((p1 = strstr(buf, "offset="))) {
282 p1 += 7;
283 if ((p2 = strstr(buf, "}"))) {
284 memcpy(value, p1, p2 - p1);
285 }
286 offset = strtoull(value, NULL, 10);
287 }
hualing chen2aba4022020-03-02 13:49:55 +0800288 if (0)
289 {
290 DVR_DEBUG(1, "seek buf[%s]", buf);
291 DVR_DEBUG(1, "seek time=%llu, offset=%lld\n", pts, offset);
292 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800293 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800294 //DVR_DEBUG(1, "seek time=%llu, offset=%lld\n", pts, offset);
295 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800296 if (block_size > 0) {
297 offset = offset - offset%block_size;
298 }
hualing chen2aba4022020-03-02 13:49:55 +0800299 DVR_DEBUG(1, "seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800300 DVR_RETURN_IF_FALSE(lseek64(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800301 return offset;
302 }
hualing chen2aba4022020-03-02 13:49:55 +0800303 }
304 DVR_DEBUG(1, "seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800305 return DVR_FAILURE;
306}
307
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800308loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800309{
310 Segment_Context_t *p_ctx;
311
312 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800313 DVR_RETURN_IF_FALSE(p_ctx);
314 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800315
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800316 return lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
317}
318
pengfei.liu8b563292020-02-26 15:49:02 +0800319uint64_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800320{
321 Segment_Context_t *p_ctx;
322 char buf[256];
323 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800324 uint64_t pts = 0L;
325 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800326 char *p1, *p2;
327
328 p_ctx = (Segment_Context_t *)handle;
329 DVR_RETURN_IF_FALSE(p_ctx);
330 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
331 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
332
333 memset(buf, 0, sizeof(buf));
334 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
335 position = lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
336 DVR_RETURN_IF_FALSE(position != -1);
337
338 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
339 memset(value, 0, sizeof(value));
340 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800341 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800342 if ((p2 = strstr(buf, ","))) {
343 memcpy(value, p1, p2 - p1);
344 }
345 pts = strtoull(value, NULL, 10);
346 }
347
348 memset(value, 0, sizeof(value));
349 if ((p1 = strstr(buf, "offset="))) {
350 p1 += 7;
351 if ((p2 = strstr(buf, "}"))) {
352 memcpy(value, p1, p2 - p1);
353 }
354 offset = strtoull(value, NULL, 10);
355 }
356
357 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800358 //DVR_DEBUG(1, "tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800359 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800360 return pts;
361 }
362 }
hualing chena540a7e2020-03-27 16:44:05 +0800363 //DVR_DEBUG(1, "tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800364 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800365}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800366
pengfei.liu8b563292020-02-26 15:49:02 +0800367uint64_t segment_tell_total_time(Segment_Handle_t handle)
368{
369 Segment_Context_t *p_ctx;
370 char buf[256];
371 char last_buf[256];
372 char value[256];
373 uint64_t pts = ULLONG_MAX;
374 loff_t offset = 0, position = 0;
375 char *p1, *p2;
376 int line = 0;
377
378 p_ctx = (Segment_Context_t *)handle;
379 DVR_RETURN_IF_FALSE(p_ctx);
380 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
381 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
382
383 memset(buf, 0, sizeof(buf));
384 memset(last_buf, 0, sizeof(last_buf));
385 position = lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
386 DVR_RETURN_IF_FALSE(position != -1);
387
hualing chen041c4092020-04-05 15:11:50 +0800388 //DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, -1000L, SEEK_END) != -1);
389 //if seek error.we need seek 0 pos.
390 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
391 fseek(p_ctx->index_fp, 0L, SEEK_SET);
392 }
pengfei.liu8b563292020-02-26 15:49:02 +0800393 /* Save last line buffer */
394 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800395 if (strlen(buf) <= 0) {
hualing chen87072a82020-03-12 16:20:12 +0800396 DVR_DEBUG(1, "read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800397 continue;
398 }
pengfei.liu8b563292020-02-26 15:49:02 +0800399 memset(last_buf, 0, sizeof(last_buf));
400 memcpy(last_buf, buf, strlen(buf));
401 memset(buf, 0, sizeof(buf));
402 line++;
403 }
404
405 /* Extract time value */
406 memset(value, 0, sizeof(value));
407 if ((p1 = strstr(last_buf, "time="))) {
408 p1 += 5;
409 if ((p2 = strstr(last_buf, ","))) {
410 memcpy(value, p1, p2 - p1);
411 }
412 pts = strtoull(value, NULL, 10);
413 }
414
415 memset(value, 0, sizeof(value));
416 if ((p1 = strstr(last_buf, "offset="))) {
417 p1 += 7;
418 if ((p2 = strstr(last_buf, "}"))) {
419 memcpy(value, p1, p2 - p1);
420 }
421 offset = strtoull(value, NULL, 10);
422 }
hualing chen87072a82020-03-12 16:20:12 +0800423 //if (line < 2)
424 //DVR_DEBUG(1, "totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800425 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
426}
427
pengfei.liuab5a2262020-02-14 17:33:40 +0800428/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800429int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
430{
431 Segment_Context_t *p_ctx;
432 char buf[256];
433 uint32_t i;
434
435 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800436 DVR_RETURN_IF_FALSE(p_ctx);
437 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
438 DVR_RETURN_IF_FALSE(p_info);
hualing chen87072a82020-03-12 16:20:12 +0800439 //seek 0, rewrite info
440 DVR_RETURN_IF_FALSE(fseek(p_ctx->dat_fp, 0, SEEK_SET) != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800441
442 /*Save segment id*/
443 memset(buf, 0, sizeof(buf));
444 sprintf(buf, "id=%lld\n", p_info->id);
445 fputs(buf, p_ctx->dat_fp);
446
447 /*Save number of pids*/
448 memset(buf, 0, sizeof(buf));
449 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
450 fputs(buf, p_ctx->dat_fp);
451
452 /*Save pid information*/
453 for (i = 0; i < p_info->nb_pids; i++) {
454 memset(buf, 0, sizeof(buf));
455 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
456 fputs(buf, p_ctx->dat_fp);
457 }
458
459 /*Save segment duration*/
460 memset(buf, 0, sizeof(buf));
hualing chen87072a82020-03-12 16:20:12 +0800461 DVR_DEBUG(1, "duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800462 sprintf(buf, "duration=%ld\n", p_info->duration);
463 fputs(buf, p_ctx->dat_fp);
464
465 /*Save segment size*/
466 memset(buf, 0, sizeof(buf));
467 sprintf(buf, "size=%zu\n", p_info->size);
468 fputs(buf, p_ctx->dat_fp);
469
470 /*Save number of packets*/
471 memset(buf, 0, sizeof(buf));
472 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
473 fputs(buf, p_ctx->dat_fp);
474
475 fflush(p_ctx->dat_fp);
476 fsync(fileno(p_ctx->dat_fp));
477 return DVR_SUCCESS;
478}
479
pengfei.liuab5a2262020-02-14 17:33:40 +0800480/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800481int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
482{
483 Segment_Context_t *p_ctx;
484 uint32_t i;
485 char buf[256];
486 char value[256];
487 char *p1, *p2;
488
489 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800490 DVR_RETURN_IF_FALSE(p_ctx);
491 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800492
493 /*Load segment id*/
494 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800495 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800496 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800497 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800498 p_info->id = strtoull(p1 + 3, NULL, 10);
499
500 /*Save number of pids*/
501 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800502 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800503 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800504 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800505 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
506
507 /*Save pid information*/
508 for (i = 0; i < p_info->nb_pids; i++) {
509 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800510 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800511 memset(value, 0, sizeof(value));
512 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800513 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800514 p1 += 4;
515 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800516 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800517 memcpy(value, p1, p2 - p1);
518 }
519 p_info->pids[i].pid = strtoull(value, NULL, 10);
520 }
521
522 memset(value, 0, sizeof(value));
523 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800524 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800525 p1 += 5;
526 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800527 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800528 memcpy(value, p1, p2 - p1);
529 }
530 p_info->pids[i].type = strtoull(value, NULL, 10);
531 }
532 }
533
534 /*Save segment duration*/
535 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800536 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800537 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800538 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800539 p_info->duration = strtoull(p1 + 9, NULL, 10);
hualing chena540a7e2020-03-27 16:44:05 +0800540 //DVR_DEBUG(1, "load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800541
542 /*Save segment size*/
543 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800544 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800545 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800546 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800547 p_info->size = strtoull(p1 + 5, NULL, 10);
548
549 /*Save number of packets*/
550 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800551 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800552 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800553 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800554 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
555
556 return DVR_SUCCESS;
557}
558
559int segment_delete(const char *location, uint64_t segment_id)
560{
561 char fname[MAX_SEGMENT_PATH_SIZE];
562 int ret;
563
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800564 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800565
566 /*delete ts file*/
567 memset(fname, 0, sizeof(fname));
568 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
569 ret = unlink(fname);
570 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800571 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800572
573 /*delete index file*/
574 memset(fname, 0, sizeof(fname));
575 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
576 unlink(fname);
577 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800578 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800579
580 /*delete store information file*/
581 memset(fname, 0, sizeof(fname));
582 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
583 unlink(fname);
584 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800585 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800586
587 return DVR_SUCCESS;
588}
589
hualing chen87072a82020-03-12 16:20:12 +0800590int segment_ongoing(Segment_Handle_t handle)
591{
592 Segment_Context_t *p_ctx;
593 p_ctx = (Segment_Context_t *)handle;
594 struct stat mstat;
595
596 char going_name[MAX_SEGMENT_PATH_SIZE];
597 memset(going_name, 0, sizeof(going_name));
598 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
599 int ret = stat(going_name, &mstat);
600 DVR_DEBUG(1, "segment check ongoing [%s] ret [%d]", going_name, ret);
601 if (ret != 0) {
602 return DVR_FAILURE;
603 }
604 return DVR_SUCCESS;
605}
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800606loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800607{
608 Segment_Context_t *p_ctx;
609 char buf[256];
610 char value[256];
611 uint64_t pts;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800612 loff_t offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800613 char *p1, *p2;
614
615 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800616 DVR_RETURN_IF_FALSE(p_ctx);
617 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
618 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800619
620 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800621 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800622 printf("start gets pts\n");
623 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
624 printf("buf[%s]\n", buf);
625 memset(value, 0, sizeof(value));
626 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800627 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800628 if ((p2 = strstr(buf, ","))) {
629 memcpy(value, p1, p2 - p1);
630 }
631 pts = strtoull(value, NULL, 10);
632 }
633
634 memset(value, 0, sizeof(value));
635 if ((p1 = strstr(buf, "offset="))) {
636 p1 += 7;
637 if ((p2 = strstr(buf, "}"))) {
638 memcpy(value, p1, p2 - p1);
639 }
640 offset = strtoull(value, NULL, 10);
641 }
642
643 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800644 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800645 }
646
647 return 0;
648}