blob: 856deae86db51e05b2cf07444e7dbf0ee6951059 [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)
Pengfei Liub4734232020-01-17 18:25:10 +080016/**\brief Segment context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080017typedef struct {
Pengfei Liu3b1a8202020-02-12 23:04:21 +080018 int ts_fd; /**< Segment ts file fd*/
Pengfei Liub4734232020-01-17 18:25:10 +080019 FILE *index_fp; /**< Time index file fd*/
20 FILE *dat_fp; /**< Information file fd*/
pengfei.liu567d6d82020-04-17 16:48:59 +080021 FILE *ongoing_fp; /**< Ongoing file fd, used to verify timedhift mode*/
Pengfei Liub4734232020-01-17 18:25:10 +080022 uint64_t first_pts; /**< First pts value, use for write mode*/
pengfei.liu567d6d82020-04-17 16:48:59 +080023 uint64_t last_pts; /**< Last input pts value, use for write mode*/
24 uint64_t last_record_pts; /**< Last record pts value, use for write mode*/
pengfei.liuab5a2262020-02-14 17:33:40 +080025 uint64_t cur_time; /**< Current time save in index file */
pengfei.liu567d6d82020-04-17 16:48:59 +080026 uint64_t segment_id; /**< Current segment ID */
27 char location[MAX_SEGMENT_PATH_SIZE]; /**< Current time save in index file */
Pengfei Liuc181a982020-01-07 19:27:13 +080028} Segment_Context_t;
29
Pengfei Liub4734232020-01-17 18:25:10 +080030/**\brief Segment file type*/
Pengfei Liuc181a982020-01-07 19:27:13 +080031typedef enum {
Pengfei Liub4734232020-01-17 18:25:10 +080032 SEGMENT_FILE_TYPE_TS, /**< Used for store TS data*/
33 SEGMENT_FILE_TYPE_INDEX, /**< Used for store index data*/
34 SEGMENT_FILE_TYPE_DAT, /**< Used for store information data, such as duration etc*/
pengfei.liu567d6d82020-04-17 16:48:59 +080035 SEGMENT_FILE_TYPE_ONGOING, /**< Used for store information data, such as duration etc*/
Pengfei Liuc181a982020-01-07 19:27:13 +080036} Segment_FileType_t;
37
38static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
Pengfei Liub4734232020-01-17 18:25:10 +080039 const char location[DVR_MAX_LOCATION_SIZE],
Pengfei Liuc181a982020-01-07 19:27:13 +080040 uint64_t segment_id,
41 Segment_FileType_t type)
42{
43 int offset;
44
45 memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
46 strncpy(fname, location, strlen(location));
47 offset = strlen(location);
48 strncpy(fname + offset, "-", 1);
49 offset += 1;
50 sprintf(fname + offset, "%04llu", segment_id);
51 offset += 4;
52 if (type == SEGMENT_FILE_TYPE_TS)
53 strncpy(fname + offset, ".ts", 3);
54 else if (type == SEGMENT_FILE_TYPE_INDEX)
55 strncpy(fname + offset, ".idx", 4);
Pengfei Liub4734232020-01-17 18:25:10 +080056 else if (type == SEGMENT_FILE_TYPE_DAT)
57 strncpy(fname + offset, ".dat", 4);
hualing chen87072a82020-03-12 16:20:12 +080058 else if (type == SEGMENT_FILE_TYPE_ONGOING)
59 strncpy(fname + offset, ".going", 6);
Pengfei Liuc181a982020-01-07 19:27:13 +080060}
61
Pengfei Liu3b1a8202020-02-12 23:04:21 +080062static void segment_get_dirname(char dir_name[MAX_SEGMENT_PATH_SIZE],
63 const char location[DVR_MAX_LOCATION_SIZE])
64{
65 char *p;
66 int i;
67 int found = 0;
68
69 for (i = 0; i < (int)strlen(location); i++) {
70 if (location[i] == '/') {
71 p = (char *)location + i;
72 found = 1;
73 }
74 }
75 if (found)
76 memcpy(dir_name, location, p - location);
77}
78
Pengfei Liuc181a982020-01-07 19:27:13 +080079int segment_open(Segment_OpenParams_t *params, Segment_Handle_t *p_handle)
80{
81 Segment_Context_t *p_ctx;
82 char ts_fname[MAX_SEGMENT_PATH_SIZE];
83 char index_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liub4734232020-01-17 18:25:10 +080084 char dat_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liu3b1a8202020-02-12 23:04:21 +080085 char dir_name[MAX_SEGMENT_PATH_SIZE];
hualing chen87072a82020-03-12 16:20:12 +080086 char going_name[MAX_SEGMENT_PATH_SIZE];
Pengfei Liuc181a982020-01-07 19:27:13 +080087
Pengfei Liu3b1a8202020-02-12 23:04:21 +080088 DVR_RETURN_IF_FALSE(params);
89 DVR_RETURN_IF_FALSE(p_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +080090
hualing chena540a7e2020-03-27 16:44:05 +080091 //DVR_DEBUG(1, "%s, location:%s, id:%llu", __func__, params->location, params->segment_id);
Pengfei Liuc181a982020-01-07 19:27:13 +080092
Pengfei Liub038b6a2020-01-14 15:57:01 +080093 p_ctx = (void*)malloc(sizeof(Segment_Context_t));
Pengfei Liu3b1a8202020-02-12 23:04:21 +080094 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +080095 memset(p_ctx, 0, sizeof(Segment_Context_t));
Pengfei Liuc181a982020-01-07 19:27:13 +080096
97 memset(ts_fname, 0, sizeof(ts_fname));
98 segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
99
100 memset(index_fname, 0, sizeof(index_fname));
101 segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
102
Pengfei Liub4734232020-01-17 18:25:10 +0800103 memset(dat_fname, 0, sizeof(dat_fname));
104 segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
105
hualing chen87072a82020-03-12 16:20:12 +0800106 memset(going_name, 0, sizeof(going_name));
107 segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
108
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800109 memset(dir_name, 0, sizeof(dir_name));
110 segment_get_dirname(dir_name, params->location);
111 if (access(dir_name, F_OK) == -1) {
112 DVR_DEBUG(1, "%s dir %s is not exist, create it", __func__, dir_name);
113 mkdir(dir_name, 0666);
114 }
115
Pengfei Liuc181a982020-01-07 19:27:13 +0800116 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800117 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800118 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800119 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800120 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800121 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800122 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800123 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800124 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chen87072a82020-03-12 16:20:12 +0800125 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800126 p_ctx->first_pts = ULLONG_MAX;
127 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800128 p_ctx->last_record_pts = ULLONG_MAX;
Pengfei Liuc181a982020-01-07 19:27:13 +0800129 } else {
130 DVR_DEBUG(1, "%s, unknow mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800131 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800132 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800133 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800134 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800135 }
136
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800137 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Pengfei Liub4734232020-01-17 18:25:10 +0800138 DVR_DEBUG(1, "%s open file failed [%s, %s, %s], reason:%s", __func__,
139 ts_fname, index_fname, dat_fname, strerror(errno));
Pengfei Liuc181a982020-01-07 19:27:13 +0800140 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800141 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800142 return DVR_FAILURE;
143 }
hualing chen87072a82020-03-12 16:20:12 +0800144 p_ctx->segment_id = params->segment_id;
145 strncpy(p_ctx->location, params->location, strlen(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800146
hualing chen7a56cba2020-04-14 14:09:27 +0800147 //DVR_DEBUG(1, "%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800148 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800149 return DVR_SUCCESS;
150}
151
152int segment_close(Segment_Handle_t handle)
153{
154 Segment_Context_t *p_ctx;
155
Pengfei Liub038b6a2020-01-14 15:57:01 +0800156 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800157 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800158
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800159 if (p_ctx->ts_fd != -1) {
160 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800161 }
162
163 if (p_ctx->index_fp) {
164 fclose(p_ctx->index_fp);
165 }
166
Pengfei Liub4734232020-01-17 18:25:10 +0800167 if (p_ctx->dat_fp) {
168 fclose(p_ctx->dat_fp);
169 }
170
hualing chen87072a82020-03-12 16:20:12 +0800171 if (p_ctx->ongoing_fp != NULL) {
172 fclose(p_ctx->ongoing_fp);
173 char going_name[MAX_SEGMENT_PATH_SIZE];
174 memset(going_name, 0, sizeof(going_name));
175 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
176 DVR_DEBUG(1, "segment close del [%s]", going_name);
177 unlink(going_name);
178 }
179
Pengfei Liuc181a982020-01-07 19:27:13 +0800180 free(p_ctx);
181 return 0;
182}
183
184ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
185{
186 Segment_Context_t *p_ctx;
187
188 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800189 DVR_RETURN_IF_FALSE(p_ctx);
190 DVR_RETURN_IF_FALSE(buf);
191 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800192
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800193 return read(p_ctx->ts_fd, buf, count);
Pengfei Liuc181a982020-01-07 19:27:13 +0800194}
195
196ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
197{
198 Segment_Context_t *p_ctx;
199
200 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800201 DVR_RETURN_IF_FALSE(p_ctx);
202 DVR_RETURN_IF_FALSE(buf);
203 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800204
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800205 return write(p_ctx->ts_fd, buf, count);
Pengfei Liuc181a982020-01-07 19:27:13 +0800206}
207
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800208int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800209{
210 Segment_Context_t *p_ctx;
211 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800212 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800213
214 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800215 DVR_RETURN_IF_FALSE(p_ctx);
216 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800217
Pengfei Liub038b6a2020-01-14 15:57:01 +0800218 if (p_ctx->first_pts == ULLONG_MAX) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800219 DVR_DEBUG(1, "%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800220 p_ctx->first_pts = pts;
221 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800222 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800223 if (p_ctx->last_pts == ULLONG_MAX) {
224 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800225 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800226 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800227 } else {
228 /*Last pts has valid value*/
pengfei.liu567d6d82020-04-17 16:48:59 +0800229 int diff = pts - p_ctx->last_pts;
hualing chen4b7c15d2020-04-07 16:13:48 +0800230 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
Pengfei Liub038b6a2020-01-14 15:57:01 +0800231 /*Current pts has a transition*/
pengfei.liuab5a2262020-02-14 17:33:40 +0800232 DVR_DEBUG(1, "Current pts has a transition, [%llu, %llu, %llu]",
233 p_ctx->first_pts, p_ctx->last_pts, pts);
pengfei.liu567d6d82020-04-17 16:48:59 +0800234 p_ctx->last_record_pts = pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800235 } else {
236 /*This is a normal pts, record it*/
hualing chen4b7c15d2020-04-07 16:13:48 +0800237 p_ctx->cur_time += diff;
hualing chen2aba4022020-03-02 13:49:55 +0800238 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800239 }
240 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800241
242 record_diff = pts - p_ctx->last_record_pts;
243 if (strlen(buf) > 0 &&
244 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800245 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800246 fflush(p_ctx->index_fp);
247 fsync(fileno(p_ctx->index_fp));
248 p_ctx->last_record_pts = pts;
249 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800250 p_ctx->last_pts = pts;
Pengfei Liub4734232020-01-17 18:25:10 +0800251
Pengfei Liuc181a982020-01-07 19:27:13 +0800252 return DVR_SUCCESS;
253}
254
hualing chen266b9502020-04-04 17:39:39 +0800255loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800256{
257 Segment_Context_t *p_ctx;
258 char buf[256];
259 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800260 uint64_t pts = 0L;
261 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800262 char *p1, *p2;
263
264 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800265 DVR_RETURN_IF_FALSE(p_ctx);
266 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
267 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800268
hualing chen266b9502020-04-04 17:39:39 +0800269 if (time == 0) {
270 offset = 0;
271 DVR_DEBUG(1, "seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
272 DVR_RETURN_IF_FALSE(lseek64(p_ctx->ts_fd, offset, SEEK_SET) != -1);
273 return offset;
274 }
275
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800276 memset(buf, 0, sizeof(buf));
277 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800278 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800279 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800280 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800281 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800282 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800283 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800284 if ((p2 = strstr(buf, ","))) {
285 memcpy(value, p1, p2 - p1);
286 }
287 pts = strtoull(value, NULL, 10);
288 }
289
290 memset(value, 0, sizeof(value));
291 if ((p1 = strstr(buf, "offset="))) {
292 p1 += 7;
293 if ((p2 = strstr(buf, "}"))) {
294 memcpy(value, p1, p2 - p1);
295 }
296 offset = strtoull(value, NULL, 10);
297 }
hualing chen2aba4022020-03-02 13:49:55 +0800298 if (0)
299 {
300 DVR_DEBUG(1, "seek buf[%s]", buf);
301 DVR_DEBUG(1, "seek time=%llu, offset=%lld\n", pts, offset);
302 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800303 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800304 //DVR_DEBUG(1, "seek time=%llu, offset=%lld\n", pts, offset);
305 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800306 if (block_size > 0) {
307 offset = offset - offset%block_size;
308 }
hualing chen2aba4022020-03-02 13:49:55 +0800309 DVR_DEBUG(1, "seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800310 DVR_RETURN_IF_FALSE(lseek64(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800311 return offset;
312 }
hualing chen2aba4022020-03-02 13:49:55 +0800313 }
314 DVR_DEBUG(1, "seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800315 return DVR_FAILURE;
316}
317
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800318loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800319{
320 Segment_Context_t *p_ctx;
321
322 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800323 DVR_RETURN_IF_FALSE(p_ctx);
324 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800325
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800326 return lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
327}
328
pengfei.liu8b563292020-02-26 15:49:02 +0800329uint64_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800330{
331 Segment_Context_t *p_ctx;
332 char buf[256];
333 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800334 uint64_t pts = 0L;
335 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800336 char *p1, *p2;
337
338 p_ctx = (Segment_Context_t *)handle;
339 DVR_RETURN_IF_FALSE(p_ctx);
340 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
341 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
342
343 memset(buf, 0, sizeof(buf));
344 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
345 position = lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
346 DVR_RETURN_IF_FALSE(position != -1);
347
348 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
349 memset(value, 0, sizeof(value));
350 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800351 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800352 if ((p2 = strstr(buf, ","))) {
353 memcpy(value, p1, p2 - p1);
354 }
355 pts = strtoull(value, NULL, 10);
356 }
357
358 memset(value, 0, sizeof(value));
359 if ((p1 = strstr(buf, "offset="))) {
360 p1 += 7;
361 if ((p2 = strstr(buf, "}"))) {
362 memcpy(value, p1, p2 - p1);
363 }
364 offset = strtoull(value, NULL, 10);
365 }
366
367 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800368 //DVR_DEBUG(1, "tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800369 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800370 return pts;
371 }
372 }
hualing chena540a7e2020-03-27 16:44:05 +0800373 //DVR_DEBUG(1, "tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800374 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800375}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800376
pengfei.liu8b563292020-02-26 15:49:02 +0800377uint64_t segment_tell_total_time(Segment_Handle_t handle)
378{
379 Segment_Context_t *p_ctx;
380 char buf[256];
381 char last_buf[256];
382 char value[256];
383 uint64_t pts = ULLONG_MAX;
384 loff_t offset = 0, position = 0;
385 char *p1, *p2;
386 int line = 0;
387
388 p_ctx = (Segment_Context_t *)handle;
389 DVR_RETURN_IF_FALSE(p_ctx);
390 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
391 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
392
393 memset(buf, 0, sizeof(buf));
394 memset(last_buf, 0, sizeof(last_buf));
395 position = lseek64(p_ctx->ts_fd, 0, SEEK_CUR);
396 DVR_RETURN_IF_FALSE(position != -1);
397
hualing chen041c4092020-04-05 15:11:50 +0800398 //DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, -1000L, SEEK_END) != -1);
399 //if seek error.we need seek 0 pos.
400 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
401 fseek(p_ctx->index_fp, 0L, SEEK_SET);
402 }
pengfei.liu8b563292020-02-26 15:49:02 +0800403 /* Save last line buffer */
404 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800405 if (strlen(buf) <= 0) {
hualing chen87072a82020-03-12 16:20:12 +0800406 DVR_DEBUG(1, "read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800407 continue;
408 }
pengfei.liu8b563292020-02-26 15:49:02 +0800409 memset(last_buf, 0, sizeof(last_buf));
410 memcpy(last_buf, buf, strlen(buf));
411 memset(buf, 0, sizeof(buf));
412 line++;
413 }
414
415 /* Extract time value */
416 memset(value, 0, sizeof(value));
417 if ((p1 = strstr(last_buf, "time="))) {
418 p1 += 5;
419 if ((p2 = strstr(last_buf, ","))) {
420 memcpy(value, p1, p2 - p1);
421 }
422 pts = strtoull(value, NULL, 10);
423 }
424
425 memset(value, 0, sizeof(value));
426 if ((p1 = strstr(last_buf, "offset="))) {
427 p1 += 7;
428 if ((p2 = strstr(last_buf, "}"))) {
429 memcpy(value, p1, p2 - p1);
430 }
431 offset = strtoull(value, NULL, 10);
432 }
hualing chen87072a82020-03-12 16:20:12 +0800433 //if (line < 2)
434 //DVR_DEBUG(1, "totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800435 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
436}
437
pengfei.liuab5a2262020-02-14 17:33:40 +0800438/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800439int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
440{
441 Segment_Context_t *p_ctx;
442 char buf[256];
443 uint32_t i;
444
445 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800446 DVR_RETURN_IF_FALSE(p_ctx);
447 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
448 DVR_RETURN_IF_FALSE(p_info);
hualing chen87072a82020-03-12 16:20:12 +0800449 //seek 0, rewrite info
450 DVR_RETURN_IF_FALSE(fseek(p_ctx->dat_fp, 0, SEEK_SET) != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800451
452 /*Save segment id*/
453 memset(buf, 0, sizeof(buf));
454 sprintf(buf, "id=%lld\n", p_info->id);
455 fputs(buf, p_ctx->dat_fp);
456
457 /*Save number of pids*/
458 memset(buf, 0, sizeof(buf));
459 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
460 fputs(buf, p_ctx->dat_fp);
461
462 /*Save pid information*/
463 for (i = 0; i < p_info->nb_pids; i++) {
464 memset(buf, 0, sizeof(buf));
465 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
466 fputs(buf, p_ctx->dat_fp);
467 }
468
469 /*Save segment duration*/
470 memset(buf, 0, sizeof(buf));
hualing chen87072a82020-03-12 16:20:12 +0800471 DVR_DEBUG(1, "duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800472 sprintf(buf, "duration=%ld\n", p_info->duration);
473 fputs(buf, p_ctx->dat_fp);
474
475 /*Save segment size*/
476 memset(buf, 0, sizeof(buf));
477 sprintf(buf, "size=%zu\n", p_info->size);
478 fputs(buf, p_ctx->dat_fp);
479
480 /*Save number of packets*/
481 memset(buf, 0, sizeof(buf));
482 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
483 fputs(buf, p_ctx->dat_fp);
484
485 fflush(p_ctx->dat_fp);
486 fsync(fileno(p_ctx->dat_fp));
487 return DVR_SUCCESS;
488}
489
pengfei.liuab5a2262020-02-14 17:33:40 +0800490/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800491int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
492{
493 Segment_Context_t *p_ctx;
494 uint32_t i;
495 char buf[256];
496 char value[256];
497 char *p1, *p2;
498
499 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800500 DVR_RETURN_IF_FALSE(p_ctx);
501 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800502
503 /*Load segment id*/
504 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800505 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800506 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800507 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800508 p_info->id = strtoull(p1 + 3, NULL, 10);
509
510 /*Save number of pids*/
511 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800512 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800513 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800514 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800515 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
516
517 /*Save pid information*/
518 for (i = 0; i < p_info->nb_pids; i++) {
519 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800520 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800521 memset(value, 0, sizeof(value));
522 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800523 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800524 p1 += 4;
525 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800526 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800527 memcpy(value, p1, p2 - p1);
528 }
529 p_info->pids[i].pid = strtoull(value, NULL, 10);
530 }
531
532 memset(value, 0, sizeof(value));
533 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800534 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800535 p1 += 5;
536 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800537 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800538 memcpy(value, p1, p2 - p1);
539 }
540 p_info->pids[i].type = strtoull(value, NULL, 10);
541 }
542 }
543
544 /*Save segment duration*/
545 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800546 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800547 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800548 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800549 p_info->duration = strtoull(p1 + 9, NULL, 10);
hualing chena540a7e2020-03-27 16:44:05 +0800550 //DVR_DEBUG(1, "load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800551
552 /*Save segment size*/
553 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800554 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800555 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800556 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800557 p_info->size = strtoull(p1 + 5, NULL, 10);
558
559 /*Save number of packets*/
560 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800561 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800562 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800563 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800564 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
565
566 return DVR_SUCCESS;
567}
568
569int segment_delete(const char *location, uint64_t segment_id)
570{
571 char fname[MAX_SEGMENT_PATH_SIZE];
572 int ret;
573
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800574 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800575
576 /*delete ts file*/
577 memset(fname, 0, sizeof(fname));
578 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
579 ret = unlink(fname);
580 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800581 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800582
583 /*delete index file*/
584 memset(fname, 0, sizeof(fname));
585 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
586 unlink(fname);
587 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800588 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800589
590 /*delete store information file*/
591 memset(fname, 0, sizeof(fname));
592 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
593 unlink(fname);
594 DVR_DEBUG(1, "%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800595 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800596
597 return DVR_SUCCESS;
598}
599
hualing chen87072a82020-03-12 16:20:12 +0800600int segment_ongoing(Segment_Handle_t handle)
601{
602 Segment_Context_t *p_ctx;
603 p_ctx = (Segment_Context_t *)handle;
604 struct stat mstat;
605
606 char going_name[MAX_SEGMENT_PATH_SIZE];
607 memset(going_name, 0, sizeof(going_name));
608 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
609 int ret = stat(going_name, &mstat);
610 DVR_DEBUG(1, "segment check ongoing [%s] ret [%d]", going_name, ret);
611 if (ret != 0) {
612 return DVR_FAILURE;
613 }
614 return DVR_SUCCESS;
615}
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800616loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800617{
618 Segment_Context_t *p_ctx;
619 char buf[256];
620 char value[256];
621 uint64_t pts;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800622 loff_t offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800623 char *p1, *p2;
624
625 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800626 DVR_RETURN_IF_FALSE(p_ctx);
627 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
628 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800629
630 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800631 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800632 printf("start gets pts\n");
633 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
634 printf("buf[%s]\n", buf);
635 memset(value, 0, sizeof(value));
636 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800637 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800638 if ((p2 = strstr(buf, ","))) {
639 memcpy(value, p1, p2 - p1);
640 }
641 pts = strtoull(value, NULL, 10);
642 }
643
644 memset(value, 0, sizeof(value));
645 if ((p1 = strstr(buf, "offset="))) {
646 p1 += 7;
647 if ((p2 = strstr(buf, "}"))) {
648 memcpy(value, p1, p2 - p1);
649 }
650 offset = strtoull(value, NULL, 10);
651 }
652
653 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800654 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800655 }
656
657 return 0;
658}