blob: 978c117a349ef8284a3a04969ce6ce884f0e8fee [file] [log] [blame]
Pengfei Liuc181a982020-01-07 19:27:13 +08001#include <stdio.h>
Pengfei Liub038b6a2020-01-14 15:57:01 +08002#include <unistd.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08003#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <string.h>
Pengfei Liub038b6a2020-01-14 15:57:01 +08007#include <stdlib.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08008#include <errno.h>
Pengfei Liu47ed6c92020-01-17 11:23:41 +08009#include "dvr_types.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080010#include "segment.h"
11
12#define MAX_SEGMENT_FD_COUNT (128)
13#define MAX_SEGMENT_PATH_SIZE (DVR_MAX_LOCATION_SIZE + 32)
Pengfei Liub038b6a2020-01-14 15:57:01 +080014#define MAX_PTS_THRESHOLD (10*1000)
hualing chen06209692020-11-05 14:51:46 +080015#define PCR_RECORD_INTERVAL_MS (300)
Wentao MA270dc0f2022-08-23 13:17:26 +080016#define PTS_DISCONTINUED_DEVIATION (40)
hualing chen2932d372020-04-29 13:44:00 +080017#define PTS_HEAD_DEVIATION (40)
hualing chen86b8e602021-12-23 11:04:19 +080018#define PCR_JUMP_DUR (5000)
hualing chen2932d372020-04-29 13:44:00 +080019
hualing chen157641d2022-02-22 17:54:52 +080020#define IDX_FILE_SYNC_TIME (10)//10*PCR_RECORD_INTERVAL_MS
21#define TS_FILE_SYNC_TIME (9)//9*PCR_RECORD_INTERVAL_MS
22
hualing chen2932d372020-04-29 13:44:00 +080023
Pengfei Liub4734232020-01-17 18:25:10 +080024/**\brief Segment context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080025typedef struct {
Pengfei Liu3b1a8202020-02-12 23:04:21 +080026 int ts_fd; /**< Segment ts file fd*/
Pengfei Liub4734232020-01-17 18:25:10 +080027 FILE *index_fp; /**< Time index file fd*/
28 FILE *dat_fp; /**< Information file fd*/
hualing chenb9a02922021-12-14 11:29:47 +080029 FILE *all_dat_fp; /**< Information file fd*/
Wentao MA270dc0f2022-08-23 13:17:26 +080030 FILE *ongoing_fp; /**< Ongoing file fd, used to verify timeshift mode*/
Pengfei Liub4734232020-01-17 18:25:10 +080031 uint64_t first_pts; /**< First pts value, use for write mode*/
pengfei.liu567d6d82020-04-17 16:48:59 +080032 uint64_t last_pts; /**< Last input pts value, use for write mode*/
33 uint64_t last_record_pts; /**< Last record pts value, use for write mode*/
pengfei.liuab5a2262020-02-14 17:33:40 +080034 uint64_t cur_time; /**< Current time save in index file */
pengfei.liu567d6d82020-04-17 16:48:59 +080035 uint64_t segment_id; /**< Current segment ID */
36 char location[MAX_SEGMENT_PATH_SIZE]; /**< Current time save in index file */
hualing chena5f03222021-12-02 11:22:35 +080037 loff_t first_offset;
38 loff_t last_offset;
39 loff_t last_record_offset;
40 float avg_rate;
hualing chen157641d2022-02-22 17:54:52 +080041 int time;
wentao.ma35a69d42022-03-10 18:08:40 +080042 DVR_Bool_t force_sysclock; /**< If ture, force to use system clock as PVR index time source. If false, libdvr can determine index time source based on actual situation*/
hualing chen157641d2022-02-22 17:54:52 +080043 } Segment_Context_t;
Pengfei Liuc181a982020-01-07 19:27:13 +080044
Pengfei Liub4734232020-01-17 18:25:10 +080045/**\brief Segment file type*/
Pengfei Liuc181a982020-01-07 19:27:13 +080046typedef enum {
Pengfei Liub4734232020-01-17 18:25:10 +080047 SEGMENT_FILE_TYPE_TS, /**< Used for store TS data*/
48 SEGMENT_FILE_TYPE_INDEX, /**< Used for store index data*/
49 SEGMENT_FILE_TYPE_DAT, /**< Used for store information data, such as duration etc*/
pengfei.liu567d6d82020-04-17 16:48:59 +080050 SEGMENT_FILE_TYPE_ONGOING, /**< Used for store information data, such as duration etc*/
Wentao MA9a164002022-08-29 11:20:24 +080051 SEGMENT_FILE_TYPE_ALL_DATA, /**< Used for store all information data*/
Pengfei Liuc181a982020-01-07 19:27:13 +080052} Segment_FileType_t;
53
54static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
Pengfei Liub4734232020-01-17 18:25:10 +080055 const char location[DVR_MAX_LOCATION_SIZE],
Pengfei Liuc181a982020-01-07 19:27:13 +080056 uint64_t segment_id,
57 Segment_FileType_t type)
58{
59 int offset;
60
61 memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
62 strncpy(fname, location, strlen(location));
63 offset = strlen(location);
Wentao MAe88ad702022-09-02 10:35:00 +080064
65 DVR_ASSERT(offset + DVR_MAX_LOCATION_SIZE < MAX_SEGMENT_PATH_SIZE);
66
Wentao MA9a164002022-08-29 11:20:24 +080067 if (type != SEGMENT_FILE_TYPE_ALL_DATA) {
hualing chenb9a02922021-12-14 11:29:47 +080068 strncpy(fname + offset, "-", 1);
69 offset += 1;
70 sprintf(fname + offset, "%04llu", segment_id);
Wentao MAbcbc0c82022-06-28 11:24:56 +080071 offset += strlen(fname + offset);
hualing chenb9a02922021-12-14 11:29:47 +080072 }
73
Pengfei Liuc181a982020-01-07 19:27:13 +080074 if (type == SEGMENT_FILE_TYPE_TS)
75 strncpy(fname + offset, ".ts", 3);
76 else if (type == SEGMENT_FILE_TYPE_INDEX)
77 strncpy(fname + offset, ".idx", 4);
Pengfei Liub4734232020-01-17 18:25:10 +080078 else if (type == SEGMENT_FILE_TYPE_DAT)
79 strncpy(fname + offset, ".dat", 4);
hualing chen87072a82020-03-12 16:20:12 +080080 else if (type == SEGMENT_FILE_TYPE_ONGOING)
81 strncpy(fname + offset, ".going", 6);
Wentao MA9a164002022-08-29 11:20:24 +080082 else if (type == SEGMENT_FILE_TYPE_ALL_DATA)
hualing chenb9a02922021-12-14 11:29:47 +080083 strncpy(fname + offset, ".dat", 4);
84
Pengfei Liuc181a982020-01-07 19:27:13 +080085}
86
Pengfei Liu3b1a8202020-02-12 23:04:21 +080087static void segment_get_dirname(char dir_name[MAX_SEGMENT_PATH_SIZE],
88 const char location[DVR_MAX_LOCATION_SIZE])
89{
90 char *p;
91 int i;
92 int found = 0;
93
94 for (i = 0; i < (int)strlen(location); i++) {
95 if (location[i] == '/') {
96 p = (char *)location + i;
97 found = 1;
98 }
99 }
100 if (found)
101 memcpy(dir_name, location, p - location);
102}
103
Pengfei Liuc181a982020-01-07 19:27:13 +0800104int segment_open(Segment_OpenParams_t *params, Segment_Handle_t *p_handle)
105{
106 Segment_Context_t *p_ctx;
107 char ts_fname[MAX_SEGMENT_PATH_SIZE];
108 char index_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liub4734232020-01-17 18:25:10 +0800109 char dat_fname[MAX_SEGMENT_PATH_SIZE];
hualing chenb9a02922021-12-14 11:29:47 +0800110 char all_dat_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800111 char dir_name[MAX_SEGMENT_PATH_SIZE];
hualing chen87072a82020-03-12 16:20:12 +0800112 char going_name[MAX_SEGMENT_PATH_SIZE];
Pengfei Liuc181a982020-01-07 19:27:13 +0800113
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800114 DVR_RETURN_IF_FALSE(params);
115 DVR_RETURN_IF_FALSE(p_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800116
Wentao MA96f68962022-06-15 19:45:35 +0800117 //DVR_INFO("%s, location:%s, id:%llu", __func__, params->location, params->segment_id);
Pengfei Liuc181a982020-01-07 19:27:13 +0800118
Pengfei Liub038b6a2020-01-14 15:57:01 +0800119 p_ctx = (void*)malloc(sizeof(Segment_Context_t));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800120 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800121 memset(p_ctx, 0, sizeof(Segment_Context_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800122
123 memset(ts_fname, 0, sizeof(ts_fname));
124 segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
125
126 memset(index_fname, 0, sizeof(index_fname));
127 segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
128
Pengfei Liub4734232020-01-17 18:25:10 +0800129 memset(dat_fname, 0, sizeof(dat_fname));
130 segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
131
hualing chenb9a02922021-12-14 11:29:47 +0800132 memset(all_dat_fname, 0, sizeof(all_dat_fname));
Wentao MA9a164002022-08-29 11:20:24 +0800133 segment_get_fname(all_dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_ALL_DATA);
hualing chenb9a02922021-12-14 11:29:47 +0800134
135
hualing chen87072a82020-03-12 16:20:12 +0800136 memset(going_name, 0, sizeof(going_name));
137 segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
138
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800139 memset(dir_name, 0, sizeof(dir_name));
140 segment_get_dirname(dir_name, params->location);
141 if (access(dir_name, F_OK) == -1) {
Wentao MAa3388532022-08-18 15:07:07 +0800142 DVR_WARN("%s dir %s does not exist, so create it", __func__, dir_name);
143 if (mkdir(dir_name, 0666) < 0) {
144 DVR_ERROR("%s fails to create dir %s. errno:%d(%s)", __func__,
145 dir_name,errno,strerror(errno));
146 return DVR_FAILURE;
147 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800148 }
149
Pengfei Liuc181a982020-01-07 19:27:13 +0800150 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800151 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800152 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800153 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800154 p_ctx->ongoing_fp = NULL;
hualing chenb9a02922021-12-14 11:29:47 +0800155 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
Pengfei Liuc181a982020-01-07 19:27:13 +0800156 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800157 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800158 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800159 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chenb9a02922021-12-14 11:29:47 +0800160 p_ctx->all_dat_fp = fopen(all_dat_fname, "a+");
Wentao MA96f68962022-06-15 19:45:35 +0800161 DVR_INFO("%s dir %s is opened", __func__, all_dat_fname);
hualing chen87072a82020-03-12 16:20:12 +0800162 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800163 p_ctx->first_pts = ULLONG_MAX;
164 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800165 p_ctx->last_record_pts = ULLONG_MAX;
hualing chena5f03222021-12-02 11:22:35 +0800166 p_ctx->avg_rate = 0.0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800167 } else {
Wentao MA9a164002022-08-29 11:20:24 +0800168 DVR_INFO("%s, unknown mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800169 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800170 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800171 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chenb9a02922021-12-14 11:29:47 +0800172 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800173 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800174 }
175
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800176 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800177 DVR_INFO("%s open file failed [%s, %s, %s], reason:%s", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800178 ts_fname, index_fname, dat_fname, strerror(errno));
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800179 if (p_ctx->ts_fd != -1)
180 close(p_ctx->ts_fd);
181 if (p_ctx->index_fp)
182 fclose(p_ctx->index_fp);
183 if (p_ctx->dat_fp)
184 fclose(p_ctx->dat_fp);
hualing chen926a8ec2021-12-20 20:38:24 +0800185 if (p_ctx->all_dat_fp)
186 fclose(p_ctx->all_dat_fp);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800187 if (p_ctx->ongoing_fp)
188 fclose(p_ctx->ongoing_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800189 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800190 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800191 return DVR_FAILURE;
192 }
hualing chen87072a82020-03-12 16:20:12 +0800193 p_ctx->segment_id = params->segment_id;
194 strncpy(p_ctx->location, params->location, strlen(params->location));
wentao.ma35a69d42022-03-10 18:08:40 +0800195 p_ctx->force_sysclock = params->force_sysclock;
Pengfei Liub4734232020-01-17 18:25:10 +0800196
Wentao MA96f68962022-06-15 19:45:35 +0800197 //DVR_INFO("%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800198 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800199 return DVR_SUCCESS;
200}
201
202int segment_close(Segment_Handle_t handle)
203{
204 Segment_Context_t *p_ctx;
205
Pengfei Liub038b6a2020-01-14 15:57:01 +0800206 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800207 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800208
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800209 if (p_ctx->ts_fd != -1) {
210 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800211 }
212
213 if (p_ctx->index_fp) {
214 fclose(p_ctx->index_fp);
215 }
216
Pengfei Liub4734232020-01-17 18:25:10 +0800217 if (p_ctx->dat_fp) {
218 fclose(p_ctx->dat_fp);
219 }
hualing chen926a8ec2021-12-20 20:38:24 +0800220 if (p_ctx->all_dat_fp) {
221 fclose(p_ctx->all_dat_fp);
222 }
hualing chen87072a82020-03-12 16:20:12 +0800223 if (p_ctx->ongoing_fp != NULL) {
224 fclose(p_ctx->ongoing_fp);
225 char going_name[MAX_SEGMENT_PATH_SIZE];
226 memset(going_name, 0, sizeof(going_name));
227 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
Wentao MA96f68962022-06-15 19:45:35 +0800228 DVR_INFO("segment close del [%s]", going_name);
hualing chen87072a82020-03-12 16:20:12 +0800229 unlink(going_name);
230 }
231
Pengfei Liuc181a982020-01-07 19:27:13 +0800232 free(p_ctx);
233 return 0;
234}
235
236ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
237{
238 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800239 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800240 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800241 DVR_RETURN_IF_FALSE(p_ctx);
242 DVR_RETURN_IF_FALSE(buf);
243 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800244 len = read(p_ctx->ts_fd, buf, count);
245 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800246}
247
248ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
249{
250 Segment_Context_t *p_ctx;
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800251 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800252 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800253 DVR_RETURN_IF_FALSE(p_ctx);
254 DVR_RETURN_IF_FALSE(buf);
255 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800256 len = write(p_ctx->ts_fd, buf, count);
hualing chen157641d2022-02-22 17:54:52 +0800257 if (p_ctx->time % TS_FILE_SYNC_TIME == 0)
258 fsync(p_ctx->ts_fd);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800259 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800260}
261
hualing chen2932d372020-04-29 13:44:00 +0800262int segment_update_pts_force(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800263{
264 Segment_Context_t *p_ctx;
265 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800266 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800267
268 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800269 DVR_RETURN_IF_FALSE(p_ctx);
270 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800271
Pengfei Liub038b6a2020-01-14 15:57:01 +0800272 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800273 DVR_INFO("%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800274 p_ctx->first_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800275 p_ctx->first_offset = offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800276 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800277 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800278 if (p_ctx->last_pts == ULLONG_MAX) {
279 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800280 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800281 p_ctx->cur_time = pts - p_ctx->first_pts;
Wentao MA96f68962022-06-15 19:45:35 +0800282 DVR_INFO("%s force pcr:%llu -1", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800283 } else {
284 /*Last pts has valid value*/
285 int diff = pts - p_ctx->last_pts;
286 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
287 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800288 DVR_INFO("[%s]force update Current pts has a transition, [%llu, %llu, %llu]",__func__,
hualing chen2932d372020-04-29 13:44:00 +0800289 p_ctx->first_pts, p_ctx->last_pts, pts);
290 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
291 } else {
292 /*This is a normal pts, record it*/
hualing chena5f03222021-12-02 11:22:35 +0800293 //check if this pcr is transition.if true,add 200ms
294 //other case normal.
hualing chen2932d372020-04-29 13:44:00 +0800295 p_ctx->cur_time += diff;
Wentao MA96f68962022-06-15 19:45:35 +0800296 DVR_INFO("%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
hualing chen2932d372020-04-29 13:44:00 +0800297 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
298 }
299 }
300
301 record_diff = pts - p_ctx->last_record_pts;
302 if (strlen(buf) > 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800303 DVR_INFO("%s force pcr:%llu buf:%s", __func__, pts, buf);
hualing chen2932d372020-04-29 13:44:00 +0800304 fputs(buf, p_ctx->index_fp);
305 fflush(p_ctx->index_fp);
306 fsync(fileno(p_ctx->index_fp));
307 p_ctx->last_record_pts = pts;
308 }
309 p_ctx->last_pts = pts;
hualing chen2932d372020-04-29 13:44:00 +0800310 return DVR_SUCCESS;
311}
312
313int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
314{
315 Segment_Context_t *p_ctx;
316 char buf[256];
317 int record_diff = 0;
318
319 p_ctx = (Segment_Context_t *)handle;
320 DVR_RETURN_IF_FALSE(p_ctx);
321 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
322
323 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800324 DVR_INFO("%s first pcr:%llu", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800325 p_ctx->first_pts = pts;
326 //p_ctx->cur_time = p_ctx->cur_time + PTS_HEAD_DEVIATION;
327 }
328 memset(buf, 0, sizeof(buf));
329 if (p_ctx->last_pts == ULLONG_MAX) {
330 /*Last pts is init value*/
331 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
332 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800333 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800334 if (!p_ctx->force_sysclock) {
335 /* if force_sysclock is off, we follow old manner. Please refer to
336 * SWPL-75327*/
337 /*Last pts has valid value*/
338 int diff = pts - p_ctx->last_pts;
339 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
340 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800341 DVR_INFO("Current pts has a transition, [%llu, %llu, %llu]",
wentao.ma35a69d42022-03-10 18:08:40 +0800342 p_ctx->first_pts, p_ctx->last_pts, pts);
343 p_ctx->last_record_pts = pts;
Wentao MA270dc0f2022-08-23 13:17:26 +0800344 //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINUED_DEVIATION;
hualing chena5f03222021-12-02 11:22:35 +0800345 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800346 /*This is a normal pts, record it*/
347 loff_t off_diff = offset - p_ctx->last_offset;
348 float rate = (float) (off_diff) / (float)(diff);
349 if (p_ctx->avg_rate == 0.0) {
350 p_ctx->avg_rate = (float) offset / (float)(p_ctx->cur_time + diff);
351 }
352 if (diff >= PCR_JUMP_DUR) {
Wentao MA96f68962022-06-15 19:45:35 +0800353 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 +0800354 if (p_ctx->avg_rate != 0 && (int)(p_ctx->avg_rate) >= (int)(rate * 4)) {
355 diff = off_diff / p_ctx->avg_rate;
356 p_ctx->cur_time += diff;
357 } else {
358 p_ctx->cur_time += diff;
359 }
360 } else {
361 p_ctx->cur_time += diff;
362 }
hualing chena5f03222021-12-02 11:22:35 +0800363 }
wentao.ma35a69d42022-03-10 18:08:40 +0800364 } else {
365 /* if force_sysclock is on, we simply calculate cur_time based on system
366 * time. Please refer to SWPL-75327*/
367 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800368 }
wentao.ma35a69d42022-03-10 18:08:40 +0800369 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800370 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800371
372 record_diff = pts - p_ctx->last_record_pts;
373 if (strlen(buf) > 0 &&
374 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800375 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800376 fflush(p_ctx->index_fp);
hualing chen157641d2022-02-22 17:54:52 +0800377 p_ctx->time++;
378 //flush idx file 3s
379 if ((p_ctx->time > 0 && p_ctx->time % IDX_FILE_SYNC_TIME == 0))
380 fsync(fileno(p_ctx->index_fp));
381 if (p_ctx->time > IDX_FILE_SYNC_TIME)
382 p_ctx->time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800383 p_ctx->last_record_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800384 p_ctx->last_record_offset = offset;
385 if (p_ctx->cur_time > 0)
386 p_ctx->avg_rate = (float) offset / (float)p_ctx->cur_time;
pengfei.liu567d6d82020-04-17 16:48:59 +0800387 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800388 p_ctx->last_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800389 p_ctx->last_offset = offset;
Pengfei Liuc181a982020-01-07 19:27:13 +0800390 return DVR_SUCCESS;
391}
392
hualing chen266b9502020-04-04 17:39:39 +0800393loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800394{
395 Segment_Context_t *p_ctx;
396 char buf[256];
397 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800398 uint64_t pts = 0L;
399 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800400 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800401 int ret = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800402
Wentao MA96f68962022-06-15 19:45:35 +0800403 DVR_INFO("into seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chen8a657f32021-08-30 13:12:49 +0800404
Pengfei Liuc181a982020-01-07 19:27:13 +0800405 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800406 DVR_RETURN_IF_FALSE(p_ctx);
407 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
408 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800409
hualing chen266b9502020-04-04 17:39:39 +0800410 if (time == 0) {
411 offset = 0;
Wentao MA96f68962022-06-15 19:45:35 +0800412 DVR_INFO("seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chend241c7a2021-06-22 13:34:27 +0800413 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen266b9502020-04-04 17:39:39 +0800414 return offset;
415 }
416
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800417 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800418 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
419 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800420 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800421 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800422 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800423 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800424 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800425 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800426 if ((p2 = strstr(buf, ","))) {
427 memcpy(value, p1, p2 - p1);
428 }
429 pts = strtoull(value, NULL, 10);
430 }
431
432 memset(value, 0, sizeof(value));
433 if ((p1 = strstr(buf, "offset="))) {
434 p1 += 7;
435 if ((p2 = strstr(buf, "}"))) {
436 memcpy(value, p1, p2 - p1);
437 }
438 offset = strtoull(value, NULL, 10);
439 }
hualing chen2aba4022020-03-02 13:49:55 +0800440 if (0)
441 {
Wentao MA96f68962022-06-15 19:45:35 +0800442 DVR_INFO("seek buf[%s]", buf);
443 DVR_INFO("seek time=%llu, offset=%lld\n", pts, offset);
hualing chen2aba4022020-03-02 13:49:55 +0800444 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800445 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800446 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800447 if (block_size > 0) {
448 offset = offset - offset%block_size;
449 }
Wentao MA96f68962022-06-15 19:45:35 +0800450 //DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800451 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800452 return offset;
453 }
hualing chen2aba4022020-03-02 13:49:55 +0800454 }
hualing chen2932d372020-04-29 13:44:00 +0800455 if (time > pts) {
456 if (block_size > 0) {
457 offset = offset - offset%block_size;
458 }
Wentao MA96f68962022-06-15 19:45:35 +0800459 DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d end\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800460 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen2932d372020-04-29 13:44:00 +0800461 return offset;
462 }
Wentao MA96f68962022-06-15 19:45:35 +0800463 DVR_INFO("seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800464 return DVR_FAILURE;
465}
466
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800467loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800468{
469 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800470 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800471 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800472 DVR_RETURN_IF_FALSE(p_ctx);
473 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800474 pos = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
475 return pos;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800476}
477
Wentao MAa3388532022-08-18 15:07:07 +0800478loff_t segment_tell_position_time(Segment_Handle_t handle, loff_t position)
hualing chen5605eed2020-05-26 18:18:06 +0800479{
480 Segment_Context_t *p_ctx;
481 char buf[256];
482 char value[256];
hualing chen969fe7b2021-05-26 15:13:17 +0800483 uint64_t ret = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800484 uint64_t pts = 0L;
hualing chen969fe7b2021-05-26 15:13:17 +0800485 uint64_t pts_p = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800486 loff_t offset = 0;
hualing chen969fe7b2021-05-26 15:13:17 +0800487 loff_t offset_p = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800488 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800489 int ret2 = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800490
491 p_ctx = (Segment_Context_t *)handle;
492 DVR_RETURN_IF_FALSE(p_ctx);
493 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
494 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
495
496 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800497 ret2 = fseek(p_ctx->index_fp, 0, SEEK_SET);
498 DVR_RETURN_IF_FALSE(ret2 != -1);
hualing chen5605eed2020-05-26 18:18:06 +0800499 DVR_RETURN_IF_FALSE(position != -1);
500
501 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
502 memset(value, 0, sizeof(value));
503 if ((p1 = strstr(buf, "time="))) {
504 p1 += 5;
505 if ((p2 = strstr(buf, ","))) {
506 memcpy(value, p1, p2 - p1);
507 }
508 pts = strtoull(value, NULL, 10);
509 }
510
511 memset(value, 0, sizeof(value));
512 if ((p1 = strstr(buf, "offset="))) {
513 p1 += 7;
514 if ((p2 = strstr(buf, "}"))) {
515 memcpy(value, p1, p2 - p1);
516 }
517 offset = strtoull(value, NULL, 10);
518 }
519
520 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800521 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chend241c7a2021-06-22 13:34:27 +0800522 if (position <= offset
523 &&position >= offset_p
524 && offset - offset_p > 0) {
hualing chen969fe7b2021-05-26 15:13:17 +0800525 ret = pts_p + (pts - pts_p) * (position - offset_p) / (offset - offset_p);
Wentao MA96f68962022-06-15 19:45:35 +0800526 //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 +0800527 return ret;
hualing chen5605eed2020-05-26 18:18:06 +0800528 }
hualing chen969fe7b2021-05-26 15:13:17 +0800529 offset_p = offset;
530 pts_p = pts;
hualing chen5605eed2020-05-26 18:18:06 +0800531 }
Wentao MA96f68962022-06-15 19:45:35 +0800532 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen5605eed2020-05-26 18:18:06 +0800533 return pts;
534}
535
536
Wentao MAa3388532022-08-18 15:07:07 +0800537loff_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800538{
539 Segment_Context_t *p_ctx;
540 char buf[256];
541 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800542 uint64_t pts = 0L;
543 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800544 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800545 int ret = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800546
547 p_ctx = (Segment_Context_t *)handle;
548 DVR_RETURN_IF_FALSE(p_ctx);
549 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
550 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
551
552 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800553 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
554 DVR_RETURN_IF_FALSE(ret != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800555 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800556 DVR_RETURN_IF_FALSE(position != -1);
557
558 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
559 memset(value, 0, sizeof(value));
560 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800561 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800562 if ((p2 = strstr(buf, ","))) {
563 memcpy(value, p1, p2 - p1);
564 }
565 pts = strtoull(value, NULL, 10);
566 }
567
568 memset(value, 0, sizeof(value));
569 if ((p1 = strstr(buf, "offset="))) {
570 p1 += 7;
571 if ((p2 = strstr(buf, "}"))) {
572 memcpy(value, p1, p2 - p1);
573 }
574 offset = strtoull(value, NULL, 10);
575 }
576
577 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800578 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800579 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800580 return pts;
581 }
582 }
Wentao MA96f68962022-06-15 19:45:35 +0800583 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800584 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800585}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800586
Wentao MAa3388532022-08-18 15:07:07 +0800587loff_t segment_tell_total_time(Segment_Handle_t handle)
pengfei.liu8b563292020-02-26 15:49:02 +0800588{
589 Segment_Context_t *p_ctx;
590 char buf[256];
591 char last_buf[256];
592 char value[256];
593 uint64_t pts = ULLONG_MAX;
594 loff_t offset = 0, position = 0;
595 char *p1, *p2;
596 int line = 0;
Wentao MAa3388532022-08-18 15:07:07 +0800597 int ret = 0;
pengfei.liu8b563292020-02-26 15:49:02 +0800598
599 p_ctx = (Segment_Context_t *)handle;
600 DVR_RETURN_IF_FALSE(p_ctx);
601 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
602 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
603
604 memset(buf, 0, sizeof(buf));
605 memset(last_buf, 0, sizeof(last_buf));
hualing chend241c7a2021-06-22 13:34:27 +0800606 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
pengfei.liu8b563292020-02-26 15:49:02 +0800607 DVR_RETURN_IF_FALSE(position != -1);
608
Wentao MAa3388532022-08-18 15:07:07 +0800609 // if unable to seek from end, it is necessary to seek to file beginning position.
hualing chen041c4092020-04-05 15:11:50 +0800610 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
Wentao MAa3388532022-08-18 15:07:07 +0800611 ret = fseek(p_ctx->index_fp, 0L, SEEK_SET);
612 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen041c4092020-04-05 15:11:50 +0800613 }
pengfei.liu8b563292020-02-26 15:49:02 +0800614 /* Save last line buffer */
615 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800616 if (strlen(buf) <= 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800617 DVR_INFO("read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800618 continue;
619 }
pengfei.liu8b563292020-02-26 15:49:02 +0800620 memset(last_buf, 0, sizeof(last_buf));
621 memcpy(last_buf, buf, strlen(buf));
622 memset(buf, 0, sizeof(buf));
623 line++;
624 }
625
626 /* Extract time value */
627 memset(value, 0, sizeof(value));
628 if ((p1 = strstr(last_buf, "time="))) {
629 p1 += 5;
630 if ((p2 = strstr(last_buf, ","))) {
631 memcpy(value, p1, p2 - p1);
632 }
633 pts = strtoull(value, NULL, 10);
634 }
635
636 memset(value, 0, sizeof(value));
637 if ((p1 = strstr(last_buf, "offset="))) {
638 p1 += 7;
639 if ((p2 = strstr(last_buf, "}"))) {
640 memcpy(value, p1, p2 - p1);
641 }
642 offset = strtoull(value, NULL, 10);
643 }
hualing chen87072a82020-03-12 16:20:12 +0800644 //if (line < 2)
Wentao MA96f68962022-06-15 19:45:35 +0800645 //DVR_INFO("totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800646 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
647}
648
pengfei.liuab5a2262020-02-14 17:33:40 +0800649/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800650int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
651{
652 Segment_Context_t *p_ctx;
653 char buf[256];
654 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800655 int ret = 0;
Pengfei Liub4734232020-01-17 18:25:10 +0800656
657 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800658 DVR_RETURN_IF_FALSE(p_ctx);
659 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
660 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800661 // seek to 0 to rewrite info
662 ret = fseek(p_ctx->dat_fp, 0, SEEK_SET);
663 DVR_RETURN_IF_FALSE(ret != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800664
665 /*Save segment id*/
666 memset(buf, 0, sizeof(buf));
667 sprintf(buf, "id=%lld\n", p_info->id);
668 fputs(buf, p_ctx->dat_fp);
669
670 /*Save number of pids*/
671 memset(buf, 0, sizeof(buf));
672 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
673 fputs(buf, p_ctx->dat_fp);
674
675 /*Save pid information*/
676 for (i = 0; i < p_info->nb_pids; i++) {
677 memset(buf, 0, sizeof(buf));
678 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
679 fputs(buf, p_ctx->dat_fp);
680 }
681
682 /*Save segment duration*/
683 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800684 DVR_INFO("duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800685 sprintf(buf, "duration=%ld\n", p_info->duration);
686 fputs(buf, p_ctx->dat_fp);
687
688 /*Save segment size*/
689 memset(buf, 0, sizeof(buf));
690 sprintf(buf, "size=%zu\n", p_info->size);
691 fputs(buf, p_ctx->dat_fp);
692
693 /*Save number of packets*/
694 memset(buf, 0, sizeof(buf));
695 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
696 fputs(buf, p_ctx->dat_fp);
697
698 fflush(p_ctx->dat_fp);
hualing chen47c34bc2020-05-11 09:15:47 +0800699 fsync(fileno(p_ctx->dat_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800700 return DVR_SUCCESS;
701}
702
pengfei.liuab5a2262020-02-14 17:33:40 +0800703/* Should consider the case of cut power, todo... */
hualing chenb9a02922021-12-14 11:29:47 +0800704int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
705{
706 Segment_Context_t *p_ctx;
707 char buf[256];
708 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800709 int ret = 0;
hualing chenb9a02922021-12-14 11:29:47 +0800710
711 p_ctx = (Segment_Context_t *)handle;
712 DVR_RETURN_IF_FALSE(p_ctx);
713 DVR_RETURN_IF_FALSE(p_ctx->all_dat_fp);
714 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800715
716 //seek to end to append info
717 ret = fseek(p_ctx->all_dat_fp, 0, SEEK_END);
718 DVR_RETURN_IF_FALSE(ret != -1);
hualing chenb9a02922021-12-14 11:29:47 +0800719
720 /*Save segment id*/
721 memset(buf, 0, sizeof(buf));
722 sprintf(buf, "id=%lld\n", p_info->id);
723 fputs(buf, p_ctx->all_dat_fp);
724
725 /*Save number of pids*/
726 memset(buf, 0, sizeof(buf));
727 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
728 fputs(buf, p_ctx->all_dat_fp);
729
730 /*Save pid information*/
731 for (i = 0; i < p_info->nb_pids; i++) {
732 memset(buf, 0, sizeof(buf));
733 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
734 fputs(buf, p_ctx->all_dat_fp);
735 }
736
737 /*Save segment duration*/
738 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800739 DVR_INFO("duration store:[%ld]", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800740 sprintf(buf, "duration=%ld\n", p_info->duration);
741 fputs(buf, p_ctx->all_dat_fp);
742
743 /*Save segment size*/
744 memset(buf, 0, sizeof(buf));
745 sprintf(buf, "size=%zu\n", p_info->size);
746 fputs(buf, p_ctx->all_dat_fp);
747
748 /*Save number of packets*/
749 memset(buf, 0, sizeof(buf));
750 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
751 fputs(buf, p_ctx->all_dat_fp);
752
753 fflush(p_ctx->all_dat_fp);
754 fsync(fileno(p_ctx->all_dat_fp));
755 return DVR_SUCCESS;
756}
757
758/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800759int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
760{
761 Segment_Context_t *p_ctx;
762 uint32_t i;
763 char buf[256];
764 char value[256];
765 char *p1, *p2;
766
767 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800768 DVR_RETURN_IF_FALSE(p_ctx);
769 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800770
771 /*Load segment id*/
772 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800773 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800774 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800775 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800776 p_info->id = strtoull(p1 + 3, NULL, 10);
777
778 /*Save number of pids*/
779 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800780 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800781 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800782 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800783 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
784
785 /*Save pid information*/
786 for (i = 0; i < p_info->nb_pids; i++) {
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 memset(value, 0, sizeof(value));
790 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800791 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800792 p1 += 4;
793 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800794 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800795 memcpy(value, p1, p2 - p1);
796 }
797 p_info->pids[i].pid = strtoull(value, NULL, 10);
798 }
799
800 memset(value, 0, sizeof(value));
801 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800802 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800803 p1 += 5;
804 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800805 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800806 memcpy(value, p1, p2 - p1);
807 }
808 p_info->pids[i].type = strtoull(value, NULL, 10);
809 }
810 }
811
812 /*Save segment duration*/
813 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800814 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800815 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800816 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800817 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800818 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800819
820 /*Save segment size*/
821 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800822 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800823 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800824 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800825 p_info->size = strtoull(p1 + 5, NULL, 10);
826
827 /*Save number of packets*/
828 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800829 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800830 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800831 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800832 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
833
834 return DVR_SUCCESS;
835}
836
hualing chenb9a02922021-12-14 11:29:47 +0800837/* Should consider the case of cut power, todo... */
838int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
839{
840 Segment_Context_t *p_ctx;
841 uint32_t i;
842 char buf[256];
843 char value[256];
844 char *p1, *p2;
845
846 p_ctx = (Segment_Context_t *)handle;
847 DVR_RETURN_IF_FALSE(p_ctx);
848 DVR_RETURN_IF_FALSE(list);
hualing chen926a8ec2021-12-20 20:38:24 +0800849 if (p_ctx->all_dat_fp == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800850 DVR_INFO("all dat file not open\n");
hualing chen926a8ec2021-12-20 20:38:24 +0800851 return DVR_FAILURE;
852 }
hualing chenb9a02922021-12-14 11:29:47 +0800853 //first get
854 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
855 DVR_RETURN_IF_FALSE(p1);
856
857 do {
858
859 DVR_RecordSegmentInfo_t *p_info;
860
861 p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
862 memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
863
864 list_add_tail(&p_info->head, list);
865
866 /*Load segment id*/
867 DVR_RETURN_IF_FALSE(p1);
868 p1 = strstr(buf, "id=");
869 DVR_RETURN_IF_FALSE(p1);
870 p_info->id = strtoull(p1 + 3, NULL, 10);
871
872 /*Save number of pids*/
873 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
874 DVR_RETURN_IF_FALSE(p1);
875 p1 = strstr(buf, "nb_pids=");
876 DVR_RETURN_IF_FALSE(p1);
877 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
878
879 /*Save pid information*/
880 for (i = 0; i < p_info->nb_pids; i++) {
881 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
882 DVR_RETURN_IF_FALSE(p1);
883 memset(value, 0, sizeof(value));
884 if ((p1 = strstr(buf, "pid="))) {
885 DVR_RETURN_IF_FALSE(p1);
886 p1 += 4;
887 if ((p2 = strstr(buf, ","))) {
888 DVR_RETURN_IF_FALSE(p2);
889 memcpy(value, p1, p2 - p1);
890 }
891 p_info->pids[i].pid = strtoull(value, NULL, 10);
892 }
893
894 memset(value, 0, sizeof(value));
895 if ((p1 = strstr(buf, "type="))) {
896 DVR_RETURN_IF_FALSE(p1);
897 p1 += 5;
898 if ((p2 = strstr(buf, "}"))) {
899 DVR_RETURN_IF_FALSE(p2);
900 memcpy(value, p1, p2 - p1);
901 }
902 p_info->pids[i].type = strtoull(value, NULL, 10);
903 }
904 }
905
906 /*Save segment duration*/
907 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
908 DVR_RETURN_IF_FALSE(p1);
909 p1 = strstr(buf, "duration=");
910 DVR_RETURN_IF_FALSE(p1);
911 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800912 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800913
914 /*Save segment size*/
915 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
916 DVR_RETURN_IF_FALSE(p1);
917 p1 = strstr(buf, "size=");
918 DVR_RETURN_IF_FALSE(p1);
919 p_info->size = strtoull(p1 + 5, NULL, 10);
920
921 /*Save number of packets*/
922 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
923 DVR_RETURN_IF_FALSE(p1);
924 p1 = strstr(buf, "nb_packets=");
925 DVR_RETURN_IF_FALSE(p1);
926 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
927 //if reach end,exit loop
928 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
929 } while (p1);
930
931 return DVR_SUCCESS;
932}
933
Pengfei Liub4734232020-01-17 18:25:10 +0800934int segment_delete(const char *location, uint64_t segment_id)
935{
936 char fname[MAX_SEGMENT_PATH_SIZE];
937 int ret;
938
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800939 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800940
941 /*delete ts file*/
942 memset(fname, 0, sizeof(fname));
943 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
944 ret = unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000945 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800946 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800947
948 /*delete index file*/
949 memset(fname, 0, sizeof(fname));
950 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
951 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000952 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800953 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800954
955 /*delete store information file*/
956 memset(fname, 0, sizeof(fname));
957 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
958 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 return DVR_SUCCESS;
963}
964
hualing chen87072a82020-03-12 16:20:12 +0800965int segment_ongoing(Segment_Handle_t handle)
966{
967 Segment_Context_t *p_ctx;
968 p_ctx = (Segment_Context_t *)handle;
969 struct stat mstat;
970
971 char going_name[MAX_SEGMENT_PATH_SIZE];
972 memset(going_name, 0, sizeof(going_name));
973 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
974 int ret = stat(going_name, &mstat);
Wentao MA96f68962022-06-15 19:45:35 +0800975 DVR_INFO("segment check ongoing [%s] ret [%d]", going_name, ret);
hualing chen87072a82020-03-12 16:20:12 +0800976 if (ret != 0) {
977 return DVR_FAILURE;
978 }
979 return DVR_SUCCESS;
980}
Wentao MAa3388532022-08-18 15:07:07 +0800981
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800982loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800983{
984 Segment_Context_t *p_ctx;
985 char buf[256];
986 char value[256];
Wentao MA139fc612022-08-29 14:10:07 +0800987 uint64_t pts = 0;
988 loff_t offset = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800989 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800990 int ret = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800991
992 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800993 DVR_RETURN_IF_FALSE(p_ctx);
994 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
995 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800996
997 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800998 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
999 DVR_RETURN_IF_FALSE(ret != -1);
1000
Pengfei Liub038b6a2020-01-14 15:57:01 +08001001 printf("start gets pts\n");
1002 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
1003 printf("buf[%s]\n", buf);
1004 memset(value, 0, sizeof(value));
1005 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +08001006 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001007 if ((p2 = strstr(buf, ","))) {
1008 memcpy(value, p1, p2 - p1);
1009 }
1010 pts = strtoull(value, NULL, 10);
1011 }
1012
1013 memset(value, 0, sizeof(value));
1014 if ((p1 = strstr(buf, "offset="))) {
1015 p1 += 7;
1016 if ((p2 = strstr(buf, "}"))) {
1017 memcpy(value, p1, p2 - p1);
1018 }
1019 offset = strtoull(value, NULL, 10);
1020 }
1021
1022 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001023 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001024 }
1025
1026 return 0;
1027}
Wentao MA907b6432022-08-01 06:23:08 +00001028
1029off_t segment_get_cur_segment_size(Segment_Handle_t handle)
1030{
1031 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1032 DVR_RETURN_IF_FALSE(p_ctx);
1033 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
1034 struct stat sb;
1035 int ret=fstat(p_ctx->ts_fd,&sb);
1036 if (ret<0) {
1037 return -1;
1038 }
1039 return sb.st_size;
1040}
1041
1042uint64_t segment_get_cur_segment_id(Segment_Handle_t handle)
1043{
1044 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1045 DVR_RETURN_IF_FALSE(p_ctx);
1046 return p_ctx->segment_id;
1047}
1048