blob: 9ef3f413ab5b62a1a8c073d9762a91b5c073c9cd [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);
Zhiqiang Hanc43a4d22023-10-25 15:24:19 +0800261 /*remove the fsync, use /proc to control the data writeback*/
262 //if (p_ctx->time % TS_FILE_SYNC_TIME == 0)
263 // fsync(p_ctx->ts_fd);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800264 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800265}
266
hualing chen2932d372020-04-29 13:44:00 +0800267int segment_update_pts_force(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800268{
269 Segment_Context_t *p_ctx;
270 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800271 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800272
273 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800274 DVR_RETURN_IF_FALSE(p_ctx);
275 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800276
Pengfei Liub038b6a2020-01-14 15:57:01 +0800277 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800278 DVR_INFO("%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800279 p_ctx->first_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800280 p_ctx->first_offset = offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800281 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800282 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800283 if (p_ctx->last_pts == ULLONG_MAX) {
284 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800285 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800286 p_ctx->cur_time = pts - p_ctx->first_pts;
Wentao MA96f68962022-06-15 19:45:35 +0800287 DVR_INFO("%s force pcr:%llu -1", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800288 } else {
289 /*Last pts has valid value*/
290 int diff = pts - p_ctx->last_pts;
291 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
292 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800293 DVR_INFO("[%s]force update Current pts has a transition, [%llu, %llu, %llu]",__func__,
hualing chen2932d372020-04-29 13:44:00 +0800294 p_ctx->first_pts, p_ctx->last_pts, pts);
295 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
296 } else {
297 /*This is a normal pts, record it*/
hualing chena5f03222021-12-02 11:22:35 +0800298 //check if this pcr is transition.if true,add 200ms
299 //other case normal.
hualing chen2932d372020-04-29 13:44:00 +0800300 p_ctx->cur_time += diff;
Wentao MA96f68962022-06-15 19:45:35 +0800301 DVR_INFO("%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
hualing chen2932d372020-04-29 13:44:00 +0800302 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
303 }
304 }
305
306 record_diff = pts - p_ctx->last_record_pts;
307 if (strlen(buf) > 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800308 DVR_INFO("%s force pcr:%llu buf:%s", __func__, pts, buf);
hualing chen2932d372020-04-29 13:44:00 +0800309 fputs(buf, p_ctx->index_fp);
310 fflush(p_ctx->index_fp);
Zhiqiang Hanc43a4d22023-10-25 15:24:19 +0800311 //fsync(fileno(p_ctx->index_fp));
hualing chen2932d372020-04-29 13:44:00 +0800312 p_ctx->last_record_pts = pts;
313 }
314 p_ctx->last_pts = pts;
hualing chen2932d372020-04-29 13:44:00 +0800315 return DVR_SUCCESS;
316}
317
318int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
319{
320 Segment_Context_t *p_ctx;
321 char buf[256];
322 int record_diff = 0;
323
324 p_ctx = (Segment_Context_t *)handle;
325 DVR_RETURN_IF_FALSE(p_ctx);
326 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
327
328 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800329 DVR_INFO("%s first pcr:%llu", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800330 p_ctx->first_pts = pts;
331 //p_ctx->cur_time = p_ctx->cur_time + PTS_HEAD_DEVIATION;
332 }
333 memset(buf, 0, sizeof(buf));
334 if (p_ctx->last_pts == ULLONG_MAX) {
335 /*Last pts is init value*/
336 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
337 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800338 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800339 if (!p_ctx->force_sysclock) {
340 /* if force_sysclock is off, we follow old manner. Please refer to
341 * SWPL-75327*/
342 /*Last pts has valid value*/
343 int diff = pts - p_ctx->last_pts;
344 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
345 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800346 DVR_INFO("Current pts has a transition, [%llu, %llu, %llu]",
wentao.ma35a69d42022-03-10 18:08:40 +0800347 p_ctx->first_pts, p_ctx->last_pts, pts);
348 p_ctx->last_record_pts = pts;
Wentao MA270dc0f2022-08-23 13:17:26 +0800349 //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINUED_DEVIATION;
hualing chena5f03222021-12-02 11:22:35 +0800350 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800351 /*This is a normal pts, record it*/
352 loff_t off_diff = offset - p_ctx->last_offset;
353 float rate = (float) (off_diff) / (float)(diff);
354 if (p_ctx->avg_rate == 0.0) {
355 p_ctx->avg_rate = (float) offset / (float)(p_ctx->cur_time + diff);
356 }
357 if (diff >= PCR_JUMP_DUR) {
Wentao MA96f68962022-06-15 19:45:35 +0800358 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 +0800359 if (p_ctx->avg_rate != 0 && (int)(p_ctx->avg_rate) >= (int)(rate * 4)) {
360 diff = off_diff / p_ctx->avg_rate;
361 p_ctx->cur_time += diff;
362 } else {
363 p_ctx->cur_time += diff;
364 }
365 } else {
366 p_ctx->cur_time += diff;
367 }
hualing chena5f03222021-12-02 11:22:35 +0800368 }
wentao.ma35a69d42022-03-10 18:08:40 +0800369 } else {
370 /* if force_sysclock is on, we simply calculate cur_time based on system
371 * time. Please refer to SWPL-75327*/
372 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800373 }
wentao.ma35a69d42022-03-10 18:08:40 +0800374 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800375 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800376
377 record_diff = pts - p_ctx->last_record_pts;
378 if (strlen(buf) > 0 &&
379 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800380 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800381 fflush(p_ctx->index_fp);
hualing chen157641d2022-02-22 17:54:52 +0800382 p_ctx->time++;
383 //flush idx file 3s
Zhiqiang Hanc43a4d22023-10-25 15:24:19 +0800384 //if ((p_ctx->time > 0 && p_ctx->time % IDX_FILE_SYNC_TIME == 0))
385 // fsync(fileno(p_ctx->index_fp));
hualing chen157641d2022-02-22 17:54:52 +0800386 if (p_ctx->time > IDX_FILE_SYNC_TIME)
387 p_ctx->time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800388 p_ctx->last_record_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800389 p_ctx->last_record_offset = offset;
390 if (p_ctx->cur_time > 0)
391 p_ctx->avg_rate = (float) offset / (float)p_ctx->cur_time;
pengfei.liu567d6d82020-04-17 16:48:59 +0800392 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800393 p_ctx->last_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800394 p_ctx->last_offset = offset;
Pengfei Liuc181a982020-01-07 19:27:13 +0800395 return DVR_SUCCESS;
396}
397
hualing chen266b9502020-04-04 17:39:39 +0800398loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800399{
400 Segment_Context_t *p_ctx;
401 char buf[256];
402 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800403 uint64_t pts = 0L;
404 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800405 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800406 int ret = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800407
Wentao MA96f68962022-06-15 19:45:35 +0800408 DVR_INFO("into seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chen8a657f32021-08-30 13:12:49 +0800409
Pengfei Liuc181a982020-01-07 19:27:13 +0800410 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800411 DVR_RETURN_IF_FALSE(p_ctx);
412 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
413 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800414
hualing chen266b9502020-04-04 17:39:39 +0800415 if (time == 0) {
416 offset = 0;
Wentao MA96f68962022-06-15 19:45:35 +0800417 DVR_INFO("seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chend241c7a2021-06-22 13:34:27 +0800418 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen266b9502020-04-04 17:39:39 +0800419 return offset;
420 }
421
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800422 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800423 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
424 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800425 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800426 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800427 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800428 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800429 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800430 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800431 if ((p2 = strstr(buf, ","))) {
432 memcpy(value, p1, p2 - p1);
433 }
434 pts = strtoull(value, NULL, 10);
435 }
436
437 memset(value, 0, sizeof(value));
438 if ((p1 = strstr(buf, "offset="))) {
439 p1 += 7;
440 if ((p2 = strstr(buf, "}"))) {
441 memcpy(value, p1, p2 - p1);
442 }
443 offset = strtoull(value, NULL, 10);
444 }
hualing chen2aba4022020-03-02 13:49:55 +0800445 if (0)
446 {
Wentao MA96f68962022-06-15 19:45:35 +0800447 DVR_INFO("seek buf[%s]", buf);
448 DVR_INFO("seek time=%llu, offset=%lld\n", pts, offset);
hualing chen2aba4022020-03-02 13:49:55 +0800449 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800450 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800451 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800452 if (block_size > 0) {
453 offset = offset - offset%block_size;
454 }
Wentao MA96f68962022-06-15 19:45:35 +0800455 //DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800456 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800457 return offset;
458 }
hualing chen2aba4022020-03-02 13:49:55 +0800459 }
hualing chen2932d372020-04-29 13:44:00 +0800460 if (time > pts) {
461 if (block_size > 0) {
462 offset = offset - offset%block_size;
463 }
Wentao MA96f68962022-06-15 19:45:35 +0800464 DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d end\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800465 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen2932d372020-04-29 13:44:00 +0800466 return offset;
467 }
Wentao MA96f68962022-06-15 19:45:35 +0800468 DVR_INFO("seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800469 return DVR_FAILURE;
470}
471
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800472loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800473{
474 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800475 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800476 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800477 DVR_RETURN_IF_FALSE(p_ctx);
478 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800479 pos = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
480 return pos;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800481}
482
Wentao MAa3388532022-08-18 15:07:07 +0800483loff_t segment_tell_position_time(Segment_Handle_t handle, loff_t position)
hualing chen5605eed2020-05-26 18:18:06 +0800484{
485 Segment_Context_t *p_ctx;
486 char buf[256];
487 char value[256];
hualing chen969fe7b2021-05-26 15:13:17 +0800488 uint64_t ret = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800489 uint64_t pts = 0L;
hualing chen969fe7b2021-05-26 15:13:17 +0800490 uint64_t pts_p = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800491 loff_t offset = 0;
hualing chen969fe7b2021-05-26 15:13:17 +0800492 loff_t offset_p = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800493 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800494 int ret2 = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800495
496 p_ctx = (Segment_Context_t *)handle;
497 DVR_RETURN_IF_FALSE(p_ctx);
498 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
499 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
500
501 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800502 ret2 = fseek(p_ctx->index_fp, 0, SEEK_SET);
503 DVR_RETURN_IF_FALSE(ret2 != -1);
hualing chen5605eed2020-05-26 18:18:06 +0800504 DVR_RETURN_IF_FALSE(position != -1);
505
506 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
507 memset(value, 0, sizeof(value));
508 if ((p1 = strstr(buf, "time="))) {
509 p1 += 5;
510 if ((p2 = strstr(buf, ","))) {
511 memcpy(value, p1, p2 - p1);
512 }
513 pts = strtoull(value, NULL, 10);
514 }
515
516 memset(value, 0, sizeof(value));
517 if ((p1 = strstr(buf, "offset="))) {
518 p1 += 7;
519 if ((p2 = strstr(buf, "}"))) {
520 memcpy(value, p1, p2 - p1);
521 }
522 offset = strtoull(value, NULL, 10);
523 }
524
525 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800526 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chend241c7a2021-06-22 13:34:27 +0800527 if (position <= offset
528 &&position >= offset_p
529 && offset - offset_p > 0) {
wentao.maf57dd232022-10-08 16:07:29 +0800530 // Tainted data issue originating from fgets seem false positive, so we
531 // just suppress it here.
532 // coverity[tainted_data]
hualing chen969fe7b2021-05-26 15:13:17 +0800533 ret = pts_p + (pts - pts_p) * (position - offset_p) / (offset - offset_p);
Wentao MA96f68962022-06-15 19:45:35 +0800534 //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 +0800535 return ret;
hualing chen5605eed2020-05-26 18:18:06 +0800536 }
hualing chen969fe7b2021-05-26 15:13:17 +0800537 offset_p = offset;
538 pts_p = pts;
hualing chen5605eed2020-05-26 18:18:06 +0800539 }
Wentao MA96f68962022-06-15 19:45:35 +0800540 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen5605eed2020-05-26 18:18:06 +0800541 return pts;
542}
543
544
Wentao MAa3388532022-08-18 15:07:07 +0800545loff_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800546{
547 Segment_Context_t *p_ctx;
548 char buf[256];
549 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800550 uint64_t pts = 0L;
551 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800552 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800553 int ret = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800554
555 p_ctx = (Segment_Context_t *)handle;
556 DVR_RETURN_IF_FALSE(p_ctx);
557 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
558 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
559
560 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800561 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
562 DVR_RETURN_IF_FALSE(ret != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800563 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800564 DVR_RETURN_IF_FALSE(position != -1);
565
566 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
567 memset(value, 0, sizeof(value));
568 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800569 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800570 if ((p2 = strstr(buf, ","))) {
571 memcpy(value, p1, p2 - p1);
572 }
573 pts = strtoull(value, NULL, 10);
574 }
575
576 memset(value, 0, sizeof(value));
577 if ((p1 = strstr(buf, "offset="))) {
578 p1 += 7;
579 if ((p2 = strstr(buf, "}"))) {
580 memcpy(value, p1, p2 - p1);
581 }
582 offset = strtoull(value, NULL, 10);
583 }
584
585 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800586 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800587 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800588 return pts;
589 }
590 }
Wentao MA96f68962022-06-15 19:45:35 +0800591 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800592 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800593}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800594
Wentao MAa3388532022-08-18 15:07:07 +0800595loff_t segment_tell_total_time(Segment_Handle_t handle)
pengfei.liu8b563292020-02-26 15:49:02 +0800596{
597 Segment_Context_t *p_ctx;
598 char buf[256];
599 char last_buf[256];
600 char value[256];
601 uint64_t pts = ULLONG_MAX;
602 loff_t offset = 0, position = 0;
603 char *p1, *p2;
604 int line = 0;
Wentao MAa3388532022-08-18 15:07:07 +0800605 int ret = 0;
pengfei.liu8b563292020-02-26 15:49:02 +0800606
607 p_ctx = (Segment_Context_t *)handle;
608 DVR_RETURN_IF_FALSE(p_ctx);
609 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
610 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
611
612 memset(buf, 0, sizeof(buf));
613 memset(last_buf, 0, sizeof(last_buf));
hualing chend241c7a2021-06-22 13:34:27 +0800614 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
pengfei.liu8b563292020-02-26 15:49:02 +0800615 DVR_RETURN_IF_FALSE(position != -1);
616
Wentao MAa3388532022-08-18 15:07:07 +0800617 // if unable to seek from end, it is necessary to seek to file beginning position.
hualing chen041c4092020-04-05 15:11:50 +0800618 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
Wentao MAa3388532022-08-18 15:07:07 +0800619 ret = fseek(p_ctx->index_fp, 0L, SEEK_SET);
620 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen041c4092020-04-05 15:11:50 +0800621 }
pengfei.liu8b563292020-02-26 15:49:02 +0800622 /* Save last line buffer */
623 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800624 if (strlen(buf) <= 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800625 DVR_INFO("read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800626 continue;
627 }
pengfei.liu8b563292020-02-26 15:49:02 +0800628 memset(last_buf, 0, sizeof(last_buf));
629 memcpy(last_buf, buf, strlen(buf));
630 memset(buf, 0, sizeof(buf));
631 line++;
632 }
633
634 /* Extract time value */
635 memset(value, 0, sizeof(value));
636 if ((p1 = strstr(last_buf, "time="))) {
637 p1 += 5;
638 if ((p2 = strstr(last_buf, ","))) {
639 memcpy(value, p1, p2 - p1);
640 }
641 pts = strtoull(value, NULL, 10);
642 }
643
644 memset(value, 0, sizeof(value));
645 if ((p1 = strstr(last_buf, "offset="))) {
646 p1 += 7;
647 if ((p2 = strstr(last_buf, "}"))) {
648 memcpy(value, p1, p2 - p1);
649 }
650 offset = strtoull(value, NULL, 10);
651 }
hualing chen87072a82020-03-12 16:20:12 +0800652 //if (line < 2)
Wentao MA96f68962022-06-15 19:45:35 +0800653 //DVR_INFO("totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800654 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
655}
656
pengfei.liuab5a2262020-02-14 17:33:40 +0800657/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800658int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
659{
660 Segment_Context_t *p_ctx;
661 char buf[256];
662 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800663 int ret = 0;
Pengfei Liub4734232020-01-17 18:25:10 +0800664
665 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800666 DVR_RETURN_IF_FALSE(p_ctx);
667 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
668 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800669 // seek to 0 to rewrite info
670 ret = fseek(p_ctx->dat_fp, 0, SEEK_SET);
671 DVR_RETURN_IF_FALSE(ret != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800672
673 /*Save segment id*/
674 memset(buf, 0, sizeof(buf));
675 sprintf(buf, "id=%lld\n", p_info->id);
676 fputs(buf, p_ctx->dat_fp);
677
678 /*Save number of pids*/
679 memset(buf, 0, sizeof(buf));
680 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
681 fputs(buf, p_ctx->dat_fp);
682
683 /*Save pid information*/
684 for (i = 0; i < p_info->nb_pids; i++) {
685 memset(buf, 0, sizeof(buf));
686 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
687 fputs(buf, p_ctx->dat_fp);
688 }
689
690 /*Save segment duration*/
691 memset(buf, 0, sizeof(buf));
692 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);
Zhiqiang Hanc43a4d22023-10-25 15:24:19 +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));
hualing chenb9a02922021-12-14 11:29:47 +0800746 sprintf(buf, "duration=%ld\n", p_info->duration);
747 fputs(buf, p_ctx->all_dat_fp);
748
749 /*Save segment size*/
750 memset(buf, 0, sizeof(buf));
751 sprintf(buf, "size=%zu\n", p_info->size);
752 fputs(buf, p_ctx->all_dat_fp);
753
754 /*Save number of packets*/
755 memset(buf, 0, sizeof(buf));
756 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
757 fputs(buf, p_ctx->all_dat_fp);
758
759 fflush(p_ctx->all_dat_fp);
Zhiqiang Hanc43a4d22023-10-25 15:24:19 +0800760 //fsync(fileno(p_ctx->all_dat_fp));
hualing chenb9a02922021-12-14 11:29:47 +0800761 return DVR_SUCCESS;
762}
763
764/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800765int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
766{
767 Segment_Context_t *p_ctx;
768 uint32_t i;
769 char buf[256];
770 char value[256];
771 char *p1, *p2;
772
773 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800774 DVR_RETURN_IF_FALSE(p_ctx);
775 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800776
777 /*Load segment id*/
778 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800779 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800780 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800781 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800782 p_info->id = strtoull(p1 + 3, NULL, 10);
783
784 /*Save number of pids*/
785 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800786 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800787 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800788 DVR_RETURN_IF_FALSE(p1);
Wentao MAb2070812022-09-02 13:10:03 +0800789 p_info->nb_pids = strtoul(p1 + 8, NULL, 10);
Pengfei Liub4734232020-01-17 18:25:10 +0800790
791 /*Save pid information*/
wentao.maf57dd232022-10-08 16:07:29 +0800792
793 // Tainted data issue originating from fgets seem false positive, so we
794 // just suppress it here.
795 // coverity[tainted_data]
Pengfei Liub4734232020-01-17 18:25:10 +0800796 for (i = 0; i < p_info->nb_pids; i++) {
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 memset(value, 0, sizeof(value));
800 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800801 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800802 p1 += 4;
803 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800804 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800805 memcpy(value, p1, p2 - p1);
806 }
807 p_info->pids[i].pid = strtoull(value, NULL, 10);
808 }
809
810 memset(value, 0, sizeof(value));
811 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800812 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800813 p1 += 5;
814 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800815 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800816 memcpy(value, p1, p2 - p1);
817 }
818 p_info->pids[i].type = strtoull(value, NULL, 10);
819 }
820 }
821
822 /*Save segment duration*/
823 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800824 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800825 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800826 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800827 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800828 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800829
830 /*Save segment size*/
831 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800832 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800833 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800834 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800835 p_info->size = strtoull(p1 + 5, NULL, 10);
836
837 /*Save number of packets*/
838 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800839 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800840 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800841 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800842 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
843
844 return DVR_SUCCESS;
845}
846
hualing chenb9a02922021-12-14 11:29:47 +0800847/* Should consider the case of cut power, todo... */
848int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
849{
850 Segment_Context_t *p_ctx;
851 uint32_t i;
852 char buf[256];
853 char value[256];
854 char *p1, *p2;
855
856 p_ctx = (Segment_Context_t *)handle;
857 DVR_RETURN_IF_FALSE(p_ctx);
858 DVR_RETURN_IF_FALSE(list);
hualing chen926a8ec2021-12-20 20:38:24 +0800859 if (p_ctx->all_dat_fp == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800860 DVR_INFO("all dat file not open\n");
hualing chen926a8ec2021-12-20 20:38:24 +0800861 return DVR_FAILURE;
862 }
hualing chenb9a02922021-12-14 11:29:47 +0800863 //first get
864 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
865 DVR_RETURN_IF_FALSE(p1);
866
867 do {
868
869 DVR_RecordSegmentInfo_t *p_info;
870
871 p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
wentao.maa22bc852022-10-13 12:18:06 +0800872 DVR_RETURN_IF_FALSE(p_info);
hualing chenb9a02922021-12-14 11:29:47 +0800873 memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
874
wentao.maa22bc852022-10-13 12:18:06 +0800875 list_add_tail(p_info, list);
hualing chenb9a02922021-12-14 11:29:47 +0800876
877 /*Load segment id*/
878 DVR_RETURN_IF_FALSE(p1);
879 p1 = strstr(buf, "id=");
880 DVR_RETURN_IF_FALSE(p1);
881 p_info->id = strtoull(p1 + 3, NULL, 10);
882
883 /*Save number of pids*/
884 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
885 DVR_RETURN_IF_FALSE(p1);
886 p1 = strstr(buf, "nb_pids=");
887 DVR_RETURN_IF_FALSE(p1);
888 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
889
890 /*Save pid information*/
wentao.maf57dd232022-10-08 16:07:29 +0800891 // Tainted data issue originating from fgets seem false positive, so we
892 // just suppress it here.
893 // coverity[tainted_data]
hualing chenb9a02922021-12-14 11:29:47 +0800894 for (i = 0; i < p_info->nb_pids; i++) {
895 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
896 DVR_RETURN_IF_FALSE(p1);
897 memset(value, 0, sizeof(value));
898 if ((p1 = strstr(buf, "pid="))) {
899 DVR_RETURN_IF_FALSE(p1);
900 p1 += 4;
901 if ((p2 = strstr(buf, ","))) {
902 DVR_RETURN_IF_FALSE(p2);
903 memcpy(value, p1, p2 - p1);
904 }
905 p_info->pids[i].pid = strtoull(value, NULL, 10);
906 }
907
908 memset(value, 0, sizeof(value));
909 if ((p1 = strstr(buf, "type="))) {
910 DVR_RETURN_IF_FALSE(p1);
911 p1 += 5;
912 if ((p2 = strstr(buf, "}"))) {
913 DVR_RETURN_IF_FALSE(p2);
914 memcpy(value, p1, p2 - p1);
915 }
916 p_info->pids[i].type = strtoull(value, NULL, 10);
917 }
918 }
919
920 /*Save segment duration*/
921 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
922 DVR_RETURN_IF_FALSE(p1);
923 p1 = strstr(buf, "duration=");
924 DVR_RETURN_IF_FALSE(p1);
925 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800926 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800927
928 /*Save segment size*/
929 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
930 DVR_RETURN_IF_FALSE(p1);
931 p1 = strstr(buf, "size=");
932 DVR_RETURN_IF_FALSE(p1);
933 p_info->size = strtoull(p1 + 5, NULL, 10);
934
935 /*Save number of packets*/
936 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
937 DVR_RETURN_IF_FALSE(p1);
938 p1 = strstr(buf, "nb_packets=");
939 DVR_RETURN_IF_FALSE(p1);
940 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
941 //if reach end,exit loop
942 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
943 } while (p1);
944
945 return DVR_SUCCESS;
946}
947
Pengfei Liub4734232020-01-17 18:25:10 +0800948int segment_delete(const char *location, uint64_t segment_id)
949{
950 char fname[MAX_SEGMENT_PATH_SIZE];
951 int ret;
952
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800953 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800954
955 /*delete ts file*/
956 memset(fname, 0, sizeof(fname));
957 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
958 ret = unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000959 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800960 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800961
962 /*delete index file*/
963 memset(fname, 0, sizeof(fname));
964 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
965 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000966 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800967 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800968
969 /*delete store information file*/
970 memset(fname, 0, sizeof(fname));
971 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
972 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000973 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800974 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800975
976 return DVR_SUCCESS;
977}
978
hualing chen87072a82020-03-12 16:20:12 +0800979int segment_ongoing(Segment_Handle_t handle)
980{
981 Segment_Context_t *p_ctx;
982 p_ctx = (Segment_Context_t *)handle;
983 struct stat mstat;
984
985 char going_name[MAX_SEGMENT_PATH_SIZE];
986 memset(going_name, 0, sizeof(going_name));
987 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
988 int ret = stat(going_name, &mstat);
Wentao MA96f68962022-06-15 19:45:35 +0800989 DVR_INFO("segment check ongoing [%s] ret [%d]", going_name, ret);
hualing chen87072a82020-03-12 16:20:12 +0800990 if (ret != 0) {
991 return DVR_FAILURE;
992 }
993 return DVR_SUCCESS;
994}
Wentao MAa3388532022-08-18 15:07:07 +0800995
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800996loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800997{
998 Segment_Context_t *p_ctx;
999 char buf[256];
1000 char value[256];
Wentao MA139fc612022-08-29 14:10:07 +08001001 uint64_t pts = 0;
1002 loff_t offset = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001003 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +08001004 int ret = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001005
1006 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001007 DVR_RETURN_IF_FALSE(p_ctx);
1008 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
1009 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001010
1011 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +08001012 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
1013 DVR_RETURN_IF_FALSE(ret != -1);
1014
Pengfei Liub038b6a2020-01-14 15:57:01 +08001015 printf("start gets pts\n");
1016 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
1017 printf("buf[%s]\n", buf);
1018 memset(value, 0, sizeof(value));
1019 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +08001020 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001021 if ((p2 = strstr(buf, ","))) {
1022 memcpy(value, p1, p2 - p1);
1023 }
1024 pts = strtoull(value, NULL, 10);
1025 }
1026
1027 memset(value, 0, sizeof(value));
1028 if ((p1 = strstr(buf, "offset="))) {
1029 p1 += 7;
1030 if ((p2 = strstr(buf, "}"))) {
1031 memcpy(value, p1, p2 - p1);
1032 }
1033 offset = strtoull(value, NULL, 10);
1034 }
1035
1036 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001037 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001038 }
1039
1040 return 0;
1041}
Wentao MA907b6432022-08-01 06:23:08 +00001042
1043off_t segment_get_cur_segment_size(Segment_Handle_t handle)
1044{
1045 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1046 DVR_RETURN_IF_FALSE(p_ctx);
1047 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
1048 struct stat sb;
1049 int ret=fstat(p_ctx->ts_fd,&sb);
1050 if (ret<0) {
1051 return -1;
1052 }
1053 return sb.st_size;
1054}
1055
1056uint64_t segment_get_cur_segment_id(Segment_Handle_t handle)
1057{
1058 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1059 DVR_RETURN_IF_FALSE(p_ctx);
1060 return p_ctx->segment_id;
1061}
1062