blob: 6a49cf5ead1b5ba77a53b84eb8adeb1a7afc6564 [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)
hualing chen06209692020-11-05 14:51:46 +080015#define PCR_RECORD_INTERVAL_MS (300)
Wentao MA270dc0f2022-08-23 13:17:26 +080016#define PTS_DISCONTINUED_DEVIATION (40)
hualing chen2932d372020-04-29 13:44:00 +080017#define PTS_HEAD_DEVIATION (40)
hualing chen86b8e602021-12-23 11:04:19 +080018#define PCR_JUMP_DUR (5000)
hualing chen2932d372020-04-29 13:44:00 +080019
hualing chen157641d2022-02-22 17:54:52 +080020#define IDX_FILE_SYNC_TIME (10)//10*PCR_RECORD_INTERVAL_MS
21#define TS_FILE_SYNC_TIME (9)//9*PCR_RECORD_INTERVAL_MS
22
hualing chen2932d372020-04-29 13:44:00 +080023
Pengfei Liub4734232020-01-17 18:25:10 +080024/**\brief Segment context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080025typedef struct {
Pengfei Liu3b1a8202020-02-12 23:04:21 +080026 int ts_fd; /**< Segment ts file fd*/
Pengfei Liub4734232020-01-17 18:25:10 +080027 FILE *index_fp; /**< Time index file fd*/
28 FILE *dat_fp; /**< Information file fd*/
hualing chenb9a02922021-12-14 11:29:47 +080029 FILE *all_dat_fp; /**< Information file fd*/
Wentao MA270dc0f2022-08-23 13:17:26 +080030 FILE *ongoing_fp; /**< Ongoing file fd, used to verify timeshift mode*/
Pengfei Liub4734232020-01-17 18:25:10 +080031 uint64_t first_pts; /**< First pts value, use for write mode*/
pengfei.liu567d6d82020-04-17 16:48:59 +080032 uint64_t last_pts; /**< Last input pts value, use for write mode*/
33 uint64_t last_record_pts; /**< Last record pts value, use for write mode*/
pengfei.liuab5a2262020-02-14 17:33:40 +080034 uint64_t cur_time; /**< Current time save in index file */
pengfei.liu567d6d82020-04-17 16:48:59 +080035 uint64_t segment_id; /**< Current segment ID */
36 char location[MAX_SEGMENT_PATH_SIZE]; /**< Current time save in index file */
hualing chena5f03222021-12-02 11:22:35 +080037 loff_t first_offset;
38 loff_t last_offset;
39 loff_t last_record_offset;
40 float avg_rate;
hualing chen157641d2022-02-22 17:54:52 +080041 int time;
wentao.ma35a69d42022-03-10 18:08:40 +080042 DVR_Bool_t force_sysclock; /**< If ture, force to use system clock as PVR index time source. If false, libdvr can determine index time source based on actual situation*/
hualing chen157641d2022-02-22 17:54:52 +080043 } Segment_Context_t;
Pengfei Liuc181a982020-01-07 19:27:13 +080044
Pengfei Liub4734232020-01-17 18:25:10 +080045/**\brief Segment file type*/
Pengfei Liuc181a982020-01-07 19:27:13 +080046typedef enum {
Pengfei Liub4734232020-01-17 18:25:10 +080047 SEGMENT_FILE_TYPE_TS, /**< Used for store TS data*/
48 SEGMENT_FILE_TYPE_INDEX, /**< Used for store index data*/
49 SEGMENT_FILE_TYPE_DAT, /**< Used for store information data, such as duration etc*/
pengfei.liu567d6d82020-04-17 16:48:59 +080050 SEGMENT_FILE_TYPE_ONGOING, /**< Used for store information data, such as duration etc*/
Wentao MA9a164002022-08-29 11:20:24 +080051 SEGMENT_FILE_TYPE_ALL_DATA, /**< Used for store all information data*/
Pengfei Liuc181a982020-01-07 19:27:13 +080052} Segment_FileType_t;
53
54static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
Pengfei Liub4734232020-01-17 18:25:10 +080055 const char location[DVR_MAX_LOCATION_SIZE],
Pengfei Liuc181a982020-01-07 19:27:13 +080056 uint64_t segment_id,
57 Segment_FileType_t type)
58{
59 int offset;
60
61 memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
62 strncpy(fname, location, strlen(location));
63 offset = strlen(location);
Wentao MAe88ad702022-09-02 10:35:00 +080064
65 DVR_ASSERT(offset + DVR_MAX_LOCATION_SIZE < MAX_SEGMENT_PATH_SIZE);
66
Wentao MA9a164002022-08-29 11:20:24 +080067 if (type != SEGMENT_FILE_TYPE_ALL_DATA) {
hualing chenb9a02922021-12-14 11:29:47 +080068 strncpy(fname + offset, "-", 1);
69 offset += 1;
70 sprintf(fname + offset, "%04llu", segment_id);
Wentao MAbcbc0c82022-06-28 11:24:56 +080071 offset += strlen(fname + offset);
hualing chenb9a02922021-12-14 11:29:47 +080072 }
73
Pengfei Liuc181a982020-01-07 19:27:13 +080074 if (type == SEGMENT_FILE_TYPE_TS)
75 strncpy(fname + offset, ".ts", 3);
76 else if (type == SEGMENT_FILE_TYPE_INDEX)
77 strncpy(fname + offset, ".idx", 4);
Pengfei Liub4734232020-01-17 18:25:10 +080078 else if (type == SEGMENT_FILE_TYPE_DAT)
79 strncpy(fname + offset, ".dat", 4);
hualing chen87072a82020-03-12 16:20:12 +080080 else if (type == SEGMENT_FILE_TYPE_ONGOING)
81 strncpy(fname + offset, ".going", 6);
Wentao MA9a164002022-08-29 11:20:24 +080082 else if (type == SEGMENT_FILE_TYPE_ALL_DATA)
hualing chenb9a02922021-12-14 11:29:47 +080083 strncpy(fname + offset, ".dat", 4);
84
Pengfei Liuc181a982020-01-07 19:27:13 +080085}
86
Pengfei Liu3b1a8202020-02-12 23:04:21 +080087static void segment_get_dirname(char dir_name[MAX_SEGMENT_PATH_SIZE],
88 const char location[DVR_MAX_LOCATION_SIZE])
89{
90 char *p;
91 int i;
92 int found = 0;
93
94 for (i = 0; i < (int)strlen(location); i++) {
95 if (location[i] == '/') {
96 p = (char *)location + i;
97 found = 1;
98 }
99 }
100 if (found)
101 memcpy(dir_name, location, p - location);
102}
103
Pengfei Liuc181a982020-01-07 19:27:13 +0800104int segment_open(Segment_OpenParams_t *params, Segment_Handle_t *p_handle)
105{
106 Segment_Context_t *p_ctx;
107 char ts_fname[MAX_SEGMENT_PATH_SIZE];
108 char index_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liub4734232020-01-17 18:25:10 +0800109 char dat_fname[MAX_SEGMENT_PATH_SIZE];
hualing chenb9a02922021-12-14 11:29:47 +0800110 char all_dat_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800111 char dir_name[MAX_SEGMENT_PATH_SIZE];
hualing chen87072a82020-03-12 16:20:12 +0800112 char going_name[MAX_SEGMENT_PATH_SIZE];
Pengfei Liuc181a982020-01-07 19:27:13 +0800113
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800114 DVR_RETURN_IF_FALSE(params);
115 DVR_RETURN_IF_FALSE(p_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800116
Wentao MA96f68962022-06-15 19:45:35 +0800117 //DVR_INFO("%s, location:%s, id:%llu", __func__, params->location, params->segment_id);
Pengfei Liuc181a982020-01-07 19:27:13 +0800118
Pengfei Liub038b6a2020-01-14 15:57:01 +0800119 p_ctx = (void*)malloc(sizeof(Segment_Context_t));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800120 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800121 memset(p_ctx, 0, sizeof(Segment_Context_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800122
123 memset(ts_fname, 0, sizeof(ts_fname));
124 segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
125
126 memset(index_fname, 0, sizeof(index_fname));
127 segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
128
Pengfei Liub4734232020-01-17 18:25:10 +0800129 memset(dat_fname, 0, sizeof(dat_fname));
130 segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
131
hualing chenb9a02922021-12-14 11:29:47 +0800132 memset(all_dat_fname, 0, sizeof(all_dat_fname));
Wentao MA9a164002022-08-29 11:20:24 +0800133 segment_get_fname(all_dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_ALL_DATA);
hualing chenb9a02922021-12-14 11:29:47 +0800134
135
hualing chen87072a82020-03-12 16:20:12 +0800136 memset(going_name, 0, sizeof(going_name));
137 segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
138
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800139 memset(dir_name, 0, sizeof(dir_name));
140 segment_get_dirname(dir_name, params->location);
Wentao MAb2070812022-09-02 13:10:03 +0800141
142 mkdir(dir_name, 0666);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800143 if (access(dir_name, F_OK) == -1) {
Wentao MAb2070812022-09-02 13:10:03 +0800144 DVR_WARN("%s dir %s does not exist", __func__, dir_name);
145 return DVR_FAILURE;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800146 }
147
Pengfei Liuc181a982020-01-07 19:27:13 +0800148 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800149 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800150 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800151 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800152 p_ctx->ongoing_fp = NULL;
hualing chenb9a02922021-12-14 11:29:47 +0800153 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
Pengfei Liuc181a982020-01-07 19:27:13 +0800154 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800155 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800156 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800157 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chenb9a02922021-12-14 11:29:47 +0800158 p_ctx->all_dat_fp = fopen(all_dat_fname, "a+");
Wentao MA96f68962022-06-15 19:45:35 +0800159 DVR_INFO("%s dir %s is opened", __func__, all_dat_fname);
hualing chen87072a82020-03-12 16:20:12 +0800160 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800161 p_ctx->first_pts = ULLONG_MAX;
162 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800163 p_ctx->last_record_pts = ULLONG_MAX;
hualing chena5f03222021-12-02 11:22:35 +0800164 p_ctx->avg_rate = 0.0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800165 } else {
Wentao MA9a164002022-08-29 11:20:24 +0800166 DVR_INFO("%s, unknown mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800167 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800168 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800169 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chenb9a02922021-12-14 11:29:47 +0800170 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800171 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800172 }
173
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800174 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800175 DVR_INFO("%s open file failed [%s, %s, %s], reason:%s", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800176 ts_fname, index_fname, dat_fname, strerror(errno));
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800177 if (p_ctx->ts_fd != -1)
178 close(p_ctx->ts_fd);
179 if (p_ctx->index_fp)
180 fclose(p_ctx->index_fp);
181 if (p_ctx->dat_fp)
182 fclose(p_ctx->dat_fp);
hualing chen926a8ec2021-12-20 20:38:24 +0800183 if (p_ctx->all_dat_fp)
184 fclose(p_ctx->all_dat_fp);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800185 if (p_ctx->ongoing_fp)
186 fclose(p_ctx->ongoing_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800187 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800188 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800189 return DVR_FAILURE;
190 }
hualing chen87072a82020-03-12 16:20:12 +0800191 p_ctx->segment_id = params->segment_id;
192 strncpy(p_ctx->location, params->location, strlen(params->location));
wentao.ma35a69d42022-03-10 18:08:40 +0800193 p_ctx->force_sysclock = params->force_sysclock;
Pengfei Liub4734232020-01-17 18:25:10 +0800194
Wentao MA96f68962022-06-15 19:45:35 +0800195 //DVR_INFO("%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800196 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800197 return DVR_SUCCESS;
198}
199
200int segment_close(Segment_Handle_t handle)
201{
202 Segment_Context_t *p_ctx;
203
Pengfei Liub038b6a2020-01-14 15:57:01 +0800204 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800205 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800206
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800207 if (p_ctx->ts_fd != -1) {
208 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800209 }
210
211 if (p_ctx->index_fp) {
212 fclose(p_ctx->index_fp);
213 }
214
Pengfei Liub4734232020-01-17 18:25:10 +0800215 if (p_ctx->dat_fp) {
216 fclose(p_ctx->dat_fp);
217 }
hualing chen926a8ec2021-12-20 20:38:24 +0800218 if (p_ctx->all_dat_fp) {
219 fclose(p_ctx->all_dat_fp);
220 }
hualing chen87072a82020-03-12 16:20:12 +0800221 if (p_ctx->ongoing_fp != NULL) {
222 fclose(p_ctx->ongoing_fp);
223 char going_name[MAX_SEGMENT_PATH_SIZE];
224 memset(going_name, 0, sizeof(going_name));
225 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
Wentao MA96f68962022-06-15 19:45:35 +0800226 DVR_INFO("segment close del [%s]", going_name);
hualing chen87072a82020-03-12 16:20:12 +0800227 unlink(going_name);
228 }
229
Pengfei Liuc181a982020-01-07 19:27:13 +0800230 free(p_ctx);
231 return 0;
232}
233
234ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
235{
236 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800237 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800238 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800239 DVR_RETURN_IF_FALSE(p_ctx);
240 DVR_RETURN_IF_FALSE(buf);
241 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800242 len = read(p_ctx->ts_fd, buf, count);
243 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800244}
245
246ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
247{
248 Segment_Context_t *p_ctx;
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800249 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800250 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800251 DVR_RETURN_IF_FALSE(p_ctx);
252 DVR_RETURN_IF_FALSE(buf);
253 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800254 len = write(p_ctx->ts_fd, buf, count);
hualing chen157641d2022-02-22 17:54:52 +0800255 if (p_ctx->time % TS_FILE_SYNC_TIME == 0)
256 fsync(p_ctx->ts_fd);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800257 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800258}
259
hualing chen2932d372020-04-29 13:44:00 +0800260int segment_update_pts_force(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800261{
262 Segment_Context_t *p_ctx;
263 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800264 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800265
266 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800267 DVR_RETURN_IF_FALSE(p_ctx);
268 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800269
Pengfei Liub038b6a2020-01-14 15:57:01 +0800270 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800271 DVR_INFO("%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800272 p_ctx->first_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800273 p_ctx->first_offset = offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800274 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800275 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800276 if (p_ctx->last_pts == ULLONG_MAX) {
277 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800278 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800279 p_ctx->cur_time = pts - p_ctx->first_pts;
Wentao MA96f68962022-06-15 19:45:35 +0800280 DVR_INFO("%s force pcr:%llu -1", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800281 } else {
282 /*Last pts has valid value*/
283 int diff = pts - p_ctx->last_pts;
284 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
285 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800286 DVR_INFO("[%s]force update Current pts has a transition, [%llu, %llu, %llu]",__func__,
hualing chen2932d372020-04-29 13:44:00 +0800287 p_ctx->first_pts, p_ctx->last_pts, pts);
288 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
289 } else {
290 /*This is a normal pts, record it*/
hualing chena5f03222021-12-02 11:22:35 +0800291 //check if this pcr is transition.if true,add 200ms
292 //other case normal.
hualing chen2932d372020-04-29 13:44:00 +0800293 p_ctx->cur_time += diff;
Wentao MA96f68962022-06-15 19:45:35 +0800294 DVR_INFO("%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
hualing chen2932d372020-04-29 13:44:00 +0800295 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
296 }
297 }
298
299 record_diff = pts - p_ctx->last_record_pts;
300 if (strlen(buf) > 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800301 DVR_INFO("%s force pcr:%llu buf:%s", __func__, pts, buf);
hualing chen2932d372020-04-29 13:44:00 +0800302 fputs(buf, p_ctx->index_fp);
303 fflush(p_ctx->index_fp);
304 fsync(fileno(p_ctx->index_fp));
305 p_ctx->last_record_pts = pts;
306 }
307 p_ctx->last_pts = pts;
hualing chen2932d372020-04-29 13:44:00 +0800308 return DVR_SUCCESS;
309}
310
311int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
312{
313 Segment_Context_t *p_ctx;
314 char buf[256];
315 int record_diff = 0;
316
317 p_ctx = (Segment_Context_t *)handle;
318 DVR_RETURN_IF_FALSE(p_ctx);
319 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
320
321 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800322 DVR_INFO("%s first pcr:%llu", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800323 p_ctx->first_pts = pts;
324 //p_ctx->cur_time = p_ctx->cur_time + PTS_HEAD_DEVIATION;
325 }
326 memset(buf, 0, sizeof(buf));
327 if (p_ctx->last_pts == ULLONG_MAX) {
328 /*Last pts is init value*/
329 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
330 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800331 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800332 if (!p_ctx->force_sysclock) {
333 /* if force_sysclock is off, we follow old manner. Please refer to
334 * SWPL-75327*/
335 /*Last pts has valid value*/
336 int diff = pts - p_ctx->last_pts;
337 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
338 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800339 DVR_INFO("Current pts has a transition, [%llu, %llu, %llu]",
wentao.ma35a69d42022-03-10 18:08:40 +0800340 p_ctx->first_pts, p_ctx->last_pts, pts);
341 p_ctx->last_record_pts = pts;
Wentao MA270dc0f2022-08-23 13:17:26 +0800342 //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINUED_DEVIATION;
hualing chena5f03222021-12-02 11:22:35 +0800343 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800344 /*This is a normal pts, record it*/
345 loff_t off_diff = offset - p_ctx->last_offset;
346 float rate = (float) (off_diff) / (float)(diff);
347 if (p_ctx->avg_rate == 0.0) {
348 p_ctx->avg_rate = (float) offset / (float)(p_ctx->cur_time + diff);
349 }
350 if (diff >= PCR_JUMP_DUR) {
Wentao MA96f68962022-06-15 19:45:35 +0800351 DVR_INFO("PTS TRANSITION ERROR last pcr[%llu]pts[%llu]pcr diff[%d]off[%llu]off_diff[%llu]rate[%f]avg rate[%f]4*rate[%d]av_diff[%d]",p_ctx->last_pts, pts, diff, offset,off_diff, rate, p_ctx->avg_rate, (int)(rate * 4), (int)(off_diff / p_ctx->avg_rate));
wentao.ma35a69d42022-03-10 18:08:40 +0800352 if (p_ctx->avg_rate != 0 && (int)(p_ctx->avg_rate) >= (int)(rate * 4)) {
353 diff = off_diff / p_ctx->avg_rate;
354 p_ctx->cur_time += diff;
355 } else {
356 p_ctx->cur_time += diff;
357 }
358 } else {
359 p_ctx->cur_time += diff;
360 }
hualing chena5f03222021-12-02 11:22:35 +0800361 }
wentao.ma35a69d42022-03-10 18:08:40 +0800362 } else {
363 /* if force_sysclock is on, we simply calculate cur_time based on system
364 * time. Please refer to SWPL-75327*/
365 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800366 }
wentao.ma35a69d42022-03-10 18:08:40 +0800367 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800368 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800369
370 record_diff = pts - p_ctx->last_record_pts;
371 if (strlen(buf) > 0 &&
372 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800373 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800374 fflush(p_ctx->index_fp);
hualing chen157641d2022-02-22 17:54:52 +0800375 p_ctx->time++;
376 //flush idx file 3s
377 if ((p_ctx->time > 0 && p_ctx->time % IDX_FILE_SYNC_TIME == 0))
378 fsync(fileno(p_ctx->index_fp));
379 if (p_ctx->time > IDX_FILE_SYNC_TIME)
380 p_ctx->time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800381 p_ctx->last_record_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800382 p_ctx->last_record_offset = offset;
383 if (p_ctx->cur_time > 0)
384 p_ctx->avg_rate = (float) offset / (float)p_ctx->cur_time;
pengfei.liu567d6d82020-04-17 16:48:59 +0800385 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800386 p_ctx->last_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800387 p_ctx->last_offset = offset;
Pengfei Liuc181a982020-01-07 19:27:13 +0800388 return DVR_SUCCESS;
389}
390
hualing chen266b9502020-04-04 17:39:39 +0800391loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800392{
393 Segment_Context_t *p_ctx;
394 char buf[256];
395 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800396 uint64_t pts = 0L;
397 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800398 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800399 int ret = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800400
Wentao MA96f68962022-06-15 19:45:35 +0800401 DVR_INFO("into seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chen8a657f32021-08-30 13:12:49 +0800402
Pengfei Liuc181a982020-01-07 19:27:13 +0800403 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800404 DVR_RETURN_IF_FALSE(p_ctx);
405 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
406 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800407
hualing chen266b9502020-04-04 17:39:39 +0800408 if (time == 0) {
409 offset = 0;
Wentao MA96f68962022-06-15 19:45:35 +0800410 DVR_INFO("seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chend241c7a2021-06-22 13:34:27 +0800411 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen266b9502020-04-04 17:39:39 +0800412 return offset;
413 }
414
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800415 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800416 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
417 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800418 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800419 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800420 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800421 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800422 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800423 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800424 if ((p2 = strstr(buf, ","))) {
425 memcpy(value, p1, p2 - p1);
426 }
427 pts = strtoull(value, NULL, 10);
428 }
429
430 memset(value, 0, sizeof(value));
431 if ((p1 = strstr(buf, "offset="))) {
432 p1 += 7;
433 if ((p2 = strstr(buf, "}"))) {
434 memcpy(value, p1, p2 - p1);
435 }
436 offset = strtoull(value, NULL, 10);
437 }
hualing chen2aba4022020-03-02 13:49:55 +0800438 if (0)
439 {
Wentao MA96f68962022-06-15 19:45:35 +0800440 DVR_INFO("seek buf[%s]", buf);
441 DVR_INFO("seek time=%llu, offset=%lld\n", pts, offset);
hualing chen2aba4022020-03-02 13:49:55 +0800442 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800443 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800444 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800445 if (block_size > 0) {
446 offset = offset - offset%block_size;
447 }
Wentao MA96f68962022-06-15 19:45:35 +0800448 //DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800449 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800450 return offset;
451 }
hualing chen2aba4022020-03-02 13:49:55 +0800452 }
hualing chen2932d372020-04-29 13:44:00 +0800453 if (time > pts) {
454 if (block_size > 0) {
455 offset = offset - offset%block_size;
456 }
Wentao MA96f68962022-06-15 19:45:35 +0800457 DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d end\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800458 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen2932d372020-04-29 13:44:00 +0800459 return offset;
460 }
Wentao MA96f68962022-06-15 19:45:35 +0800461 DVR_INFO("seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800462 return DVR_FAILURE;
463}
464
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800465loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800466{
467 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800468 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800469 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800470 DVR_RETURN_IF_FALSE(p_ctx);
471 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800472 pos = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
473 return pos;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800474}
475
Wentao MAa3388532022-08-18 15:07:07 +0800476loff_t segment_tell_position_time(Segment_Handle_t handle, loff_t position)
hualing chen5605eed2020-05-26 18:18:06 +0800477{
478 Segment_Context_t *p_ctx;
479 char buf[256];
480 char value[256];
hualing chen969fe7b2021-05-26 15:13:17 +0800481 uint64_t ret = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800482 uint64_t pts = 0L;
hualing chen969fe7b2021-05-26 15:13:17 +0800483 uint64_t pts_p = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800484 loff_t offset = 0;
hualing chen969fe7b2021-05-26 15:13:17 +0800485 loff_t offset_p = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800486 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800487 int ret2 = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800488
489 p_ctx = (Segment_Context_t *)handle;
490 DVR_RETURN_IF_FALSE(p_ctx);
491 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
492 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
493
494 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800495 ret2 = fseek(p_ctx->index_fp, 0, SEEK_SET);
496 DVR_RETURN_IF_FALSE(ret2 != -1);
hualing chen5605eed2020-05-26 18:18:06 +0800497 DVR_RETURN_IF_FALSE(position != -1);
498
499 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
500 memset(value, 0, sizeof(value));
501 if ((p1 = strstr(buf, "time="))) {
502 p1 += 5;
503 if ((p2 = strstr(buf, ","))) {
504 memcpy(value, p1, p2 - p1);
505 }
506 pts = strtoull(value, NULL, 10);
507 }
508
509 memset(value, 0, sizeof(value));
510 if ((p1 = strstr(buf, "offset="))) {
511 p1 += 7;
512 if ((p2 = strstr(buf, "}"))) {
513 memcpy(value, p1, p2 - p1);
514 }
515 offset = strtoull(value, NULL, 10);
516 }
517
518 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800519 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chend241c7a2021-06-22 13:34:27 +0800520 if (position <= offset
521 &&position >= offset_p
522 && offset - offset_p > 0) {
hualing chen969fe7b2021-05-26 15:13:17 +0800523 ret = pts_p + (pts - pts_p) * (position - offset_p) / (offset - offset_p);
Wentao MA96f68962022-06-15 19:45:35 +0800524 //DVR_INFO("tell cur time=%llu, pts_p = %llu, offset=%lld, position=%lld offset_p+%lld\n", pts, pts_p, offset, position, offset_p);
hualing chen969fe7b2021-05-26 15:13:17 +0800525 return ret;
hualing chen5605eed2020-05-26 18:18:06 +0800526 }
hualing chen969fe7b2021-05-26 15:13:17 +0800527 offset_p = offset;
528 pts_p = pts;
hualing chen5605eed2020-05-26 18:18:06 +0800529 }
Wentao MA96f68962022-06-15 19:45:35 +0800530 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen5605eed2020-05-26 18:18:06 +0800531 return pts;
532}
533
534
Wentao MAa3388532022-08-18 15:07:07 +0800535loff_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800536{
537 Segment_Context_t *p_ctx;
538 char buf[256];
539 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800540 uint64_t pts = 0L;
541 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800542 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800543 int ret = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800544
545 p_ctx = (Segment_Context_t *)handle;
546 DVR_RETURN_IF_FALSE(p_ctx);
547 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
548 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
549
550 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800551 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
552 DVR_RETURN_IF_FALSE(ret != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800553 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800554 DVR_RETURN_IF_FALSE(position != -1);
555
556 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
557 memset(value, 0, sizeof(value));
558 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800559 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800560 if ((p2 = strstr(buf, ","))) {
561 memcpy(value, p1, p2 - p1);
562 }
563 pts = strtoull(value, NULL, 10);
564 }
565
566 memset(value, 0, sizeof(value));
567 if ((p1 = strstr(buf, "offset="))) {
568 p1 += 7;
569 if ((p2 = strstr(buf, "}"))) {
570 memcpy(value, p1, p2 - p1);
571 }
572 offset = strtoull(value, NULL, 10);
573 }
574
575 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800576 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800577 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800578 return pts;
579 }
580 }
Wentao MA96f68962022-06-15 19:45:35 +0800581 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800582 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800583}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800584
Wentao MAa3388532022-08-18 15:07:07 +0800585loff_t segment_tell_total_time(Segment_Handle_t handle)
pengfei.liu8b563292020-02-26 15:49:02 +0800586{
587 Segment_Context_t *p_ctx;
588 char buf[256];
589 char last_buf[256];
590 char value[256];
591 uint64_t pts = ULLONG_MAX;
592 loff_t offset = 0, position = 0;
593 char *p1, *p2;
594 int line = 0;
Wentao MAa3388532022-08-18 15:07:07 +0800595 int ret = 0;
pengfei.liu8b563292020-02-26 15:49:02 +0800596
597 p_ctx = (Segment_Context_t *)handle;
598 DVR_RETURN_IF_FALSE(p_ctx);
599 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
600 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
601
602 memset(buf, 0, sizeof(buf));
603 memset(last_buf, 0, sizeof(last_buf));
hualing chend241c7a2021-06-22 13:34:27 +0800604 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
pengfei.liu8b563292020-02-26 15:49:02 +0800605 DVR_RETURN_IF_FALSE(position != -1);
606
Wentao MAa3388532022-08-18 15:07:07 +0800607 // if unable to seek from end, it is necessary to seek to file beginning position.
hualing chen041c4092020-04-05 15:11:50 +0800608 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
Wentao MAa3388532022-08-18 15:07:07 +0800609 ret = fseek(p_ctx->index_fp, 0L, SEEK_SET);
610 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen041c4092020-04-05 15:11:50 +0800611 }
pengfei.liu8b563292020-02-26 15:49:02 +0800612 /* Save last line buffer */
613 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800614 if (strlen(buf) <= 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800615 DVR_INFO("read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800616 continue;
617 }
pengfei.liu8b563292020-02-26 15:49:02 +0800618 memset(last_buf, 0, sizeof(last_buf));
619 memcpy(last_buf, buf, strlen(buf));
620 memset(buf, 0, sizeof(buf));
621 line++;
622 }
623
624 /* Extract time value */
625 memset(value, 0, sizeof(value));
626 if ((p1 = strstr(last_buf, "time="))) {
627 p1 += 5;
628 if ((p2 = strstr(last_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(last_buf, "offset="))) {
636 p1 += 7;
637 if ((p2 = strstr(last_buf, "}"))) {
638 memcpy(value, p1, p2 - p1);
639 }
640 offset = strtoull(value, NULL, 10);
641 }
hualing chen87072a82020-03-12 16:20:12 +0800642 //if (line < 2)
Wentao MA96f68962022-06-15 19:45:35 +0800643 //DVR_INFO("totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800644 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
645}
646
pengfei.liuab5a2262020-02-14 17:33:40 +0800647/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800648int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
649{
650 Segment_Context_t *p_ctx;
651 char buf[256];
652 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800653 int ret = 0;
Pengfei Liub4734232020-01-17 18:25:10 +0800654
655 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800656 DVR_RETURN_IF_FALSE(p_ctx);
657 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
658 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800659 // seek to 0 to rewrite info
660 ret = fseek(p_ctx->dat_fp, 0, SEEK_SET);
661 DVR_RETURN_IF_FALSE(ret != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800662
663 /*Save segment id*/
664 memset(buf, 0, sizeof(buf));
665 sprintf(buf, "id=%lld\n", p_info->id);
666 fputs(buf, p_ctx->dat_fp);
667
668 /*Save number of pids*/
669 memset(buf, 0, sizeof(buf));
670 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
671 fputs(buf, p_ctx->dat_fp);
672
673 /*Save pid information*/
674 for (i = 0; i < p_info->nb_pids; i++) {
675 memset(buf, 0, sizeof(buf));
676 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
677 fputs(buf, p_ctx->dat_fp);
678 }
679
680 /*Save segment duration*/
681 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800682 DVR_INFO("duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800683 sprintf(buf, "duration=%ld\n", p_info->duration);
684 fputs(buf, p_ctx->dat_fp);
685
686 /*Save segment size*/
687 memset(buf, 0, sizeof(buf));
688 sprintf(buf, "size=%zu\n", p_info->size);
689 fputs(buf, p_ctx->dat_fp);
690
691 /*Save number of packets*/
692 memset(buf, 0, sizeof(buf));
693 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
694 fputs(buf, p_ctx->dat_fp);
695
696 fflush(p_ctx->dat_fp);
hualing chen47c34bc2020-05-11 09:15:47 +0800697 fsync(fileno(p_ctx->dat_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800698 return DVR_SUCCESS;
699}
700
pengfei.liuab5a2262020-02-14 17:33:40 +0800701/* Should consider the case of cut power, todo... */
hualing chenb9a02922021-12-14 11:29:47 +0800702int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
703{
704 Segment_Context_t *p_ctx;
705 char buf[256];
706 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800707 int ret = 0;
hualing chenb9a02922021-12-14 11:29:47 +0800708
709 p_ctx = (Segment_Context_t *)handle;
710 DVR_RETURN_IF_FALSE(p_ctx);
711 DVR_RETURN_IF_FALSE(p_ctx->all_dat_fp);
712 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800713
714 //seek to end to append info
715 ret = fseek(p_ctx->all_dat_fp, 0, SEEK_END);
716 DVR_RETURN_IF_FALSE(ret != -1);
hualing chenb9a02922021-12-14 11:29:47 +0800717
718 /*Save segment id*/
719 memset(buf, 0, sizeof(buf));
720 sprintf(buf, "id=%lld\n", p_info->id);
721 fputs(buf, p_ctx->all_dat_fp);
722
723 /*Save number of pids*/
724 memset(buf, 0, sizeof(buf));
725 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
726 fputs(buf, p_ctx->all_dat_fp);
727
728 /*Save pid information*/
729 for (i = 0; i < p_info->nb_pids; i++) {
730 memset(buf, 0, sizeof(buf));
731 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
732 fputs(buf, p_ctx->all_dat_fp);
733 }
734
735 /*Save segment duration*/
736 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800737 DVR_INFO("duration store:[%ld]", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800738 sprintf(buf, "duration=%ld\n", p_info->duration);
739 fputs(buf, p_ctx->all_dat_fp);
740
741 /*Save segment size*/
742 memset(buf, 0, sizeof(buf));
743 sprintf(buf, "size=%zu\n", p_info->size);
744 fputs(buf, p_ctx->all_dat_fp);
745
746 /*Save number of packets*/
747 memset(buf, 0, sizeof(buf));
748 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
749 fputs(buf, p_ctx->all_dat_fp);
750
751 fflush(p_ctx->all_dat_fp);
752 fsync(fileno(p_ctx->all_dat_fp));
753 return DVR_SUCCESS;
754}
755
756/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800757int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
758{
759 Segment_Context_t *p_ctx;
760 uint32_t i;
761 char buf[256];
762 char value[256];
763 char *p1, *p2;
764
765 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800766 DVR_RETURN_IF_FALSE(p_ctx);
767 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800768
769 /*Load segment id*/
770 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800771 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800772 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800773 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800774 p_info->id = strtoull(p1 + 3, NULL, 10);
775
776 /*Save number of pids*/
777 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800778 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800779 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800780 DVR_RETURN_IF_FALSE(p1);
Wentao MAb2070812022-09-02 13:10:03 +0800781 p_info->nb_pids = strtoul(p1 + 8, NULL, 10);
Pengfei Liub4734232020-01-17 18:25:10 +0800782
783 /*Save pid information*/
784 for (i = 0; i < p_info->nb_pids; i++) {
785 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800786 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800787 memset(value, 0, sizeof(value));
788 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800789 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800790 p1 += 4;
791 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800792 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800793 memcpy(value, p1, p2 - p1);
794 }
795 p_info->pids[i].pid = strtoull(value, NULL, 10);
796 }
797
798 memset(value, 0, sizeof(value));
799 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800800 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800801 p1 += 5;
802 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800803 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800804 memcpy(value, p1, p2 - p1);
805 }
806 p_info->pids[i].type = strtoull(value, NULL, 10);
807 }
808 }
809
810 /*Save segment duration*/
811 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800812 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800813 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800814 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800815 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800816 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800817
818 /*Save segment size*/
819 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800820 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800821 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800822 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800823 p_info->size = strtoull(p1 + 5, NULL, 10);
824
825 /*Save number of packets*/
826 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800827 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800828 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800829 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800830 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
831
832 return DVR_SUCCESS;
833}
834
hualing chenb9a02922021-12-14 11:29:47 +0800835/* Should consider the case of cut power, todo... */
836int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
837{
838 Segment_Context_t *p_ctx;
839 uint32_t i;
840 char buf[256];
841 char value[256];
842 char *p1, *p2;
843
844 p_ctx = (Segment_Context_t *)handle;
845 DVR_RETURN_IF_FALSE(p_ctx);
846 DVR_RETURN_IF_FALSE(list);
hualing chen926a8ec2021-12-20 20:38:24 +0800847 if (p_ctx->all_dat_fp == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800848 DVR_INFO("all dat file not open\n");
hualing chen926a8ec2021-12-20 20:38:24 +0800849 return DVR_FAILURE;
850 }
hualing chenb9a02922021-12-14 11:29:47 +0800851 //first get
852 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
853 DVR_RETURN_IF_FALSE(p1);
854
855 do {
856
857 DVR_RecordSegmentInfo_t *p_info;
858
859 p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
860 memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
861
862 list_add_tail(&p_info->head, list);
863
864 /*Load segment id*/
865 DVR_RETURN_IF_FALSE(p1);
866 p1 = strstr(buf, "id=");
867 DVR_RETURN_IF_FALSE(p1);
868 p_info->id = strtoull(p1 + 3, NULL, 10);
869
870 /*Save number of pids*/
871 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
872 DVR_RETURN_IF_FALSE(p1);
873 p1 = strstr(buf, "nb_pids=");
874 DVR_RETURN_IF_FALSE(p1);
875 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
876
877 /*Save pid information*/
878 for (i = 0; i < p_info->nb_pids; i++) {
879 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
880 DVR_RETURN_IF_FALSE(p1);
881 memset(value, 0, sizeof(value));
882 if ((p1 = strstr(buf, "pid="))) {
883 DVR_RETURN_IF_FALSE(p1);
884 p1 += 4;
885 if ((p2 = strstr(buf, ","))) {
886 DVR_RETURN_IF_FALSE(p2);
887 memcpy(value, p1, p2 - p1);
888 }
889 p_info->pids[i].pid = strtoull(value, NULL, 10);
890 }
891
892 memset(value, 0, sizeof(value));
893 if ((p1 = strstr(buf, "type="))) {
894 DVR_RETURN_IF_FALSE(p1);
895 p1 += 5;
896 if ((p2 = strstr(buf, "}"))) {
897 DVR_RETURN_IF_FALSE(p2);
898 memcpy(value, p1, p2 - p1);
899 }
900 p_info->pids[i].type = strtoull(value, NULL, 10);
901 }
902 }
903
904 /*Save segment duration*/
905 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
906 DVR_RETURN_IF_FALSE(p1);
907 p1 = strstr(buf, "duration=");
908 DVR_RETURN_IF_FALSE(p1);
909 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800910 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800911
912 /*Save segment size*/
913 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
914 DVR_RETURN_IF_FALSE(p1);
915 p1 = strstr(buf, "size=");
916 DVR_RETURN_IF_FALSE(p1);
917 p_info->size = strtoull(p1 + 5, NULL, 10);
918
919 /*Save number of packets*/
920 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
921 DVR_RETURN_IF_FALSE(p1);
922 p1 = strstr(buf, "nb_packets=");
923 DVR_RETURN_IF_FALSE(p1);
924 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
925 //if reach end,exit loop
926 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
927 } while (p1);
928
929 return DVR_SUCCESS;
930}
931
Pengfei Liub4734232020-01-17 18:25:10 +0800932int segment_delete(const char *location, uint64_t segment_id)
933{
934 char fname[MAX_SEGMENT_PATH_SIZE];
935 int ret;
936
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800937 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800938
939 /*delete ts file*/
940 memset(fname, 0, sizeof(fname));
941 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
942 ret = unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000943 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800944 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800945
946 /*delete index file*/
947 memset(fname, 0, sizeof(fname));
948 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
949 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000950 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800951 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800952
953 /*delete store information file*/
954 memset(fname, 0, sizeof(fname));
955 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
956 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000957 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800958 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800959
960 return DVR_SUCCESS;
961}
962
hualing chen87072a82020-03-12 16:20:12 +0800963int segment_ongoing(Segment_Handle_t handle)
964{
965 Segment_Context_t *p_ctx;
966 p_ctx = (Segment_Context_t *)handle;
967 struct stat mstat;
968
969 char going_name[MAX_SEGMENT_PATH_SIZE];
970 memset(going_name, 0, sizeof(going_name));
971 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
972 int ret = stat(going_name, &mstat);
Wentao MA96f68962022-06-15 19:45:35 +0800973 DVR_INFO("segment check ongoing [%s] ret [%d]", going_name, ret);
hualing chen87072a82020-03-12 16:20:12 +0800974 if (ret != 0) {
975 return DVR_FAILURE;
976 }
977 return DVR_SUCCESS;
978}
Wentao MAa3388532022-08-18 15:07:07 +0800979
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800980loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800981{
982 Segment_Context_t *p_ctx;
983 char buf[256];
984 char value[256];
Wentao MA139fc612022-08-29 14:10:07 +0800985 uint64_t pts = 0;
986 loff_t offset = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800987 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800988 int ret = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800989
990 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800991 DVR_RETURN_IF_FALSE(p_ctx);
992 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
993 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800994
995 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800996 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
997 DVR_RETURN_IF_FALSE(ret != -1);
998
Pengfei Liub038b6a2020-01-14 15:57:01 +0800999 printf("start gets pts\n");
1000 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
1001 printf("buf[%s]\n", buf);
1002 memset(value, 0, sizeof(value));
1003 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +08001004 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001005 if ((p2 = strstr(buf, ","))) {
1006 memcpy(value, p1, p2 - p1);
1007 }
1008 pts = strtoull(value, NULL, 10);
1009 }
1010
1011 memset(value, 0, sizeof(value));
1012 if ((p1 = strstr(buf, "offset="))) {
1013 p1 += 7;
1014 if ((p2 = strstr(buf, "}"))) {
1015 memcpy(value, p1, p2 - p1);
1016 }
1017 offset = strtoull(value, NULL, 10);
1018 }
1019
1020 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001021 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001022 }
1023
1024 return 0;
1025}
Wentao MA907b6432022-08-01 06:23:08 +00001026
1027off_t segment_get_cur_segment_size(Segment_Handle_t handle)
1028{
1029 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1030 DVR_RETURN_IF_FALSE(p_ctx);
1031 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
1032 struct stat sb;
1033 int ret=fstat(p_ctx->ts_fd,&sb);
1034 if (ret<0) {
1035 return -1;
1036 }
1037 return sb.st_size;
1038}
1039
1040uint64_t segment_get_cur_segment_id(Segment_Handle_t handle)
1041{
1042 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1043 DVR_RETURN_IF_FALSE(p_ctx);
1044 return p_ctx->segment_id;
1045}
1046