blob: a7d8078cc3651ebc259c79200f2419b08e5ee67f [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);
141 if (access(dir_name, F_OK) == -1) {
Wentao MA96f68962022-06-15 19:45:35 +0800142 DVR_INFO("%s dir %s is not exist, create it", __func__, dir_name);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800143 mkdir(dir_name, 0666);
144 }
145
Pengfei Liuc181a982020-01-07 19:27:13 +0800146 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800147 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800148 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800149 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800150 p_ctx->ongoing_fp = NULL;
hualing chenb9a02922021-12-14 11:29:47 +0800151 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
Pengfei Liuc181a982020-01-07 19:27:13 +0800152 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800153 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800154 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800155 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chenb9a02922021-12-14 11:29:47 +0800156 p_ctx->all_dat_fp = fopen(all_dat_fname, "a+");
Wentao MA96f68962022-06-15 19:45:35 +0800157 DVR_INFO("%s dir %s is opened", __func__, all_dat_fname);
hualing chen87072a82020-03-12 16:20:12 +0800158 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800159 p_ctx->first_pts = ULLONG_MAX;
160 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800161 p_ctx->last_record_pts = ULLONG_MAX;
hualing chena5f03222021-12-02 11:22:35 +0800162 p_ctx->avg_rate = 0.0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800163 } else {
Wentao MA9a164002022-08-29 11:20:24 +0800164 DVR_INFO("%s, unknown mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800165 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800166 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800167 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chenb9a02922021-12-14 11:29:47 +0800168 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800169 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800170 }
171
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800172 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800173 DVR_INFO("%s open file failed [%s, %s, %s], reason:%s", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800174 ts_fname, index_fname, dat_fname, strerror(errno));
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800175 if (p_ctx->ts_fd != -1)
176 close(p_ctx->ts_fd);
177 if (p_ctx->index_fp)
178 fclose(p_ctx->index_fp);
179 if (p_ctx->dat_fp)
180 fclose(p_ctx->dat_fp);
hualing chen926a8ec2021-12-20 20:38:24 +0800181 if (p_ctx->all_dat_fp)
182 fclose(p_ctx->all_dat_fp);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800183 if (p_ctx->ongoing_fp)
184 fclose(p_ctx->ongoing_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800185 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800186 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800187 return DVR_FAILURE;
188 }
hualing chen87072a82020-03-12 16:20:12 +0800189 p_ctx->segment_id = params->segment_id;
190 strncpy(p_ctx->location, params->location, strlen(params->location));
wentao.ma35a69d42022-03-10 18:08:40 +0800191 p_ctx->force_sysclock = params->force_sysclock;
Pengfei Liub4734232020-01-17 18:25:10 +0800192
Wentao MA96f68962022-06-15 19:45:35 +0800193 //DVR_INFO("%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800194 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800195 return DVR_SUCCESS;
196}
197
198int segment_close(Segment_Handle_t handle)
199{
200 Segment_Context_t *p_ctx;
201
Pengfei Liub038b6a2020-01-14 15:57:01 +0800202 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800203 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800204
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800205 if (p_ctx->ts_fd != -1) {
206 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800207 }
208
209 if (p_ctx->index_fp) {
210 fclose(p_ctx->index_fp);
211 }
212
Pengfei Liub4734232020-01-17 18:25:10 +0800213 if (p_ctx->dat_fp) {
214 fclose(p_ctx->dat_fp);
215 }
hualing chen926a8ec2021-12-20 20:38:24 +0800216 if (p_ctx->all_dat_fp) {
217 fclose(p_ctx->all_dat_fp);
218 }
hualing chen87072a82020-03-12 16:20:12 +0800219 if (p_ctx->ongoing_fp != NULL) {
220 fclose(p_ctx->ongoing_fp);
221 char going_name[MAX_SEGMENT_PATH_SIZE];
222 memset(going_name, 0, sizeof(going_name));
223 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
Wentao MA96f68962022-06-15 19:45:35 +0800224 DVR_INFO("segment close del [%s]", going_name);
hualing chen87072a82020-03-12 16:20:12 +0800225 unlink(going_name);
226 }
227
Pengfei Liuc181a982020-01-07 19:27:13 +0800228 free(p_ctx);
229 return 0;
230}
231
232ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
233{
234 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800235 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800236 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800237 DVR_RETURN_IF_FALSE(p_ctx);
238 DVR_RETURN_IF_FALSE(buf);
239 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800240 len = read(p_ctx->ts_fd, buf, count);
241 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800242}
243
244ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
245{
246 Segment_Context_t *p_ctx;
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800247 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800248 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800249 DVR_RETURN_IF_FALSE(p_ctx);
250 DVR_RETURN_IF_FALSE(buf);
251 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800252 len = write(p_ctx->ts_fd, buf, count);
hualing chen157641d2022-02-22 17:54:52 +0800253 if (p_ctx->time % TS_FILE_SYNC_TIME == 0)
254 fsync(p_ctx->ts_fd);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800255 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800256}
257
hualing chen2932d372020-04-29 13:44:00 +0800258int segment_update_pts_force(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800259{
260 Segment_Context_t *p_ctx;
261 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800262 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800263
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);
Pengfei Liuc181a982020-01-07 19:27:13 +0800267
Pengfei Liub038b6a2020-01-14 15:57:01 +0800268 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800269 DVR_INFO("%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800270 p_ctx->first_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800271 p_ctx->first_offset = offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800272 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800273 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800274 if (p_ctx->last_pts == ULLONG_MAX) {
275 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800276 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800277 p_ctx->cur_time = pts - p_ctx->first_pts;
Wentao MA96f68962022-06-15 19:45:35 +0800278 DVR_INFO("%s force pcr:%llu -1", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800279 } else {
280 /*Last pts has valid value*/
281 int diff = pts - p_ctx->last_pts;
282 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
283 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800284 DVR_INFO("[%s]force update Current pts has a transition, [%llu, %llu, %llu]",__func__,
hualing chen2932d372020-04-29 13:44:00 +0800285 p_ctx->first_pts, p_ctx->last_pts, pts);
286 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
287 } else {
288 /*This is a normal pts, record it*/
hualing chena5f03222021-12-02 11:22:35 +0800289 //check if this pcr is transition.if true,add 200ms
290 //other case normal.
hualing chen2932d372020-04-29 13:44:00 +0800291 p_ctx->cur_time += diff;
Wentao MA96f68962022-06-15 19:45:35 +0800292 DVR_INFO("%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
hualing chen2932d372020-04-29 13:44:00 +0800293 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
294 }
295 }
296
297 record_diff = pts - p_ctx->last_record_pts;
298 if (strlen(buf) > 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800299 DVR_INFO("%s force pcr:%llu buf:%s", __func__, pts, buf);
hualing chen2932d372020-04-29 13:44:00 +0800300 fputs(buf, p_ctx->index_fp);
301 fflush(p_ctx->index_fp);
302 fsync(fileno(p_ctx->index_fp));
303 p_ctx->last_record_pts = pts;
304 }
305 p_ctx->last_pts = pts;
hualing chen2932d372020-04-29 13:44:00 +0800306 return DVR_SUCCESS;
307}
308
309int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
310{
311 Segment_Context_t *p_ctx;
312 char buf[256];
313 int record_diff = 0;
314
315 p_ctx = (Segment_Context_t *)handle;
316 DVR_RETURN_IF_FALSE(p_ctx);
317 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
318
319 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800320 DVR_INFO("%s first pcr:%llu", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800321 p_ctx->first_pts = pts;
322 //p_ctx->cur_time = p_ctx->cur_time + PTS_HEAD_DEVIATION;
323 }
324 memset(buf, 0, sizeof(buf));
325 if (p_ctx->last_pts == ULLONG_MAX) {
326 /*Last pts is init value*/
327 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
328 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800329 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800330 if (!p_ctx->force_sysclock) {
331 /* if force_sysclock is off, we follow old manner. Please refer to
332 * SWPL-75327*/
333 /*Last pts has valid value*/
334 int diff = pts - p_ctx->last_pts;
335 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
336 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800337 DVR_INFO("Current pts has a transition, [%llu, %llu, %llu]",
wentao.ma35a69d42022-03-10 18:08:40 +0800338 p_ctx->first_pts, p_ctx->last_pts, pts);
339 p_ctx->last_record_pts = pts;
Wentao MA270dc0f2022-08-23 13:17:26 +0800340 //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINUED_DEVIATION;
hualing chena5f03222021-12-02 11:22:35 +0800341 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800342 /*This is a normal pts, record it*/
343 loff_t off_diff = offset - p_ctx->last_offset;
344 float rate = (float) (off_diff) / (float)(diff);
345 if (p_ctx->avg_rate == 0.0) {
346 p_ctx->avg_rate = (float) offset / (float)(p_ctx->cur_time + diff);
347 }
348 if (diff >= PCR_JUMP_DUR) {
Wentao MA96f68962022-06-15 19:45:35 +0800349 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 +0800350 if (p_ctx->avg_rate != 0 && (int)(p_ctx->avg_rate) >= (int)(rate * 4)) {
351 diff = off_diff / p_ctx->avg_rate;
352 p_ctx->cur_time += diff;
353 } else {
354 p_ctx->cur_time += diff;
355 }
356 } else {
357 p_ctx->cur_time += diff;
358 }
hualing chena5f03222021-12-02 11:22:35 +0800359 }
wentao.ma35a69d42022-03-10 18:08:40 +0800360 } else {
361 /* if force_sysclock is on, we simply calculate cur_time based on system
362 * time. Please refer to SWPL-75327*/
363 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800364 }
wentao.ma35a69d42022-03-10 18:08:40 +0800365 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800366 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800367
368 record_diff = pts - p_ctx->last_record_pts;
369 if (strlen(buf) > 0 &&
370 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800371 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800372 fflush(p_ctx->index_fp);
hualing chen157641d2022-02-22 17:54:52 +0800373 p_ctx->time++;
374 //flush idx file 3s
375 if ((p_ctx->time > 0 && p_ctx->time % IDX_FILE_SYNC_TIME == 0))
376 fsync(fileno(p_ctx->index_fp));
377 if (p_ctx->time > IDX_FILE_SYNC_TIME)
378 p_ctx->time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800379 p_ctx->last_record_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800380 p_ctx->last_record_offset = offset;
381 if (p_ctx->cur_time > 0)
382 p_ctx->avg_rate = (float) offset / (float)p_ctx->cur_time;
pengfei.liu567d6d82020-04-17 16:48:59 +0800383 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800384 p_ctx->last_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800385 p_ctx->last_offset = offset;
Pengfei Liuc181a982020-01-07 19:27:13 +0800386 return DVR_SUCCESS;
387}
388
hualing chen266b9502020-04-04 17:39:39 +0800389loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800390{
391 Segment_Context_t *p_ctx;
392 char buf[256];
393 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800394 uint64_t pts = 0L;
395 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800396 char *p1, *p2;
397
Wentao MA96f68962022-06-15 19:45:35 +0800398 DVR_INFO("into seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chen8a657f32021-08-30 13:12:49 +0800399
Pengfei Liuc181a982020-01-07 19:27:13 +0800400 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800401 DVR_RETURN_IF_FALSE(p_ctx);
402 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
403 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800404
hualing chen266b9502020-04-04 17:39:39 +0800405 if (time == 0) {
406 offset = 0;
Wentao MA96f68962022-06-15 19:45:35 +0800407 DVR_INFO("seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chend241c7a2021-06-22 13:34:27 +0800408 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen266b9502020-04-04 17:39:39 +0800409 return offset;
410 }
411
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800412 memset(buf, 0, sizeof(buf));
413 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800414 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800415 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800416 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800417 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800418 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800419 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800420 if ((p2 = strstr(buf, ","))) {
421 memcpy(value, p1, p2 - p1);
422 }
423 pts = strtoull(value, NULL, 10);
424 }
425
426 memset(value, 0, sizeof(value));
427 if ((p1 = strstr(buf, "offset="))) {
428 p1 += 7;
429 if ((p2 = strstr(buf, "}"))) {
430 memcpy(value, p1, p2 - p1);
431 }
432 offset = strtoull(value, NULL, 10);
433 }
hualing chen2aba4022020-03-02 13:49:55 +0800434 if (0)
435 {
Wentao MA96f68962022-06-15 19:45:35 +0800436 DVR_INFO("seek buf[%s]", buf);
437 DVR_INFO("seek time=%llu, offset=%lld\n", pts, offset);
hualing chen2aba4022020-03-02 13:49:55 +0800438 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800439 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800440 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800441 if (block_size > 0) {
442 offset = offset - offset%block_size;
443 }
Wentao MA96f68962022-06-15 19:45:35 +0800444 //DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800445 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800446 return offset;
447 }
hualing chen2aba4022020-03-02 13:49:55 +0800448 }
hualing chen2932d372020-04-29 13:44:00 +0800449 if (time > pts) {
450 if (block_size > 0) {
451 offset = offset - offset%block_size;
452 }
Wentao MA96f68962022-06-15 19:45:35 +0800453 DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d end\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800454 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen2932d372020-04-29 13:44:00 +0800455 return offset;
456 }
Wentao MA96f68962022-06-15 19:45:35 +0800457 DVR_INFO("seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800458 return DVR_FAILURE;
459}
460
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800461loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800462{
463 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800464 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800465 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800466 DVR_RETURN_IF_FALSE(p_ctx);
467 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800468 pos = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
469 return pos;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800470}
471
hualing chen5605eed2020-05-26 18:18:06 +0800472uint64_t segment_tell_position_time(Segment_Handle_t handle, loff_t position)
473{
474 Segment_Context_t *p_ctx;
475 char buf[256];
476 char value[256];
hualing chen969fe7b2021-05-26 15:13:17 +0800477 uint64_t ret = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800478 uint64_t pts = 0L;
hualing chen969fe7b2021-05-26 15:13:17 +0800479 uint64_t pts_p = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800480 loff_t offset = 0;
hualing chen969fe7b2021-05-26 15:13:17 +0800481 loff_t offset_p = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800482 char *p1, *p2;
483
484 p_ctx = (Segment_Context_t *)handle;
485 DVR_RETURN_IF_FALSE(p_ctx);
486 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
487 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
488
489 memset(buf, 0, sizeof(buf));
490 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
491 DVR_RETURN_IF_FALSE(position != -1);
492
493 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
494 memset(value, 0, sizeof(value));
495 if ((p1 = strstr(buf, "time="))) {
496 p1 += 5;
497 if ((p2 = strstr(buf, ","))) {
498 memcpy(value, p1, p2 - p1);
499 }
500 pts = strtoull(value, NULL, 10);
501 }
502
503 memset(value, 0, sizeof(value));
504 if ((p1 = strstr(buf, "offset="))) {
505 p1 += 7;
506 if ((p2 = strstr(buf, "}"))) {
507 memcpy(value, p1, p2 - p1);
508 }
509 offset = strtoull(value, NULL, 10);
510 }
511
512 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800513 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chend241c7a2021-06-22 13:34:27 +0800514 if (position <= offset
515 &&position >= offset_p
516 && offset - offset_p > 0) {
hualing chen969fe7b2021-05-26 15:13:17 +0800517 ret = pts_p + (pts - pts_p) * (position - offset_p) / (offset - offset_p);
Wentao MA96f68962022-06-15 19:45:35 +0800518 //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 +0800519 return ret;
hualing chen5605eed2020-05-26 18:18:06 +0800520 }
hualing chen969fe7b2021-05-26 15:13:17 +0800521 offset_p = offset;
522 pts_p = pts;
hualing chen5605eed2020-05-26 18:18:06 +0800523 }
Wentao MA96f68962022-06-15 19:45:35 +0800524 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen5605eed2020-05-26 18:18:06 +0800525 return pts;
526}
527
528
pengfei.liu8b563292020-02-26 15:49:02 +0800529uint64_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800530{
531 Segment_Context_t *p_ctx;
532 char buf[256];
533 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800534 uint64_t pts = 0L;
535 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800536 char *p1, *p2;
537
538 p_ctx = (Segment_Context_t *)handle;
539 DVR_RETURN_IF_FALSE(p_ctx);
540 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
541 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
542
543 memset(buf, 0, sizeof(buf));
544 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800545 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800546 DVR_RETURN_IF_FALSE(position != -1);
547
548 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
549 memset(value, 0, sizeof(value));
550 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800551 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800552 if ((p2 = strstr(buf, ","))) {
553 memcpy(value, p1, p2 - p1);
554 }
555 pts = strtoull(value, NULL, 10);
556 }
557
558 memset(value, 0, sizeof(value));
559 if ((p1 = strstr(buf, "offset="))) {
560 p1 += 7;
561 if ((p2 = strstr(buf, "}"))) {
562 memcpy(value, p1, p2 - p1);
563 }
564 offset = strtoull(value, NULL, 10);
565 }
566
567 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800568 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800569 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800570 return pts;
571 }
572 }
Wentao MA96f68962022-06-15 19:45:35 +0800573 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800574 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800575}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800576
pengfei.liu8b563292020-02-26 15:49:02 +0800577uint64_t segment_tell_total_time(Segment_Handle_t handle)
578{
579 Segment_Context_t *p_ctx;
580 char buf[256];
581 char last_buf[256];
582 char value[256];
583 uint64_t pts = ULLONG_MAX;
584 loff_t offset = 0, position = 0;
585 char *p1, *p2;
586 int line = 0;
587
588 p_ctx = (Segment_Context_t *)handle;
589 DVR_RETURN_IF_FALSE(p_ctx);
590 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
591 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
592
593 memset(buf, 0, sizeof(buf));
594 memset(last_buf, 0, sizeof(last_buf));
hualing chend241c7a2021-06-22 13:34:27 +0800595 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
pengfei.liu8b563292020-02-26 15:49:02 +0800596 DVR_RETURN_IF_FALSE(position != -1);
597
hualing chen041c4092020-04-05 15:11:50 +0800598 //DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, -1000L, SEEK_END) != -1);
599 //if seek error.we need seek 0 pos.
600 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
601 fseek(p_ctx->index_fp, 0L, SEEK_SET);
602 }
pengfei.liu8b563292020-02-26 15:49:02 +0800603 /* Save last line buffer */
604 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800605 if (strlen(buf) <= 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800606 DVR_INFO("read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800607 continue;
608 }
pengfei.liu8b563292020-02-26 15:49:02 +0800609 memset(last_buf, 0, sizeof(last_buf));
610 memcpy(last_buf, buf, strlen(buf));
611 memset(buf, 0, sizeof(buf));
612 line++;
613 }
614
615 /* Extract time value */
616 memset(value, 0, sizeof(value));
617 if ((p1 = strstr(last_buf, "time="))) {
618 p1 += 5;
619 if ((p2 = strstr(last_buf, ","))) {
620 memcpy(value, p1, p2 - p1);
621 }
622 pts = strtoull(value, NULL, 10);
623 }
624
625 memset(value, 0, sizeof(value));
626 if ((p1 = strstr(last_buf, "offset="))) {
627 p1 += 7;
628 if ((p2 = strstr(last_buf, "}"))) {
629 memcpy(value, p1, p2 - p1);
630 }
631 offset = strtoull(value, NULL, 10);
632 }
hualing chen87072a82020-03-12 16:20:12 +0800633 //if (line < 2)
Wentao MA96f68962022-06-15 19:45:35 +0800634 //DVR_INFO("totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800635 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
636}
637
pengfei.liuab5a2262020-02-14 17:33:40 +0800638/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800639int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
640{
641 Segment_Context_t *p_ctx;
642 char buf[256];
643 uint32_t i;
644
645 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800646 DVR_RETURN_IF_FALSE(p_ctx);
647 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
648 DVR_RETURN_IF_FALSE(p_info);
hualing chen87072a82020-03-12 16:20:12 +0800649 //seek 0, rewrite info
650 DVR_RETURN_IF_FALSE(fseek(p_ctx->dat_fp, 0, SEEK_SET) != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800651
652 /*Save segment id*/
653 memset(buf, 0, sizeof(buf));
654 sprintf(buf, "id=%lld\n", p_info->id);
655 fputs(buf, p_ctx->dat_fp);
656
657 /*Save number of pids*/
658 memset(buf, 0, sizeof(buf));
659 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
660 fputs(buf, p_ctx->dat_fp);
661
662 /*Save pid information*/
663 for (i = 0; i < p_info->nb_pids; i++) {
664 memset(buf, 0, sizeof(buf));
665 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
666 fputs(buf, p_ctx->dat_fp);
667 }
668
669 /*Save segment duration*/
670 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800671 DVR_INFO("duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800672 sprintf(buf, "duration=%ld\n", p_info->duration);
673 fputs(buf, p_ctx->dat_fp);
674
675 /*Save segment size*/
676 memset(buf, 0, sizeof(buf));
677 sprintf(buf, "size=%zu\n", p_info->size);
678 fputs(buf, p_ctx->dat_fp);
679
680 /*Save number of packets*/
681 memset(buf, 0, sizeof(buf));
682 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
683 fputs(buf, p_ctx->dat_fp);
684
685 fflush(p_ctx->dat_fp);
hualing chen47c34bc2020-05-11 09:15:47 +0800686 fsync(fileno(p_ctx->dat_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800687 return DVR_SUCCESS;
688}
689
pengfei.liuab5a2262020-02-14 17:33:40 +0800690/* Should consider the case of cut power, todo... */
hualing chenb9a02922021-12-14 11:29:47 +0800691int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
692{
693 Segment_Context_t *p_ctx;
694 char buf[256];
695 uint32_t i;
696
697 p_ctx = (Segment_Context_t *)handle;
698 DVR_RETURN_IF_FALSE(p_ctx);
699 DVR_RETURN_IF_FALSE(p_ctx->all_dat_fp);
700 DVR_RETURN_IF_FALSE(p_info);
701 //seek 0, rewrite info
702 DVR_RETURN_IF_FALSE(fseek(p_ctx->all_dat_fp, 0, SEEK_END) != -1);
703
704 /*Save segment id*/
705 memset(buf, 0, sizeof(buf));
706 sprintf(buf, "id=%lld\n", p_info->id);
707 fputs(buf, p_ctx->all_dat_fp);
708
709 /*Save number of pids*/
710 memset(buf, 0, sizeof(buf));
711 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
712 fputs(buf, p_ctx->all_dat_fp);
713
714 /*Save pid information*/
715 for (i = 0; i < p_info->nb_pids; i++) {
716 memset(buf, 0, sizeof(buf));
717 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
718 fputs(buf, p_ctx->all_dat_fp);
719 }
720
721 /*Save segment duration*/
722 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800723 DVR_INFO("duration store:[%ld]", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800724 sprintf(buf, "duration=%ld\n", p_info->duration);
725 fputs(buf, p_ctx->all_dat_fp);
726
727 /*Save segment size*/
728 memset(buf, 0, sizeof(buf));
729 sprintf(buf, "size=%zu\n", p_info->size);
730 fputs(buf, p_ctx->all_dat_fp);
731
732 /*Save number of packets*/
733 memset(buf, 0, sizeof(buf));
734 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
735 fputs(buf, p_ctx->all_dat_fp);
736
737 fflush(p_ctx->all_dat_fp);
738 fsync(fileno(p_ctx->all_dat_fp));
739 return DVR_SUCCESS;
740}
741
742/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800743int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
744{
745 Segment_Context_t *p_ctx;
746 uint32_t i;
747 char buf[256];
748 char value[256];
749 char *p1, *p2;
750
751 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800752 DVR_RETURN_IF_FALSE(p_ctx);
753 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800754
755 /*Load segment id*/
756 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800757 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800758 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800759 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800760 p_info->id = strtoull(p1 + 3, NULL, 10);
761
762 /*Save number of pids*/
763 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800764 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800765 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800766 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800767 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
768
769 /*Save pid information*/
770 for (i = 0; i < p_info->nb_pids; i++) {
771 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800772 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800773 memset(value, 0, sizeof(value));
774 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800775 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800776 p1 += 4;
777 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800778 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800779 memcpy(value, p1, p2 - p1);
780 }
781 p_info->pids[i].pid = strtoull(value, NULL, 10);
782 }
783
784 memset(value, 0, sizeof(value));
785 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800786 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800787 p1 += 5;
788 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800789 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800790 memcpy(value, p1, p2 - p1);
791 }
792 p_info->pids[i].type = strtoull(value, NULL, 10);
793 }
794 }
795
796 /*Save segment duration*/
797 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800798 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800799 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800800 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800801 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800802 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800803
804 /*Save segment size*/
805 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800806 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800807 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800808 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800809 p_info->size = strtoull(p1 + 5, NULL, 10);
810
811 /*Save number of packets*/
812 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800813 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800814 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800815 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800816 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
817
818 return DVR_SUCCESS;
819}
820
hualing chenb9a02922021-12-14 11:29:47 +0800821/* Should consider the case of cut power, todo... */
822int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
823{
824 Segment_Context_t *p_ctx;
825 uint32_t i;
826 char buf[256];
827 char value[256];
828 char *p1, *p2;
829
830 p_ctx = (Segment_Context_t *)handle;
831 DVR_RETURN_IF_FALSE(p_ctx);
832 DVR_RETURN_IF_FALSE(list);
hualing chen926a8ec2021-12-20 20:38:24 +0800833 if (p_ctx->all_dat_fp == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800834 DVR_INFO("all dat file not open\n");
hualing chen926a8ec2021-12-20 20:38:24 +0800835 return DVR_FAILURE;
836 }
hualing chenb9a02922021-12-14 11:29:47 +0800837 //first get
838 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
839 DVR_RETURN_IF_FALSE(p1);
840
841 do {
842
843 DVR_RecordSegmentInfo_t *p_info;
844
845 p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
846 memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
847
848 list_add_tail(&p_info->head, list);
849
850 /*Load segment id*/
851 DVR_RETURN_IF_FALSE(p1);
852 p1 = strstr(buf, "id=");
853 DVR_RETURN_IF_FALSE(p1);
854 p_info->id = strtoull(p1 + 3, NULL, 10);
855
856 /*Save number of pids*/
857 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
858 DVR_RETURN_IF_FALSE(p1);
859 p1 = strstr(buf, "nb_pids=");
860 DVR_RETURN_IF_FALSE(p1);
861 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
862
863 /*Save pid information*/
864 for (i = 0; i < p_info->nb_pids; i++) {
865 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
866 DVR_RETURN_IF_FALSE(p1);
867 memset(value, 0, sizeof(value));
868 if ((p1 = strstr(buf, "pid="))) {
869 DVR_RETURN_IF_FALSE(p1);
870 p1 += 4;
871 if ((p2 = strstr(buf, ","))) {
872 DVR_RETURN_IF_FALSE(p2);
873 memcpy(value, p1, p2 - p1);
874 }
875 p_info->pids[i].pid = strtoull(value, NULL, 10);
876 }
877
878 memset(value, 0, sizeof(value));
879 if ((p1 = strstr(buf, "type="))) {
880 DVR_RETURN_IF_FALSE(p1);
881 p1 += 5;
882 if ((p2 = strstr(buf, "}"))) {
883 DVR_RETURN_IF_FALSE(p2);
884 memcpy(value, p1, p2 - p1);
885 }
886 p_info->pids[i].type = strtoull(value, NULL, 10);
887 }
888 }
889
890 /*Save segment duration*/
891 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
892 DVR_RETURN_IF_FALSE(p1);
893 p1 = strstr(buf, "duration=");
894 DVR_RETURN_IF_FALSE(p1);
895 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800896 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800897
898 /*Save segment size*/
899 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
900 DVR_RETURN_IF_FALSE(p1);
901 p1 = strstr(buf, "size=");
902 DVR_RETURN_IF_FALSE(p1);
903 p_info->size = strtoull(p1 + 5, NULL, 10);
904
905 /*Save number of packets*/
906 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
907 DVR_RETURN_IF_FALSE(p1);
908 p1 = strstr(buf, "nb_packets=");
909 DVR_RETURN_IF_FALSE(p1);
910 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
911 //if reach end,exit loop
912 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
913 } while (p1);
914
915 return DVR_SUCCESS;
916}
917
Pengfei Liub4734232020-01-17 18:25:10 +0800918int segment_delete(const char *location, uint64_t segment_id)
919{
920 char fname[MAX_SEGMENT_PATH_SIZE];
921 int ret;
922
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800923 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800924
925 /*delete ts file*/
926 memset(fname, 0, sizeof(fname));
927 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
928 ret = unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000929 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800930 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800931
932 /*delete index file*/
933 memset(fname, 0, sizeof(fname));
934 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
935 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000936 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800937 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800938
939 /*delete store information file*/
940 memset(fname, 0, sizeof(fname));
941 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
942 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 return DVR_SUCCESS;
947}
948
hualing chen87072a82020-03-12 16:20:12 +0800949int segment_ongoing(Segment_Handle_t handle)
950{
951 Segment_Context_t *p_ctx;
952 p_ctx = (Segment_Context_t *)handle;
953 struct stat mstat;
954
955 char going_name[MAX_SEGMENT_PATH_SIZE];
956 memset(going_name, 0, sizeof(going_name));
957 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
958 int ret = stat(going_name, &mstat);
Wentao MA96f68962022-06-15 19:45:35 +0800959 DVR_INFO("segment check ongoing [%s] ret [%d]", going_name, ret);
hualing chen87072a82020-03-12 16:20:12 +0800960 if (ret != 0) {
961 return DVR_FAILURE;
962 }
963 return DVR_SUCCESS;
964}
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800965loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800966{
967 Segment_Context_t *p_ctx;
968 char buf[256];
969 char value[256];
Wentao MA139fc612022-08-29 14:10:07 +0800970 uint64_t pts = 0;
971 loff_t offset = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800972 char *p1, *p2;
973
974 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800975 DVR_RETURN_IF_FALSE(p_ctx);
976 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
977 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800978
979 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800980 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800981 printf("start gets pts\n");
982 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
983 printf("buf[%s]\n", buf);
984 memset(value, 0, sizeof(value));
985 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800986 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800987 if ((p2 = strstr(buf, ","))) {
988 memcpy(value, p1, p2 - p1);
989 }
990 pts = strtoull(value, NULL, 10);
991 }
992
993 memset(value, 0, sizeof(value));
994 if ((p1 = strstr(buf, "offset="))) {
995 p1 += 7;
996 if ((p2 = strstr(buf, "}"))) {
997 memcpy(value, p1, p2 - p1);
998 }
999 offset = strtoull(value, NULL, 10);
1000 }
1001
1002 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001003 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001004 }
1005
1006 return 0;
1007}
Wentao MA907b6432022-08-01 06:23:08 +00001008
1009off_t segment_get_cur_segment_size(Segment_Handle_t handle)
1010{
1011 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1012 DVR_RETURN_IF_FALSE(p_ctx);
1013 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
1014 struct stat sb;
1015 int ret=fstat(p_ctx->ts_fd,&sb);
1016 if (ret<0) {
1017 return -1;
1018 }
1019 return sb.st_size;
1020}
1021
1022uint64_t segment_get_cur_segment_id(Segment_Handle_t handle)
1023{
1024 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1025 DVR_RETURN_IF_FALSE(p_ctx);
1026 return p_ctx->segment_id;
1027}
1028