blob: 347b2585381a863432d92a191710c09f30904da1 [file] [log] [blame]
Pengfei Liuc181a982020-01-07 19:27:13 +08001#include <stdio.h>
Pengfei Liub038b6a2020-01-14 15:57:01 +08002#include <unistd.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08003#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <string.h>
Pengfei Liub038b6a2020-01-14 15:57:01 +08007#include <stdlib.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08008#include <errno.h>
Pengfei Liu47ed6c92020-01-17 11:23:41 +08009#include "dvr_types.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080010#include "segment.h"
11
12#define MAX_SEGMENT_FD_COUNT (128)
13#define MAX_SEGMENT_PATH_SIZE (DVR_MAX_LOCATION_SIZE + 32)
Pengfei Liub038b6a2020-01-14 15:57:01 +080014#define MAX_PTS_THRESHOLD (10*1000)
hualing chen06209692020-11-05 14:51:46 +080015#define PCR_RECORD_INTERVAL_MS (300)
Wentao MA270dc0f2022-08-23 13:17:26 +080016#define PTS_DISCONTINUED_DEVIATION (40)
hualing chen2932d372020-04-29 13:44:00 +080017#define PTS_HEAD_DEVIATION (40)
hualing chen86b8e602021-12-23 11:04:19 +080018#define PCR_JUMP_DUR (5000)
hualing chen2932d372020-04-29 13:44:00 +080019
hualing chen157641d2022-02-22 17:54:52 +080020#define IDX_FILE_SYNC_TIME (10)//10*PCR_RECORD_INTERVAL_MS
21#define TS_FILE_SYNC_TIME (9)//9*PCR_RECORD_INTERVAL_MS
22
hualing chen2932d372020-04-29 13:44:00 +080023
Pengfei Liub4734232020-01-17 18:25:10 +080024/**\brief Segment context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080025typedef struct {
Pengfei Liu3b1a8202020-02-12 23:04:21 +080026 int ts_fd; /**< Segment ts file fd*/
Pengfei Liub4734232020-01-17 18:25:10 +080027 FILE *index_fp; /**< Time index file fd*/
28 FILE *dat_fp; /**< Information file fd*/
hualing chenb9a02922021-12-14 11:29:47 +080029 FILE *all_dat_fp; /**< Information file fd*/
Wentao MA270dc0f2022-08-23 13:17:26 +080030 FILE *ongoing_fp; /**< Ongoing file fd, used to verify timeshift mode*/
Pengfei Liub4734232020-01-17 18:25:10 +080031 uint64_t first_pts; /**< First pts value, use for write mode*/
pengfei.liu567d6d82020-04-17 16:48:59 +080032 uint64_t last_pts; /**< Last input pts value, use for write mode*/
33 uint64_t last_record_pts; /**< Last record pts value, use for write mode*/
pengfei.liuab5a2262020-02-14 17:33:40 +080034 uint64_t cur_time; /**< Current time save in index file */
pengfei.liu567d6d82020-04-17 16:48:59 +080035 uint64_t segment_id; /**< Current segment ID */
36 char location[MAX_SEGMENT_PATH_SIZE]; /**< Current time save in index file */
hualing chena5f03222021-12-02 11:22:35 +080037 loff_t first_offset;
38 loff_t last_offset;
39 loff_t last_record_offset;
40 float avg_rate;
hualing chen157641d2022-02-22 17:54:52 +080041 int time;
wentao.ma35a69d42022-03-10 18:08:40 +080042 DVR_Bool_t force_sysclock; /**< If ture, force to use system clock as PVR index time source. If false, libdvr can determine index time source based on actual situation*/
hualing chen157641d2022-02-22 17:54:52 +080043 } Segment_Context_t;
Pengfei Liuc181a982020-01-07 19:27:13 +080044
Pengfei Liub4734232020-01-17 18:25:10 +080045/**\brief Segment file type*/
Pengfei Liuc181a982020-01-07 19:27:13 +080046typedef enum {
Pengfei Liub4734232020-01-17 18:25:10 +080047 SEGMENT_FILE_TYPE_TS, /**< Used for store TS data*/
48 SEGMENT_FILE_TYPE_INDEX, /**< Used for store index data*/
49 SEGMENT_FILE_TYPE_DAT, /**< Used for store information data, such as duration etc*/
pengfei.liu567d6d82020-04-17 16:48:59 +080050 SEGMENT_FILE_TYPE_ONGOING, /**< Used for store information data, such as duration etc*/
Wentao MA9a164002022-08-29 11:20:24 +080051 SEGMENT_FILE_TYPE_ALL_DATA, /**< Used for store all information data*/
Pengfei Liuc181a982020-01-07 19:27:13 +080052} Segment_FileType_t;
53
54static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
Pengfei Liub4734232020-01-17 18:25:10 +080055 const char location[DVR_MAX_LOCATION_SIZE],
Pengfei Liuc181a982020-01-07 19:27:13 +080056 uint64_t segment_id,
57 Segment_FileType_t type)
58{
59 int offset;
60
61 memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
62 strncpy(fname, location, strlen(location));
63 offset = strlen(location);
Wentao MAe88ad702022-09-02 10:35:00 +080064
65 DVR_ASSERT(offset + DVR_MAX_LOCATION_SIZE < MAX_SEGMENT_PATH_SIZE);
66
Wentao MA9a164002022-08-29 11:20:24 +080067 if (type != SEGMENT_FILE_TYPE_ALL_DATA) {
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);
151 p_ctx = NULL;
Wentao MAb2070812022-09-02 13:10:03 +0800152 return DVR_FAILURE;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800153 }
154
Pengfei Liuc181a982020-01-07 19:27:13 +0800155 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800156 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800157 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800158 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800159 p_ctx->ongoing_fp = NULL;
hualing chenb9a02922021-12-14 11:29:47 +0800160 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
Pengfei Liuc181a982020-01-07 19:27:13 +0800161 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800162 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800163 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800164 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chenb9a02922021-12-14 11:29:47 +0800165 p_ctx->all_dat_fp = fopen(all_dat_fname, "a+");
Wentao MA96f68962022-06-15 19:45:35 +0800166 DVR_INFO("%s dir %s is opened", __func__, all_dat_fname);
hualing chen87072a82020-03-12 16:20:12 +0800167 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800168 p_ctx->first_pts = ULLONG_MAX;
169 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800170 p_ctx->last_record_pts = ULLONG_MAX;
hualing chena5f03222021-12-02 11:22:35 +0800171 p_ctx->avg_rate = 0.0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800172 } else {
Wentao MA9a164002022-08-29 11:20:24 +0800173 DVR_INFO("%s, unknown mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800174 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800175 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800176 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chenb9a02922021-12-14 11:29:47 +0800177 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800178 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800179 }
180
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800181 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800182 DVR_INFO("%s open file failed [%s, %s, %s], reason:%s", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800183 ts_fname, index_fname, dat_fname, strerror(errno));
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800184 if (p_ctx->ts_fd != -1)
185 close(p_ctx->ts_fd);
186 if (p_ctx->index_fp)
187 fclose(p_ctx->index_fp);
188 if (p_ctx->dat_fp)
189 fclose(p_ctx->dat_fp);
hualing chen926a8ec2021-12-20 20:38:24 +0800190 if (p_ctx->all_dat_fp)
191 fclose(p_ctx->all_dat_fp);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800192 if (p_ctx->ongoing_fp)
193 fclose(p_ctx->ongoing_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800194 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800195 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800196 return DVR_FAILURE;
197 }
hualing chen87072a82020-03-12 16:20:12 +0800198 p_ctx->segment_id = params->segment_id;
wentao.maf57dd232022-10-08 16:07:29 +0800199 strncpy(p_ctx->location, params->location, strlen(params->location)+1);
wentao.ma35a69d42022-03-10 18:08:40 +0800200 p_ctx->force_sysclock = params->force_sysclock;
Pengfei Liub4734232020-01-17 18:25:10 +0800201
Wentao MA96f68962022-06-15 19:45:35 +0800202 //DVR_INFO("%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800203 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800204 return DVR_SUCCESS;
205}
206
207int segment_close(Segment_Handle_t handle)
208{
209 Segment_Context_t *p_ctx;
210
Pengfei Liub038b6a2020-01-14 15:57:01 +0800211 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800212 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800213
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800214 if (p_ctx->ts_fd != -1) {
215 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800216 }
217
218 if (p_ctx->index_fp) {
219 fclose(p_ctx->index_fp);
220 }
221
Pengfei Liub4734232020-01-17 18:25:10 +0800222 if (p_ctx->dat_fp) {
223 fclose(p_ctx->dat_fp);
224 }
hualing chen926a8ec2021-12-20 20:38:24 +0800225 if (p_ctx->all_dat_fp) {
226 fclose(p_ctx->all_dat_fp);
227 }
hualing chen87072a82020-03-12 16:20:12 +0800228 if (p_ctx->ongoing_fp != NULL) {
229 fclose(p_ctx->ongoing_fp);
230 char going_name[MAX_SEGMENT_PATH_SIZE];
231 memset(going_name, 0, sizeof(going_name));
232 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
Wentao MA96f68962022-06-15 19:45:35 +0800233 DVR_INFO("segment close del [%s]", going_name);
hualing chen87072a82020-03-12 16:20:12 +0800234 unlink(going_name);
235 }
236
Pengfei Liuc181a982020-01-07 19:27:13 +0800237 free(p_ctx);
238 return 0;
239}
240
241ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
242{
243 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800244 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800245 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800246 DVR_RETURN_IF_FALSE(p_ctx);
247 DVR_RETURN_IF_FALSE(buf);
248 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800249 len = read(p_ctx->ts_fd, buf, count);
250 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800251}
252
253ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
254{
255 Segment_Context_t *p_ctx;
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800256 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800257 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800258 DVR_RETURN_IF_FALSE(p_ctx);
259 DVR_RETURN_IF_FALSE(buf);
260 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800261 len = write(p_ctx->ts_fd, buf, count);
hualing chen157641d2022-02-22 17:54:52 +0800262 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);
311 fsync(fileno(p_ctx->index_fp));
312 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
384 if ((p_ctx->time > 0 && p_ctx->time % IDX_FILE_SYNC_TIME == 0))
385 fsync(fileno(p_ctx->index_fp));
386 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));
Wentao MA96f68962022-06-15 19:45:35 +0800692 DVR_INFO("duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800693 sprintf(buf, "duration=%ld\n", p_info->duration);
694 fputs(buf, p_ctx->dat_fp);
695
696 /*Save segment size*/
697 memset(buf, 0, sizeof(buf));
698 sprintf(buf, "size=%zu\n", p_info->size);
699 fputs(buf, p_ctx->dat_fp);
700
701 /*Save number of packets*/
702 memset(buf, 0, sizeof(buf));
703 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
704 fputs(buf, p_ctx->dat_fp);
705
706 fflush(p_ctx->dat_fp);
hualing chen47c34bc2020-05-11 09:15:47 +0800707 fsync(fileno(p_ctx->dat_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800708 return DVR_SUCCESS;
709}
710
pengfei.liuab5a2262020-02-14 17:33:40 +0800711/* Should consider the case of cut power, todo... */
hualing chenb9a02922021-12-14 11:29:47 +0800712int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
713{
714 Segment_Context_t *p_ctx;
715 char buf[256];
716 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800717 int ret = 0;
hualing chenb9a02922021-12-14 11:29:47 +0800718
719 p_ctx = (Segment_Context_t *)handle;
720 DVR_RETURN_IF_FALSE(p_ctx);
721 DVR_RETURN_IF_FALSE(p_ctx->all_dat_fp);
722 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800723
724 //seek to end to append info
725 ret = fseek(p_ctx->all_dat_fp, 0, SEEK_END);
726 DVR_RETURN_IF_FALSE(ret != -1);
hualing chenb9a02922021-12-14 11:29:47 +0800727
728 /*Save segment id*/
729 memset(buf, 0, sizeof(buf));
730 sprintf(buf, "id=%lld\n", p_info->id);
731 fputs(buf, p_ctx->all_dat_fp);
732
733 /*Save number of pids*/
734 memset(buf, 0, sizeof(buf));
735 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
736 fputs(buf, p_ctx->all_dat_fp);
737
738 /*Save pid information*/
739 for (i = 0; i < p_info->nb_pids; i++) {
740 memset(buf, 0, sizeof(buf));
741 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
742 fputs(buf, p_ctx->all_dat_fp);
743 }
744
745 /*Save segment duration*/
746 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800747 DVR_INFO("duration store:[%ld]", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800748 sprintf(buf, "duration=%ld\n", p_info->duration);
749 fputs(buf, p_ctx->all_dat_fp);
750
751 /*Save segment size*/
752 memset(buf, 0, sizeof(buf));
753 sprintf(buf, "size=%zu\n", p_info->size);
754 fputs(buf, p_ctx->all_dat_fp);
755
756 /*Save number of packets*/
757 memset(buf, 0, sizeof(buf));
758 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
759 fputs(buf, p_ctx->all_dat_fp);
760
761 fflush(p_ctx->all_dat_fp);
762 fsync(fileno(p_ctx->all_dat_fp));
763 return DVR_SUCCESS;
764}
765
766/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800767int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
768{
769 Segment_Context_t *p_ctx;
770 uint32_t i;
771 char buf[256];
772 char value[256];
773 char *p1, *p2;
774
775 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800776 DVR_RETURN_IF_FALSE(p_ctx);
777 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800778
779 /*Load segment id*/
780 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800781 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800782 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800783 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800784 p_info->id = strtoull(p1 + 3, NULL, 10);
785
786 /*Save number of pids*/
787 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800788 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800789 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800790 DVR_RETURN_IF_FALSE(p1);
Wentao MAb2070812022-09-02 13:10:03 +0800791 p_info->nb_pids = strtoul(p1 + 8, NULL, 10);
Pengfei Liub4734232020-01-17 18:25:10 +0800792
793 /*Save pid information*/
wentao.maf57dd232022-10-08 16:07:29 +0800794
795 // Tainted data issue originating from fgets seem false positive, so we
796 // just suppress it here.
797 // coverity[tainted_data]
Pengfei Liub4734232020-01-17 18:25:10 +0800798 for (i = 0; i < p_info->nb_pids; i++) {
799 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800800 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800801 memset(value, 0, sizeof(value));
802 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800803 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800804 p1 += 4;
805 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800806 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800807 memcpy(value, p1, p2 - p1);
808 }
809 p_info->pids[i].pid = strtoull(value, NULL, 10);
810 }
811
812 memset(value, 0, sizeof(value));
813 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800814 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800815 p1 += 5;
816 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800817 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800818 memcpy(value, p1, p2 - p1);
819 }
820 p_info->pids[i].type = strtoull(value, NULL, 10);
821 }
822 }
823
824 /*Save segment duration*/
825 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800826 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800827 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800828 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800829 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800830 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800831
832 /*Save segment size*/
833 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800834 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800835 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800836 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800837 p_info->size = strtoull(p1 + 5, NULL, 10);
838
839 /*Save number of packets*/
840 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800841 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800842 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800843 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800844 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
845
846 return DVR_SUCCESS;
847}
848
hualing chenb9a02922021-12-14 11:29:47 +0800849/* Should consider the case of cut power, todo... */
850int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
851{
852 Segment_Context_t *p_ctx;
853 uint32_t i;
854 char buf[256];
855 char value[256];
856 char *p1, *p2;
857
858 p_ctx = (Segment_Context_t *)handle;
859 DVR_RETURN_IF_FALSE(p_ctx);
860 DVR_RETURN_IF_FALSE(list);
hualing chen926a8ec2021-12-20 20:38:24 +0800861 if (p_ctx->all_dat_fp == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800862 DVR_INFO("all dat file not open\n");
hualing chen926a8ec2021-12-20 20:38:24 +0800863 return DVR_FAILURE;
864 }
hualing chenb9a02922021-12-14 11:29:47 +0800865 //first get
866 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
867 DVR_RETURN_IF_FALSE(p1);
868
869 do {
870
871 DVR_RecordSegmentInfo_t *p_info;
872
873 p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
874 memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
875
876 list_add_tail(&p_info->head, list);
877
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