blob: 80f4c8ccc2c8ffa99d67f564189bb165414ae26d [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
Pengfei Liuc181a982020-01-07 19:27:13 +080061 offset = strlen(location);
wentao.ma9628d362022-10-08 11:07:24 +080062 DVR_ASSERT(offset < DVR_MAX_LOCATION_SIZE);
Wentao MAe88ad702022-09-02 10:35:00 +080063
wentao.ma9628d362022-10-08 11:07:24 +080064 memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
65 strncpy(fname, location, offset);
Wentao MAe88ad702022-09-02 10:35:00 +080066
Wentao MA9a164002022-08-29 11:20:24 +080067 if (type != SEGMENT_FILE_TYPE_ALL_DATA) {
Wentao MA4d85ff32022-09-23 11:36:18 +080068 strncpy(fname + offset, "-", 2);
hualing chenb9a02922021-12-14 11:29:47 +080069 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)
Wentao MA4d85ff32022-09-23 11:36:18 +080075 strncpy(fname + offset, ".ts", 4);
Pengfei Liuc181a982020-01-07 19:27:13 +080076 else if (type == SEGMENT_FILE_TYPE_INDEX)
Wentao MA4d85ff32022-09-23 11:36:18 +080077 strncpy(fname + offset, ".idx", 5);
Pengfei Liub4734232020-01-17 18:25:10 +080078 else if (type == SEGMENT_FILE_TYPE_DAT)
Wentao MA4d85ff32022-09-23 11:36:18 +080079 strncpy(fname + offset, ".dat", 5);
hualing chen87072a82020-03-12 16:20:12 +080080 else if (type == SEGMENT_FILE_TYPE_ONGOING)
Wentao MA4d85ff32022-09-23 11:36:18 +080081 strncpy(fname + offset, ".going", 7);
Wentao MA9a164002022-08-29 11:20:24 +080082 else if (type == SEGMENT_FILE_TYPE_ALL_DATA)
Wentao MA4d85ff32022-09-23 11:36:18 +080083 strncpy(fname + offset, ".dat", 5);
hualing chenb9a02922021-12-14 11:29:47 +080084
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];
Wentao MA4d85ff32022-09-23 11:36:18 +0800113 int ret = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800114
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800115 DVR_RETURN_IF_FALSE(params);
116 DVR_RETURN_IF_FALSE(p_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800117
Wentao MA96f68962022-06-15 19:45:35 +0800118 //DVR_INFO("%s, location:%s, id:%llu", __func__, params->location, params->segment_id);
Pengfei Liuc181a982020-01-07 19:27:13 +0800119
Pengfei Liub038b6a2020-01-14 15:57:01 +0800120 p_ctx = (void*)malloc(sizeof(Segment_Context_t));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800121 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800122 memset(p_ctx, 0, sizeof(Segment_Context_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800123
124 memset(ts_fname, 0, sizeof(ts_fname));
125 segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
126
127 memset(index_fname, 0, sizeof(index_fname));
128 segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
129
Pengfei Liub4734232020-01-17 18:25:10 +0800130 memset(dat_fname, 0, sizeof(dat_fname));
131 segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
132
hualing chenb9a02922021-12-14 11:29:47 +0800133 memset(all_dat_fname, 0, sizeof(all_dat_fname));
Wentao MA9a164002022-08-29 11:20:24 +0800134 segment_get_fname(all_dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_ALL_DATA);
hualing chenb9a02922021-12-14 11:29:47 +0800135
136
hualing chen87072a82020-03-12 16:20:12 +0800137 memset(going_name, 0, sizeof(going_name));
138 segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
139
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800140 memset(dir_name, 0, sizeof(dir_name));
141 segment_get_dirname(dir_name, params->location);
Wentao MAb2070812022-09-02 13:10:03 +0800142
Wentao MA4d85ff32022-09-23 11:36:18 +0800143 ret = mkdir(dir_name, 0666);
144 if (ret == -1) {
145 DVR_WARN("mkdir of %s returns %d due to errno:%d,%s",
146 dir_name,ret,errno,strerror(errno));
147 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800148 if (access(dir_name, F_OK) == -1) {
Wentao MA4d85ff32022-09-23 11:36:18 +0800149 DVR_ERROR("%s dir %s does not exist", __func__, dir_name);
150 free(p_ctx);
Wentao MAb2070812022-09-02 13:10:03 +0800151 return DVR_FAILURE;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800152 }
153
Pengfei Liuc181a982020-01-07 19:27:13 +0800154 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800155 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800156 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800157 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800158 p_ctx->ongoing_fp = NULL;
hualing chenb9a02922021-12-14 11:29:47 +0800159 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
Pengfei Liuc181a982020-01-07 19:27:13 +0800160 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800161 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800162 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800163 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chenb9a02922021-12-14 11:29:47 +0800164 p_ctx->all_dat_fp = fopen(all_dat_fname, "a+");
Wentao MA96f68962022-06-15 19:45:35 +0800165 DVR_INFO("%s dir %s is opened", __func__, all_dat_fname);
hualing chen87072a82020-03-12 16:20:12 +0800166 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800167 p_ctx->first_pts = ULLONG_MAX;
168 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800169 p_ctx->last_record_pts = ULLONG_MAX;
hualing chena5f03222021-12-02 11:22:35 +0800170 p_ctx->avg_rate = 0.0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800171 } else {
Wentao MA9a164002022-08-29 11:20:24 +0800172 DVR_INFO("%s, unknown mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800173 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800174 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800175 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chenb9a02922021-12-14 11:29:47 +0800176 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800177 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800178 }
179
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800180 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800181 DVR_INFO("%s open file failed [%s, %s, %s], reason:%s", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800182 ts_fname, index_fname, dat_fname, strerror(errno));
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800183 if (p_ctx->ts_fd != -1)
184 close(p_ctx->ts_fd);
185 if (p_ctx->index_fp)
186 fclose(p_ctx->index_fp);
187 if (p_ctx->dat_fp)
188 fclose(p_ctx->dat_fp);
hualing chen926a8ec2021-12-20 20:38:24 +0800189 if (p_ctx->all_dat_fp)
190 fclose(p_ctx->all_dat_fp);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800191 if (p_ctx->ongoing_fp)
192 fclose(p_ctx->ongoing_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800193 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800194 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800195 return DVR_FAILURE;
196 }
hualing chen87072a82020-03-12 16:20:12 +0800197 p_ctx->segment_id = params->segment_id;
wentao.maf57dd232022-10-08 16:07:29 +0800198 strncpy(p_ctx->location, params->location, strlen(params->location)+1);
wentao.ma35a69d42022-03-10 18:08:40 +0800199 p_ctx->force_sysclock = params->force_sysclock;
Pengfei Liub4734232020-01-17 18:25:10 +0800200
Wentao MA96f68962022-06-15 19:45:35 +0800201 //DVR_INFO("%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800202 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800203 return DVR_SUCCESS;
204}
205
206int segment_close(Segment_Handle_t handle)
207{
208 Segment_Context_t *p_ctx;
209
Pengfei Liub038b6a2020-01-14 15:57:01 +0800210 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800211 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800212
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800213 if (p_ctx->ts_fd != -1) {
214 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800215 }
216
217 if (p_ctx->index_fp) {
218 fclose(p_ctx->index_fp);
219 }
220
Pengfei Liub4734232020-01-17 18:25:10 +0800221 if (p_ctx->dat_fp) {
222 fclose(p_ctx->dat_fp);
223 }
hualing chen926a8ec2021-12-20 20:38:24 +0800224 if (p_ctx->all_dat_fp) {
225 fclose(p_ctx->all_dat_fp);
226 }
hualing chen87072a82020-03-12 16:20:12 +0800227 if (p_ctx->ongoing_fp != NULL) {
228 fclose(p_ctx->ongoing_fp);
229 char going_name[MAX_SEGMENT_PATH_SIZE];
230 memset(going_name, 0, sizeof(going_name));
231 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
Wentao MA96f68962022-06-15 19:45:35 +0800232 DVR_INFO("segment close del [%s]", going_name);
hualing chen87072a82020-03-12 16:20:12 +0800233 unlink(going_name);
234 }
235
Pengfei Liuc181a982020-01-07 19:27:13 +0800236 free(p_ctx);
237 return 0;
238}
239
240ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
241{
242 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800243 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800244 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800245 DVR_RETURN_IF_FALSE(p_ctx);
246 DVR_RETURN_IF_FALSE(buf);
247 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800248 len = read(p_ctx->ts_fd, buf, count);
249 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800250}
251
252ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
253{
254 Segment_Context_t *p_ctx;
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800255 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800256 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800257 DVR_RETURN_IF_FALSE(p_ctx);
258 DVR_RETURN_IF_FALSE(buf);
259 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800260 len = write(p_ctx->ts_fd, buf, count);
hualing chen157641d2022-02-22 17:54:52 +0800261 if (p_ctx->time % TS_FILE_SYNC_TIME == 0)
262 fsync(p_ctx->ts_fd);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800263 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800264}
265
hualing chen2932d372020-04-29 13:44:00 +0800266int segment_update_pts_force(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800267{
268 Segment_Context_t *p_ctx;
269 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800270 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800271
272 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800273 DVR_RETURN_IF_FALSE(p_ctx);
274 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800275
Pengfei Liub038b6a2020-01-14 15:57:01 +0800276 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800277 DVR_INFO("%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800278 p_ctx->first_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800279 p_ctx->first_offset = offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800280 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800281 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800282 if (p_ctx->last_pts == ULLONG_MAX) {
283 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800284 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800285 p_ctx->cur_time = pts - p_ctx->first_pts;
Wentao MA96f68962022-06-15 19:45:35 +0800286 DVR_INFO("%s force pcr:%llu -1", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800287 } else {
288 /*Last pts has valid value*/
289 int diff = pts - p_ctx->last_pts;
290 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
291 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800292 DVR_INFO("[%s]force update Current pts has a transition, [%llu, %llu, %llu]",__func__,
hualing chen2932d372020-04-29 13:44:00 +0800293 p_ctx->first_pts, p_ctx->last_pts, pts);
294 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
295 } else {
296 /*This is a normal pts, record it*/
hualing chena5f03222021-12-02 11:22:35 +0800297 //check if this pcr is transition.if true,add 200ms
298 //other case normal.
hualing chen2932d372020-04-29 13:44:00 +0800299 p_ctx->cur_time += diff;
Wentao MA96f68962022-06-15 19:45:35 +0800300 DVR_INFO("%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
hualing chen2932d372020-04-29 13:44:00 +0800301 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
302 }
303 }
304
305 record_diff = pts - p_ctx->last_record_pts;
306 if (strlen(buf) > 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800307 DVR_INFO("%s force pcr:%llu buf:%s", __func__, pts, buf);
hualing chen2932d372020-04-29 13:44:00 +0800308 fputs(buf, p_ctx->index_fp);
309 fflush(p_ctx->index_fp);
310 fsync(fileno(p_ctx->index_fp));
311 p_ctx->last_record_pts = pts;
312 }
313 p_ctx->last_pts = pts;
hualing chen2932d372020-04-29 13:44:00 +0800314 return DVR_SUCCESS;
315}
316
317int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
318{
319 Segment_Context_t *p_ctx;
320 char buf[256];
321 int record_diff = 0;
322
323 p_ctx = (Segment_Context_t *)handle;
324 DVR_RETURN_IF_FALSE(p_ctx);
325 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
326
327 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800328 DVR_INFO("%s first pcr:%llu", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800329 p_ctx->first_pts = pts;
330 //p_ctx->cur_time = p_ctx->cur_time + PTS_HEAD_DEVIATION;
331 }
332 memset(buf, 0, sizeof(buf));
333 if (p_ctx->last_pts == ULLONG_MAX) {
334 /*Last pts is init value*/
335 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
336 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800337 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800338 if (!p_ctx->force_sysclock) {
339 /* if force_sysclock is off, we follow old manner. Please refer to
340 * SWPL-75327*/
341 /*Last pts has valid value*/
342 int diff = pts - p_ctx->last_pts;
343 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
344 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800345 DVR_INFO("Current pts has a transition, [%llu, %llu, %llu]",
wentao.ma35a69d42022-03-10 18:08:40 +0800346 p_ctx->first_pts, p_ctx->last_pts, pts);
347 p_ctx->last_record_pts = pts;
Wentao MA270dc0f2022-08-23 13:17:26 +0800348 //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINUED_DEVIATION;
hualing chena5f03222021-12-02 11:22:35 +0800349 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800350 /*This is a normal pts, record it*/
351 loff_t off_diff = offset - p_ctx->last_offset;
352 float rate = (float) (off_diff) / (float)(diff);
353 if (p_ctx->avg_rate == 0.0) {
354 p_ctx->avg_rate = (float) offset / (float)(p_ctx->cur_time + diff);
355 }
356 if (diff >= PCR_JUMP_DUR) {
Wentao MA96f68962022-06-15 19:45:35 +0800357 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 +0800358 if (p_ctx->avg_rate != 0 && (int)(p_ctx->avg_rate) >= (int)(rate * 4)) {
359 diff = off_diff / p_ctx->avg_rate;
360 p_ctx->cur_time += diff;
361 } else {
362 p_ctx->cur_time += diff;
363 }
364 } else {
365 p_ctx->cur_time += diff;
366 }
hualing chena5f03222021-12-02 11:22:35 +0800367 }
wentao.ma35a69d42022-03-10 18:08:40 +0800368 } else {
369 /* if force_sysclock is on, we simply calculate cur_time based on system
370 * time. Please refer to SWPL-75327*/
371 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800372 }
wentao.ma35a69d42022-03-10 18:08:40 +0800373 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800374 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800375
376 record_diff = pts - p_ctx->last_record_pts;
377 if (strlen(buf) > 0 &&
378 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800379 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800380 fflush(p_ctx->index_fp);
hualing chen157641d2022-02-22 17:54:52 +0800381 p_ctx->time++;
382 //flush idx file 3s
383 if ((p_ctx->time > 0 && p_ctx->time % IDX_FILE_SYNC_TIME == 0))
384 fsync(fileno(p_ctx->index_fp));
385 if (p_ctx->time > IDX_FILE_SYNC_TIME)
386 p_ctx->time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800387 p_ctx->last_record_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800388 p_ctx->last_record_offset = offset;
389 if (p_ctx->cur_time > 0)
390 p_ctx->avg_rate = (float) offset / (float)p_ctx->cur_time;
pengfei.liu567d6d82020-04-17 16:48:59 +0800391 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800392 p_ctx->last_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800393 p_ctx->last_offset = offset;
Pengfei Liuc181a982020-01-07 19:27:13 +0800394 return DVR_SUCCESS;
395}
396
hualing chen266b9502020-04-04 17:39:39 +0800397loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800398{
399 Segment_Context_t *p_ctx;
400 char buf[256];
401 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800402 uint64_t pts = 0L;
403 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800404 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800405 int ret = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800406
Wentao MA96f68962022-06-15 19:45:35 +0800407 DVR_INFO("into seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chen8a657f32021-08-30 13:12:49 +0800408
Pengfei Liuc181a982020-01-07 19:27:13 +0800409 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800410 DVR_RETURN_IF_FALSE(p_ctx);
411 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
412 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800413
hualing chen266b9502020-04-04 17:39:39 +0800414 if (time == 0) {
415 offset = 0;
Wentao MA96f68962022-06-15 19:45:35 +0800416 DVR_INFO("seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chend241c7a2021-06-22 13:34:27 +0800417 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen266b9502020-04-04 17:39:39 +0800418 return offset;
419 }
420
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800421 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800422 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
423 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800424 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800425 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800426 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800427 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800428 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800429 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800430 if ((p2 = strstr(buf, ","))) {
431 memcpy(value, p1, p2 - p1);
432 }
433 pts = strtoull(value, NULL, 10);
434 }
435
436 memset(value, 0, sizeof(value));
437 if ((p1 = strstr(buf, "offset="))) {
438 p1 += 7;
439 if ((p2 = strstr(buf, "}"))) {
440 memcpy(value, p1, p2 - p1);
441 }
442 offset = strtoull(value, NULL, 10);
443 }
hualing chen2aba4022020-03-02 13:49:55 +0800444 if (0)
445 {
Wentao MA96f68962022-06-15 19:45:35 +0800446 DVR_INFO("seek buf[%s]", buf);
447 DVR_INFO("seek time=%llu, offset=%lld\n", pts, offset);
hualing chen2aba4022020-03-02 13:49:55 +0800448 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800449 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800450 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800451 if (block_size > 0) {
452 offset = offset - offset%block_size;
453 }
Wentao MA96f68962022-06-15 19:45:35 +0800454 //DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800455 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800456 return offset;
457 }
hualing chen2aba4022020-03-02 13:49:55 +0800458 }
hualing chen2932d372020-04-29 13:44:00 +0800459 if (time > pts) {
460 if (block_size > 0) {
461 offset = offset - offset%block_size;
462 }
Wentao MA96f68962022-06-15 19:45:35 +0800463 DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d end\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800464 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen2932d372020-04-29 13:44:00 +0800465 return offset;
466 }
Wentao MA96f68962022-06-15 19:45:35 +0800467 DVR_INFO("seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800468 return DVR_FAILURE;
469}
470
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800471loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800472{
473 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800474 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800475 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800476 DVR_RETURN_IF_FALSE(p_ctx);
477 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800478 pos = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
479 return pos;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800480}
481
Wentao MAa3388532022-08-18 15:07:07 +0800482loff_t segment_tell_position_time(Segment_Handle_t handle, loff_t position)
hualing chen5605eed2020-05-26 18:18:06 +0800483{
484 Segment_Context_t *p_ctx;
485 char buf[256];
486 char value[256];
hualing chen969fe7b2021-05-26 15:13:17 +0800487 uint64_t ret = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800488 uint64_t pts = 0L;
hualing chen969fe7b2021-05-26 15:13:17 +0800489 uint64_t pts_p = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800490 loff_t offset = 0;
hualing chen969fe7b2021-05-26 15:13:17 +0800491 loff_t offset_p = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800492 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800493 int ret2 = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800494
495 p_ctx = (Segment_Context_t *)handle;
496 DVR_RETURN_IF_FALSE(p_ctx);
497 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
498 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
499
500 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800501 ret2 = fseek(p_ctx->index_fp, 0, SEEK_SET);
502 DVR_RETURN_IF_FALSE(ret2 != -1);
hualing chen5605eed2020-05-26 18:18:06 +0800503 DVR_RETURN_IF_FALSE(position != -1);
504
505 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
506 memset(value, 0, sizeof(value));
507 if ((p1 = strstr(buf, "time="))) {
508 p1 += 5;
509 if ((p2 = strstr(buf, ","))) {
510 memcpy(value, p1, p2 - p1);
511 }
512 pts = strtoull(value, NULL, 10);
513 }
514
515 memset(value, 0, sizeof(value));
516 if ((p1 = strstr(buf, "offset="))) {
517 p1 += 7;
518 if ((p2 = strstr(buf, "}"))) {
519 memcpy(value, p1, p2 - p1);
520 }
521 offset = strtoull(value, NULL, 10);
522 }
523
524 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800525 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chend241c7a2021-06-22 13:34:27 +0800526 if (position <= offset
527 &&position >= offset_p
528 && offset - offset_p > 0) {
wentao.maf57dd232022-10-08 16:07:29 +0800529 // Tainted data issue originating from fgets seem false positive, so we
530 // just suppress it here.
531 // coverity[tainted_data]
hualing chen969fe7b2021-05-26 15:13:17 +0800532 ret = pts_p + (pts - pts_p) * (position - offset_p) / (offset - offset_p);
Wentao MA96f68962022-06-15 19:45:35 +0800533 //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 +0800534 return ret;
hualing chen5605eed2020-05-26 18:18:06 +0800535 }
hualing chen969fe7b2021-05-26 15:13:17 +0800536 offset_p = offset;
537 pts_p = pts;
hualing chen5605eed2020-05-26 18:18:06 +0800538 }
Wentao MA96f68962022-06-15 19:45:35 +0800539 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen5605eed2020-05-26 18:18:06 +0800540 return pts;
541}
542
543
Wentao MAa3388532022-08-18 15:07:07 +0800544loff_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800545{
546 Segment_Context_t *p_ctx;
547 char buf[256];
548 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800549 uint64_t pts = 0L;
550 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800551 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800552 int ret = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800553
554 p_ctx = (Segment_Context_t *)handle;
555 DVR_RETURN_IF_FALSE(p_ctx);
556 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
557 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
558
559 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800560 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
561 DVR_RETURN_IF_FALSE(ret != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800562 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800563 DVR_RETURN_IF_FALSE(position != -1);
564
565 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
566 memset(value, 0, sizeof(value));
567 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800568 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800569 if ((p2 = strstr(buf, ","))) {
570 memcpy(value, p1, p2 - p1);
571 }
572 pts = strtoull(value, NULL, 10);
573 }
574
575 memset(value, 0, sizeof(value));
576 if ((p1 = strstr(buf, "offset="))) {
577 p1 += 7;
578 if ((p2 = strstr(buf, "}"))) {
579 memcpy(value, p1, p2 - p1);
580 }
581 offset = strtoull(value, NULL, 10);
582 }
583
584 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800585 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800586 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800587 return pts;
588 }
589 }
Wentao MA96f68962022-06-15 19:45:35 +0800590 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800591 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800592}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800593
Wentao MAa3388532022-08-18 15:07:07 +0800594loff_t segment_tell_total_time(Segment_Handle_t handle)
pengfei.liu8b563292020-02-26 15:49:02 +0800595{
596 Segment_Context_t *p_ctx;
597 char buf[256];
598 char last_buf[256];
599 char value[256];
600 uint64_t pts = ULLONG_MAX;
601 loff_t offset = 0, position = 0;
602 char *p1, *p2;
603 int line = 0;
Wentao MAa3388532022-08-18 15:07:07 +0800604 int ret = 0;
pengfei.liu8b563292020-02-26 15:49:02 +0800605
606 p_ctx = (Segment_Context_t *)handle;
607 DVR_RETURN_IF_FALSE(p_ctx);
608 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
609 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
610
611 memset(buf, 0, sizeof(buf));
612 memset(last_buf, 0, sizeof(last_buf));
hualing chend241c7a2021-06-22 13:34:27 +0800613 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
pengfei.liu8b563292020-02-26 15:49:02 +0800614 DVR_RETURN_IF_FALSE(position != -1);
615
Wentao MAa3388532022-08-18 15:07:07 +0800616 // if unable to seek from end, it is necessary to seek to file beginning position.
hualing chen041c4092020-04-05 15:11:50 +0800617 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
Wentao MAa3388532022-08-18 15:07:07 +0800618 ret = fseek(p_ctx->index_fp, 0L, SEEK_SET);
619 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen041c4092020-04-05 15:11:50 +0800620 }
pengfei.liu8b563292020-02-26 15:49:02 +0800621 /* Save last line buffer */
622 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800623 if (strlen(buf) <= 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800624 DVR_INFO("read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800625 continue;
626 }
pengfei.liu8b563292020-02-26 15:49:02 +0800627 memset(last_buf, 0, sizeof(last_buf));
628 memcpy(last_buf, buf, strlen(buf));
629 memset(buf, 0, sizeof(buf));
630 line++;
631 }
632
633 /* Extract time value */
634 memset(value, 0, sizeof(value));
635 if ((p1 = strstr(last_buf, "time="))) {
636 p1 += 5;
637 if ((p2 = strstr(last_buf, ","))) {
638 memcpy(value, p1, p2 - p1);
639 }
640 pts = strtoull(value, NULL, 10);
641 }
642
643 memset(value, 0, sizeof(value));
644 if ((p1 = strstr(last_buf, "offset="))) {
645 p1 += 7;
646 if ((p2 = strstr(last_buf, "}"))) {
647 memcpy(value, p1, p2 - p1);
648 }
649 offset = strtoull(value, NULL, 10);
650 }
hualing chen87072a82020-03-12 16:20:12 +0800651 //if (line < 2)
Wentao MA96f68962022-06-15 19:45:35 +0800652 //DVR_INFO("totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800653 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
654}
655
pengfei.liuab5a2262020-02-14 17:33:40 +0800656/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800657int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
658{
659 Segment_Context_t *p_ctx;
660 char buf[256];
661 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800662 int ret = 0;
Pengfei Liub4734232020-01-17 18:25:10 +0800663
664 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800665 DVR_RETURN_IF_FALSE(p_ctx);
666 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
667 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800668 // seek to 0 to rewrite info
669 ret = fseek(p_ctx->dat_fp, 0, SEEK_SET);
670 DVR_RETURN_IF_FALSE(ret != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800671
672 /*Save segment id*/
673 memset(buf, 0, sizeof(buf));
674 sprintf(buf, "id=%lld\n", p_info->id);
675 fputs(buf, p_ctx->dat_fp);
676
677 /*Save number of pids*/
678 memset(buf, 0, sizeof(buf));
679 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
680 fputs(buf, p_ctx->dat_fp);
681
682 /*Save pid information*/
683 for (i = 0; i < p_info->nb_pids; i++) {
684 memset(buf, 0, sizeof(buf));
685 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
686 fputs(buf, p_ctx->dat_fp);
687 }
688
689 /*Save segment duration*/
690 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800691 DVR_INFO("duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800692 sprintf(buf, "duration=%ld\n", p_info->duration);
693 fputs(buf, p_ctx->dat_fp);
694
695 /*Save segment size*/
696 memset(buf, 0, sizeof(buf));
697 sprintf(buf, "size=%zu\n", p_info->size);
698 fputs(buf, p_ctx->dat_fp);
699
700 /*Save number of packets*/
701 memset(buf, 0, sizeof(buf));
702 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
703 fputs(buf, p_ctx->dat_fp);
704
705 fflush(p_ctx->dat_fp);
hualing chen47c34bc2020-05-11 09:15:47 +0800706 fsync(fileno(p_ctx->dat_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800707 return DVR_SUCCESS;
708}
709
pengfei.liuab5a2262020-02-14 17:33:40 +0800710/* Should consider the case of cut power, todo... */
hualing chenb9a02922021-12-14 11:29:47 +0800711int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
712{
713 Segment_Context_t *p_ctx;
714 char buf[256];
715 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800716 int ret = 0;
hualing chenb9a02922021-12-14 11:29:47 +0800717
718 p_ctx = (Segment_Context_t *)handle;
719 DVR_RETURN_IF_FALSE(p_ctx);
720 DVR_RETURN_IF_FALSE(p_ctx->all_dat_fp);
721 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800722
723 //seek to end to append info
724 ret = fseek(p_ctx->all_dat_fp, 0, SEEK_END);
725 DVR_RETURN_IF_FALSE(ret != -1);
hualing chenb9a02922021-12-14 11:29:47 +0800726
727 /*Save segment id*/
728 memset(buf, 0, sizeof(buf));
729 sprintf(buf, "id=%lld\n", p_info->id);
730 fputs(buf, p_ctx->all_dat_fp);
731
732 /*Save number of pids*/
733 memset(buf, 0, sizeof(buf));
734 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
735 fputs(buf, p_ctx->all_dat_fp);
736
737 /*Save pid information*/
738 for (i = 0; i < p_info->nb_pids; i++) {
739 memset(buf, 0, sizeof(buf));
740 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
741 fputs(buf, p_ctx->all_dat_fp);
742 }
743
744 /*Save segment duration*/
745 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800746 DVR_INFO("duration store:[%ld]", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800747 sprintf(buf, "duration=%ld\n", p_info->duration);
748 fputs(buf, p_ctx->all_dat_fp);
749
750 /*Save segment size*/
751 memset(buf, 0, sizeof(buf));
752 sprintf(buf, "size=%zu\n", p_info->size);
753 fputs(buf, p_ctx->all_dat_fp);
754
755 /*Save number of packets*/
756 memset(buf, 0, sizeof(buf));
757 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
758 fputs(buf, p_ctx->all_dat_fp);
759
760 fflush(p_ctx->all_dat_fp);
761 fsync(fileno(p_ctx->all_dat_fp));
762 return DVR_SUCCESS;
763}
764
765/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800766int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
767{
768 Segment_Context_t *p_ctx;
769 uint32_t i;
770 char buf[256];
771 char value[256];
772 char *p1, *p2;
773
774 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800775 DVR_RETURN_IF_FALSE(p_ctx);
776 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800777
778 /*Load segment id*/
779 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800780 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800781 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800782 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800783 p_info->id = strtoull(p1 + 3, NULL, 10);
784
785 /*Save number of pids*/
786 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800787 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800788 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800789 DVR_RETURN_IF_FALSE(p1);
Wentao MAb2070812022-09-02 13:10:03 +0800790 p_info->nb_pids = strtoul(p1 + 8, NULL, 10);
Pengfei Liub4734232020-01-17 18:25:10 +0800791
792 /*Save pid information*/
wentao.maf57dd232022-10-08 16:07:29 +0800793
794 // Tainted data issue originating from fgets seem false positive, so we
795 // just suppress it here.
796 // coverity[tainted_data]
Pengfei Liub4734232020-01-17 18:25:10 +0800797 for (i = 0; i < p_info->nb_pids; i++) {
798 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800799 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800800 memset(value, 0, sizeof(value));
801 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800802 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800803 p1 += 4;
804 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800805 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800806 memcpy(value, p1, p2 - p1);
807 }
808 p_info->pids[i].pid = strtoull(value, NULL, 10);
809 }
810
811 memset(value, 0, sizeof(value));
812 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800813 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800814 p1 += 5;
815 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800816 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800817 memcpy(value, p1, p2 - p1);
818 }
819 p_info->pids[i].type = strtoull(value, NULL, 10);
820 }
821 }
822
823 /*Save segment duration*/
824 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800825 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800826 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800827 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800828 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800829 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800830
831 /*Save segment size*/
832 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800833 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800834 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800835 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800836 p_info->size = strtoull(p1 + 5, NULL, 10);
837
838 /*Save number of packets*/
839 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800840 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800841 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800842 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800843 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
844
845 return DVR_SUCCESS;
846}
847
hualing chenb9a02922021-12-14 11:29:47 +0800848/* Should consider the case of cut power, todo... */
849int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
850{
851 Segment_Context_t *p_ctx;
852 uint32_t i;
853 char buf[256];
854 char value[256];
855 char *p1, *p2;
856
857 p_ctx = (Segment_Context_t *)handle;
858 DVR_RETURN_IF_FALSE(p_ctx);
859 DVR_RETURN_IF_FALSE(list);
hualing chen926a8ec2021-12-20 20:38:24 +0800860 if (p_ctx->all_dat_fp == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800861 DVR_INFO("all dat file not open\n");
hualing chen926a8ec2021-12-20 20:38:24 +0800862 return DVR_FAILURE;
863 }
hualing chenb9a02922021-12-14 11:29:47 +0800864 //first get
865 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
866 DVR_RETURN_IF_FALSE(p1);
867
868 do {
869
870 DVR_RecordSegmentInfo_t *p_info;
871
872 p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
wentao.maa22bc852022-10-13 12:18:06 +0800873 DVR_RETURN_IF_FALSE(p_info);
hualing chenb9a02922021-12-14 11:29:47 +0800874 memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
875
wentao.maa22bc852022-10-13 12:18:06 +0800876 list_add_tail(p_info, list);
hualing chenb9a02922021-12-14 11:29:47 +0800877
878 /*Load segment id*/
879 DVR_RETURN_IF_FALSE(p1);
880 p1 = strstr(buf, "id=");
881 DVR_RETURN_IF_FALSE(p1);
882 p_info->id = strtoull(p1 + 3, NULL, 10);
883
884 /*Save number of pids*/
885 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
886 DVR_RETURN_IF_FALSE(p1);
887 p1 = strstr(buf, "nb_pids=");
888 DVR_RETURN_IF_FALSE(p1);
889 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
890
891 /*Save pid information*/
wentao.maf57dd232022-10-08 16:07:29 +0800892 // Tainted data issue originating from fgets seem false positive, so we
893 // just suppress it here.
894 // coverity[tainted_data]
hualing chenb9a02922021-12-14 11:29:47 +0800895 for (i = 0; i < p_info->nb_pids; i++) {
896 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
897 DVR_RETURN_IF_FALSE(p1);
898 memset(value, 0, sizeof(value));
899 if ((p1 = strstr(buf, "pid="))) {
900 DVR_RETURN_IF_FALSE(p1);
901 p1 += 4;
902 if ((p2 = strstr(buf, ","))) {
903 DVR_RETURN_IF_FALSE(p2);
904 memcpy(value, p1, p2 - p1);
905 }
906 p_info->pids[i].pid = strtoull(value, NULL, 10);
907 }
908
909 memset(value, 0, sizeof(value));
910 if ((p1 = strstr(buf, "type="))) {
911 DVR_RETURN_IF_FALSE(p1);
912 p1 += 5;
913 if ((p2 = strstr(buf, "}"))) {
914 DVR_RETURN_IF_FALSE(p2);
915 memcpy(value, p1, p2 - p1);
916 }
917 p_info->pids[i].type = strtoull(value, NULL, 10);
918 }
919 }
920
921 /*Save segment duration*/
922 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
923 DVR_RETURN_IF_FALSE(p1);
924 p1 = strstr(buf, "duration=");
925 DVR_RETURN_IF_FALSE(p1);
926 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800927 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800928
929 /*Save segment size*/
930 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
931 DVR_RETURN_IF_FALSE(p1);
932 p1 = strstr(buf, "size=");
933 DVR_RETURN_IF_FALSE(p1);
934 p_info->size = strtoull(p1 + 5, NULL, 10);
935
936 /*Save number of packets*/
937 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
938 DVR_RETURN_IF_FALSE(p1);
939 p1 = strstr(buf, "nb_packets=");
940 DVR_RETURN_IF_FALSE(p1);
941 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
942 //if reach end,exit loop
943 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
944 } while (p1);
945
946 return DVR_SUCCESS;
947}
948
Pengfei Liub4734232020-01-17 18:25:10 +0800949int segment_delete(const char *location, uint64_t segment_id)
950{
951 char fname[MAX_SEGMENT_PATH_SIZE];
952 int ret;
953
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800954 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800955
956 /*delete ts file*/
957 memset(fname, 0, sizeof(fname));
958 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
959 ret = unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000960 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800961 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800962
963 /*delete index file*/
964 memset(fname, 0, sizeof(fname));
965 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
966 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000967 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800968 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800969
970 /*delete store information file*/
971 memset(fname, 0, sizeof(fname));
972 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
973 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000974 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800975 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800976
977 return DVR_SUCCESS;
978}
979
hualing chen87072a82020-03-12 16:20:12 +0800980int segment_ongoing(Segment_Handle_t handle)
981{
982 Segment_Context_t *p_ctx;
983 p_ctx = (Segment_Context_t *)handle;
984 struct stat mstat;
985
986 char going_name[MAX_SEGMENT_PATH_SIZE];
987 memset(going_name, 0, sizeof(going_name));
988 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
989 int ret = stat(going_name, &mstat);
Wentao MA96f68962022-06-15 19:45:35 +0800990 DVR_INFO("segment check ongoing [%s] ret [%d]", going_name, ret);
hualing chen87072a82020-03-12 16:20:12 +0800991 if (ret != 0) {
992 return DVR_FAILURE;
993 }
994 return DVR_SUCCESS;
995}
Wentao MAa3388532022-08-18 15:07:07 +0800996
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800997loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800998{
999 Segment_Context_t *p_ctx;
1000 char buf[256];
1001 char value[256];
Wentao MA139fc612022-08-29 14:10:07 +08001002 uint64_t pts = 0;
1003 loff_t offset = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001004 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +08001005 int ret = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001006
1007 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001008 DVR_RETURN_IF_FALSE(p_ctx);
1009 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
1010 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001011
1012 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +08001013 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
1014 DVR_RETURN_IF_FALSE(ret != -1);
1015
Pengfei Liub038b6a2020-01-14 15:57:01 +08001016 printf("start gets pts\n");
1017 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
1018 printf("buf[%s]\n", buf);
1019 memset(value, 0, sizeof(value));
1020 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +08001021 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001022 if ((p2 = strstr(buf, ","))) {
1023 memcpy(value, p1, p2 - p1);
1024 }
1025 pts = strtoull(value, NULL, 10);
1026 }
1027
1028 memset(value, 0, sizeof(value));
1029 if ((p1 = strstr(buf, "offset="))) {
1030 p1 += 7;
1031 if ((p2 = strstr(buf, "}"))) {
1032 memcpy(value, p1, p2 - p1);
1033 }
1034 offset = strtoull(value, NULL, 10);
1035 }
1036
1037 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001038 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001039 }
1040
1041 return 0;
1042}
Wentao MA907b6432022-08-01 06:23:08 +00001043
1044off_t segment_get_cur_segment_size(Segment_Handle_t handle)
1045{
1046 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1047 DVR_RETURN_IF_FALSE(p_ctx);
1048 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
1049 struct stat sb;
1050 int ret=fstat(p_ctx->ts_fd,&sb);
1051 if (ret<0) {
1052 return -1;
1053 }
1054 return sb.st_size;
1055}
1056
1057uint64_t segment_get_cur_segment_id(Segment_Handle_t handle)
1058{
1059 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1060 DVR_RETURN_IF_FALSE(p_ctx);
1061 return p_ctx->segment_id;
1062}
1063