blob: 8e0763ae8f2dcdf82e0238a34bab862f2f4e26fd [file] [log] [blame]
Pengfei Liuc181a982020-01-07 19:27:13 +08001#include <stdio.h>
Pengfei Liub038b6a2020-01-14 15:57:01 +08002#include <unistd.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08003#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <string.h>
Pengfei Liub038b6a2020-01-14 15:57:01 +08007#include <stdlib.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08008#include <errno.h>
Pengfei Liu47ed6c92020-01-17 11:23:41 +08009#include "dvr_types.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080010#include "segment.h"
11
12#define MAX_SEGMENT_FD_COUNT (128)
13#define MAX_SEGMENT_PATH_SIZE (DVR_MAX_LOCATION_SIZE + 32)
Pengfei Liub038b6a2020-01-14 15:57:01 +080014#define MAX_PTS_THRESHOLD (10*1000)
hualing chen06209692020-11-05 14:51:46 +080015#define PCR_RECORD_INTERVAL_MS (300)
Wentao MA270dc0f2022-08-23 13:17:26 +080016#define PTS_DISCONTINUED_DEVIATION (40)
hualing chen2932d372020-04-29 13:44:00 +080017#define PTS_HEAD_DEVIATION (40)
hualing chen86b8e602021-12-23 11:04:19 +080018#define PCR_JUMP_DUR (5000)
hualing chen2932d372020-04-29 13:44:00 +080019
hualing chen157641d2022-02-22 17:54:52 +080020#define IDX_FILE_SYNC_TIME (10)//10*PCR_RECORD_INTERVAL_MS
21#define TS_FILE_SYNC_TIME (9)//9*PCR_RECORD_INTERVAL_MS
22
hualing chen2932d372020-04-29 13:44:00 +080023
Pengfei Liub4734232020-01-17 18:25:10 +080024/**\brief Segment context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080025typedef struct {
Pengfei Liu3b1a8202020-02-12 23:04:21 +080026 int ts_fd; /**< Segment ts file fd*/
Pengfei Liub4734232020-01-17 18:25:10 +080027 FILE *index_fp; /**< Time index file fd*/
28 FILE *dat_fp; /**< Information file fd*/
hualing chenb9a02922021-12-14 11:29:47 +080029 FILE *all_dat_fp; /**< Information file fd*/
Wentao MA270dc0f2022-08-23 13:17:26 +080030 FILE *ongoing_fp; /**< Ongoing file fd, used to verify timeshift mode*/
Pengfei Liub4734232020-01-17 18:25:10 +080031 uint64_t first_pts; /**< First pts value, use for write mode*/
pengfei.liu567d6d82020-04-17 16:48:59 +080032 uint64_t last_pts; /**< Last input pts value, use for write mode*/
33 uint64_t last_record_pts; /**< Last record pts value, use for write mode*/
pengfei.liuab5a2262020-02-14 17:33:40 +080034 uint64_t cur_time; /**< Current time save in index file */
pengfei.liu567d6d82020-04-17 16:48:59 +080035 uint64_t segment_id; /**< Current segment ID */
36 char location[MAX_SEGMENT_PATH_SIZE]; /**< Current time save in index file */
hualing chena5f03222021-12-02 11:22:35 +080037 loff_t first_offset;
38 loff_t last_offset;
39 loff_t last_record_offset;
40 float avg_rate;
hualing chen157641d2022-02-22 17:54:52 +080041 int time;
wentao.ma35a69d42022-03-10 18:08:40 +080042 DVR_Bool_t force_sysclock; /**< If ture, force to use system clock as PVR index time source. If false, libdvr can determine index time source based on actual situation*/
hualing chen157641d2022-02-22 17:54:52 +080043 } Segment_Context_t;
Pengfei Liuc181a982020-01-07 19:27:13 +080044
Pengfei Liub4734232020-01-17 18:25:10 +080045/**\brief Segment file type*/
Pengfei Liuc181a982020-01-07 19:27:13 +080046typedef enum {
Pengfei Liub4734232020-01-17 18:25:10 +080047 SEGMENT_FILE_TYPE_TS, /**< Used for store TS data*/
48 SEGMENT_FILE_TYPE_INDEX, /**< Used for store index data*/
49 SEGMENT_FILE_TYPE_DAT, /**< Used for store information data, such as duration etc*/
pengfei.liu567d6d82020-04-17 16:48:59 +080050 SEGMENT_FILE_TYPE_ONGOING, /**< Used for store information data, such as duration etc*/
Wentao MA9a164002022-08-29 11:20:24 +080051 SEGMENT_FILE_TYPE_ALL_DATA, /**< Used for store all information data*/
Pengfei Liuc181a982020-01-07 19:27:13 +080052} Segment_FileType_t;
53
54static void segment_get_fname(char fname[MAX_SEGMENT_PATH_SIZE],
Pengfei Liub4734232020-01-17 18:25:10 +080055 const char location[DVR_MAX_LOCATION_SIZE],
Pengfei Liuc181a982020-01-07 19:27:13 +080056 uint64_t segment_id,
57 Segment_FileType_t type)
58{
59 int offset;
60
61 memset(fname, 0, MAX_SEGMENT_PATH_SIZE);
62 strncpy(fname, location, strlen(location));
63 offset = strlen(location);
Wentao MAe88ad702022-09-02 10:35:00 +080064
65 DVR_ASSERT(offset + DVR_MAX_LOCATION_SIZE < MAX_SEGMENT_PATH_SIZE);
66
Wentao MA9a164002022-08-29 11:20:24 +080067 if (type != SEGMENT_FILE_TYPE_ALL_DATA) {
Wentao MA4d85ff32022-09-23 11:36:18 +080068 strncpy(fname + offset, "-", 2);
hualing chenb9a02922021-12-14 11:29:47 +080069 offset += 1;
70 sprintf(fname + offset, "%04llu", segment_id);
Wentao MAbcbc0c82022-06-28 11:24:56 +080071 offset += strlen(fname + offset);
hualing chenb9a02922021-12-14 11:29:47 +080072 }
73
Pengfei Liuc181a982020-01-07 19:27:13 +080074 if (type == SEGMENT_FILE_TYPE_TS)
Wentao MA4d85ff32022-09-23 11:36:18 +080075 strncpy(fname + offset, ".ts", 4);
Pengfei Liuc181a982020-01-07 19:27:13 +080076 else if (type == SEGMENT_FILE_TYPE_INDEX)
Wentao MA4d85ff32022-09-23 11:36:18 +080077 strncpy(fname + offset, ".idx", 5);
Pengfei Liub4734232020-01-17 18:25:10 +080078 else if (type == SEGMENT_FILE_TYPE_DAT)
Wentao MA4d85ff32022-09-23 11:36:18 +080079 strncpy(fname + offset, ".dat", 5);
hualing chen87072a82020-03-12 16:20:12 +080080 else if (type == SEGMENT_FILE_TYPE_ONGOING)
Wentao MA4d85ff32022-09-23 11:36:18 +080081 strncpy(fname + offset, ".going", 7);
Wentao MA9a164002022-08-29 11:20:24 +080082 else if (type == SEGMENT_FILE_TYPE_ALL_DATA)
Wentao MA4d85ff32022-09-23 11:36:18 +080083 strncpy(fname + offset, ".dat", 5);
hualing chenb9a02922021-12-14 11:29:47 +080084
Pengfei Liuc181a982020-01-07 19:27:13 +080085}
86
Pengfei Liu3b1a8202020-02-12 23:04:21 +080087static void segment_get_dirname(char dir_name[MAX_SEGMENT_PATH_SIZE],
88 const char location[DVR_MAX_LOCATION_SIZE])
89{
90 char *p;
91 int i;
92 int found = 0;
93
94 for (i = 0; i < (int)strlen(location); i++) {
95 if (location[i] == '/') {
96 p = (char *)location + i;
97 found = 1;
98 }
99 }
100 if (found)
101 memcpy(dir_name, location, p - location);
102}
103
Pengfei Liuc181a982020-01-07 19:27:13 +0800104int segment_open(Segment_OpenParams_t *params, Segment_Handle_t *p_handle)
105{
106 Segment_Context_t *p_ctx;
107 char ts_fname[MAX_SEGMENT_PATH_SIZE];
108 char index_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liub4734232020-01-17 18:25:10 +0800109 char dat_fname[MAX_SEGMENT_PATH_SIZE];
hualing chenb9a02922021-12-14 11:29:47 +0800110 char all_dat_fname[MAX_SEGMENT_PATH_SIZE];
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800111 char dir_name[MAX_SEGMENT_PATH_SIZE];
hualing chen87072a82020-03-12 16:20:12 +0800112 char going_name[MAX_SEGMENT_PATH_SIZE];
Wentao MA4d85ff32022-09-23 11:36:18 +0800113 int ret = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800114
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800115 DVR_RETURN_IF_FALSE(params);
116 DVR_RETURN_IF_FALSE(p_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800117
Wentao MA96f68962022-06-15 19:45:35 +0800118 //DVR_INFO("%s, location:%s, id:%llu", __func__, params->location, params->segment_id);
Pengfei Liuc181a982020-01-07 19:27:13 +0800119
Pengfei Liub038b6a2020-01-14 15:57:01 +0800120 p_ctx = (void*)malloc(sizeof(Segment_Context_t));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800121 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800122 memset(p_ctx, 0, sizeof(Segment_Context_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800123
124 memset(ts_fname, 0, sizeof(ts_fname));
125 segment_get_fname(ts_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_TS);
126
127 memset(index_fname, 0, sizeof(index_fname));
128 segment_get_fname(index_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_INDEX);
129
Pengfei Liub4734232020-01-17 18:25:10 +0800130 memset(dat_fname, 0, sizeof(dat_fname));
131 segment_get_fname(dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_DAT);
132
hualing chenb9a02922021-12-14 11:29:47 +0800133 memset(all_dat_fname, 0, sizeof(all_dat_fname));
Wentao MA9a164002022-08-29 11:20:24 +0800134 segment_get_fname(all_dat_fname, params->location, params->segment_id, SEGMENT_FILE_TYPE_ALL_DATA);
hualing chenb9a02922021-12-14 11:29:47 +0800135
136
hualing chen87072a82020-03-12 16:20:12 +0800137 memset(going_name, 0, sizeof(going_name));
138 segment_get_fname(going_name, params->location, params->segment_id, SEGMENT_FILE_TYPE_ONGOING);
139
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800140 memset(dir_name, 0, sizeof(dir_name));
141 segment_get_dirname(dir_name, params->location);
Wentao MAb2070812022-09-02 13:10:03 +0800142
Wentao MA4d85ff32022-09-23 11:36:18 +0800143 ret = mkdir(dir_name, 0666);
144 if (ret == -1) {
145 DVR_WARN("mkdir of %s returns %d due to errno:%d,%s",
146 dir_name,ret,errno,strerror(errno));
147 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800148 if (access(dir_name, F_OK) == -1) {
Wentao MA4d85ff32022-09-23 11:36:18 +0800149 DVR_ERROR("%s dir %s does not exist", __func__, dir_name);
150 free(p_ctx);
151 p_ctx = NULL;
Wentao MAb2070812022-09-02 13:10:03 +0800152 return DVR_FAILURE;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800153 }
154
Pengfei Liuc181a982020-01-07 19:27:13 +0800155 if (params->mode == SEGMENT_MODE_READ) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800156 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800157 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800158 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800159 p_ctx->ongoing_fp = NULL;
hualing chenb9a02922021-12-14 11:29:47 +0800160 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
Pengfei Liuc181a982020-01-07 19:27:13 +0800161 } else if (params->mode == SEGMENT_MODE_WRITE) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800162 p_ctx->ts_fd = open(ts_fname, O_CREAT | O_RDWR | O_TRUNC, 0644);
Pengfei Liuc181a982020-01-07 19:27:13 +0800163 p_ctx->index_fp = fopen(index_fname, "w+");
Pengfei Liub4734232020-01-17 18:25:10 +0800164 p_ctx->dat_fp = fopen(dat_fname, "w+");
hualing chenb9a02922021-12-14 11:29:47 +0800165 p_ctx->all_dat_fp = fopen(all_dat_fname, "a+");
Wentao MA96f68962022-06-15 19:45:35 +0800166 DVR_INFO("%s dir %s is opened", __func__, all_dat_fname);
hualing chen87072a82020-03-12 16:20:12 +0800167 p_ctx->ongoing_fp = fopen(going_name, "w+");
Pengfei Liub038b6a2020-01-14 15:57:01 +0800168 p_ctx->first_pts = ULLONG_MAX;
169 p_ctx->last_pts = ULLONG_MAX;
pengfei.liu567d6d82020-04-17 16:48:59 +0800170 p_ctx->last_record_pts = ULLONG_MAX;
hualing chena5f03222021-12-02 11:22:35 +0800171 p_ctx->avg_rate = 0.0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800172 } else {
Wentao MA9a164002022-08-29 11:20:24 +0800173 DVR_INFO("%s, unknown mode use default", __func__);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800174 p_ctx->ts_fd = open(ts_fname, O_RDONLY);
Pengfei Liuc181a982020-01-07 19:27:13 +0800175 p_ctx->index_fp = fopen(index_fname, "r");
Pengfei Liub4734232020-01-17 18:25:10 +0800176 p_ctx->dat_fp = fopen(dat_fname, "r");
hualing chenb9a02922021-12-14 11:29:47 +0800177 p_ctx->all_dat_fp = fopen(all_dat_fname, "r");
hualing chen87072a82020-03-12 16:20:12 +0800178 p_ctx->ongoing_fp = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800179 }
180
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800181 if (p_ctx->ts_fd == -1 || !p_ctx->index_fp || !p_ctx->dat_fp) {
Wentao MA96f68962022-06-15 19:45:35 +0800182 DVR_INFO("%s open file failed [%s, %s, %s], reason:%s", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800183 ts_fname, index_fname, dat_fname, strerror(errno));
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800184 if (p_ctx->ts_fd != -1)
185 close(p_ctx->ts_fd);
186 if (p_ctx->index_fp)
187 fclose(p_ctx->index_fp);
188 if (p_ctx->dat_fp)
189 fclose(p_ctx->dat_fp);
hualing chen926a8ec2021-12-20 20:38:24 +0800190 if (p_ctx->all_dat_fp)
191 fclose(p_ctx->all_dat_fp);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800192 if (p_ctx->ongoing_fp)
193 fclose(p_ctx->ongoing_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800194 free(p_ctx);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800195 *p_handle = NULL;
Pengfei Liuc181a982020-01-07 19:27:13 +0800196 return DVR_FAILURE;
197 }
hualing chen87072a82020-03-12 16:20:12 +0800198 p_ctx->segment_id = params->segment_id;
199 strncpy(p_ctx->location, params->location, strlen(params->location));
wentao.ma35a69d42022-03-10 18:08:40 +0800200 p_ctx->force_sysclock = params->force_sysclock;
Pengfei Liub4734232020-01-17 18:25:10 +0800201
Wentao MA96f68962022-06-15 19:45:35 +0800202 //DVR_INFO("%s, open file success p_ctx->location [%s]", __func__, p_ctx->location, params->mode);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800203 *p_handle = (Segment_Handle_t)p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800204 return DVR_SUCCESS;
205}
206
207int segment_close(Segment_Handle_t handle)
208{
209 Segment_Context_t *p_ctx;
210
Pengfei Liub038b6a2020-01-14 15:57:01 +0800211 p_ctx = (void *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800212 DVR_RETURN_IF_FALSE(p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800213
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800214 if (p_ctx->ts_fd != -1) {
215 close(p_ctx->ts_fd);
Pengfei Liuc181a982020-01-07 19:27:13 +0800216 }
217
218 if (p_ctx->index_fp) {
219 fclose(p_ctx->index_fp);
220 }
221
Pengfei Liub4734232020-01-17 18:25:10 +0800222 if (p_ctx->dat_fp) {
223 fclose(p_ctx->dat_fp);
224 }
hualing chen926a8ec2021-12-20 20:38:24 +0800225 if (p_ctx->all_dat_fp) {
226 fclose(p_ctx->all_dat_fp);
227 }
hualing chen87072a82020-03-12 16:20:12 +0800228 if (p_ctx->ongoing_fp != NULL) {
229 fclose(p_ctx->ongoing_fp);
230 char going_name[MAX_SEGMENT_PATH_SIZE];
231 memset(going_name, 0, sizeof(going_name));
232 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
Wentao MA96f68962022-06-15 19:45:35 +0800233 DVR_INFO("segment close del [%s]", going_name);
hualing chen87072a82020-03-12 16:20:12 +0800234 unlink(going_name);
235 }
236
Pengfei Liuc181a982020-01-07 19:27:13 +0800237 free(p_ctx);
238 return 0;
239}
240
241ssize_t segment_read(Segment_Handle_t handle, void *buf, size_t count)
242{
243 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800244 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800245 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800246 DVR_RETURN_IF_FALSE(p_ctx);
247 DVR_RETURN_IF_FALSE(buf);
248 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800249 len = read(p_ctx->ts_fd, buf, count);
250 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800251}
252
253ssize_t segment_write(Segment_Handle_t handle, void *buf, size_t count)
254{
255 Segment_Context_t *p_ctx;
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800256 ssize_t len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800257 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800258 DVR_RETURN_IF_FALSE(p_ctx);
259 DVR_RETURN_IF_FALSE(buf);
260 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800261 len = write(p_ctx->ts_fd, buf, count);
hualing chen157641d2022-02-22 17:54:52 +0800262 if (p_ctx->time % TS_FILE_SYNC_TIME == 0)
263 fsync(p_ctx->ts_fd);
Chuanzhi Wangccecb8d2020-12-02 11:22:54 +0800264 return len;
Pengfei Liuc181a982020-01-07 19:27:13 +0800265}
266
hualing chen2932d372020-04-29 13:44:00 +0800267int segment_update_pts_force(Segment_Handle_t handle, uint64_t pts, loff_t offset)
Pengfei Liuc181a982020-01-07 19:27:13 +0800268{
269 Segment_Context_t *p_ctx;
270 char buf[256];
pengfei.liu567d6d82020-04-17 16:48:59 +0800271 int record_diff = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800272
273 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800274 DVR_RETURN_IF_FALSE(p_ctx);
275 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
Pengfei Liuc181a982020-01-07 19:27:13 +0800276
Pengfei Liub038b6a2020-01-14 15:57:01 +0800277 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800278 DVR_INFO("%s first pcr:%llu", __func__, pts);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800279 p_ctx->first_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800280 p_ctx->first_offset = offset;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800281 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800282 memset(buf, 0, sizeof(buf));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800283 if (p_ctx->last_pts == ULLONG_MAX) {
284 /*Last pts is init value*/
hualing chen2aba4022020-03-02 13:49:55 +0800285 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
pengfei.liuab5a2262020-02-14 17:33:40 +0800286 p_ctx->cur_time = pts - p_ctx->first_pts;
Wentao MA96f68962022-06-15 19:45:35 +0800287 DVR_INFO("%s force pcr:%llu -1", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800288 } else {
289 /*Last pts has valid value*/
290 int diff = pts - p_ctx->last_pts;
291 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
292 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800293 DVR_INFO("[%s]force update Current pts has a transition, [%llu, %llu, %llu]",__func__,
hualing chen2932d372020-04-29 13:44:00 +0800294 p_ctx->first_pts, p_ctx->last_pts, pts);
295 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
296 } else {
297 /*This is a normal pts, record it*/
hualing chena5f03222021-12-02 11:22:35 +0800298 //check if this pcr is transition.if true,add 200ms
299 //other case normal.
hualing chen2932d372020-04-29 13:44:00 +0800300 p_ctx->cur_time += diff;
Wentao MA96f68962022-06-15 19:45:35 +0800301 DVR_INFO("%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
hualing chen2932d372020-04-29 13:44:00 +0800302 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
303 }
304 }
305
306 record_diff = pts - p_ctx->last_record_pts;
307 if (strlen(buf) > 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800308 DVR_INFO("%s force pcr:%llu buf:%s", __func__, pts, buf);
hualing chen2932d372020-04-29 13:44:00 +0800309 fputs(buf, p_ctx->index_fp);
310 fflush(p_ctx->index_fp);
311 fsync(fileno(p_ctx->index_fp));
312 p_ctx->last_record_pts = pts;
313 }
314 p_ctx->last_pts = pts;
hualing chen2932d372020-04-29 13:44:00 +0800315 return DVR_SUCCESS;
316}
317
318int segment_update_pts(Segment_Handle_t handle, uint64_t pts, loff_t offset)
319{
320 Segment_Context_t *p_ctx;
321 char buf[256];
322 int record_diff = 0;
323
324 p_ctx = (Segment_Context_t *)handle;
325 DVR_RETURN_IF_FALSE(p_ctx);
326 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
327
328 if (p_ctx->first_pts == ULLONG_MAX) {
Wentao MA96f68962022-06-15 19:45:35 +0800329 DVR_INFO("%s first pcr:%llu", __func__, pts);
hualing chen2932d372020-04-29 13:44:00 +0800330 p_ctx->first_pts = pts;
331 //p_ctx->cur_time = p_ctx->cur_time + PTS_HEAD_DEVIATION;
332 }
333 memset(buf, 0, sizeof(buf));
334 if (p_ctx->last_pts == ULLONG_MAX) {
335 /*Last pts is init value*/
336 sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
337 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800338 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800339 if (!p_ctx->force_sysclock) {
340 /* if force_sysclock is off, we follow old manner. Please refer to
341 * SWPL-75327*/
342 /*Last pts has valid value*/
343 int diff = pts - p_ctx->last_pts;
344 if ((diff > MAX_PTS_THRESHOLD) || (diff < 0)) {
345 /*Current pts has a transition*/
Wentao MA96f68962022-06-15 19:45:35 +0800346 DVR_INFO("Current pts has a transition, [%llu, %llu, %llu]",
wentao.ma35a69d42022-03-10 18:08:40 +0800347 p_ctx->first_pts, p_ctx->last_pts, pts);
348 p_ctx->last_record_pts = pts;
Wentao MA270dc0f2022-08-23 13:17:26 +0800349 //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINUED_DEVIATION;
hualing chena5f03222021-12-02 11:22:35 +0800350 } else {
wentao.ma35a69d42022-03-10 18:08:40 +0800351 /*This is a normal pts, record it*/
352 loff_t off_diff = offset - p_ctx->last_offset;
353 float rate = (float) (off_diff) / (float)(diff);
354 if (p_ctx->avg_rate == 0.0) {
355 p_ctx->avg_rate = (float) offset / (float)(p_ctx->cur_time + diff);
356 }
357 if (diff >= PCR_JUMP_DUR) {
Wentao MA96f68962022-06-15 19:45:35 +0800358 DVR_INFO("PTS TRANSITION ERROR last pcr[%llu]pts[%llu]pcr diff[%d]off[%llu]off_diff[%llu]rate[%f]avg rate[%f]4*rate[%d]av_diff[%d]",p_ctx->last_pts, pts, diff, offset,off_diff, rate, p_ctx->avg_rate, (int)(rate * 4), (int)(off_diff / p_ctx->avg_rate));
wentao.ma35a69d42022-03-10 18:08:40 +0800359 if (p_ctx->avg_rate != 0 && (int)(p_ctx->avg_rate) >= (int)(rate * 4)) {
360 diff = off_diff / p_ctx->avg_rate;
361 p_ctx->cur_time += diff;
362 } else {
363 p_ctx->cur_time += diff;
364 }
365 } else {
366 p_ctx->cur_time += diff;
367 }
hualing chena5f03222021-12-02 11:22:35 +0800368 }
wentao.ma35a69d42022-03-10 18:08:40 +0800369 } else {
370 /* if force_sysclock is on, we simply calculate cur_time based on system
371 * time. Please refer to SWPL-75327*/
372 p_ctx->cur_time = pts - p_ctx->first_pts;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800373 }
wentao.ma35a69d42022-03-10 18:08:40 +0800374 sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +0800375 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800376
377 record_diff = pts - p_ctx->last_record_pts;
378 if (strlen(buf) > 0 &&
379 (record_diff > PCR_RECORD_INTERVAL_MS || p_ctx->last_record_pts == ULLONG_MAX)){
hualing chen4b7c15d2020-04-07 16:13:48 +0800380 fputs(buf, p_ctx->index_fp);
pengfei.liu567d6d82020-04-17 16:48:59 +0800381 fflush(p_ctx->index_fp);
hualing chen157641d2022-02-22 17:54:52 +0800382 p_ctx->time++;
383 //flush idx file 3s
384 if ((p_ctx->time > 0 && p_ctx->time % IDX_FILE_SYNC_TIME == 0))
385 fsync(fileno(p_ctx->index_fp));
386 if (p_ctx->time > IDX_FILE_SYNC_TIME)
387 p_ctx->time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800388 p_ctx->last_record_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800389 p_ctx->last_record_offset = offset;
390 if (p_ctx->cur_time > 0)
391 p_ctx->avg_rate = (float) offset / (float)p_ctx->cur_time;
pengfei.liu567d6d82020-04-17 16:48:59 +0800392 }
Pengfei Liub038b6a2020-01-14 15:57:01 +0800393 p_ctx->last_pts = pts;
hualing chena5f03222021-12-02 11:22:35 +0800394 p_ctx->last_offset = offset;
Pengfei Liuc181a982020-01-07 19:27:13 +0800395 return DVR_SUCCESS;
396}
397
hualing chen266b9502020-04-04 17:39:39 +0800398loff_t segment_seek(Segment_Handle_t handle, uint64_t time, int block_size)
Pengfei Liuc181a982020-01-07 19:27:13 +0800399{
400 Segment_Context_t *p_ctx;
401 char buf[256];
402 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800403 uint64_t pts = 0L;
404 loff_t offset = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800405 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800406 int ret = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800407
Wentao MA96f68962022-06-15 19:45:35 +0800408 DVR_INFO("into seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chen8a657f32021-08-30 13:12:49 +0800409
Pengfei Liuc181a982020-01-07 19:27:13 +0800410 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800411 DVR_RETURN_IF_FALSE(p_ctx);
412 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
413 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800414
hualing chen266b9502020-04-04 17:39:39 +0800415 if (time == 0) {
416 offset = 0;
Wentao MA96f68962022-06-15 19:45:35 +0800417 DVR_INFO("seek time=%llu, offset=%lld time--%llu\n", pts, offset, time);
hualing chend241c7a2021-06-22 13:34:27 +0800418 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen266b9502020-04-04 17:39:39 +0800419 return offset;
420 }
421
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800422 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800423 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
424 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen2aba4022020-03-02 13:49:55 +0800425 int line = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800426 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800427 line++;
Pengfei Liuc181a982020-01-07 19:27:13 +0800428 memset(value, 0, sizeof(value));
Pengfei Liub038b6a2020-01-14 15:57:01 +0800429 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800430 p1 += 5;
Pengfei Liuc181a982020-01-07 19:27:13 +0800431 if ((p2 = strstr(buf, ","))) {
432 memcpy(value, p1, p2 - p1);
433 }
434 pts = strtoull(value, NULL, 10);
435 }
436
437 memset(value, 0, sizeof(value));
438 if ((p1 = strstr(buf, "offset="))) {
439 p1 += 7;
440 if ((p2 = strstr(buf, "}"))) {
441 memcpy(value, p1, p2 - p1);
442 }
443 offset = strtoull(value, NULL, 10);
444 }
hualing chen2aba4022020-03-02 13:49:55 +0800445 if (0)
446 {
Wentao MA96f68962022-06-15 19:45:35 +0800447 DVR_INFO("seek buf[%s]", buf);
448 DVR_INFO("seek time=%llu, offset=%lld\n", pts, offset);
hualing chen2aba4022020-03-02 13:49:55 +0800449 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800450 memset(buf, 0, sizeof(buf));
hualing chencc91e1c2020-02-28 13:26:17 +0800451 if (time <= pts) {
hualing chen266b9502020-04-04 17:39:39 +0800452 if (block_size > 0) {
453 offset = offset - offset%block_size;
454 }
Wentao MA96f68962022-06-15 19:45:35 +0800455 //DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800456 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
Pengfei Liuc181a982020-01-07 19:27:13 +0800457 return offset;
458 }
hualing chen2aba4022020-03-02 13:49:55 +0800459 }
hualing chen2932d372020-04-29 13:44:00 +0800460 if (time > pts) {
461 if (block_size > 0) {
462 offset = offset - offset%block_size;
463 }
Wentao MA96f68962022-06-15 19:45:35 +0800464 DVR_INFO("seek time=%llu, offset=%lld time--%llu line %d end\n", pts, offset, time, line);
hualing chend241c7a2021-06-22 13:34:27 +0800465 DVR_RETURN_IF_FALSE(lseek(p_ctx->ts_fd, offset, SEEK_SET) != -1);
hualing chen2932d372020-04-29 13:44:00 +0800466 return offset;
467 }
Wentao MA96f68962022-06-15 19:45:35 +0800468 DVR_INFO("seek error line [%d]", line);
Pengfei Liuc181a982020-01-07 19:27:13 +0800469 return DVR_FAILURE;
470}
471
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800472loff_t segment_tell_position(Segment_Handle_t handle)
Pengfei Liuc181a982020-01-07 19:27:13 +0800473{
474 Segment_Context_t *p_ctx;
hualing chend241c7a2021-06-22 13:34:27 +0800475 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800476 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800477 DVR_RETURN_IF_FALSE(p_ctx);
478 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800479 pos = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
480 return pos;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800481}
482
Wentao MAa3388532022-08-18 15:07:07 +0800483loff_t segment_tell_position_time(Segment_Handle_t handle, loff_t position)
hualing chen5605eed2020-05-26 18:18:06 +0800484{
485 Segment_Context_t *p_ctx;
486 char buf[256];
487 char value[256];
hualing chen969fe7b2021-05-26 15:13:17 +0800488 uint64_t ret = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800489 uint64_t pts = 0L;
hualing chen969fe7b2021-05-26 15:13:17 +0800490 uint64_t pts_p = 0L;
hualing chen5605eed2020-05-26 18:18:06 +0800491 loff_t offset = 0;
hualing chen969fe7b2021-05-26 15:13:17 +0800492 loff_t offset_p = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800493 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800494 int ret2 = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800495
496 p_ctx = (Segment_Context_t *)handle;
497 DVR_RETURN_IF_FALSE(p_ctx);
498 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
499 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
500
501 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800502 ret2 = fseek(p_ctx->index_fp, 0, SEEK_SET);
503 DVR_RETURN_IF_FALSE(ret2 != -1);
hualing chen5605eed2020-05-26 18:18:06 +0800504 DVR_RETURN_IF_FALSE(position != -1);
505
506 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
507 memset(value, 0, sizeof(value));
508 if ((p1 = strstr(buf, "time="))) {
509 p1 += 5;
510 if ((p2 = strstr(buf, ","))) {
511 memcpy(value, p1, p2 - p1);
512 }
513 pts = strtoull(value, NULL, 10);
514 }
515
516 memset(value, 0, sizeof(value));
517 if ((p1 = strstr(buf, "offset="))) {
518 p1 += 7;
519 if ((p2 = strstr(buf, "}"))) {
520 memcpy(value, p1, p2 - p1);
521 }
522 offset = strtoull(value, NULL, 10);
523 }
524
525 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800526 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chend241c7a2021-06-22 13:34:27 +0800527 if (position <= offset
528 &&position >= offset_p
529 && offset - offset_p > 0) {
hualing chen969fe7b2021-05-26 15:13:17 +0800530 ret = pts_p + (pts - pts_p) * (position - offset_p) / (offset - offset_p);
Wentao MA96f68962022-06-15 19:45:35 +0800531 //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 +0800532 return ret;
hualing chen5605eed2020-05-26 18:18:06 +0800533 }
hualing chen969fe7b2021-05-26 15:13:17 +0800534 offset_p = offset;
535 pts_p = pts;
hualing chen5605eed2020-05-26 18:18:06 +0800536 }
Wentao MA96f68962022-06-15 19:45:35 +0800537 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen5605eed2020-05-26 18:18:06 +0800538 return pts;
539}
540
541
Wentao MAa3388532022-08-18 15:07:07 +0800542loff_t segment_tell_current_time(Segment_Handle_t handle)
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800543{
544 Segment_Context_t *p_ctx;
545 char buf[256];
546 char value[256];
hualing chen2aba4022020-03-02 13:49:55 +0800547 uint64_t pts = 0L;
548 loff_t offset = 0, position = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800549 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800550 int ret = 0;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800551
552 p_ctx = (Segment_Context_t *)handle;
553 DVR_RETURN_IF_FALSE(p_ctx);
554 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
555 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
556
557 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +0800558 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
559 DVR_RETURN_IF_FALSE(ret != -1);
hualing chend241c7a2021-06-22 13:34:27 +0800560 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800561 DVR_RETURN_IF_FALSE(position != -1);
562
563 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
564 memset(value, 0, sizeof(value));
565 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +0800566 p1 += 5;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800567 if ((p2 = strstr(buf, ","))) {
568 memcpy(value, p1, p2 - p1);
569 }
570 pts = strtoull(value, NULL, 10);
571 }
572
573 memset(value, 0, sizeof(value));
574 if ((p1 = strstr(buf, "offset="))) {
575 p1 += 7;
576 if ((p2 = strstr(buf, "}"))) {
577 memcpy(value, p1, p2 - p1);
578 }
579 offset = strtoull(value, NULL, 10);
580 }
581
582 memset(buf, 0, sizeof(buf));
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 if (position <= offset) {
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800585 return pts;
586 }
587 }
Wentao MA96f68962022-06-15 19:45:35 +0800588 //DVR_INFO("tell cur time=%llu, offset=%lld, position=%lld\n", pts, offset, position);
hualing chen2aba4022020-03-02 13:49:55 +0800589 return pts;
Pengfei Liuc181a982020-01-07 19:27:13 +0800590}
Pengfei Liub038b6a2020-01-14 15:57:01 +0800591
Wentao MAa3388532022-08-18 15:07:07 +0800592loff_t segment_tell_total_time(Segment_Handle_t handle)
pengfei.liu8b563292020-02-26 15:49:02 +0800593{
594 Segment_Context_t *p_ctx;
595 char buf[256];
596 char last_buf[256];
597 char value[256];
598 uint64_t pts = ULLONG_MAX;
599 loff_t offset = 0, position = 0;
600 char *p1, *p2;
601 int line = 0;
Wentao MAa3388532022-08-18 15:07:07 +0800602 int ret = 0;
pengfei.liu8b563292020-02-26 15:49:02 +0800603
604 p_ctx = (Segment_Context_t *)handle;
605 DVR_RETURN_IF_FALSE(p_ctx);
606 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
607 DVR_RETURN_IF_FALSE(p_ctx->ts_fd);
608
609 memset(buf, 0, sizeof(buf));
610 memset(last_buf, 0, sizeof(last_buf));
hualing chend241c7a2021-06-22 13:34:27 +0800611 position = lseek(p_ctx->ts_fd, 0, SEEK_CUR);
pengfei.liu8b563292020-02-26 15:49:02 +0800612 DVR_RETURN_IF_FALSE(position != -1);
613
Wentao MAa3388532022-08-18 15:07:07 +0800614 // if unable to seek from end, it is necessary to seek to file beginning position.
hualing chen041c4092020-04-05 15:11:50 +0800615 if (fseek(p_ctx->index_fp, -1000L, SEEK_END) == -1) {
Wentao MAa3388532022-08-18 15:07:07 +0800616 ret = fseek(p_ctx->index_fp, 0L, SEEK_SET);
617 DVR_RETURN_IF_FALSE(ret != -1);
hualing chen041c4092020-04-05 15:11:50 +0800618 }
pengfei.liu8b563292020-02-26 15:49:02 +0800619 /* Save last line buffer */
620 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
hualing chen2aba4022020-03-02 13:49:55 +0800621 if (strlen(buf) <= 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800622 DVR_INFO("read index buf is len 0");
hualing chen2aba4022020-03-02 13:49:55 +0800623 continue;
624 }
pengfei.liu8b563292020-02-26 15:49:02 +0800625 memset(last_buf, 0, sizeof(last_buf));
626 memcpy(last_buf, buf, strlen(buf));
627 memset(buf, 0, sizeof(buf));
628 line++;
629 }
630
631 /* Extract time value */
632 memset(value, 0, sizeof(value));
633 if ((p1 = strstr(last_buf, "time="))) {
634 p1 += 5;
635 if ((p2 = strstr(last_buf, ","))) {
636 memcpy(value, p1, p2 - p1);
637 }
638 pts = strtoull(value, NULL, 10);
639 }
640
641 memset(value, 0, sizeof(value));
642 if ((p1 = strstr(last_buf, "offset="))) {
643 p1 += 7;
644 if ((p2 = strstr(last_buf, "}"))) {
645 memcpy(value, p1, p2 - p1);
646 }
647 offset = strtoull(value, NULL, 10);
648 }
hualing chen87072a82020-03-12 16:20:12 +0800649 //if (line < 2)
Wentao MA96f68962022-06-15 19:45:35 +0800650 //DVR_INFO("totle time=%llu, offset=%lld, position=%lld, line:%d\n", pts, offset, position, line);
pengfei.liu8b563292020-02-26 15:49:02 +0800651 return (pts == ULLONG_MAX ? DVR_FAILURE : pts);
652}
653
pengfei.liuab5a2262020-02-14 17:33:40 +0800654/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800655int segment_store_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
656{
657 Segment_Context_t *p_ctx;
658 char buf[256];
659 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800660 int ret = 0;
Pengfei Liub4734232020-01-17 18:25:10 +0800661
662 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800663 DVR_RETURN_IF_FALSE(p_ctx);
664 DVR_RETURN_IF_FALSE(p_ctx->dat_fp);
665 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800666 // seek to 0 to rewrite info
667 ret = fseek(p_ctx->dat_fp, 0, SEEK_SET);
668 DVR_RETURN_IF_FALSE(ret != -1);
Pengfei Liub4734232020-01-17 18:25:10 +0800669
670 /*Save segment id*/
671 memset(buf, 0, sizeof(buf));
672 sprintf(buf, "id=%lld\n", p_info->id);
673 fputs(buf, p_ctx->dat_fp);
674
675 /*Save number of pids*/
676 memset(buf, 0, sizeof(buf));
677 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
678 fputs(buf, p_ctx->dat_fp);
679
680 /*Save pid information*/
681 for (i = 0; i < p_info->nb_pids; i++) {
682 memset(buf, 0, sizeof(buf));
683 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
684 fputs(buf, p_ctx->dat_fp);
685 }
686
687 /*Save segment duration*/
688 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800689 DVR_INFO("duration store:[%ld]", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800690 sprintf(buf, "duration=%ld\n", p_info->duration);
691 fputs(buf, p_ctx->dat_fp);
692
693 /*Save segment size*/
694 memset(buf, 0, sizeof(buf));
695 sprintf(buf, "size=%zu\n", p_info->size);
696 fputs(buf, p_ctx->dat_fp);
697
698 /*Save number of packets*/
699 memset(buf, 0, sizeof(buf));
700 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
701 fputs(buf, p_ctx->dat_fp);
702
703 fflush(p_ctx->dat_fp);
hualing chen47c34bc2020-05-11 09:15:47 +0800704 fsync(fileno(p_ctx->dat_fp));
Pengfei Liub4734232020-01-17 18:25:10 +0800705 return DVR_SUCCESS;
706}
707
pengfei.liuab5a2262020-02-14 17:33:40 +0800708/* Should consider the case of cut power, todo... */
hualing chenb9a02922021-12-14 11:29:47 +0800709int segment_store_allInfo(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
710{
711 Segment_Context_t *p_ctx;
712 char buf[256];
713 uint32_t i;
Wentao MAa3388532022-08-18 15:07:07 +0800714 int ret = 0;
hualing chenb9a02922021-12-14 11:29:47 +0800715
716 p_ctx = (Segment_Context_t *)handle;
717 DVR_RETURN_IF_FALSE(p_ctx);
718 DVR_RETURN_IF_FALSE(p_ctx->all_dat_fp);
719 DVR_RETURN_IF_FALSE(p_info);
Wentao MAa3388532022-08-18 15:07:07 +0800720
721 //seek to end to append info
722 ret = fseek(p_ctx->all_dat_fp, 0, SEEK_END);
723 DVR_RETURN_IF_FALSE(ret != -1);
hualing chenb9a02922021-12-14 11:29:47 +0800724
725 /*Save segment id*/
726 memset(buf, 0, sizeof(buf));
727 sprintf(buf, "id=%lld\n", p_info->id);
728 fputs(buf, p_ctx->all_dat_fp);
729
730 /*Save number of pids*/
731 memset(buf, 0, sizeof(buf));
732 sprintf(buf, "nb_pids=%d\n", p_info->nb_pids);
733 fputs(buf, p_ctx->all_dat_fp);
734
735 /*Save pid information*/
736 for (i = 0; i < p_info->nb_pids; i++) {
737 memset(buf, 0, sizeof(buf));
738 sprintf(buf, "{pid=%d, type=%d}\n", p_info->pids[i].pid, p_info->pids[i].type);
739 fputs(buf, p_ctx->all_dat_fp);
740 }
741
742 /*Save segment duration*/
743 memset(buf, 0, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800744 DVR_INFO("duration store:[%ld]", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800745 sprintf(buf, "duration=%ld\n", p_info->duration);
746 fputs(buf, p_ctx->all_dat_fp);
747
748 /*Save segment size*/
749 memset(buf, 0, sizeof(buf));
750 sprintf(buf, "size=%zu\n", p_info->size);
751 fputs(buf, p_ctx->all_dat_fp);
752
753 /*Save number of packets*/
754 memset(buf, 0, sizeof(buf));
755 sprintf(buf, "nb_packets=%d\n", p_info->nb_packets);
756 fputs(buf, p_ctx->all_dat_fp);
757
758 fflush(p_ctx->all_dat_fp);
759 fsync(fileno(p_ctx->all_dat_fp));
760 return DVR_SUCCESS;
761}
762
763/* Should consider the case of cut power, todo... */
Pengfei Liub4734232020-01-17 18:25:10 +0800764int segment_load_info(Segment_Handle_t handle, Segment_StoreInfo_t *p_info)
765{
766 Segment_Context_t *p_ctx;
767 uint32_t i;
768 char buf[256];
769 char value[256];
770 char *p1, *p2;
771
772 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800773 DVR_RETURN_IF_FALSE(p_ctx);
774 DVR_RETURN_IF_FALSE(p_info);
Pengfei Liub4734232020-01-17 18:25:10 +0800775
776 /*Load segment id*/
777 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800778 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800779 p1 = strstr(buf, "id=");
hualing chen2aba4022020-03-02 13:49:55 +0800780 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800781 p_info->id = strtoull(p1 + 3, NULL, 10);
782
783 /*Save number of pids*/
784 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800785 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800786 p1 = strstr(buf, "nb_pids=");
hualing chen2aba4022020-03-02 13:49:55 +0800787 DVR_RETURN_IF_FALSE(p1);
Wentao MAb2070812022-09-02 13:10:03 +0800788 p_info->nb_pids = strtoul(p1 + 8, NULL, 10);
Pengfei Liub4734232020-01-17 18:25:10 +0800789
790 /*Save pid information*/
791 for (i = 0; i < p_info->nb_pids; i++) {
792 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800793 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800794 memset(value, 0, sizeof(value));
795 if ((p1 = strstr(buf, "pid="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800796 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800797 p1 += 4;
798 if ((p2 = strstr(buf, ","))) {
hualing chen2aba4022020-03-02 13:49:55 +0800799 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800800 memcpy(value, p1, p2 - p1);
801 }
802 p_info->pids[i].pid = strtoull(value, NULL, 10);
803 }
804
805 memset(value, 0, sizeof(value));
806 if ((p1 = strstr(buf, "type="))) {
hualing chen2aba4022020-03-02 13:49:55 +0800807 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800808 p1 += 5;
809 if ((p2 = strstr(buf, "}"))) {
hualing chen2aba4022020-03-02 13:49:55 +0800810 DVR_RETURN_IF_FALSE(p2);
Pengfei Liub4734232020-01-17 18:25:10 +0800811 memcpy(value, p1, p2 - p1);
812 }
813 p_info->pids[i].type = strtoull(value, NULL, 10);
814 }
815 }
816
817 /*Save segment duration*/
818 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800819 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800820 p1 = strstr(buf, "duration=");
hualing chen2aba4022020-03-02 13:49:55 +0800821 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800822 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800823 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
Pengfei Liub4734232020-01-17 18:25:10 +0800824
825 /*Save segment size*/
826 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800827 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800828 p1 = strstr(buf, "size=");
hualing chen2aba4022020-03-02 13:49:55 +0800829 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800830 p_info->size = strtoull(p1 + 5, NULL, 10);
831
832 /*Save number of packets*/
833 p1 = fgets(buf, sizeof(buf), p_ctx->dat_fp);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800834 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800835 p1 = strstr(buf, "nb_packets=");
hualing chen2aba4022020-03-02 13:49:55 +0800836 DVR_RETURN_IF_FALSE(p1);
Pengfei Liub4734232020-01-17 18:25:10 +0800837 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
838
839 return DVR_SUCCESS;
840}
841
hualing chenb9a02922021-12-14 11:29:47 +0800842/* Should consider the case of cut power, todo... */
843int segment_load_allInfo(Segment_Handle_t handle, struct list_head *list)
844{
845 Segment_Context_t *p_ctx;
846 uint32_t i;
847 char buf[256];
848 char value[256];
849 char *p1, *p2;
850
851 p_ctx = (Segment_Context_t *)handle;
852 DVR_RETURN_IF_FALSE(p_ctx);
853 DVR_RETURN_IF_FALSE(list);
hualing chen926a8ec2021-12-20 20:38:24 +0800854 if (p_ctx->all_dat_fp == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800855 DVR_INFO("all dat file not open\n");
hualing chen926a8ec2021-12-20 20:38:24 +0800856 return DVR_FAILURE;
857 }
hualing chenb9a02922021-12-14 11:29:47 +0800858 //first get
859 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
860 DVR_RETURN_IF_FALSE(p1);
861
862 do {
863
864 DVR_RecordSegmentInfo_t *p_info;
865
866 p_info = malloc(sizeof(DVR_RecordSegmentInfo_t));
867 memset(p_info, 0, sizeof(DVR_RecordSegmentInfo_t));
868
869 list_add_tail(&p_info->head, list);
870
871 /*Load segment id*/
872 DVR_RETURN_IF_FALSE(p1);
873 p1 = strstr(buf, "id=");
874 DVR_RETURN_IF_FALSE(p1);
875 p_info->id = strtoull(p1 + 3, NULL, 10);
876
877 /*Save number of pids*/
878 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
879 DVR_RETURN_IF_FALSE(p1);
880 p1 = strstr(buf, "nb_pids=");
881 DVR_RETURN_IF_FALSE(p1);
882 p_info->nb_pids = strtoull(p1 + 8, NULL, 10);
883
884 /*Save pid information*/
885 for (i = 0; i < p_info->nb_pids; i++) {
886 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
887 DVR_RETURN_IF_FALSE(p1);
888 memset(value, 0, sizeof(value));
889 if ((p1 = strstr(buf, "pid="))) {
890 DVR_RETURN_IF_FALSE(p1);
891 p1 += 4;
892 if ((p2 = strstr(buf, ","))) {
893 DVR_RETURN_IF_FALSE(p2);
894 memcpy(value, p1, p2 - p1);
895 }
896 p_info->pids[i].pid = strtoull(value, NULL, 10);
897 }
898
899 memset(value, 0, sizeof(value));
900 if ((p1 = strstr(buf, "type="))) {
901 DVR_RETURN_IF_FALSE(p1);
902 p1 += 5;
903 if ((p2 = strstr(buf, "}"))) {
904 DVR_RETURN_IF_FALSE(p2);
905 memcpy(value, p1, p2 - p1);
906 }
907 p_info->pids[i].type = strtoull(value, NULL, 10);
908 }
909 }
910
911 /*Save segment duration*/
912 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
913 DVR_RETURN_IF_FALSE(p1);
914 p1 = strstr(buf, "duration=");
915 DVR_RETURN_IF_FALSE(p1);
916 p_info->duration = strtoull(p1 + 9, NULL, 10);
Wentao MA96f68962022-06-15 19:45:35 +0800917 //DVR_INFO("load info p_info->duration:%lld", p_info->duration);
hualing chenb9a02922021-12-14 11:29:47 +0800918
919 /*Save segment size*/
920 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
921 DVR_RETURN_IF_FALSE(p1);
922 p1 = strstr(buf, "size=");
923 DVR_RETURN_IF_FALSE(p1);
924 p_info->size = strtoull(p1 + 5, NULL, 10);
925
926 /*Save number of packets*/
927 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
928 DVR_RETURN_IF_FALSE(p1);
929 p1 = strstr(buf, "nb_packets=");
930 DVR_RETURN_IF_FALSE(p1);
931 p_info->nb_packets = strtoull(p1 + 11, NULL, 10);
932 //if reach end,exit loop
933 p1 = fgets(buf, sizeof(buf), p_ctx->all_dat_fp);
934 } while (p1);
935
936 return DVR_SUCCESS;
937}
938
Pengfei Liub4734232020-01-17 18:25:10 +0800939int segment_delete(const char *location, uint64_t segment_id)
940{
941 char fname[MAX_SEGMENT_PATH_SIZE];
942 int ret;
943
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800944 DVR_RETURN_IF_FALSE(location);
Pengfei Liub4734232020-01-17 18:25:10 +0800945
946 /*delete ts file*/
947 memset(fname, 0, sizeof(fname));
948 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_TS);
949 ret = unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000950 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800951 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800952
953 /*delete index file*/
954 memset(fname, 0, sizeof(fname));
955 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_INDEX);
956 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000957 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800958 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800959
960 /*delete store information file*/
961 memset(fname, 0, sizeof(fname));
962 segment_get_fname(fname, location, segment_id, SEGMENT_FILE_TYPE_DAT);
963 unlink(fname);
Wentao MA907b6432022-08-01 06:23:08 +0000964 DVR_ERROR("%s, [%s] return:%s", __func__, fname, strerror(errno));
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800965 DVR_RETURN_IF_FALSE(ret == 0);
Pengfei Liub4734232020-01-17 18:25:10 +0800966
967 return DVR_SUCCESS;
968}
969
hualing chen87072a82020-03-12 16:20:12 +0800970int segment_ongoing(Segment_Handle_t handle)
971{
972 Segment_Context_t *p_ctx;
973 p_ctx = (Segment_Context_t *)handle;
974 struct stat mstat;
975
976 char going_name[MAX_SEGMENT_PATH_SIZE];
977 memset(going_name, 0, sizeof(going_name));
978 segment_get_fname(going_name, p_ctx->location, p_ctx->segment_id, SEGMENT_FILE_TYPE_ONGOING);
979 int ret = stat(going_name, &mstat);
Wentao MA96f68962022-06-15 19:45:35 +0800980 DVR_INFO("segment check ongoing [%s] ret [%d]", going_name, ret);
hualing chen87072a82020-03-12 16:20:12 +0800981 if (ret != 0) {
982 return DVR_FAILURE;
983 }
984 return DVR_SUCCESS;
985}
Wentao MAa3388532022-08-18 15:07:07 +0800986
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800987loff_t segment_dump_pts(Segment_Handle_t handle)
Pengfei Liub038b6a2020-01-14 15:57:01 +0800988{
989 Segment_Context_t *p_ctx;
990 char buf[256];
991 char value[256];
Wentao MA139fc612022-08-29 14:10:07 +0800992 uint64_t pts = 0;
993 loff_t offset = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800994 char *p1, *p2;
Wentao MAa3388532022-08-18 15:07:07 +0800995 int ret = 0;
Pengfei Liub038b6a2020-01-14 15:57:01 +0800996
997 p_ctx = (Segment_Context_t *)handle;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800998 DVR_RETURN_IF_FALSE(p_ctx);
999 DVR_RETURN_IF_FALSE(p_ctx->index_fp);
1000 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001001
1002 memset(buf, 0, sizeof(buf));
Wentao MAa3388532022-08-18 15:07:07 +08001003 ret = fseek(p_ctx->index_fp, 0, SEEK_SET);
1004 DVR_RETURN_IF_FALSE(ret != -1);
1005
Pengfei Liub038b6a2020-01-14 15:57:01 +08001006 printf("start gets pts\n");
1007 while (fgets(buf, sizeof(buf), p_ctx->index_fp) != NULL) {
1008 printf("buf[%s]\n", buf);
1009 memset(value, 0, sizeof(value));
1010 if ((p1 = strstr(buf, "time="))) {
hualing chencc91e1c2020-02-28 13:26:17 +08001011 p1 += 5;
Pengfei Liub038b6a2020-01-14 15:57:01 +08001012 if ((p2 = strstr(buf, ","))) {
1013 memcpy(value, p1, p2 - p1);
1014 }
1015 pts = strtoull(value, NULL, 10);
1016 }
1017
1018 memset(value, 0, sizeof(value));
1019 if ((p1 = strstr(buf, "offset="))) {
1020 p1 += 7;
1021 if ((p2 = strstr(buf, "}"))) {
1022 memcpy(value, p1, p2 - p1);
1023 }
1024 offset = strtoull(value, NULL, 10);
1025 }
1026
1027 memset(buf, 0, sizeof(buf));
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001028 printf("pts=%llu, offset=%lld\n", pts, offset);
Pengfei Liub038b6a2020-01-14 15:57:01 +08001029 }
1030
1031 return 0;
1032}
Wentao MA907b6432022-08-01 06:23:08 +00001033
1034off_t segment_get_cur_segment_size(Segment_Handle_t handle)
1035{
1036 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1037 DVR_RETURN_IF_FALSE(p_ctx);
1038 DVR_RETURN_IF_FALSE(p_ctx->ts_fd != -1);
1039 struct stat sb;
1040 int ret=fstat(p_ctx->ts_fd,&sb);
1041 if (ret<0) {
1042 return -1;
1043 }
1044 return sb.st_size;
1045}
1046
1047uint64_t segment_get_cur_segment_id(Segment_Handle_t handle)
1048{
1049 Segment_Context_t *p_ctx = (Segment_Context_t *)handle;
1050 DVR_RETURN_IF_FALSE(p_ctx);
1051 return p_ctx->segment_id;
1052}
1053