blob: 961452f3b7c427442c07c1bdb535d021eecc0859 [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*/
hualing chenb9a02922021-12-14 11:29:47 +080051 SEGMENT_FILE_TYPE_ALLDAT, /**< 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);
hualing chenb9a02922021-12-14 11:29:47 +080064 if (type != SEGMENT_FILE_TYPE_ALLDAT) {
65 strncpy(fname + offset, "-", 1);
66 offset += 1;
67 sprintf(fname + offset, "%04llu", segment_id);
Wentao MAbcbc0c82022-06-28 11:24:56 +080068 offset += strlen(fname + offset);
hualing chenb9a02922021-12-14 11:29:47 +080069 }
70
Pengfei Liuc181a982020-01-07 19:27:13 +080071 if (type == SEGMENT_FILE_TYPE_TS)
72 strncpy(fname + offset, ".ts", 3);
73 else if (type == SEGMENT_FILE_TYPE_INDEX)
74 strncpy(fname + offset, ".idx", 4);
Pengfei Liub4734232020-01-17 18:25:10 +080075 else if (type == SEGMENT_FILE_TYPE_DAT)
76 strncpy(fname + offset, ".dat", 4);
hualing chen87072a82020-03-12 16:20:12 +080077 else if (type == SEGMENT_FILE_TYPE_ONGOING)
78 strncpy(fname + offset, ".going", 6);
hualing chenb9a02922021-12-14 11:29:47 +080079 else if (type == SEGMENT_FILE_TYPE_ALLDAT)
80 strncpy(fname + offset, ".dat", 4);
81
Pengfei Liuc181a982020-01-07 19:27:13 +080082}
83
Pengfei Liu3b1a8202020-02-12 23:04:21 +080084static void segment_get_dirname(char dir_name[MAX_SEGMENT_PATH_SIZE],
85 const char location[DVR_MAX_LOCATION_SIZE])
86{
87 char *p;
88 int i;
89 int found = 0;
90
91 for (i = 0; i < (int)strlen(location); i++) {
92 if (location[i] == '/') {
93 p = (char *)location + i;
94 found = 1;
95 }
96 }
97 if (found)
98 memcpy(dir_name, location, p - location);
99}
100
Pengfei Liuc181a982020-01-07 19:27:13 +0800101int segment_open(Segment_OpenParams_t *params, Segment_Handle_t *p_handle)
102{
103 Segment_Context_t *p_ctx;
104 char ts_fname[MAX_SEGMENT_PATH_SIZE];
105 char index_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liub4734232020-01-17 18:25:10 +0800106 char dat_fname[MAX_SEGMENT_PATH_SIZE];
hualing chenb9a02922021-12-14 11:29:47 +0800107 char all_dat_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800108 char dir_name[MAX_SEGMENT_PATH_SIZE];
hualing chen87072a82020-03-12 16:20:12 +0800109 char going_name[MAX_SEGMENT_PATH_SIZE];
Pengfei Liuc181a982020-01-07 19:27:13 +0800110
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800111 DVR_RETURN_IF_FALSE(params);
112 DVR_RETURN_IF_FALSE(p_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800113
Wentao MA96f68962022-06-15 19:45:35 +0800114 //DVR_INFO("%s, location:%s, id:%llu", __func__, params->location, params->segment_id);
Pengfei Liuc181a982020-01-07 19:27:13 +0800115
Pengfei Liub038b6a2020-01-14 15:57:01 +0800116 p_ctx = (void*)malloc(sizeof(Segment_Context_t));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800117 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800118 memset(p_ctx, 0, sizeof(Segment_Context_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800119
120 memset(ts_fname, 0, sizeof(ts_fname));
121 segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
122
123 memset(index_fname, 0, sizeof(index_fname));
124 segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
125
Pengfei Liub4734232020-01-17 18:25:10 +0800126 memset(dat_fname, 0, sizeof(dat_fname));
127 segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
128
hualing chenb9a02922021-12-14 11:29:47 +0800129 memset(all_dat_fname, 0, sizeof(all_dat_fname));
130 segment_get_fname(all_dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_ALLDAT);
131
132
hualing chen87072a82020-03-12 16:20:12 +0800133 memset(going_name, 0, sizeof(going_name));
134 segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
135
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800136 memset(dir_name, 0, sizeof(dir_name));
137 segment_get_dirname(dir_name, params->location);
138 if (access(dir_name, F_OK) == -1) {
Wentao MA96f68962022-06-15 19:45:35 +0800139 DVR_INFO("%s dir %s is not exist, create it", __func__, dir_name);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800140 mkdir(dir_name, 0666);
141 }
142
Pengfei Liuc181a982020-01-07 19:27:13 +0800143 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800144 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800145 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800146 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800147 p_ctx->ongoing_fp = NULL;
hualing chenb9a02922021-12-14 11:29:47 +0800148 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
Pengfei Liuc181a982020-01-07 19:27:13 +0800149 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800150 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800151 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800152 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chenb9a02922021-12-14 11:29:47 +0800153 p_ctx->all_dat_fp = fopen(all_dat_fname, "a+");
Wentao MA96f68962022-06-15 19:45:35 +0800154 DVR_INFO("%s dir %s is opened", __func__, all_dat_fname);
hualing chen87072a82020-03-12 16:20:12 +0800155 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800156 p_ctx->first_pts = ULLONG_MAX;
157 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800158 p_ctx->last_record_pts = ULLONG_MAX;
hualing chena5f03222021-12-02 11:22:35 +0800159 p_ctx->avg_rate = 0.0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800160 } else {
Wentao MA96f68962022-06-15 19:45:35 +0800161 DVR_INFO("%s, unknow mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800162 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800163 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800164 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chenb9a02922021-12-14 11:29:47 +0800165 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800166 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800167 }
168
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800169 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800170 DVR_INFO("%s open file failed [%s, %s, %s], reason:%s", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800171 ts_fname, index_fname, dat_fname, strerror(errno));
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800172 if (p_ctx->ts_fd != -1)
173 close(p_ctx->ts_fd);
174 if (p_ctx->index_fp)
175 fclose(p_ctx->index_fp);
176 if (p_ctx->dat_fp)
177 fclose(p_ctx->dat_fp);
hualing chen926a8ec2021-12-20 20:38:24 +0800178 if (p_ctx->all_dat_fp)
179 fclose(p_ctx->all_dat_fp);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800180 if (p_ctx->ongoing_fp)
181 fclose(p_ctx->ongoing_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800182 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800183 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800184 return DVR_FAILURE;
185 }
hualing chen87072a82020-03-12 16:20:12 +0800186 p_ctx->segment_id = params->segment_id;
187 strncpy(p_ctx->location, params->location, strlen(params->location));
wentao.ma35a69d42022-03-10 18:08:40 +0800188 p_ctx->force_sysclock = params->force_sysclock;
Pengfei Liub4734232020-01-17 18:25:10 +0800189
Wentao MA96f68962022-06-15 19:45:35 +0800190 //DVR_INFO("%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800191 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800192 return DVR_SUCCESS;
193}
194
195int segment_close(Segment_Handle_t handle)
196{
197 Segment_Context_t *p_ctx;
198
Pengfei Liub038b6a2020-01-14 15:57:01 +0800199 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800200 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800201
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800202 if (p_ctx->ts_fd != -1) {
203 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800204 }
205
206 if (p_ctx->index_fp) {
207 fclose(p_ctx->index_fp);
208 }
209
Pengfei Liub4734232020-01-17 18:25:10 +0800210 if (p_ctx->dat_fp) {
211 fclose(p_ctx->dat_fp);
212 }
hualing chen926a8ec2021-12-20 20:38:24 +0800213 if (p_ctx->all_dat_fp) {
214 fclose(p_ctx->all_dat_fp);
215 }
hualing chen87072a82020-03-12 16:20:12 +0800216 if (p_ctx->ongoing_fp != NULL) {
217 fclose(p_ctx->ongoing_fp);
218 char going_name[MAX_SEGMENT_PATH_SIZE];
219 memset(going_name, 0, sizeof(going_name));
220 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
Wentao MA96f68962022-06-15 19:45:35 +0800221 DVR_INFO("segment close del [%s]", going_name);
hualing chen87072a82020-03-12 16:20:12 +0800222 unlink(going_name);
223 }
224
Pengfei Liuc181a982020-01-07 19:27:13 +0800225 free(p_ctx);
226 return 0;
227}
228
229ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
230{
231 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800232 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800233 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800234 DVR_RETURN_IF_FALSE(p_ctx);
235 DVR_RETURN_IF_FALSE(buf);
236 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800237 len = read(p_ctx->ts_fd, buf, count);
238 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800239}
240
241ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
242{
243 Segment_Context_t *p_ctx;
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +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);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800249 len = write(p_ctx->ts_fd, buf, count);
hualing chen157641d2022-02-22 17:54:52 +0800250 if (p_ctx->time % TS_FILE_SYNC_TIME == 0)
251 fsync(p_ctx->ts_fd);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800252 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800253}
254
hualing chen2932d372020-04-29 13:44:00 +0800255int segment_update_pts_force(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800256{
257 Segment_Context_t *p_ctx;
258 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800259 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800260
261 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800262 DVR_RETURN_IF_FALSE(p_ctx);
263 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800264
Pengfei Liub038b6a2020-01-14 15:57:01 +0800265 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800266 DVR_INFO("%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800267 p_ctx->first_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800268 p_ctx->first_offset = offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800269 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800270 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800271 if (p_ctx->last_pts == ULLONG_MAX) {
272 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800273 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800274 p_ctx->cur_time = pts - p_ctx->first_pts;
Wentao MA96f68962022-06-15 19:45:35 +0800275 DVR_INFO("%s force pcr:%llu -1", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800276 } else {
277 /*Last pts has valid value*/
278 int diff = pts - p_ctx->last_pts;
279 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
280 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800281 DVR_INFO("[%s]force update Current pts has a transition, [%llu, %llu, %llu]",__func__,
hualing chen2932d372020-04-29 13:44:00 +0800282 p_ctx->first_pts, p_ctx->last_pts, pts);
283 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
284 } else {
285 /*This is a normal pts, record it*/
hualing chena5f03222021-12-02 11:22:35 +0800286 //check if this pcr is transition.if true,add 200ms
287 //other case normal.
hualing chen2932d372020-04-29 13:44:00 +0800288 p_ctx->cur_time += diff;
Wentao MA96f68962022-06-15 19:45:35 +0800289 DVR_INFO("%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
hualing chen2932d372020-04-29 13:44:00 +0800290 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
291 }
292 }
293
294 record_diff = pts - p_ctx->last_record_pts;
295 if (strlen(buf) > 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800296 DVR_INFO("%s force pcr:%llu buf:%s", __func__, pts, buf);
hualing chen2932d372020-04-29 13:44:00 +0800297 fputs(buf, p_ctx->index_fp);
298 fflush(p_ctx->index_fp);
299 fsync(fileno(p_ctx->index_fp));
300 p_ctx->last_record_pts = pts;
301 }
302 p_ctx->last_pts = pts;
hualing chen2932d372020-04-29 13:44:00 +0800303 return DVR_SUCCESS;
304}
305
306int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
307{
308 Segment_Context_t *p_ctx;
309 char buf[256];
310 int record_diff = 0;
311
312 p_ctx = (Segment_Context_t *)handle;
313 DVR_RETURN_IF_FALSE(p_ctx);
314 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
315
316 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800317 DVR_INFO("%s first pcr:%llu", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800318 p_ctx->first_pts = pts;
319 //p_ctx->cur_time = p_ctx->cur_time + PTS_HEAD_DEVIATION;
320 }
321 memset(buf, 0, sizeof(buf));
322 if (p_ctx->last_pts == ULLONG_MAX) {
323 /*Last pts is init value*/
324 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
325 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800326 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800327 if (!p_ctx->force_sysclock) {
328 /* if force_sysclock is off, we follow old manner. Please refer to
329 * SWPL-75327*/
330 /*Last pts has valid value*/
331 int diff = pts - p_ctx->last_pts;
332 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
333 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800334 DVR_INFO("Current pts has a transition, [%llu, %llu, %llu]",
wentao.ma35a69d42022-03-10 18:08:40 +0800335 p_ctx->first_pts, p_ctx->last_pts, pts);
336 p_ctx->last_record_pts = pts;
Wentao MA270dc0f2022-08-23 13:17:26 +0800337 //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINUED_DEVIATION;
hualing chena5f03222021-12-02 11:22:35 +0800338 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800339 /*This is a normal pts, record it*/
340 loff_t off_diff = offset - p_ctx->last_offset;
341 float rate = (float) (off_diff) / (float)(diff);
342 if (p_ctx->avg_rate == 0.0) {
343 p_ctx->avg_rate = (float) offset / (float)(p_ctx->cur_time + diff);
344 }
345 if (diff >= PCR_JUMP_DUR) {
Wentao MA96f68962022-06-15 19:45:35 +0800346 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 +0800347 if (p_ctx->avg_rate != 0 && (int)(p_ctx->avg_rate) >= (int)(rate * 4)) {
348 diff = off_diff / p_ctx->avg_rate;
349 p_ctx->cur_time += diff;
350 } else {
351 p_ctx->cur_time += diff;
352 }
353 } else {
354 p_ctx->cur_time += diff;
355 }
hualing chena5f03222021-12-02 11:22:35 +0800356 }
wentao.ma35a69d42022-03-10 18:08:40 +0800357 } else {
358 /* if force_sysclock is on, we simply calculate cur_time based on system
359 * time. Please refer to SWPL-75327*/
360 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800361 }
wentao.ma35a69d42022-03-10 18:08:40 +0800362 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800363 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800364
365 record_diff = pts - p_ctx->last_record_pts;
366 if (strlen(buf) > 0 &&
367 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800368 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800369 fflush(p_ctx->index_fp);
hualing chen157641d2022-02-22 17:54:52 +0800370 p_ctx->time++;
371 //flush idx file 3s
372 if ((p_ctx->time > 0 && p_ctx->time % IDX_FILE_SYNC_TIME == 0))
373 fsync(fileno(p_ctx->index_fp));
374 if (p_ctx->time > IDX_FILE_SYNC_TIME)
375 p_ctx->time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800376 p_ctx->last_record_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800377 p_ctx->last_record_offset = offset;
378 if (p_ctx->cur_time > 0)
379 p_ctx->avg_rate = (float) offset / (float)p_ctx->cur_time;
pengfei.liu567d6d82020-04-17 16:48:59 +0800380 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800381 p_ctx->last_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800382 p_ctx->last_offset = offset;
Pengfei Liuc181a982020-01-07 19:27:13 +0800383 return DVR_SUCCESS;
384}
385
hualing chen266b9502020-04-04 17:39:39 +0800386loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800387{
388 Segment_Context_t *p_ctx;
389 char buf[256];
390 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800391 uint64_t pts = 0L;
392 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800393 char *p1, *p2;
394
Wentao MA96f68962022-06-15 19:45:35 +0800395 DVR_INFO("into seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chen8a657f32021-08-30 13:12:49 +0800396
Pengfei Liuc181a982020-01-07 19:27:13 +0800397 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800398 DVR_RETURN_IF_FALSE(p_ctx);
399 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
400 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800401
hualing chen266b9502020-04-04 17:39:39 +0800402 if (time == 0) {
403 offset = 0;
Wentao MA96f68962022-06-15 19:45:35 +0800404 DVR_INFO("seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chend241c7a2021-06-22 13:34:27 +0800405 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen266b9502020-04-04 17:39:39 +0800406 return offset;
407 }
408
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800409 memset(buf, 0, sizeof(buf));
410 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800411 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800412 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800413 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800414 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800415 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800416 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800417 if ((p2 = strstr(buf, ","))) {
418 memcpy(value, p1, p2 - p1);
419 }
420 pts = strtoull(value, NULL, 10);
421 }
422
423 memset(value, 0, sizeof(value));
424 if ((p1 = strstr(buf, "offset="))) {
425 p1 += 7;
426 if ((p2 = strstr(buf, "}"))) {
427 memcpy(value, p1, p2 - p1);
428 }
429 offset = strtoull(value, NULL, 10);
430 }
hualing chen2aba4022020-03-02 13:49:55 +0800431 if (0)
432 {
Wentao MA96f68962022-06-15 19:45:35 +0800433 DVR_INFO("seek buf[%s]", buf);
434 DVR_INFO("seek time=%llu, offset=%lld\n", pts, offset);
hualing chen2aba4022020-03-02 13:49:55 +0800435 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800436 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800437 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800438 if (block_size > 0) {
439 offset = offset - offset%block_size;
440 }
Wentao MA96f68962022-06-15 19:45:35 +0800441 //DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800442 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800443 return offset;
444 }
hualing chen2aba4022020-03-02 13:49:55 +0800445 }
hualing chen2932d372020-04-29 13:44:00 +0800446 if (time > pts) {
447 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 end\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);
hualing chen2932d372020-04-29 13:44:00 +0800452 return offset;
453 }
Wentao MA96f68962022-06-15 19:45:35 +0800454 DVR_INFO("seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800455 return DVR_FAILURE;
456}
457
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800458loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800459{
460 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800461 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800462 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800463 DVR_RETURN_IF_FALSE(p_ctx);
464 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800465 pos = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
466 return pos;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800467}
468
hualing chen5605eed2020-05-26 18:18:06 +0800469uint64_t segment_tell_position_time(Segment_Handle_t handle, loff_t position)
470{
471 Segment_Context_t *p_ctx;
472 char buf[256];
473 char value[256];
hualing chen969fe7b2021-05-26 15:13:17 +0800474 uint64_t ret = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800475 uint64_t pts = 0L;
hualing chen969fe7b2021-05-26 15:13:17 +0800476 uint64_t pts_p = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800477 loff_t offset = 0;
hualing chen969fe7b2021-05-26 15:13:17 +0800478 loff_t offset_p = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800479 char *p1, *p2;
480
481 p_ctx = (Segment_Context_t *)handle;
482 DVR_RETURN_IF_FALSE(p_ctx);
483 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
484 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
485
486 memset(buf, 0, sizeof(buf));
487 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
488 DVR_RETURN_IF_FALSE(position != -1);
489
490 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
491 memset(value, 0, sizeof(value));
492 if ((p1 = strstr(buf, "time="))) {
493 p1 += 5;
494 if ((p2 = strstr(buf, ","))) {
495 memcpy(value, p1, p2 - p1);
496 }
497 pts = strtoull(value, NULL, 10);
498 }
499
500 memset(value, 0, sizeof(value));
501 if ((p1 = strstr(buf, "offset="))) {
502 p1 += 7;
503 if ((p2 = strstr(buf, "}"))) {
504 memcpy(value, p1, p2 - p1);
505 }
506 offset = strtoull(value, NULL, 10);
507 }
508
509 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800510 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chend241c7a2021-06-22 13:34:27 +0800511 if (position <= offset
512 &&position >= offset_p
513 && offset - offset_p > 0) {
hualing chen969fe7b2021-05-26 15:13:17 +0800514 ret = pts_p + (pts - pts_p) * (position - offset_p) / (offset - offset_p);
Wentao MA96f68962022-06-15 19:45:35 +0800515 //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 +0800516 return ret;
hualing chen5605eed2020-05-26 18:18:06 +0800517 }
hualing chen969fe7b2021-05-26 15:13:17 +0800518 offset_p = offset;
519 pts_p = pts;
hualing chen5605eed2020-05-26 18:18:06 +0800520 }
Wentao MA96f68962022-06-15 19:45:35 +0800521 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen5605eed2020-05-26 18:18:06 +0800522 return pts;
523}
524
525
pengfei.liu8b563292020-02-26 15:49:02 +0800526uint64_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800527{
528 Segment_Context_t *p_ctx;
529 char buf[256];
530 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800531 uint64_t pts = 0L;
532 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800533 char *p1, *p2;
534
535 p_ctx = (Segment_Context_t *)handle;
536 DVR_RETURN_IF_FALSE(p_ctx);
537 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
538 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
539
540 memset(buf, 0, sizeof(buf));
541 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800542 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800543 DVR_RETURN_IF_FALSE(position != -1);
544
545 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
546 memset(value, 0, sizeof(value));
547 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800548 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800549 if ((p2 = strstr(buf, ","))) {
550 memcpy(value, p1, p2 - p1);
551 }
552 pts = strtoull(value, NULL, 10);
553 }
554
555 memset(value, 0, sizeof(value));
556 if ((p1 = strstr(buf, "offset="))) {
557 p1 += 7;
558 if ((p2 = strstr(buf, "}"))) {
559 memcpy(value, p1, p2 - p1);
560 }
561 offset = strtoull(value, NULL, 10);
562 }
563
564 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800565 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800566 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800567 return pts;
568 }
569 }
Wentao MA96f68962022-06-15 19:45:35 +0800570 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800571 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800572}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800573
pengfei.liu8b563292020-02-26 15:49:02 +0800574uint64_t segment_tell_total_time(Segment_Handle_t handle)
575{
576 Segment_Context_t *p_ctx;
577 char buf[256];
578 char last_buf[256];
579 char value[256];
580 uint64_t pts = ULLONG_MAX;
581 loff_t offset = 0, position = 0;
582 char *p1, *p2;
583 int line = 0;
584
585 p_ctx = (Segment_Context_t *)handle;
586 DVR_RETURN_IF_FALSE(p_ctx);
587 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
588 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
589
590 memset(buf, 0, sizeof(buf));
591 memset(last_buf, 0, sizeof(last_buf));
hualing chend241c7a2021-06-22 13:34:27 +0800592 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
pengfei.liu8b563292020-02-26 15:49:02 +0800593 DVR_RETURN_IF_FALSE(position != -1);
594
hualing chen041c4092020-04-05 15:11:50 +0800595 //DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, -1000L, SEEK_END) != -1);
596 //if seek error.we need seek 0 pos.
597 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
598 fseek(p_ctx->index_fp, 0L, SEEK_SET);
599 }
pengfei.liu8b563292020-02-26 15:49:02 +0800600 /* Save last line buffer */
601 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800602 if (strlen(buf) <= 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800603 DVR_INFO("read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800604 continue;
605 }
pengfei.liu8b563292020-02-26 15:49:02 +0800606 memset(last_buf, 0, sizeof(last_buf));
607 memcpy(last_buf, buf, strlen(buf));
608 memset(buf, 0, sizeof(buf));
609 line++;
610 }
611
612 /* Extract time value */
613 memset(value, 0, sizeof(value));
614 if ((p1 = strstr(last_buf, "time="))) {
615 p1 += 5;
616 if ((p2 = strstr(last_buf, ","))) {
617 memcpy(value, p1, p2 - p1);
618 }
619 pts = strtoull(value, NULL, 10);
620 }
621
622 memset(value, 0, sizeof(value));
623 if ((p1 = strstr(last_buf, "offset="))) {
624 p1 += 7;
625 if ((p2 = strstr(last_buf, "}"))) {
626 memcpy(value, p1, p2 - p1);
627 }
628 offset = strtoull(value, NULL, 10);
629 }
hualing chen87072a82020-03-12 16:20:12 +0800630 //if (line < 2)
Wentao MA96f68962022-06-15 19:45:35 +0800631 //DVR_INFO("totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800632 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
633}
634
pengfei.liuab5a2262020-02-14 17:33:40 +0800635/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800636int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
637{
638 Segment_Context_t *p_ctx;
639 char buf[256];
640 uint32_t i;
641
642 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800643 DVR_RETURN_IF_FALSE(p_ctx);
644 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
645 DVR_RETURN_IF_FALSE(p_info);
hualing chen87072a82020-03-12 16:20:12 +0800646 //seek 0, rewrite info
647 DVR_RETURN_IF_FALSE(fseek(p_ctx->dat_fp, 0, SEEK_SET) != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800648
649 /*Save segment id*/
650 memset(buf, 0, sizeof(buf));
651 sprintf(buf, "id=%lld\n", p_info->id);
652 fputs(buf, p_ctx->dat_fp);
653
654 /*Save number of pids*/
655 memset(buf, 0, sizeof(buf));
656 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
657 fputs(buf, p_ctx->dat_fp);
658
659 /*Save pid information*/
660 for (i = 0; i < p_info->nb_pids; i++) {
661 memset(buf, 0, sizeof(buf));
662 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
663 fputs(buf, p_ctx->dat_fp);
664 }
665
666 /*Save segment duration*/
667 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800668 DVR_INFO("duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800669 sprintf(buf, "duration=%ld\n", p_info->duration);
670 fputs(buf, p_ctx->dat_fp);
671
672 /*Save segment size*/
673 memset(buf, 0, sizeof(buf));
674 sprintf(buf, "size=%zu\n", p_info->size);
675 fputs(buf, p_ctx->dat_fp);
676
677 /*Save number of packets*/
678 memset(buf, 0, sizeof(buf));
679 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
680 fputs(buf, p_ctx->dat_fp);
681
682 fflush(p_ctx->dat_fp);
hualing chen47c34bc2020-05-11 09:15:47 +0800683 fsync(fileno(p_ctx->dat_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800684 return DVR_SUCCESS;
685}
686
pengfei.liuab5a2262020-02-14 17:33:40 +0800687/* Should consider the case of cut power, todo... */
hualing chenb9a02922021-12-14 11:29:47 +0800688int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
689{
690 Segment_Context_t *p_ctx;
691 char buf[256];
692 uint32_t i;
693
694 p_ctx = (Segment_Context_t *)handle;
695 DVR_RETURN_IF_FALSE(p_ctx);
696 DVR_RETURN_IF_FALSE(p_ctx->all_dat_fp);
697 DVR_RETURN_IF_FALSE(p_info);
698 //seek 0, rewrite info
699 DVR_RETURN_IF_FALSE(fseek(p_ctx->all_dat_fp, 0, SEEK_END) != -1);
700
701 /*Save segment id*/
702 memset(buf, 0, sizeof(buf));
703 sprintf(buf, "id=%lld\n", p_info->id);
704 fputs(buf, p_ctx->all_dat_fp);
705
706 /*Save number of pids*/
707 memset(buf, 0, sizeof(buf));
708 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
709 fputs(buf, p_ctx->all_dat_fp);
710
711 /*Save pid information*/
712 for (i = 0; i < p_info->nb_pids; i++) {
713 memset(buf, 0, sizeof(buf));
714 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
715 fputs(buf, p_ctx->all_dat_fp);
716 }
717
718 /*Save segment duration*/
719 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800720 DVR_INFO("duration store:[%ld]", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800721 sprintf(buf, "duration=%ld\n", p_info->duration);
722 fputs(buf, p_ctx->all_dat_fp);
723
724 /*Save segment size*/
725 memset(buf, 0, sizeof(buf));
726 sprintf(buf, "size=%zu\n", p_info->size);
727 fputs(buf, p_ctx->all_dat_fp);
728
729 /*Save number of packets*/
730 memset(buf, 0, sizeof(buf));
731 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
732 fputs(buf, p_ctx->all_dat_fp);
733
734 fflush(p_ctx->all_dat_fp);
735 fsync(fileno(p_ctx->all_dat_fp));
736 return DVR_SUCCESS;
737}
738
739/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800740int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
741{
742 Segment_Context_t *p_ctx;
743 uint32_t i;
744 char buf[256];
745 char value[256];
746 char *p1, *p2;
747
748 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800749 DVR_RETURN_IF_FALSE(p_ctx);
750 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800751
752 /*Load segment id*/
753 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800754 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800755 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800756 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800757 p_info->id = strtoull(p1 + 3, NULL, 10);
758
759 /*Save number of pids*/
760 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800761 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800762 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800763 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800764 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
765
766 /*Save pid information*/
767 for (i = 0; i < p_info->nb_pids; i++) {
768 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800769 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800770 memset(value, 0, sizeof(value));
771 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800772 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800773 p1 += 4;
774 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800775 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800776 memcpy(value, p1, p2 - p1);
777 }
778 p_info->pids[i].pid = strtoull(value, NULL, 10);
779 }
780
781 memset(value, 0, sizeof(value));
782 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800783 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800784 p1 += 5;
785 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800786 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800787 memcpy(value, p1, p2 - p1);
788 }
789 p_info->pids[i].type = strtoull(value, NULL, 10);
790 }
791 }
792
793 /*Save segment duration*/
794 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800795 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800796 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800797 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800798 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800799 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800800
801 /*Save segment size*/
802 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800803 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800804 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800805 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800806 p_info->size = strtoull(p1 + 5, NULL, 10);
807
808 /*Save number of packets*/
809 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800810 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800811 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800812 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800813 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
814
815 return DVR_SUCCESS;
816}
817
hualing chenb9a02922021-12-14 11:29:47 +0800818/* Should consider the case of cut power, todo... */
819int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
820{
821 Segment_Context_t *p_ctx;
822 uint32_t i;
823 char buf[256];
824 char value[256];
825 char *p1, *p2;
826
827 p_ctx = (Segment_Context_t *)handle;
828 DVR_RETURN_IF_FALSE(p_ctx);
829 DVR_RETURN_IF_FALSE(list);
hualing chen926a8ec2021-12-20 20:38:24 +0800830 if (p_ctx->all_dat_fp == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800831 DVR_INFO("all dat file not open\n");
hualing chen926a8ec2021-12-20 20:38:24 +0800832 return DVR_FAILURE;
833 }
hualing chenb9a02922021-12-14 11:29:47 +0800834 //first get
835 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
836 DVR_RETURN_IF_FALSE(p1);
837
838 do {
839
840 DVR_RecordSegmentInfo_t *p_info;
841
842 p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
843 memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
844
845 list_add_tail(&p_info->head, list);
846
847 /*Load segment id*/
848 DVR_RETURN_IF_FALSE(p1);
849 p1 = strstr(buf, "id=");
850 DVR_RETURN_IF_FALSE(p1);
851 p_info->id = strtoull(p1 + 3, NULL, 10);
852
853 /*Save number of pids*/
854 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
855 DVR_RETURN_IF_FALSE(p1);
856 p1 = strstr(buf, "nb_pids=");
857 DVR_RETURN_IF_FALSE(p1);
858 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
859
860 /*Save pid information*/
861 for (i = 0; i < p_info->nb_pids; i++) {
862 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
863 DVR_RETURN_IF_FALSE(p1);
864 memset(value, 0, sizeof(value));
865 if ((p1 = strstr(buf, "pid="))) {
866 DVR_RETURN_IF_FALSE(p1);
867 p1 += 4;
868 if ((p2 = strstr(buf, ","))) {
869 DVR_RETURN_IF_FALSE(p2);
870 memcpy(value, p1, p2 - p1);
871 }
872 p_info->pids[i].pid = strtoull(value, NULL, 10);
873 }
874
875 memset(value, 0, sizeof(value));
876 if ((p1 = strstr(buf, "type="))) {
877 DVR_RETURN_IF_FALSE(p1);
878 p1 += 5;
879 if ((p2 = strstr(buf, "}"))) {
880 DVR_RETURN_IF_FALSE(p2);
881 memcpy(value, p1, p2 - p1);
882 }
883 p_info->pids[i].type = strtoull(value, NULL, 10);
884 }
885 }
886
887 /*Save segment duration*/
888 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
889 DVR_RETURN_IF_FALSE(p1);
890 p1 = strstr(buf, "duration=");
891 DVR_RETURN_IF_FALSE(p1);
892 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800893 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800894
895 /*Save segment size*/
896 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
897 DVR_RETURN_IF_FALSE(p1);
898 p1 = strstr(buf, "size=");
899 DVR_RETURN_IF_FALSE(p1);
900 p_info->size = strtoull(p1 + 5, NULL, 10);
901
902 /*Save number of packets*/
903 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
904 DVR_RETURN_IF_FALSE(p1);
905 p1 = strstr(buf, "nb_packets=");
906 DVR_RETURN_IF_FALSE(p1);
907 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
908 //if reach end,exit loop
909 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
910 } while (p1);
911
912 return DVR_SUCCESS;
913}
914
Pengfei Liub4734232020-01-17 18:25:10 +0800915int segment_delete(const char *location, uint64_t segment_id)
916{
917 char fname[MAX_SEGMENT_PATH_SIZE];
918 int ret;
919
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800920 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800921
922 /*delete ts file*/
923 memset(fname, 0, sizeof(fname));
924 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
925 ret = unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000926 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800927 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800928
929 /*delete index file*/
930 memset(fname, 0, sizeof(fname));
931 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
932 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000933 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800934 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800935
936 /*delete store information file*/
937 memset(fname, 0, sizeof(fname));
938 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
939 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000940 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800941 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800942
943 return DVR_SUCCESS;
944}
945
hualing chen87072a82020-03-12 16:20:12 +0800946int segment_ongoing(Segment_Handle_t handle)
947{
948 Segment_Context_t *p_ctx;
949 p_ctx = (Segment_Context_t *)handle;
950 struct stat mstat;
951
952 char going_name[MAX_SEGMENT_PATH_SIZE];
953 memset(going_name, 0, sizeof(going_name));
954 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
955 int ret = stat(going_name, &mstat);
Wentao MA96f68962022-06-15 19:45:35 +0800956 DVR_INFO("segment check ongoing [%s] ret [%d]", going_name, ret);
hualing chen87072a82020-03-12 16:20:12 +0800957 if (ret != 0) {
958 return DVR_FAILURE;
959 }
960 return DVR_SUCCESS;
961}
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800962loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800963{
964 Segment_Context_t *p_ctx;
965 char buf[256];
966 char value[256];
967 uint64_t pts;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800968 loff_t offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800969 char *p1, *p2;
970
971 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800972 DVR_RETURN_IF_FALSE(p_ctx);
973 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
974 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800975
976 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800977 DVR_RETURN_IF_FALSE(fseek(p_ctx->index_fp, 0, SEEK_SET) != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800978 printf("start gets pts\n");
979 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
980 printf("buf[%s]\n", buf);
981 memset(value, 0, sizeof(value));
982 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800983 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800984 if ((p2 = strstr(buf, ","))) {
985 memcpy(value, p1, p2 - p1);
986 }
987 pts = strtoull(value, NULL, 10);
988 }
989
990 memset(value, 0, sizeof(value));
991 if ((p1 = strstr(buf, "offset="))) {
992 p1 += 7;
993 if ((p2 = strstr(buf, "}"))) {
994 memcpy(value, p1, p2 - p1);
995 }
996 offset = strtoull(value, NULL, 10);
997 }
998
999 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001000 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001001 }
1002
1003 return 0;
1004}
Wentao MA907b6432022-08-01 06:23:08 +00001005
1006off_t segment_get_cur_segment_size(Segment_Handle_t handle)
1007{
1008 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1009 DVR_RETURN_IF_FALSE(p_ctx);
1010 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
1011 struct stat sb;
1012 int ret=fstat(p_ctx->ts_fd,&sb);
1013 if (ret<0) {
1014 return -1;
1015 }
1016 return sb.st_size;
1017}
1018
1019uint64_t segment_get_cur_segment_id(Segment_Handle_t handle)
1020{
1021 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1022 DVR_RETURN_IF_FALSE(p_ctx);
1023 return p_ctx->segment_id;
1024}
1025