blob: 409957841eb28846a5168cf1f4c1639dbb7361a3 [file] [log] [blame]
Pengfei Liuc181a982020-01-07 19:27:13 +08001#include <stdio.h>
Pengfei Liub4734232020-01-17 18:25:10 +08002#include <unistd.h>
3#include <stdlib.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08004#include <pthread.h>
Pengfei Liub4734232020-01-17 18:25:10 +08005#include <string.h>
Pengfei Liu47ed6c92020-01-17 11:23:41 +08006#include "dvr_types.h"
Pengfei Liuc181a982020-01-07 19:27:13 +08007#include "dvr_record.h"
8#include "dvr_crypto.h"
Gong Ke2a0ebbe2021-05-25 15:22:50 +08009#include "dvb_utils.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080010#include "record_device.h"
pengfei.liu567d6d82020-04-17 16:48:59 +080011#include <sys/time.h>
Wentao MA361eaac2023-03-21 13:12:28 +080012#include <sys/prctl.h>
Yahui Han1fbf3292021-11-08 18:17:19 +080013#include "am_crypt.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080014
Zhiqiang Han2f019af2023-08-31 11:12:02 +080015#include "segment.h"
16#include "segment_dataout.h"
17
hualing chen3092e1c2022-01-21 20:02:21 +080018#define CHECK_PTS_MAX_COUNT (20)
19
hualing chenc7aa4c82021-02-03 15:41:37 +080020//#define DEBUG_PERFORMANCE
Yahui Han10993892021-11-02 14:27:33 +080021#define MAX_DVR_RECORD_SESSION_COUNT 4
hualing chen266b9502020-04-04 17:39:39 +080022#define RECORD_BLOCK_SIZE (256 * 1024)
Yahui Hance15e9c2020-12-08 18:08:32 +080023#define NEW_DEVICE_RECORD_BLOCK_SIZE (1024 * 188)
pengfei.liuab5a2262020-02-14 17:33:40 +080024
25/**\brief DVR index file type*/
26typedef enum {
27 DVR_INDEX_TYPE_PCR, /**< DVR index file use pcr*/
28 DVR_INDEX_TYPE_LOCAL_CLOCK, /**< DVR index file use local clock*/
29 DVR_INDEX_TYPE_INVALID /**< DVR index file type invalid type*/
30} DVR_IndexType_t;
31
32/**\brief DVR VOD context*/
33typedef struct {
34 pthread_mutex_t mutex; /**< VOD mutex lock*/
35 pthread_cond_t cond; /**< VOD condition*/
36 void *buffer; /**< VOD buffer*/
37 uint32_t buf_len; /**< VOD buffer len*/
38} DVR_VodContext_t;
39
pengfei.liu07ddc8a2020-03-24 23:36:53 +080040/**\brief DVR record secure mode buffer*/
41typedef struct {
42 uint32_t addr; /**< Secure mode record buffer address*/
43 uint32_t len; /**< Secure mode record buffer length*/
44} DVR_SecureBuffer_t;
45
hualing chenf9867402020-09-23 17:06:20 +080046/**\brief DVR record new dmx secure mode buffer*/
47typedef struct {
48 uint32_t buf_start; /**< Secure mode record buffer address*/
49 uint32_t buf_end; /**< Secure mode record buffer length*/
50 uint32_t data_start; /**< Secure mode record buffer address*/
51 uint32_t data_end; /**< Secure mode record buffer length*/
52} DVR_NewDmxSecureBuffer_t;
53
Pengfei Liub4734232020-01-17 18:25:10 +080054/**\brief DVR record context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080055typedef struct {
Pengfei Liub4734232020-01-17 18:25:10 +080056 pthread_t thread; /**< DVR thread handle*/
57 Record_DeviceHandle_t dev_handle; /**< DVR device handle*/
58 Segment_Handle_t segment_handle; /**< DVR segment handle*/
59 DVR_RecordState_t state; /**< DVR record state*/
60 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
61 DVR_RecordSegmentStartParams_t segment_params; /**< DVR record start parameters*/
62 DVR_RecordSegmentInfo_t segment_info; /**< DVR record current segment info*/
Wentao MA270dc0f2022-08-23 13:17:26 +080063 size_t notification_size; /**< DVR record notification size*/
Pengfei Liub4734232020-01-17 18:25:10 +080064 DVR_RecordEventFunction_t event_notify_fn; /**< DVR record event notify function*/
65 void *event_userdata; /**< DVR record event userdata*/
pengfei.liuab5a2262020-02-14 17:33:40 +080066 //DVR_VodContext_t vod; /**< DVR record vod context*/
67 int is_vod; /**< Indicate current mode is VOD record mode*/
pengfei.liu27cc4ec2020-04-03 16:28:16 +080068 DVR_CryptoFunction_t enc_func; /**< Encrypt function*/
pengfei.liu07ddc8a2020-03-24 23:36:53 +080069 void *enc_userdata; /**< Encrypt userdata*/
70 int is_secure_mode; /**< Record session run in secure pipeline */
Yahui Han1fbf3292021-11-08 18:17:19 +080071 void *cryptor; /**< Cryptor for encrypted PVR on FTA.*/
hualing chen2615aa82020-04-02 21:32:51 +080072 size_t last_send_size; /**< Last send notify segment size */
pengfei.liufda2a972020-04-09 14:47:15 +080073 uint32_t block_size; /**< DVR record block size */
hualing chenf9867402020-09-23 17:06:20 +080074 DVR_Bool_t is_new_dmx; /**< DVR is used new dmx driver */
hualing chen40accc32021-04-21 15:58:09 +080075 int index_type; /**< DVR is used pcr or local time */
wentao.ma35a69d42022-03-10 18:08:40 +080076 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 chen94d8dd22021-12-29 15:13:43 +080077 uint64_t pts; /**< The newest pcr or local time */
hualing chen3092e1c2022-01-21 20:02:21 +080078 int check_pts_count; /**< The check count of pts */
hualing chen002e5b92022-02-23 17:51:21 +080079 int check_no_pts_count; /**< The check count of no pts */
Wentao MA270dc0f2022-08-23 13:17:26 +080080 int notification_time; /**< DVR record notification time*/
hualing chen002e5b92022-02-23 17:51:21 +080081 time_t last_send_time; /**< Last send notify segment duration */
Wentao MAeeffdb02022-06-27 16:34:35 +080082 loff_t guarded_segment_size; /**< Guarded segment size in bytes. Libdvr will be forcely stopped to write anymore if current segment reaches this size*/
Yahui Han4577db82022-07-05 17:46:19 +080083 size_t secbuf_size; /**< DVR record secure buffer length*/
Wentao MAf4072032022-06-30 13:50:45 +080084 DVR_Bool_t discard_coming_data; /**< Whether to discard subsequent recording data due to exceeding total size limit too much.*/
Zhiqiang Han2f019af2023-08-31 11:12:02 +080085 Segment_Ops_t segment_ops;
86 struct list_head segment_ctrls;
Pengfei Liuc181a982020-01-07 19:27:13 +080087} DVR_RecordContext_t;
88
Zhiqiang Han2f019af2023-08-31 11:12:02 +080089typedef struct {
90 struct list_head head;
91 unsigned int cmd;
92 void *data;
93 size_t size;
94} DVR_Control_t;
95
96#define SEG_CALL_INIT(_ops) Segment_Ops_t *ops = (_ops)
97#define SEG_CALL_RET_VALID(_name, _args, _ret, _def_ret) do {\
98 if (ops->segment_##_name)\
99 (_ret) = ops->segment_##_name _args;\
100 else\
101 (_ret) = (_def_ret);\
102 } while(0);
103#define SEG_CALL_RET(_name, _args, _ret) SEG_CALL_RET_VALID(_name, _args, _ret, _ret)
104#define SEG_CALL(_name, _args) do {\
105 if (ops->segment_##_name)\
106 ops->segment_##_name _args;\
107 } while(0)
108#define SEG_CALL_IS_VALID(_name) (!!ops->segment_##_name)
109
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800110extern ssize_t record_device_read_ext(Record_DeviceHandle_t handle, size_t *buf, size_t *len);
111
Pengfei Liuc181a982020-01-07 19:27:13 +0800112static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
113 {
Pengfei Liub4734232020-01-17 18:25:10 +0800114 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +0800115 },
116 {
Pengfei Liub4734232020-01-17 18:25:10 +0800117 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +0800118 }
119};
120
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800121
122static int record_set_segment_ops(DVR_RecordContext_t *p_ctx, int flags)
123{
124 Segment_Ops_t *ops = &p_ctx->segment_ops;
125
126 memset(ops, 0, sizeof(Segment_Ops_t));
127
128 if (flags & DVR_RECORD_FLAG_DATAOUT) {
129 DVR_INFO("%s segment mode: dataout", __func__);
130 #define _SET(_op)\
131 ops->segment_##_op = segment_dataout_##_op
132 _SET(open);
133 _SET(close);
134 _SET(ioctl);
135 _SET(write);
136 _SET(update_pts);
137 _SET(update_pts_force);
138 _SET(tell_position);
139 _SET(tell_total_time);
140 _SET(store_info);
141 _SET(store_allInfo);
142 #undef _SET
143 } else {
144 #define _SET(_op)\
145 ops->segment_##_op = segment_##_op
146 _SET(open);
147 _SET(close);
148 _SET(read);
149 _SET(write);
150 _SET(update_pts);
151 _SET(update_pts_force);
152 _SET(seek);
153 _SET(tell_position);
154 _SET(tell_position_time);
155 _SET(tell_current_time);
156 _SET(tell_total_time);
157 _SET(store_info);
158 _SET(store_allInfo);
159 _SET(load_info);
160 _SET(load_allInfo);
161 _SET(delete);
162 _SET(ongoing);
163 _SET(get_cur_segment_size);
164 _SET(get_cur_segment_id);
165 #undef _SET
166 }
167 return DVR_SUCCESS;
168}
169
Zhiqiang Han51646a02020-04-05 18:43:22 +0800170static int record_is_valid_pid(DVR_RecordContext_t *p_ctx, int pid)
171{
172 int i;
173
174 for (i = 0; i < p_ctx->segment_info.nb_pids; i++) {
175 if (pid == p_ctx->segment_info.pids[i].pid)
176 return 1;
177 }
178 return 0;
179}
180
pengfei.liuab5a2262020-02-14 17:33:40 +0800181static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
182{
183 uint8_t *p = buf;
184 int len;
185 uint8_t afc;
186 uint64_t pcr = 0;
187 int has_pcr = 0;
188 int pid;
189 int adp_field_len;
190
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800191 SEG_CALL_INIT(&p_ctx->segment_ops);
192
pengfei.liuab5a2262020-02-14 17:33:40 +0800193 pid = ((p[1] & 0x1f) << 8) | p[2];
Zhiqiang Han51646a02020-04-05 18:43:22 +0800194 if (pid == 0x1fff || !record_is_valid_pid(p_ctx, pid))
pengfei.liuab5a2262020-02-14 17:33:40 +0800195 return has_pcr;
196
197 //scramble = p[3] >> 6;
198 //cc = p[3] & 0x0f;
199 afc = (p[3] >> 4) & 0x03;
200
201 p += 4;
202 len = 184;
203
204 if (afc & 2) {
205 adp_field_len = p[0];
206 /* Skip adaptation len */
207 p++;
208 len--;
209 /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
hualing chen5605eed2020-05-26 18:18:06 +0800210 if (p[0] & 0x10 && len >= 6 && adp_field_len >= 6) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800211 /* get pcr value,pcr is 33bit value */
212 pcr = (((uint64_t)(p[1])) << 25)
213 | (((uint64_t)p[2]) << 17)
214 | (((uint64_t)(p[3])) << 9)
215 | (((uint64_t)p[4]) << 1)
216 | ((((uint64_t)p[5]) & 0x80) >> 7);
217 has_pcr = 1;
218 }
219
pengfei.liuab5a2262020-02-14 17:33:40 +0800220 len -= adp_field_len;
221
222 if (len < 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800223 DVR_INFO("parser pcr: illegal adaptation field length");
pengfei.liuab5a2262020-02-14 17:33:40 +0800224 return 0;
225 }
226 }
227
hualing chen40accc32021-04-21 15:58:09 +0800228 if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
hualing chen94d8dd22021-12-29 15:13:43 +0800229 //save newest pcr
hualing chen3092e1c2022-01-21 20:02:21 +0800230 if (p_ctx->pts == pcr/90 &&
231 p_ctx->check_pts_count < CHECK_PTS_MAX_COUNT) {
hualing chen3092e1c2022-01-21 20:02:21 +0800232 p_ctx->check_pts_count ++;
233 }
hualing chen94d8dd22021-12-29 15:13:43 +0800234 p_ctx->pts = pcr/90;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800235
236 SEG_CALL(update_pts, (p_ctx->segment_handle, pcr/90, pos));
pengfei.liuab5a2262020-02-14 17:33:40 +0800237 }
238 return has_pcr;
239}
240
241static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
242{
243 uint8_t *p = buf;
244 int left = len;
245 loff_t pos;
246 int has_pcr = 0;
247
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800248 SEG_CALL_INIT(&p_ctx->segment_ops);
249
250 SEG_CALL_RET_VALID(tell_position, (p_ctx->segment_handle), pos, -1);
251
252 if (pos == -1)
253 return has_pcr;
254
hualing chen3e0d3a42022-01-25 17:22:01 +0800255 if (pos >= len) {
256 pos = pos - len;
257 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800258 while (left >= 188) {
259 if (*p == 0x47) {
260 has_pcr |= record_save_pcr(p_ctx, p, pos);
261 p += 188;
262 left -= 188;
263 pos += 188;
264 } else {
265 p++;
266 left --;
267 pos++;
268 }
269 }
270 return has_pcr;
271}
272
pengfei.liu567d6d82020-04-17 16:48:59 +0800273static int get_diff_time(struct timeval start_tv, struct timeval end_tv)
274{
275 return end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000 - start_tv.tv_sec * 1000 - start_tv.tv_usec / 1000;
276}
277
Pengfei Liuc181a982020-01-07 19:27:13 +0800278void *record_thread(void *arg)
279{
280 DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
281 ssize_t len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800282 uint8_t *buf, *buf_out;
pengfei.liufda2a972020-04-09 14:47:15 +0800283 uint32_t block_size = p_ctx->block_size;
pengfei.liuab5a2262020-02-14 17:33:40 +0800284 loff_t pos = 0;
Wentao MA139fc612022-08-29 14:10:07 +0800285 int ret = DVR_SUCCESS;
Wentao MA270dc0f2022-08-23 13:17:26 +0800286 struct timespec start_ts, end_ts, start_no_pcr_ts, end_no_pcr_ts;
Pengfei Liub4734232020-01-17 18:25:10 +0800287 DVR_RecordStatus_t record_status;
pengfei.liuab5a2262020-02-14 17:33:40 +0800288 int has_pcr;
hualing chen3092e1c2022-01-21 20:02:21 +0800289 int pcr_rec_len = 0;
Wentao MAeeffdb02022-06-27 16:34:35 +0800290 DVR_Bool_t guarded_size_exceeded = DVR_FALSE;
hualing chen40accc32021-04-21 15:58:09 +0800291
hualing chen87072a82020-03-12 16:20:12 +0800292 time_t pre_time = 0;
hualing chen2932d372020-04-29 13:44:00 +0800293 #define DVR_STORE_INFO_TIME (400)
Wentao MA139fc612022-08-29 14:10:07 +0800294 DVR_SecureBuffer_t secure_buf = {0,0};
hualing chenf9867402020-09-23 17:06:20 +0800295 DVR_NewDmxSecureBuffer_t new_dmx_secure_buf;
hualing chena5f03222021-12-02 11:22:35 +0800296 int first_read = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800297
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800298 SEG_CALL_INIT(&p_ctx->segment_ops);
299
Wentao MA361eaac2023-03-21 13:12:28 +0800300 prctl(PR_SET_NAME,"DvrRecording");
301
wentao.ma35a69d42022-03-10 18:08:40 +0800302 // Force to use LOCAL_CLOCK as index type if force_sysclock is on. Please
303 // refer to SWPL-75327
304 if (p_ctx->force_sysclock)
305 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
shenghui.gengbec6a462023-01-12 15:21:02 +0800306 else
307 p_ctx->index_type = DVR_INDEX_TYPE_INVALID;
Pengfei Liub4734232020-01-17 18:25:10 +0800308 buf = (uint8_t *)malloc(block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800309 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +0800310 DVR_INFO("%s, malloc failed", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800311 return NULL;
312 }
Wentao MAe2a2db92024-08-26 16:21:41 +0800313 memset(buf,0,block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800314
Yahui Han4577db82022-07-05 17:46:19 +0800315 if (p_ctx->is_secure_mode) {
316 buf_out = (uint8_t *)malloc(p_ctx->secbuf_size + 188);
317 } else {
318 buf_out = (uint8_t *)malloc(block_size + 188);
319 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800320 if (!buf_out) {
Wentao MA96f68962022-06-15 19:45:35 +0800321 DVR_INFO("%s, malloc failed", __func__);
Pengfei Liufaf38e42020-05-22 00:28:02 +0800322 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800323 return NULL;
324 }
325
hualing chen266b9502020-04-04 17:39:39 +0800326 memset(&record_status, 0, sizeof(record_status));
327 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800328 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800329 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800330 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
Wentao MA96f68962022-06-15 19:45:35 +0800331 DVR_INFO("%s line %d notify record status, state:%d id=%lld",
hualing chen4b7c15d2020-04-07 16:13:48 +0800332 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800333 }
Wentao MA96f68962022-06-15 19:45:35 +0800334 DVR_INFO("%s, --secure_mode:%d, block_size:%d, cryptor:%p",
hualing chen002e5b92022-02-23 17:51:21 +0800335 __func__, p_ctx->is_secure_mode,
336 block_size, p_ctx->cryptor);
Pengfei Liub4734232020-01-17 18:25:10 +0800337 clock_gettime(CLOCK_MONOTONIC, &start_ts);
hualing chen3092e1c2022-01-21 20:02:21 +0800338 p_ctx->check_pts_count = 0;
339 p_ctx->check_no_pts_count++;
hualing chen002e5b92022-02-23 17:51:21 +0800340 p_ctx->last_send_size = 0;
341 p_ctx->last_send_time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800342 struct timeval t1, t2, t3, t4, t5, t6, t7;
hualing chen03fd4942021-07-15 15:56:41 +0800343 while (p_ctx->state == DVR_RECORD_STATE_STARTED ||
344 p_ctx->state == DVR_RECORD_STATE_PAUSE) {
345
pengfei.liu567d6d82020-04-17 16:48:59 +0800346 gettimeofday(&t1, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800347
pengfei.liuab5a2262020-02-14 17:33:40 +0800348 /* data from dmx, normal dvr case */
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800349 if (p_ctx->is_secure_mode) {
hualing chenf9867402020-09-23 17:06:20 +0800350 if (p_ctx->is_new_dmx) {
Wentao MA804bab12022-11-29 10:01:26 +0800351 /* We resolve the below invoke for dvbcore to be under safety status */
352 memset(&new_dmx_secure_buf, 0, sizeof(new_dmx_secure_buf));
Wentao MAe2a2db92024-08-26 16:21:41 +0800353 record_device_read(p_ctx->dev_handle, &new_dmx_secure_buf,
Wentao MA804bab12022-11-29 10:01:26 +0800354 sizeof(new_dmx_secure_buf), 10);
Yahui Hance15e9c2020-12-08 18:08:32 +0800355
Wentao MA804bab12022-11-29 10:01:26 +0800356 /* Read data from secure demux TA */
357 len = record_device_read_ext(p_ctx->dev_handle, &secure_buf.addr,
358 &secure_buf.len);
hualing chenf9867402020-09-23 17:06:20 +0800359 } else {
360 memset(&secure_buf, 0, sizeof(secure_buf));
Wentao MA804bab12022-11-29 10:01:26 +0800361 len = record_device_read(p_ctx->dev_handle, &secure_buf,
362 sizeof(secure_buf), 1000);
hualing chenf9867402020-09-23 17:06:20 +0800363 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800364 } else {
365 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
366 }
Pengfei Liub4734232020-01-17 18:25:10 +0800367 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800368 //usleep(10*1000);
Wentao MA96f68962022-06-15 19:45:35 +0800369 //DVR_INFO("%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800370 continue;
371 }
Wentao MA41532372024-02-28 12:22:02 +0800372 if (p_ctx->state == DVR_RECORD_STATE_PAUSE) {
373 //wait resume record
374 usleep(20*1000);
375 continue;
376 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800377 gettimeofday(&t2, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800378
Wentao MAeeffdb02022-06-27 16:34:35 +0800379 guarded_size_exceeded = DVR_FALSE;
wentao.mad08db842022-11-14 17:35:40 +0800380 if ( p_ctx->guarded_segment_size > 0 &&
381 p_ctx->segment_info.size+len >= p_ctx->guarded_segment_size) {
Wentao MAeeffdb02022-06-27 16:34:35 +0800382 guarded_size_exceeded = DVR_TRUE;
383 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800384 /* Got data from device, record it */
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800385 ret = 0;
Wentao MAeeffdb02022-06-27 16:34:35 +0800386 if (guarded_size_exceeded) {
387 len = 0;
388 ret = 0;
Wentao MAf4072032022-06-30 13:50:45 +0800389 DVR_ERROR("Skip segment_write due to current segment size %u exceeding"
390 " guarded segment size", p_ctx->segment_info.size);
391 } else if (p_ctx->discard_coming_data) {
392 len = 0;
393 ret = 0;
394 DVR_ERROR("Skip segment_write due to total size exceeding max size too much");
Wentao MAeeffdb02022-06-27 16:34:35 +0800395 } else if (p_ctx->enc_func) {
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800396 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800397 DVR_CryptoParams_t crypto_params;
398
399 memset(&crypto_params, 0, sizeof(crypto_params));
400 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800401 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800402 crypto_params.segment_id = p_ctx->segment_info.id;
403 crypto_params.offset = p_ctx->segment_info.size;
404
405 if (p_ctx->is_secure_mode) {
406 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
Yahui Han1fbf3292021-11-08 18:17:19 +0800407 crypto_params.input_buffer.addr = secure_buf.addr;
408 crypto_params.input_buffer.size = secure_buf.len;
Yahui Hanaf03b142022-08-17 17:52:37 +0800409 crypto_params.output_buffer.size = p_ctx->secbuf_size + 188;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800410 } else {
411 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
412 crypto_params.input_buffer.addr = (size_t)buf;
413 crypto_params.input_buffer.size = len;
Yahui Hanaf03b142022-08-17 17:52:37 +0800414 crypto_params.output_buffer.size = block_size + 188;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800415 }
416
417 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
418 crypto_params.output_buffer.addr = (size_t)buf_out;
hualing chen9811b212020-10-29 11:21:44 +0800419
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800420 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800421 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800422 /* Out buffer length may not equal in buffer length */
hualing chenf9867402020-09-23 17:06:20 +0800423 if (crypto_params.output_size > 0) {
Wentao MAe2a2db92024-08-26 16:21:41 +0800424 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800425 SEG_CALL_RET(write, (p_ctx->segment_handle, buf_out, crypto_params.output_size), ret);
hualing chenf9867402020-09-23 17:06:20 +0800426 len = crypto_params.output_size;
hualing chenbafc62d2020-11-02 15:44:05 +0800427 } else {
428 len = 0;
hualing chenf9867402020-09-23 17:06:20 +0800429 }
Yahui Han1fbf3292021-11-08 18:17:19 +0800430 } else if (p_ctx->cryptor) {
431 /* Encrypt with clear key */
Yahui Han63b23b42021-12-07 15:37:46 +0800432 int crypt_len = len;
433 am_crypt_des_crypt(p_ctx->cryptor, buf_out, buf, &crypt_len, 0);
434 len = crypt_len;
Yahui Han1fbf3292021-11-08 18:17:19 +0800435 gettimeofday(&t3, NULL);
Wentao MAe2a2db92024-08-26 16:21:41 +0800436 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800437 SEG_CALL_RET(write, (p_ctx->segment_handle, buf_out, len), ret);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800438 } else {
hualing chena5f03222021-12-02 11:22:35 +0800439 if (first_read == 0) {
440 first_read = 1;
Wentao MA96f68962022-06-15 19:45:35 +0800441 DVR_INFO("%s:%d,first read ts", __func__,__LINE__);
hualing chena5f03222021-12-02 11:22:35 +0800442 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800443 gettimeofday(&t3, NULL);
Wentao MAe2a2db92024-08-26 16:21:41 +0800444 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800445 SEG_CALL_RET(write, (p_ctx->segment_handle, buf, len), ret);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800446 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800447 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800448 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800449 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800450 //send write event
hualing chen9b434f02020-06-10 15:06:54 +0800451 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800452 memset(&record_status, 0, sizeof(record_status));
Wentao MAeeffdb02022-06-27 16:34:35 +0800453 DVR_INFO("%s:%d,send event write error", __func__,__LINE__);
hualing chen9ce7d942021-06-30 13:31:01 +0800454 record_status.info.id = p_ctx->segment_info.id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800455 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
456 }
Wentao MA96f68962022-06-15 19:45:35 +0800457 DVR_INFO("%s,write error %d", __func__,__LINE__);
hualing chen626204e2020-04-07 11:55:08 +0800458 goto end;
459 }
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800460
461 if (len > 0 && SEG_CALL_IS_VALID(tell_position)) {
Wentao MAf4072032022-06-30 13:50:45 +0800462 /* Do time index */
463 uint8_t *index_buf = (p_ctx->enc_func || p_ctx->cryptor)? buf_out : buf;
Wentao MAe2a2db92024-08-26 16:21:41 +0800464 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800465 SEG_CALL_RET(tell_position, (p_ctx->segment_handle), pos);
Wentao MAf4072032022-06-30 13:50:45 +0800466 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
467 if (has_pcr == 0 && p_ctx->index_type == DVR_INDEX_TYPE_INVALID) {
468 clock_gettime(CLOCK_MONOTONIC, &end_ts);
469 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
470 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800471 /* PCR interval threshold > 40 ms*/
Wentao MAf4072032022-06-30 13:50:45 +0800472 DVR_INFO("%s use local clock time index", __func__);
hualing chen3092e1c2022-01-21 20:02:21 +0800473 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
Wentao MAf4072032022-06-30 13:50:45 +0800474 }
475 } else if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_INVALID){
476 DVR_INFO("%s use pcr time index", __func__);
477 p_ctx->index_type = DVR_INDEX_TYPE_PCR;
478 record_do_pcr_index(p_ctx, index_buf, len);
479 }
480 gettimeofday(&t5, NULL);
481 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
482 if (has_pcr == 0) {
483 if (p_ctx->check_no_pts_count < 2 * CHECK_PTS_MAX_COUNT) {
484 if (p_ctx->check_no_pts_count == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800485 clock_gettime(CLOCK_MONOTONIC, &start_no_pcr_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800486 clock_gettime(CLOCK_MONOTONIC, &start_ts);
487 }
488 p_ctx->check_no_pts_count++;
489 }
490 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +0800491 clock_gettime(CLOCK_MONOTONIC, &start_no_pcr_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800492 p_ctx->check_no_pts_count = 0;
493 }
494 }
495 /* Update segment i nfo */
496 p_ctx->segment_info.size += len;
Pengfei Liub4734232020-01-17 18:25:10 +0800497
Wentao MAf4072032022-06-30 13:50:45 +0800498 /*Duration need use pcr to calculate, todo...*/
499 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
Wentao MAe2a2db92024-08-26 16:21:41 +0800500 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800501 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), p_ctx->segment_info.duration);
Wentao MAf4072032022-06-30 13:50:45 +0800502 if (pre_time == 0)
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800503 pre_time = p_ctx->segment_info.duration;
Wentao MAf4072032022-06-30 13:50:45 +0800504 } else if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
505 clock_gettime(CLOCK_MONOTONIC, &end_ts);
506 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
507 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) + pcr_rec_len;
508 if (pre_time == 0)
509 pre_time = p_ctx->segment_info.duration;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800510 SEG_CALL(update_pts, (p_ctx->segment_handle, p_ctx->segment_info.duration, pos));
Wentao MAf4072032022-06-30 13:50:45 +0800511 } else {
512 DVR_INFO("%s can NOT do time index", __func__);
513 }
514 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR &&
515 p_ctx->check_pts_count == CHECK_PTS_MAX_COUNT) {
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800516 DVR_INFO("%s change time from pcr to local time", __func__);
517 if (pcr_rec_len == 0) {
Wentao MAe2a2db92024-08-26 16:21:41 +0800518 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800519 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), pcr_rec_len);
520 }
521 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
522 if (pcr_rec_len == 0) {
Wentao MAe2a2db92024-08-26 16:21:41 +0800523 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800524 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), pcr_rec_len);
525 }
526 clock_gettime(CLOCK_MONOTONIC, &start_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800527 }
528
529 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR ) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800530 clock_gettime(CLOCK_MONOTONIC, &end_no_pcr_ts);
531 int diff = (int)(end_no_pcr_ts.tv_sec*1000 + end_no_pcr_ts.tv_nsec/1000000) -
532 (int)(start_no_pcr_ts.tv_sec*1000 + start_no_pcr_ts.tv_nsec/1000000);
Wentao MAf4072032022-06-30 13:50:45 +0800533 if (diff > 3000) {
534 DVR_INFO("%s no pcr change time from pcr to local time diff[%d]", __func__, diff);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800535 if (pcr_rec_len == 0) {
Wentao MAe2a2db92024-08-26 16:21:41 +0800536 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800537 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), pcr_rec_len);
538 }
Wentao MAf4072032022-06-30 13:50:45 +0800539 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
540 }
541 }
542 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
543
544 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
545 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
546 time_t duration = p_ctx->segment_info.duration;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800547 if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
Wentao MAe2a2db92024-08-26 16:21:41 +0800548 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800549 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), p_ctx->segment_info.duration);
550 }
551 SEG_CALL(store_info, (p_ctx->segment_handle, &p_ctx->segment_info));
Wentao MAf4072032022-06-30 13:50:45 +0800552 p_ctx->segment_info.duration = duration;
553 }
554 } else {
555 gettimeofday(&t5, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800556 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800557 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800558 /*Event notification*/
Wentao MAf4072032022-06-30 13:50:45 +0800559 DVR_Bool_t condA1 = (p_ctx->notification_size > 0);
560 DVR_Bool_t condA2 = ((p_ctx->segment_info.size-p_ctx->last_send_size) >= p_ctx->notification_size);
561 DVR_Bool_t condA3 = (p_ctx->notification_time > 0);
562 DVR_Bool_t condA4 = ((p_ctx->segment_info.duration-p_ctx->last_send_time) >= p_ctx->notification_time);
563 DVR_Bool_t condA5 = (guarded_size_exceeded);
564 DVR_Bool_t condA6 = (p_ctx->discard_coming_data);
565 DVR_Bool_t condB = (p_ctx->event_notify_fn != NULL);
566 DVR_Bool_t condC = (p_ctx->segment_info.duration > 0);
567 DVR_Bool_t condD = (p_ctx->state == DVR_RECORD_STATE_STARTED);
568 if (((condA1 && condA2) || (condA3 && condA4) || condA5 || condA6)
569 && condB && condC && condD) {
Pengfei Liub4734232020-01-17 18:25:10 +0800570 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800571 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800572 p_ctx->last_send_size = p_ctx->segment_info.size;
hualing chen002e5b92022-02-23 17:51:21 +0800573 p_ctx->last_send_time = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800574 record_status.state = p_ctx->state;
575 record_status.info.id = p_ctx->segment_info.id;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800576 if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
Wentao MAe2a2db92024-08-26 16:21:41 +0800577 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800578 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), record_status.info.duration);
579 } else
hualing chenc94227e2022-02-17 09:48:43 +0800580 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800581 record_status.info.size = p_ctx->segment_info.size;
582 record_status.info.nb_packets = p_ctx->segment_info.size/188;
583 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
Wentao MA96f68962022-06-15 19:45:35 +0800584 DVR_INFO("%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu loc[%s]",
hualing chen4fe3bee2020-10-23 13:58:52 +0800585 __func__, record_status.state,
586 record_status.info.id, record_status.info.duration,
587 record_status.info.size, p_ctx->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800588 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800589 gettimeofday(&t7, NULL);
590#ifdef DEBUG_PERFORMANCE
Wentao MA96f68962022-06-15 19:45:35 +0800591 DVR_INFO("record count, read:%dms, encrypt:%dms, write:%dms, index:%dms, store:%dms, notify:%dms total:%dms read len:%zd notify [%d]diff[%d]",
pengfei.liu567d6d82020-04-17 16:48:59 +0800592 get_diff_time(t1, t2), get_diff_time(t2, t3), get_diff_time(t3, t4), get_diff_time(t4, t5),
hualing chen002e5b92022-02-23 17:51:21 +0800593 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len,
594 p_ctx->notification_time,p_ctx->segment_info.duration -p_ctx->last_send_time);
pengfei.liu567d6d82020-04-17 16:48:59 +0800595#endif
Wentao MAf4072032022-06-30 13:50:45 +0800596 if (len == 0) {
597 usleep(20*1000);
598 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800599 }
hualing chen626204e2020-04-07 11:55:08 +0800600end:
Pengfei Liub4734232020-01-17 18:25:10 +0800601 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800602 free((void *)buf_out);
Wentao MA96f68962022-06-15 19:45:35 +0800603 DVR_INFO("exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800604 return NULL;
605}
606
607int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
608{
609 DVR_RecordContext_t *p_ctx;
610 Record_DeviceOpenParams_t dev_open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800611 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800612 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800613
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800614 DVR_RETURN_IF_FALSE(p_handle);
615 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800616
617 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800618 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800619 break;
620 }
621 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800622 DVR_RETURN_IF_FALSE(i < MAX_DVR_RECORD_SESSION_COUNT);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800623 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800624 p_ctx = &record_ctx[i];
Wentao MA96f68962022-06-15 19:45:35 +0800625 DVR_INFO("%s , current state:%d, dmx_id:%d, notification_size:%zu, flags:%d, keylen:%d ",
Yahui Han1fbf3292021-11-08 18:17:19 +0800626 __func__, p_ctx->state, params->dmx_dev_id,
hualing chen002e5b92022-02-23 17:51:21 +0800627 params->notification_size,
628 params->flags, params->keylen);
Pengfei Liuc181a982020-01-07 19:27:13 +0800629
Pengfei Liub4734232020-01-17 18:25:10 +0800630 /*Process event params*/
631 p_ctx->notification_size = params->notification_size;
hualing chen002e5b92022-02-23 17:51:21 +0800632 p_ctx->notification_time = params->notification_time;
633
Pengfei Liub4734232020-01-17 18:25:10 +0800634 p_ctx->event_notify_fn = params->event_fn;
635 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800636 p_ctx->last_send_size = 0;
hualing chen002e5b92022-02-23 17:51:21 +0800637 p_ctx->last_send_time = 0;
hualing chen94d8dd22021-12-29 15:13:43 +0800638 p_ctx->pts = ULLONG_MAX;
Yahui Han1fbf3292021-11-08 18:17:19 +0800639
640 if (params->keylen > 0) {
641 p_ctx->cryptor = am_crypt_des_open(params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +0800642 params->cleariv,
643 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +0800644 if (!p_ctx->cryptor)
Wentao MA96f68962022-06-15 19:45:35 +0800645 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +0800646 } else {
647 p_ctx->cryptor = NULL;
648 }
649
hualing chenf9867402020-09-23 17:06:20 +0800650 //check is new driver
651 p_ctx->is_new_dmx = dvr_check_dmx_isNew();
Pengfei Liub4734232020-01-17 18:25:10 +0800652 /*Process crypto params, todo*/
Pengfei Liub4734232020-01-17 18:25:10 +0800653 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800654 if (params->data_from_memory) {
655 /* data from memory, VOD case */
656 p_ctx->is_vod = 1;
657 } else {
658 p_ctx->is_vod = 0;
659 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800660 dev_open_params.dmx_dev_id = params->dmx_dev_id;
hualing chen157641d2022-02-22 17:54:52 +0800661 //set dvr flush size
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800662 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen157641d2022-02-22 17:54:52 +0800663 //set dvbcore ringbuf size
hualing chen03fd4942021-07-15 15:56:41 +0800664 dev_open_params.ringbuf_size = params->ringbuf_size;
hualing chen157641d2022-02-22 17:54:52 +0800665
pengfei.liuab5a2262020-02-14 17:33:40 +0800666 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
667 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +0800668 DVR_INFO("%s, open record devices failed", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800669 return DVR_FAILURE;
670 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800671 }
672
pengfei.liufda2a972020-04-09 14:47:15 +0800673 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen157641d2022-02-22 17:54:52 +0800674
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800675 p_ctx->enc_func = NULL;
676 p_ctx->enc_userdata = NULL;
677 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800678 p_ctx->state = DVR_RECORD_STATE_OPENED;
wentao.ma35a69d42022-03-10 18:08:40 +0800679 p_ctx->force_sysclock = params->force_sysclock;
Wentao MAeeffdb02022-06-27 16:34:35 +0800680 p_ctx->guarded_segment_size = params->guarded_segment_size;
wentao.mad08db842022-11-14 17:35:40 +0800681 if (p_ctx->guarded_segment_size <= 0) {
682 DVR_WARN("Odd guarded_segment_size value %lld is given. Change it to"
683 " 0 to disable segment guarding mechanism.", p_ctx->guarded_segment_size);
684 p_ctx->guarded_segment_size = 0;
685 }
Wentao MAf4072032022-06-30 13:50:45 +0800686 p_ctx->discard_coming_data = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +0800687 DVR_INFO("%s, block_size:%d is_new:%d", __func__, p_ctx->block_size, p_ctx->is_new_dmx);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800688
689 record_set_segment_ops(p_ctx, params->flags);
690 INIT_LIST_HEAD(&p_ctx->segment_ctrls);
691
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800692 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800693 return DVR_SUCCESS;
694}
695
696int dvr_record_close(DVR_RecordHandle_t handle)
697{
698 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800699 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800700 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800701
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800702 p_ctx = (DVR_RecordContext_t *)handle;
703 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
704 if (p_ctx == &record_ctx[i])
705 break;
706 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800707 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800708
Wentao MA96f68962022-06-15 19:45:35 +0800709 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800710 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Yahui Han1fbf3292021-11-08 18:17:19 +0800711 if (p_ctx->cryptor) {
712 am_crypt_des_close(p_ctx->cryptor);
713 p_ctx->cryptor = NULL;
714 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800715 if (p_ctx->is_vod) {
716 ret = DVR_SUCCESS;
717 } else {
718 ret = record_device_close(p_ctx->dev_handle);
719 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +0800720 DVR_INFO("%s, failed", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800721 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800722 }
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800723
724 if (!list_empty(&p_ctx->segment_ctrls)) {
725 DVR_Control_t *pc, *pc_tmp;
726 list_for_each_entry_safe(pc, pc_tmp, &p_ctx->segment_ctrls, head) {
727 list_del(&pc->head);
728 if (pc->data)
729 free(pc->data);
730 free(pc);
731 }
732 }
733
hualing chencedcb862022-01-04 15:32:43 +0800734 memset(p_ctx, 0, sizeof(DVR_RecordContext_t));
Pengfei Liub4734232020-01-17 18:25:10 +0800735 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800736 return ret;
737}
738
hualing chen03fd4942021-07-15 15:56:41 +0800739int dvr_record_pause(DVR_RecordHandle_t handle)
740{
741 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800742 int ret = DVR_SUCCESS;
hualing chen03fd4942021-07-15 15:56:41 +0800743 uint32_t i;
744
745 p_ctx = (DVR_RecordContext_t *)handle;
746 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
747 if (p_ctx == &record_ctx[i])
748 break;
749 }
750 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
751
Wentao MA96f68962022-06-15 19:45:35 +0800752 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
hualing chen03fd4942021-07-15 15:56:41 +0800753 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
754
755 if (p_ctx->is_vod) {
756 ret = DVR_SUCCESS;
757 }
758 //set pause state,will not store ts into segment
759 p_ctx->state = DVR_RECORD_STATE_PAUSE;
760 return ret;
761}
762
763int dvr_record_resume(DVR_RecordHandle_t handle)
764{
765 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800766 int ret = DVR_SUCCESS;
hualing chen03fd4942021-07-15 15:56:41 +0800767 uint32_t i;
768
769 p_ctx = (DVR_RecordContext_t *)handle;
770 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
771 if (p_ctx == &record_ctx[i])
772 break;
773 }
774 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
775
Wentao MA96f68962022-06-15 19:45:35 +0800776 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
hualing chen03fd4942021-07-15 15:56:41 +0800777 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
778
779 if (p_ctx->is_vod) {
780 ret = DVR_SUCCESS;
781 }
782 //set stated state,will resume store ts into segment
783 p_ctx->state = DVR_RECORD_STATE_STARTED;
784 return ret;
785}
786
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800787#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800788int dvr_record_register_encryption(DVR_RecordHandle_t handle,
789 DVR_CryptoFunction_t cb,
790 DVR_CryptoParams_t params,
791 void *userdata)
792{
793 return DVR_SUCCESS;
794}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800795#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800796
797int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
798{
799 DVR_RecordContext_t *p_ctx;
800 Segment_OpenParams_t open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800801 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800802 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800803
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800804 p_ctx = (DVR_RecordContext_t *)handle;
805 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
806 if (p_ctx == &record_ctx[i])
807 break;
808 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800809 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800810
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800811 SEG_CALL_INIT(&p_ctx->segment_ops);
812
Wentao MA96f68962022-06-15 19:45:35 +0800813 DVR_INFO("%s , current state:%d pids:%d params->location:%s", __func__, p_ctx->state, params->segment.nb_pids, params->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800814 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
815 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
816 DVR_RETURN_IF_FALSE(params);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800817 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800818
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800819 if (SEG_CALL_IS_VALID(open)) {
820 memset(&open_params, 0, sizeof(open_params));
821
822 memcpy(open_params.location, params->location, sizeof(params->location));
823 open_params.segment_id = params->segment.segment_id;
824 open_params.mode = SEGMENT_MODE_WRITE;
825 open_params.force_sysclock = p_ctx->force_sysclock;
826
Wentao MAe2a2db92024-08-26 16:21:41 +0800827 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800828 SEG_CALL_RET(open, (&open_params, &p_ctx->segment_handle), ret);
829 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
830
831 if (SEG_CALL_IS_VALID(ioctl)) {
832 DVR_Control_t *pc;
833 list_for_each_entry(pc, &p_ctx->segment_ctrls, head) {
Wentao MAe2a2db92024-08-26 16:21:41 +0800834 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800835 SEG_CALL_RET(ioctl, (p_ctx->segment_handle, pc->cmd, pc->data, pc->size), ret);
836 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
837 }
838 }
839 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800840
Pengfei Liub4734232020-01-17 18:25:10 +0800841 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800842 {
hualing chen7a56cba2020-04-14 14:09:27 +0800843 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800844 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800845 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800846 /*save current segment info*/
847 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
848 p_ctx->segment_info.id = params->segment.segment_id;
849 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
850 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800851 }
852
pengfei.liuab5a2262020-02-14 17:33:40 +0800853 if (!p_ctx->is_vod) {
854 /* normal dvr case */
855 for (i = 0; i < params->segment.nb_pids; i++) {
856 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
857 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
858 }
859 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800860 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800861 }
862
Wentao MAe2a2db92024-08-26 16:21:41 +0800863 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800864 SEG_CALL_RET(store_info, (p_ctx->segment_handle, &p_ctx->segment_info), ret);
wentao.maa210e5e2022-10-12 16:10:03 +0800865 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800866
Pengfei Liuc181a982020-01-07 19:27:13 +0800867 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800868 if (!p_ctx->is_vod)
869 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800870
Pengfei Liuc181a982020-01-07 19:27:13 +0800871 return DVR_SUCCESS;
872}
873
874int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
875{
876 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800877 Segment_OpenParams_t open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800878 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800879 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800880 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800881
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800882 p_ctx = (DVR_RecordContext_t *)handle;
883 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
884 if (p_ctx == &record_ctx[i])
885 break;
886 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800887 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800888
Wentao MA96f68962022-06-15 19:45:35 +0800889 DVR_INFO("%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800890 DVR_RETURN_IF_FALSE(p_ctx->state == DVR_RECORD_STATE_STARTED);
891 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
892 DVR_RETURN_IF_FALSE(params);
893 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800894 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800895
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800896 SEG_CALL_INIT(&p_ctx->segment_ops);
897
Pengfei Liuc181a982020-01-07 19:27:13 +0800898 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800899 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800900 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800901 p_ctx->state = DVR_RECORD_STATE_STOPPED;
902 pthread_join(p_ctx->thread, NULL);
903
hualing chen2932d372020-04-29 13:44:00 +0800904 //add index file store
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800905 if (SEG_CALL_IS_VALID(update_pts_force)) {
906 SEG_CALL_RET_VALID(tell_position, (p_ctx->segment_handle), pos, -1);
907 if (pos != -1) {
908 SEG_CALL(update_pts_force, (p_ctx->segment_handle, p_ctx->segment_info.duration, pos));
909 }
910 }
hualing chen2932d372020-04-29 13:44:00 +0800911
Wentao MAe2a2db92024-08-26 16:21:41 +0800912 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800913 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), p_ctx->segment_info.duration);
914
Pengfei Liub4734232020-01-17 18:25:10 +0800915 /*Update segment info*/
916 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
917
Wentao MAe2a2db92024-08-26 16:21:41 +0800918 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800919 SEG_CALL_RET(store_info, (p_ctx->segment_handle, p_info), ret);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800920 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800921
922 SEG_CALL(store_allInfo, (p_ctx->segment_handle, p_info));
923
Wentao MA96f68962022-06-15 19:45:35 +0800924 DVR_INFO("%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d params->segment.nb_pids:%d",
hualing chena540a7e2020-03-27 16:44:05 +0800925 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets, params->segment.nb_pids);
Pengfei Liuc181a982020-01-07 19:27:13 +0800926
Pengfei Liub4734232020-01-17 18:25:10 +0800927 /*Close current segment*/
Wentao MAe2a2db92024-08-26 16:21:41 +0800928 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800929 SEG_CALL_RET(close, (p_ctx->segment_handle), ret);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800930 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800931
hualing chen002e5b92022-02-23 17:51:21 +0800932 p_ctx->last_send_size = 0;
933 p_ctx->last_send_time = 0;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800934
935 /*Open the new record segment*/
936 if (SEG_CALL_IS_VALID(open)) {
937 memset(&open_params, 0, sizeof(open_params));
Zhiqiang Hand83644e2024-06-04 14:54:53 +0800938
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800939 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
940 open_params.segment_id = params->segment.segment_id;
941 open_params.mode = SEGMENT_MODE_WRITE;
942 open_params.force_sysclock = p_ctx->force_sysclock;
Zhiqiang Hand83644e2024-06-04 14:54:53 +0800943
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800944 DVR_INFO("%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
Wentao MAe2a2db92024-08-26 16:21:41 +0800945 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800946 SEG_CALL_RET(open, (&open_params, &p_ctx->segment_handle), ret);
947 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Hand83644e2024-06-04 14:54:53 +0800948
949 if (SEG_CALL_IS_VALID(ioctl)) {
950 DVR_Control_t *pc;
951 list_for_each_entry(pc, &p_ctx->segment_ctrls, head) {
Zhiqiang Han267bf092024-07-15 15:33:46 +0800952 DVR_INFO("%s, replay ctrl[cmd:%d]", __func__, pc->cmd);
Wentao MAe2a2db92024-08-26 16:21:41 +0800953 // coverity[self_assign]
Zhiqiang Hand83644e2024-06-04 14:54:53 +0800954 SEG_CALL_RET(ioctl, (p_ctx->segment_handle, pc->cmd, pc->data, pc->size), ret);
955 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
956 }
957 }
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800958 }
959
Pengfei Liub4734232020-01-17 18:25:10 +0800960 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800961 {
Pengfei Liub4734232020-01-17 18:25:10 +0800962 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800963 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800964 /*save current segment info*/
965 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
966 p_ctx->segment_info.id = params->segment.segment_id;
967 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800968 }
969
Pengfei Liub4734232020-01-17 18:25:10 +0800970 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800971 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800972 switch (params->segment.pid_action[i]) {
973 case DVR_RECORD_PID_CREATE:
Wentao MA96f68962022-06-15 19:45:35 +0800974 DVR_INFO("%s create pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800975 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
976 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800977 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800978 break;
979 case DVR_RECORD_PID_KEEP:
Wentao MA96f68962022-06-15 19:45:35 +0800980 DVR_INFO("%s keep pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800981 p_ctx->segment_info.nb_pids++;
982 break;
983 case DVR_RECORD_PID_CLOSE:
Wentao MA96f68962022-06-15 19:45:35 +0800984 DVR_INFO("%s close pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800985 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800986 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800987 break;
988 default:
Wentao MA96f68962022-06-15 19:45:35 +0800989 DVR_INFO("%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800990 return DVR_FAILURE;
991 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800992 }
993
Pengfei Liub4734232020-01-17 18:25:10 +0800994 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800995 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800996
hualing chen4b7c15d2020-04-07 16:13:48 +0800997 /*Update segment info*/
Wentao MAe2a2db92024-08-26 16:21:41 +0800998 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800999 SEG_CALL_RET(store_info, (p_ctx->segment_handle, &p_ctx->segment_info), ret);
wentao.maa210e5e2022-10-12 16:10:03 +08001000 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001001
1002 if (p_ctx->pts != ULLONG_MAX) {
1003 SEG_CALL(update_pts, (p_ctx->segment_handle, p_ctx->pts, 0));
1004 }
Pengfei Liuc181a982020-01-07 19:27:13 +08001005
Pengfei Liuc181a982020-01-07 19:27:13 +08001006 p_ctx->state = DVR_RECORD_STATE_STARTED;
Zhiqiang Han0d60f2b2020-05-26 14:39:54 +08001007 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +08001008 return DVR_SUCCESS;
1009}
1010
1011int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
1012{
1013 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +08001014 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +08001015 uint32_t i;
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001016 loff_t pos = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +08001017
Pengfei Liu47ed6c92020-01-17 11:23:41 +08001018 p_ctx = (DVR_RecordContext_t *)handle;
1019 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1020 if (p_ctx == &record_ctx[i])
1021 break;
1022 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001023 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +08001024
Wentao MAd71e2062023-02-15 10:10:49 +08001025 if (p_ctx->segment_handle == NULL) {
1026 // It seems this stop function has been called twice on the same recording,
1027 // so just return success.
1028 return DVR_SUCCESS;
1029 }
1030
Wentao MA96f68962022-06-15 19:45:35 +08001031 DVR_INFO("%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001032 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STOPPED);
1033 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001034 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +08001035
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001036 SEG_CALL_INIT(&p_ctx->segment_ops);
1037
Pengfei Liuc181a982020-01-07 19:27:13 +08001038 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +08001039 if (p_ctx->is_vod) {
pengfei.liuab5a2262020-02-14 17:33:40 +08001040 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
1041 } else {
Chao Yin0e6cb602022-08-02 15:41:24 +08001042 pthread_join(p_ctx->thread, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +08001043 ret = record_device_stop(p_ctx->dev_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +08001044 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
1045 if (ret != DVR_SUCCESS)
1046 goto end;
pengfei.liuab5a2262020-02-14 17:33:40 +08001047 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +08001048 }
1049
hualing chen2932d372020-04-29 13:44:00 +08001050 //add index file store
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001051 if (SEG_CALL_IS_VALID(update_pts_force)) {
1052 SEG_CALL_RET_VALID(tell_position, (p_ctx->segment_handle), pos, -1);
1053 if (pos != -1) {
1054 SEG_CALL(update_pts_force, (p_ctx->segment_handle, p_ctx->segment_info.duration, pos));
1055 }
1056 }
1057
Wentao MAe2a2db92024-08-26 16:21:41 +08001058 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001059 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), p_ctx->segment_info.duration);
Pengfei Liuc181a982020-01-07 19:27:13 +08001060
Pengfei Liub4734232020-01-17 18:25:10 +08001061 /*Update segment info*/
1062 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
1063
Wentao MAe2a2db92024-08-26 16:21:41 +08001064 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001065 SEG_CALL_RET(store_info, (p_ctx->segment_handle, p_info), ret);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +08001066 if (ret != DVR_SUCCESS)
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001067 goto end;
Pengfei Liub4734232020-01-17 18:25:10 +08001068
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001069 SEG_CALL(store_allInfo, (p_ctx->segment_handle, p_info));
hualing chenb9a02922021-12-14 11:29:47 +08001070
Wentao MA96f68962022-06-15 19:45:35 +08001071 DVR_INFO("%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
Pengfei Liub4734232020-01-17 18:25:10 +08001072 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
1073
Zhiqiang Han5c805cf2020-05-09 16:51:08 +08001074end:
Wentao MAe2a2db92024-08-26 16:21:41 +08001075 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001076 SEG_CALL_RET(close, (p_ctx->segment_handle), ret);
hualing chencedcb862022-01-04 15:32:43 +08001077 p_ctx->segment_handle = NULL;
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001078 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001079
Pengfei Liub4734232020-01-17 18:25:10 +08001080 return DVR_SUCCESS;
1081}
Pengfei Liuc181a982020-01-07 19:27:13 +08001082
Pengfei Liub4734232020-01-17 18:25:10 +08001083int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
1084{
1085 DVR_RecordContext_t *p_ctx;
1086 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001087 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +08001088
1089 p_ctx = (DVR_RecordContext_t *)handle;
1090 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1091 if (p_ctx == &record_ctx[i])
1092 break;
Pengfei Liuc181a982020-01-07 19:27:13 +08001093 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001094 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1095 DVR_RETURN_IF_FALSE(params);
1096 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +08001097
Wentao MA96f68962022-06-15 19:45:35 +08001098 DVR_INFO("%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
pengfei.liuab5a2262020-02-14 17:33:40 +08001099 ret = dvr_record_start_segment(handle, params);
1100 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
1101
1102 p_ctx->segment_info.size = *p_resume_size;
1103
1104 return DVR_SUCCESS;
1105}
1106
1107int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
1108{
1109 DVR_RecordContext_t *p_ctx;
1110 int i;
1111
1112 p_ctx = (DVR_RecordContext_t *)handle;
1113 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1114 if (p_ctx == &record_ctx[i])
1115 break;
1116 }
1117 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1118 DVR_RETURN_IF_FALSE(p_status);
1119
1120 //lock
1121 p_status->state = p_ctx->state;
1122 p_status->info.id = p_ctx->segment_info.id;
1123 p_status->info.duration = p_ctx->segment_info.duration;
1124 p_status->info.size = p_ctx->segment_info.size;
1125 p_status->info.nb_packets = p_ctx->segment_info.size/188;
1126
1127 return DVR_SUCCESS;
1128}
1129
1130int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
1131{
1132 DVR_RecordContext_t *p_ctx;
1133 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001134 int ret = DVR_SUCCESS;
pengfei.liuab5a2262020-02-14 17:33:40 +08001135 int has_pcr;
1136
1137 p_ctx = (DVR_RecordContext_t *)handle;
1138 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1139 if (p_ctx == &record_ctx[i])
1140 break;
1141 }
1142 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1143 DVR_RETURN_IF_FALSE(buffer);
1144 DVR_RETURN_IF_FALSE(len);
1145
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001146 SEG_CALL_INIT(&p_ctx->segment_ops);
1147
pengfei.liuab5a2262020-02-14 17:33:40 +08001148 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
1149 if (has_pcr == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001150 /* Pull VOD record should use PCR time index */
Wentao MA96f68962022-06-15 19:45:35 +08001151 DVR_INFO("%s has no pcr, can NOT do time index", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +08001152 }
Wentao MAe2a2db92024-08-26 16:21:41 +08001153 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001154 SEG_CALL_RET(write, (p_ctx->segment_handle, buffer, len), ret);
hualing chen2932d372020-04-29 13:44:00 +08001155 if (ret != len) {
Wentao MA96f68962022-06-15 19:45:35 +08001156 DVR_INFO("%s write error ret:%d len:%d", __func__, ret, len);
hualing chen2932d372020-04-29 13:44:00 +08001157 }
pengfei.liuab5a2262020-02-14 17:33:40 +08001158 p_ctx->segment_info.size += len;
1159 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
1160
Pengfei Liuc181a982020-01-07 19:27:13 +08001161 return DVR_SUCCESS;
1162}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001163
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001164int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001165{
1166 DVR_RecordContext_t *p_ctx;
1167 uint32_t i;
1168
1169 p_ctx = (DVR_RecordContext_t *)handle;
1170 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1171 if (p_ctx == &record_ctx[i])
1172 break;
1173 }
1174 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1175 DVR_RETURN_IF_FALSE(func);
1176
Wentao MA96f68962022-06-15 19:45:35 +08001177 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001178 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
1179 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
1180
1181 p_ctx->enc_func = func;
1182 p_ctx->enc_userdata = userdata;
1183 return DVR_SUCCESS;
1184}
1185
1186int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
1187{
1188 DVR_RecordContext_t *p_ctx;
1189 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001190 int ret = DVR_SUCCESS;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001191
1192 p_ctx = (DVR_RecordContext_t *)handle;
1193 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1194 if (p_ctx == &record_ctx[i])
1195 break;
1196 }
1197 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1198 DVR_RETURN_IF_FALSE(p_secure_buf);
1199 DVR_RETURN_IF_FALSE(len);
1200
Wentao MA96f68962022-06-15 19:45:35 +08001201 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001202 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
1203 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
1204
1205 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
1206 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
1207
1208 p_ctx->is_secure_mode = 1;
Yahui Han4577db82022-07-05 17:46:19 +08001209 p_ctx->secbuf_size = len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001210 return ret;
1211}
hualing chen4fe3bee2020-10-23 13:58:52 +08001212
1213int dvr_record_is_secure_mode(DVR_RecordHandle_t handle)
1214{
1215 DVR_RecordContext_t *p_ctx;
1216 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001217 int ret = DVR_SUCCESS;
hualing chen4fe3bee2020-10-23 13:58:52 +08001218
1219 p_ctx = (DVR_RecordContext_t *)handle;
1220 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1221 if (p_ctx == &record_ctx[i])
1222 break;
1223 }
hualing chen002e5b92022-02-23 17:51:21 +08001224
hualing chen4fe3bee2020-10-23 13:58:52 +08001225 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1226
1227 if (p_ctx->is_secure_mode == 1)
1228 ret = 1;
1229 else
1230 ret = 0;
1231 return ret;
Yahui Hance15e9c2020-12-08 18:08:32 +08001232}
Wentao MAf4072032022-06-30 13:50:45 +08001233
1234int dvr_record_discard_coming_data(DVR_RecordHandle_t handle, DVR_Bool_t discard)
1235{
1236 DVR_RecordContext_t *p_ctx;
1237 int i;
1238
1239 p_ctx = (DVR_RecordContext_t *)handle;
1240 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1241 if (p_ctx == &record_ctx[i])
1242 break;
1243 }
1244 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1245
1246 if (p_ctx->discard_coming_data != discard) {
1247 p_ctx->discard_coming_data = discard;
1248 if (discard) {
1249 DVR_WARN("%s, start discarding coming data. discard:%d",__func__,discard);
1250 } else {
1251 DVR_WARN("%s, finish discarding coming data. discard:%d",__func__,discard);
1252 }
1253 }
1254
1255 return DVR_TRUE;
1256}
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001257
1258int dvr_record_ioctl(DVR_RecordHandle_t handle, unsigned int cmd, void *data, size_t size)
1259{
1260 DVR_RecordContext_t *p_ctx;
1261 int ret = DVR_FAILURE;
1262 int i;
1263
1264 p_ctx = (DVR_RecordContext_t *)handle;
1265 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1266 if (p_ctx == &record_ctx[i])
1267 break;
1268 }
1269 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1270
1271 SEG_CALL_INIT(&p_ctx->segment_ops);
1272
1273 if (SEG_CALL_IS_VALID(ioctl)) {
1274 if (p_ctx->segment_handle) {
Wentao MAe2a2db92024-08-26 16:21:41 +08001275 // coverity[self_assign]
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001276 SEG_CALL_RET(ioctl, (p_ctx->segment_handle, cmd, data, size), ret);
Zhiqiang Han267bf092024-07-15 15:33:46 +08001277 }
1278
1279 {
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001280 DVR_Control_t *ctrl = (DVR_Control_t *)calloc(1, sizeof(DVR_Control_t));
1281 if (ctrl) {
1282 ctrl->cmd = cmd;
1283 if (size) {
1284 void *pdata = malloc(size);
1285 if (pdata) {
1286 memcpy(pdata, data, size);
1287 ctrl->data = pdata;
1288 ctrl->size = size;
1289 } else {
1290 free(ctrl);
1291 ctrl = NULL;
1292 }
1293 }
1294 }
1295 if (ctrl) {
1296 list_add_tail(&ctrl->head, &p_ctx->segment_ctrls);
Zhiqiang Han267bf092024-07-15 15:33:46 +08001297 DVR_INFO("%s, save ctrl[cmd:%d]", __func__, ctrl->cmd);
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001298 ret = DVR_SUCCESS;
1299 }
1300 }
1301 }
1302
1303 return ret;
1304}