blob: f013ee62225fef520bb6e4cbb4e6f3d5bff2bfc1 [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 }
313
Yahui Han4577db82022-07-05 17:46:19 +0800314 if (p_ctx->is_secure_mode) {
315 buf_out = (uint8_t *)malloc(p_ctx->secbuf_size + 188);
316 } else {
317 buf_out = (uint8_t *)malloc(block_size + 188);
318 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800319 if (!buf_out) {
Wentao MA96f68962022-06-15 19:45:35 +0800320 DVR_INFO("%s, malloc failed", __func__);
Pengfei Liufaf38e42020-05-22 00:28:02 +0800321 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800322 return NULL;
323 }
324
hualing chen266b9502020-04-04 17:39:39 +0800325 memset(&record_status, 0, sizeof(record_status));
326 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800327 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800328 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800329 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
Wentao MA96f68962022-06-15 19:45:35 +0800330 DVR_INFO("%s line %d notify record status, state:%d id=%lld",
hualing chen4b7c15d2020-04-07 16:13:48 +0800331 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800332 }
Wentao MA96f68962022-06-15 19:45:35 +0800333 DVR_INFO("%s, --secure_mode:%d, block_size:%d, cryptor:%p",
hualing chen002e5b92022-02-23 17:51:21 +0800334 __func__, p_ctx->is_secure_mode,
335 block_size, p_ctx->cryptor);
Pengfei Liub4734232020-01-17 18:25:10 +0800336 clock_gettime(CLOCK_MONOTONIC, &start_ts);
hualing chen3092e1c2022-01-21 20:02:21 +0800337 p_ctx->check_pts_count = 0;
338 p_ctx->check_no_pts_count++;
hualing chen002e5b92022-02-23 17:51:21 +0800339 p_ctx->last_send_size = 0;
340 p_ctx->last_send_time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800341 struct timeval t1, t2, t3, t4, t5, t6, t7;
hualing chen03fd4942021-07-15 15:56:41 +0800342 while (p_ctx->state == DVR_RECORD_STATE_STARTED ||
343 p_ctx->state == DVR_RECORD_STATE_PAUSE) {
344
pengfei.liu567d6d82020-04-17 16:48:59 +0800345 gettimeofday(&t1, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800346
pengfei.liuab5a2262020-02-14 17:33:40 +0800347 /* data from dmx, normal dvr case */
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800348 if (p_ctx->is_secure_mode) {
hualing chenf9867402020-09-23 17:06:20 +0800349 if (p_ctx->is_new_dmx) {
Wentao MA804bab12022-11-29 10:01:26 +0800350 /* We resolve the below invoke for dvbcore to be under safety status */
351 memset(&new_dmx_secure_buf, 0, sizeof(new_dmx_secure_buf));
352 len = record_device_read(p_ctx->dev_handle, &new_dmx_secure_buf,
353 sizeof(new_dmx_secure_buf), 10);
Yahui Hance15e9c2020-12-08 18:08:32 +0800354
Wentao MA804bab12022-11-29 10:01:26 +0800355 /* Read data from secure demux TA */
356 len = record_device_read_ext(p_ctx->dev_handle, &secure_buf.addr,
357 &secure_buf.len);
hualing chenf9867402020-09-23 17:06:20 +0800358 } else {
359 memset(&secure_buf, 0, sizeof(secure_buf));
Wentao MA804bab12022-11-29 10:01:26 +0800360 len = record_device_read(p_ctx->dev_handle, &secure_buf,
361 sizeof(secure_buf), 1000);
hualing chenf9867402020-09-23 17:06:20 +0800362 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800363 } else {
364 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
365 }
Pengfei Liub4734232020-01-17 18:25:10 +0800366 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800367 //usleep(10*1000);
Wentao MA96f68962022-06-15 19:45:35 +0800368 //DVR_INFO("%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800369 continue;
370 }
Wentao MA41532372024-02-28 12:22:02 +0800371 if (p_ctx->state == DVR_RECORD_STATE_PAUSE) {
372 //wait resume record
373 usleep(20*1000);
374 continue;
375 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800376 gettimeofday(&t2, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800377
Wentao MAeeffdb02022-06-27 16:34:35 +0800378 guarded_size_exceeded = DVR_FALSE;
wentao.mad08db842022-11-14 17:35:40 +0800379 if ( p_ctx->guarded_segment_size > 0 &&
380 p_ctx->segment_info.size+len >= p_ctx->guarded_segment_size) {
Wentao MAeeffdb02022-06-27 16:34:35 +0800381 guarded_size_exceeded = DVR_TRUE;
382 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800383 /* Got data from device, record it */
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800384 ret = 0;
Wentao MAeeffdb02022-06-27 16:34:35 +0800385 if (guarded_size_exceeded) {
386 len = 0;
387 ret = 0;
Wentao MAf4072032022-06-30 13:50:45 +0800388 DVR_ERROR("Skip segment_write due to current segment size %u exceeding"
389 " guarded segment size", p_ctx->segment_info.size);
390 } else if (p_ctx->discard_coming_data) {
391 len = 0;
392 ret = 0;
393 DVR_ERROR("Skip segment_write due to total size exceeding max size too much");
Wentao MAeeffdb02022-06-27 16:34:35 +0800394 } else if (p_ctx->enc_func) {
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800395 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800396 DVR_CryptoParams_t crypto_params;
397
398 memset(&crypto_params, 0, sizeof(crypto_params));
399 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800400 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800401 crypto_params.segment_id = p_ctx->segment_info.id;
402 crypto_params.offset = p_ctx->segment_info.size;
403
404 if (p_ctx->is_secure_mode) {
405 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
Yahui Han1fbf3292021-11-08 18:17:19 +0800406 crypto_params.input_buffer.addr = secure_buf.addr;
407 crypto_params.input_buffer.size = secure_buf.len;
Yahui Hanaf03b142022-08-17 17:52:37 +0800408 crypto_params.output_buffer.size = p_ctx->secbuf_size + 188;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800409 } else {
410 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
411 crypto_params.input_buffer.addr = (size_t)buf;
412 crypto_params.input_buffer.size = len;
Yahui Hanaf03b142022-08-17 17:52:37 +0800413 crypto_params.output_buffer.size = block_size + 188;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800414 }
415
416 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
417 crypto_params.output_buffer.addr = (size_t)buf_out;
hualing chen9811b212020-10-29 11:21:44 +0800418
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800419 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800420 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800421 /* Out buffer length may not equal in buffer length */
hualing chenf9867402020-09-23 17:06:20 +0800422 if (crypto_params.output_size > 0) {
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800423 SEG_CALL_RET(write, (p_ctx->segment_handle, buf_out, crypto_params.output_size), ret);
hualing chenf9867402020-09-23 17:06:20 +0800424 len = crypto_params.output_size;
hualing chenbafc62d2020-11-02 15:44:05 +0800425 } else {
426 len = 0;
hualing chenf9867402020-09-23 17:06:20 +0800427 }
Yahui Han1fbf3292021-11-08 18:17:19 +0800428 } else if (p_ctx->cryptor) {
429 /* Encrypt with clear key */
Yahui Han63b23b42021-12-07 15:37:46 +0800430 int crypt_len = len;
431 am_crypt_des_crypt(p_ctx->cryptor, buf_out, buf, &crypt_len, 0);
432 len = crypt_len;
Yahui Han1fbf3292021-11-08 18:17:19 +0800433 gettimeofday(&t3, NULL);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800434 SEG_CALL_RET(write, (p_ctx->segment_handle, buf_out, len), ret);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800435 } else {
hualing chena5f03222021-12-02 11:22:35 +0800436 if (first_read == 0) {
437 first_read = 1;
Wentao MA96f68962022-06-15 19:45:35 +0800438 DVR_INFO("%s:%d,first read ts", __func__,__LINE__);
hualing chena5f03222021-12-02 11:22:35 +0800439 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800440 gettimeofday(&t3, NULL);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800441 SEG_CALL_RET(write, (p_ctx->segment_handle, buf, len), ret);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800442 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800443 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800444 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800445 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800446 //send write event
hualing chen9b434f02020-06-10 15:06:54 +0800447 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800448 memset(&record_status, 0, sizeof(record_status));
Wentao MAeeffdb02022-06-27 16:34:35 +0800449 DVR_INFO("%s:%d,send event write error", __func__,__LINE__);
hualing chen9ce7d942021-06-30 13:31:01 +0800450 record_status.info.id = p_ctx->segment_info.id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800451 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
452 }
Wentao MA96f68962022-06-15 19:45:35 +0800453 DVR_INFO("%s,write error %d", __func__,__LINE__);
hualing chen626204e2020-04-07 11:55:08 +0800454 goto end;
455 }
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800456
457 if (len > 0 && SEG_CALL_IS_VALID(tell_position)) {
Wentao MAf4072032022-06-30 13:50:45 +0800458 /* Do time index */
459 uint8_t *index_buf = (p_ctx->enc_func || p_ctx->cryptor)? buf_out : buf;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800460 SEG_CALL_RET(tell_position, (p_ctx->segment_handle), pos);
Wentao MAf4072032022-06-30 13:50:45 +0800461 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
462 if (has_pcr == 0 && p_ctx->index_type == DVR_INDEX_TYPE_INVALID) {
463 clock_gettime(CLOCK_MONOTONIC, &end_ts);
464 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
465 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800466 /* PCR interval threshold > 40 ms*/
Wentao MAf4072032022-06-30 13:50:45 +0800467 DVR_INFO("%s use local clock time index", __func__);
hualing chen3092e1c2022-01-21 20:02:21 +0800468 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
Wentao MAf4072032022-06-30 13:50:45 +0800469 }
470 } else if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_INVALID){
471 DVR_INFO("%s use pcr time index", __func__);
472 p_ctx->index_type = DVR_INDEX_TYPE_PCR;
473 record_do_pcr_index(p_ctx, index_buf, len);
474 }
475 gettimeofday(&t5, NULL);
476 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
477 if (has_pcr == 0) {
478 if (p_ctx->check_no_pts_count < 2 * CHECK_PTS_MAX_COUNT) {
479 if (p_ctx->check_no_pts_count == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800480 clock_gettime(CLOCK_MONOTONIC, &start_no_pcr_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800481 clock_gettime(CLOCK_MONOTONIC, &start_ts);
482 }
483 p_ctx->check_no_pts_count++;
484 }
485 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +0800486 clock_gettime(CLOCK_MONOTONIC, &start_no_pcr_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800487 p_ctx->check_no_pts_count = 0;
488 }
489 }
490 /* Update segment i nfo */
491 p_ctx->segment_info.size += len;
Pengfei Liub4734232020-01-17 18:25:10 +0800492
Wentao MAf4072032022-06-30 13:50:45 +0800493 /*Duration need use pcr to calculate, todo...*/
494 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800495 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), p_ctx->segment_info.duration);
Wentao MAf4072032022-06-30 13:50:45 +0800496 if (pre_time == 0)
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800497 pre_time = p_ctx->segment_info.duration;
Wentao MAf4072032022-06-30 13:50:45 +0800498 } else if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
499 clock_gettime(CLOCK_MONOTONIC, &end_ts);
500 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
501 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) + pcr_rec_len;
502 if (pre_time == 0)
503 pre_time = p_ctx->segment_info.duration;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800504 SEG_CALL(update_pts, (p_ctx->segment_handle, p_ctx->segment_info.duration, pos));
Wentao MAf4072032022-06-30 13:50:45 +0800505 } else {
506 DVR_INFO("%s can NOT do time index", __func__);
507 }
508 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR &&
509 p_ctx->check_pts_count == CHECK_PTS_MAX_COUNT) {
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800510 DVR_INFO("%s change time from pcr to local time", __func__);
511 if (pcr_rec_len == 0) {
512 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), pcr_rec_len);
513 }
514 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
515 if (pcr_rec_len == 0) {
516 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), pcr_rec_len);
517 }
518 clock_gettime(CLOCK_MONOTONIC, &start_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800519 }
520
521 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR ) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800522 clock_gettime(CLOCK_MONOTONIC, &end_no_pcr_ts);
523 int diff = (int)(end_no_pcr_ts.tv_sec*1000 + end_no_pcr_ts.tv_nsec/1000000) -
524 (int)(start_no_pcr_ts.tv_sec*1000 + start_no_pcr_ts.tv_nsec/1000000);
Wentao MAf4072032022-06-30 13:50:45 +0800525 if (diff > 3000) {
526 DVR_INFO("%s no pcr change time from pcr to local time diff[%d]", __func__, diff);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800527 if (pcr_rec_len == 0) {
528 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), pcr_rec_len);
529 }
Wentao MAf4072032022-06-30 13:50:45 +0800530 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
531 }
532 }
533 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
534
535 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
536 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
537 time_t duration = p_ctx->segment_info.duration;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800538 if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
539 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), p_ctx->segment_info.duration);
540 }
541 SEG_CALL(store_info, (p_ctx->segment_handle, &p_ctx->segment_info));
Wentao MAf4072032022-06-30 13:50:45 +0800542 p_ctx->segment_info.duration = duration;
543 }
544 } else {
545 gettimeofday(&t5, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800546 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800547 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800548 /*Event notification*/
Wentao MAf4072032022-06-30 13:50:45 +0800549 DVR_Bool_t condA1 = (p_ctx->notification_size > 0);
550 DVR_Bool_t condA2 = ((p_ctx->segment_info.size-p_ctx->last_send_size) >= p_ctx->notification_size);
551 DVR_Bool_t condA3 = (p_ctx->notification_time > 0);
552 DVR_Bool_t condA4 = ((p_ctx->segment_info.duration-p_ctx->last_send_time) >= p_ctx->notification_time);
553 DVR_Bool_t condA5 = (guarded_size_exceeded);
554 DVR_Bool_t condA6 = (p_ctx->discard_coming_data);
555 DVR_Bool_t condB = (p_ctx->event_notify_fn != NULL);
556 DVR_Bool_t condC = (p_ctx->segment_info.duration > 0);
557 DVR_Bool_t condD = (p_ctx->state == DVR_RECORD_STATE_STARTED);
558 if (((condA1 && condA2) || (condA3 && condA4) || condA5 || condA6)
559 && condB && condC && condD) {
Pengfei Liub4734232020-01-17 18:25:10 +0800560 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800561 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800562 p_ctx->last_send_size = p_ctx->segment_info.size;
hualing chen002e5b92022-02-23 17:51:21 +0800563 p_ctx->last_send_time = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800564 record_status.state = p_ctx->state;
565 record_status.info.id = p_ctx->segment_info.id;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800566 if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
567 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), record_status.info.duration);
568 } else
hualing chenc94227e2022-02-17 09:48:43 +0800569 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800570 record_status.info.size = p_ctx->segment_info.size;
571 record_status.info.nb_packets = p_ctx->segment_info.size/188;
572 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
Wentao MA96f68962022-06-15 19:45:35 +0800573 DVR_INFO("%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu loc[%s]",
hualing chen4fe3bee2020-10-23 13:58:52 +0800574 __func__, record_status.state,
575 record_status.info.id, record_status.info.duration,
576 record_status.info.size, p_ctx->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800577 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800578 gettimeofday(&t7, NULL);
579#ifdef DEBUG_PERFORMANCE
Wentao MA96f68962022-06-15 19:45:35 +0800580 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 +0800581 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 +0800582 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len,
583 p_ctx->notification_time,p_ctx->segment_info.duration -p_ctx->last_send_time);
pengfei.liu567d6d82020-04-17 16:48:59 +0800584#endif
Wentao MAf4072032022-06-30 13:50:45 +0800585 if (len == 0) {
586 usleep(20*1000);
587 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800588 }
hualing chen626204e2020-04-07 11:55:08 +0800589end:
Pengfei Liub4734232020-01-17 18:25:10 +0800590 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800591 free((void *)buf_out);
Wentao MA96f68962022-06-15 19:45:35 +0800592 DVR_INFO("exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800593 return NULL;
594}
595
596int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
597{
598 DVR_RecordContext_t *p_ctx;
599 Record_DeviceOpenParams_t dev_open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800600 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800601 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800602
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800603 DVR_RETURN_IF_FALSE(p_handle);
604 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800605
606 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800607 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800608 break;
609 }
610 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800611 DVR_RETURN_IF_FALSE(i < MAX_DVR_RECORD_SESSION_COUNT);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800612 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800613 p_ctx = &record_ctx[i];
Wentao MA96f68962022-06-15 19:45:35 +0800614 DVR_INFO("%s , current state:%d, dmx_id:%d, notification_size:%zu, flags:%d, keylen:%d ",
Yahui Han1fbf3292021-11-08 18:17:19 +0800615 __func__, p_ctx->state, params->dmx_dev_id,
hualing chen002e5b92022-02-23 17:51:21 +0800616 params->notification_size,
617 params->flags, params->keylen);
Pengfei Liuc181a982020-01-07 19:27:13 +0800618
Pengfei Liub4734232020-01-17 18:25:10 +0800619 /*Process event params*/
620 p_ctx->notification_size = params->notification_size;
hualing chen002e5b92022-02-23 17:51:21 +0800621 p_ctx->notification_time = params->notification_time;
622
Pengfei Liub4734232020-01-17 18:25:10 +0800623 p_ctx->event_notify_fn = params->event_fn;
624 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800625 p_ctx->last_send_size = 0;
hualing chen002e5b92022-02-23 17:51:21 +0800626 p_ctx->last_send_time = 0;
hualing chen94d8dd22021-12-29 15:13:43 +0800627 p_ctx->pts = ULLONG_MAX;
Yahui Han1fbf3292021-11-08 18:17:19 +0800628
629 if (params->keylen > 0) {
630 p_ctx->cryptor = am_crypt_des_open(params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +0800631 params->cleariv,
632 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +0800633 if (!p_ctx->cryptor)
Wentao MA96f68962022-06-15 19:45:35 +0800634 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +0800635 } else {
636 p_ctx->cryptor = NULL;
637 }
638
hualing chenf9867402020-09-23 17:06:20 +0800639 //check is new driver
640 p_ctx->is_new_dmx = dvr_check_dmx_isNew();
Pengfei Liub4734232020-01-17 18:25:10 +0800641 /*Process crypto params, todo*/
Pengfei Liub4734232020-01-17 18:25:10 +0800642 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800643 if (params->data_from_memory) {
644 /* data from memory, VOD case */
645 p_ctx->is_vod = 1;
646 } else {
647 p_ctx->is_vod = 0;
648 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800649 dev_open_params.dmx_dev_id = params->dmx_dev_id;
hualing chen157641d2022-02-22 17:54:52 +0800650 //set dvr flush size
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800651 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen157641d2022-02-22 17:54:52 +0800652 //set dvbcore ringbuf size
hualing chen03fd4942021-07-15 15:56:41 +0800653 dev_open_params.ringbuf_size = params->ringbuf_size;
hualing chen157641d2022-02-22 17:54:52 +0800654
pengfei.liuab5a2262020-02-14 17:33:40 +0800655 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
656 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +0800657 DVR_INFO("%s, open record devices failed", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800658 return DVR_FAILURE;
659 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800660 }
661
pengfei.liufda2a972020-04-09 14:47:15 +0800662 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen157641d2022-02-22 17:54:52 +0800663
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800664 p_ctx->enc_func = NULL;
665 p_ctx->enc_userdata = NULL;
666 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800667 p_ctx->state = DVR_RECORD_STATE_OPENED;
wentao.ma35a69d42022-03-10 18:08:40 +0800668 p_ctx->force_sysclock = params->force_sysclock;
Wentao MAeeffdb02022-06-27 16:34:35 +0800669 p_ctx->guarded_segment_size = params->guarded_segment_size;
wentao.mad08db842022-11-14 17:35:40 +0800670 if (p_ctx->guarded_segment_size <= 0) {
671 DVR_WARN("Odd guarded_segment_size value %lld is given. Change it to"
672 " 0 to disable segment guarding mechanism.", p_ctx->guarded_segment_size);
673 p_ctx->guarded_segment_size = 0;
674 }
Wentao MAf4072032022-06-30 13:50:45 +0800675 p_ctx->discard_coming_data = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +0800676 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 +0800677
678 record_set_segment_ops(p_ctx, params->flags);
679 INIT_LIST_HEAD(&p_ctx->segment_ctrls);
680
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800681 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800682 return DVR_SUCCESS;
683}
684
685int dvr_record_close(DVR_RecordHandle_t handle)
686{
687 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800688 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800689 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800690
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800691 p_ctx = (DVR_RecordContext_t *)handle;
692 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
693 if (p_ctx == &record_ctx[i])
694 break;
695 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800696 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800697
Wentao MA96f68962022-06-15 19:45:35 +0800698 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800699 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Yahui Han1fbf3292021-11-08 18:17:19 +0800700 if (p_ctx->cryptor) {
701 am_crypt_des_close(p_ctx->cryptor);
702 p_ctx->cryptor = NULL;
703 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800704 if (p_ctx->is_vod) {
705 ret = DVR_SUCCESS;
706 } else {
707 ret = record_device_close(p_ctx->dev_handle);
708 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +0800709 DVR_INFO("%s, failed", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800710 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800711 }
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800712
713 if (!list_empty(&p_ctx->segment_ctrls)) {
714 DVR_Control_t *pc, *pc_tmp;
715 list_for_each_entry_safe(pc, pc_tmp, &p_ctx->segment_ctrls, head) {
716 list_del(&pc->head);
717 if (pc->data)
718 free(pc->data);
719 free(pc);
720 }
721 }
722
hualing chencedcb862022-01-04 15:32:43 +0800723 memset(p_ctx, 0, sizeof(DVR_RecordContext_t));
Pengfei Liub4734232020-01-17 18:25:10 +0800724 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800725 return ret;
726}
727
hualing chen03fd4942021-07-15 15:56:41 +0800728int dvr_record_pause(DVR_RecordHandle_t handle)
729{
730 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800731 int ret = DVR_SUCCESS;
hualing chen03fd4942021-07-15 15:56:41 +0800732 uint32_t i;
733
734 p_ctx = (DVR_RecordContext_t *)handle;
735 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
736 if (p_ctx == &record_ctx[i])
737 break;
738 }
739 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
740
Wentao MA96f68962022-06-15 19:45:35 +0800741 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
hualing chen03fd4942021-07-15 15:56:41 +0800742 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
743
744 if (p_ctx->is_vod) {
745 ret = DVR_SUCCESS;
746 }
747 //set pause state,will not store ts into segment
748 p_ctx->state = DVR_RECORD_STATE_PAUSE;
749 return ret;
750}
751
752int dvr_record_resume(DVR_RecordHandle_t handle)
753{
754 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800755 int ret = DVR_SUCCESS;
hualing chen03fd4942021-07-15 15:56:41 +0800756 uint32_t i;
757
758 p_ctx = (DVR_RecordContext_t *)handle;
759 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
760 if (p_ctx == &record_ctx[i])
761 break;
762 }
763 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
764
Wentao MA96f68962022-06-15 19:45:35 +0800765 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
hualing chen03fd4942021-07-15 15:56:41 +0800766 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
767
768 if (p_ctx->is_vod) {
769 ret = DVR_SUCCESS;
770 }
771 //set stated state,will resume store ts into segment
772 p_ctx->state = DVR_RECORD_STATE_STARTED;
773 return ret;
774}
775
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800776#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800777int dvr_record_register_encryption(DVR_RecordHandle_t handle,
778 DVR_CryptoFunction_t cb,
779 DVR_CryptoParams_t params,
780 void *userdata)
781{
782 return DVR_SUCCESS;
783}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800784#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800785
786int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
787{
788 DVR_RecordContext_t *p_ctx;
789 Segment_OpenParams_t open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800790 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800791 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800792
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800793 p_ctx = (DVR_RecordContext_t *)handle;
794 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
795 if (p_ctx == &record_ctx[i])
796 break;
797 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800798 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800799
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800800 SEG_CALL_INIT(&p_ctx->segment_ops);
801
Wentao MA96f68962022-06-15 19:45:35 +0800802 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 +0800803 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
804 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
805 DVR_RETURN_IF_FALSE(params);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800806 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800807
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800808 if (SEG_CALL_IS_VALID(open)) {
809 memset(&open_params, 0, sizeof(open_params));
810
811 memcpy(open_params.location, params->location, sizeof(params->location));
812 open_params.segment_id = params->segment.segment_id;
813 open_params.mode = SEGMENT_MODE_WRITE;
814 open_params.force_sysclock = p_ctx->force_sysclock;
815
816 SEG_CALL_RET(open, (&open_params, &p_ctx->segment_handle), ret);
817 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
818
819 if (SEG_CALL_IS_VALID(ioctl)) {
820 DVR_Control_t *pc;
821 list_for_each_entry(pc, &p_ctx->segment_ctrls, head) {
822 SEG_CALL_RET(ioctl, (p_ctx->segment_handle, pc->cmd, pc->data, pc->size), ret);
823 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
824 }
825 }
826 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800827
Pengfei Liub4734232020-01-17 18:25:10 +0800828 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800829 {
hualing chen7a56cba2020-04-14 14:09:27 +0800830 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800831 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800832 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800833 /*save current segment info*/
834 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
835 p_ctx->segment_info.id = params->segment.segment_id;
836 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
837 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800838 }
839
pengfei.liuab5a2262020-02-14 17:33:40 +0800840 if (!p_ctx->is_vod) {
841 /* normal dvr case */
842 for (i = 0; i < params->segment.nb_pids; i++) {
843 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
844 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
845 }
846 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800847 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800848 }
849
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800850 SEG_CALL_RET(store_info, (p_ctx->segment_handle, &p_ctx->segment_info), ret);
wentao.maa210e5e2022-10-12 16:10:03 +0800851 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800852
Pengfei Liuc181a982020-01-07 19:27:13 +0800853 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800854 if (!p_ctx->is_vod)
855 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800856
Pengfei Liuc181a982020-01-07 19:27:13 +0800857 return DVR_SUCCESS;
858}
859
860int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
861{
862 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800863 Segment_OpenParams_t open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800864 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800865 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800866 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800867
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800868 p_ctx = (DVR_RecordContext_t *)handle;
869 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
870 if (p_ctx == &record_ctx[i])
871 break;
872 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800873 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800874
Wentao MA96f68962022-06-15 19:45:35 +0800875 DVR_INFO("%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800876 DVR_RETURN_IF_FALSE(p_ctx->state == DVR_RECORD_STATE_STARTED);
877 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
878 DVR_RETURN_IF_FALSE(params);
879 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800880 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800881
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800882 SEG_CALL_INIT(&p_ctx->segment_ops);
883
Pengfei Liuc181a982020-01-07 19:27:13 +0800884 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800885 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800886 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800887 p_ctx->state = DVR_RECORD_STATE_STOPPED;
888 pthread_join(p_ctx->thread, NULL);
889
hualing chen2932d372020-04-29 13:44:00 +0800890 //add index file store
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800891 if (SEG_CALL_IS_VALID(update_pts_force)) {
892 SEG_CALL_RET_VALID(tell_position, (p_ctx->segment_handle), pos, -1);
893 if (pos != -1) {
894 SEG_CALL(update_pts_force, (p_ctx->segment_handle, p_ctx->segment_info.duration, pos));
895 }
896 }
hualing chen2932d372020-04-29 13:44:00 +0800897
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800898 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), p_ctx->segment_info.duration);
899
Pengfei Liub4734232020-01-17 18:25:10 +0800900 /*Update segment info*/
901 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
902
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800903 SEG_CALL_RET(store_info, (p_ctx->segment_handle, p_info), ret);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800904 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800905
906 SEG_CALL(store_allInfo, (p_ctx->segment_handle, p_info));
907
Wentao MA96f68962022-06-15 19:45:35 +0800908 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 +0800909 __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 +0800910
Pengfei Liub4734232020-01-17 18:25:10 +0800911 /*Close current segment*/
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800912 SEG_CALL_RET(close, (p_ctx->segment_handle), ret);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800913 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800914
hualing chen002e5b92022-02-23 17:51:21 +0800915 p_ctx->last_send_size = 0;
916 p_ctx->last_send_time = 0;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800917
918 /*Open the new record segment*/
919 if (SEG_CALL_IS_VALID(open)) {
920 memset(&open_params, 0, sizeof(open_params));
Zhiqiang Hand83644e2024-06-04 14:54:53 +0800921
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800922 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
923 open_params.segment_id = params->segment.segment_id;
924 open_params.mode = SEGMENT_MODE_WRITE;
925 open_params.force_sysclock = p_ctx->force_sysclock;
Zhiqiang Hand83644e2024-06-04 14:54:53 +0800926
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800927 DVR_INFO("%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
928 SEG_CALL_RET(open, (&open_params, &p_ctx->segment_handle), ret);
929 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Hand83644e2024-06-04 14:54:53 +0800930
931 if (SEG_CALL_IS_VALID(ioctl)) {
932 DVR_Control_t *pc;
933 list_for_each_entry(pc, &p_ctx->segment_ctrls, head) {
Zhiqiang Han267bf092024-07-15 15:33:46 +0800934 DVR_INFO("%s, replay ctrl[cmd:%d]", __func__, pc->cmd);
Zhiqiang Hand83644e2024-06-04 14:54:53 +0800935 SEG_CALL_RET(ioctl, (p_ctx->segment_handle, pc->cmd, pc->data, pc->size), ret);
936 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
937 }
938 }
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800939 }
940
Pengfei Liub4734232020-01-17 18:25:10 +0800941 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800942 {
Pengfei Liub4734232020-01-17 18:25:10 +0800943 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800944 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800945 /*save current segment info*/
946 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
947 p_ctx->segment_info.id = params->segment.segment_id;
948 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800949 }
950
Pengfei Liub4734232020-01-17 18:25:10 +0800951 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800952 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800953 switch (params->segment.pid_action[i]) {
954 case DVR_RECORD_PID_CREATE:
Wentao MA96f68962022-06-15 19:45:35 +0800955 DVR_INFO("%s create pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800956 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
957 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800958 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800959 break;
960 case DVR_RECORD_PID_KEEP:
Wentao MA96f68962022-06-15 19:45:35 +0800961 DVR_INFO("%s keep pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800962 p_ctx->segment_info.nb_pids++;
963 break;
964 case DVR_RECORD_PID_CLOSE:
Wentao MA96f68962022-06-15 19:45:35 +0800965 DVR_INFO("%s close pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800966 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800967 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800968 break;
969 default:
Wentao MA96f68962022-06-15 19:45:35 +0800970 DVR_INFO("%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800971 return DVR_FAILURE;
972 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800973 }
974
Pengfei Liub4734232020-01-17 18:25:10 +0800975 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800976 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800977
hualing chen4b7c15d2020-04-07 16:13:48 +0800978 /*Update segment info*/
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800979 SEG_CALL_RET(store_info, (p_ctx->segment_handle, &p_ctx->segment_info), ret);
wentao.maa210e5e2022-10-12 16:10:03 +0800980 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800981
982 if (p_ctx->pts != ULLONG_MAX) {
983 SEG_CALL(update_pts, (p_ctx->segment_handle, p_ctx->pts, 0));
984 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800985
Pengfei Liuc181a982020-01-07 19:27:13 +0800986 p_ctx->state = DVR_RECORD_STATE_STARTED;
Zhiqiang Han0d60f2b2020-05-26 14:39:54 +0800987 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800988 return DVR_SUCCESS;
989}
990
991int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
992{
993 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800994 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800995 uint32_t i;
Zhiqiang Han2f019af2023-08-31 11:12:02 +0800996 loff_t pos = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800997
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800998 p_ctx = (DVR_RecordContext_t *)handle;
999 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1000 if (p_ctx == &record_ctx[i])
1001 break;
1002 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001003 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +08001004
Wentao MAd71e2062023-02-15 10:10:49 +08001005 if (p_ctx->segment_handle == NULL) {
1006 // It seems this stop function has been called twice on the same recording,
1007 // so just return success.
1008 return DVR_SUCCESS;
1009 }
1010
Wentao MA96f68962022-06-15 19:45:35 +08001011 DVR_INFO("%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001012 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STOPPED);
1013 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001014 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +08001015
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001016 SEG_CALL_INIT(&p_ctx->segment_ops);
1017
Pengfei Liuc181a982020-01-07 19:27:13 +08001018 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +08001019 if (p_ctx->is_vod) {
pengfei.liuab5a2262020-02-14 17:33:40 +08001020 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
1021 } else {
Chao Yin0e6cb602022-08-02 15:41:24 +08001022 pthread_join(p_ctx->thread, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +08001023 ret = record_device_stop(p_ctx->dev_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +08001024 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
1025 if (ret != DVR_SUCCESS)
1026 goto end;
pengfei.liuab5a2262020-02-14 17:33:40 +08001027 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +08001028 }
1029
hualing chen2932d372020-04-29 13:44:00 +08001030 //add index file store
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001031 if (SEG_CALL_IS_VALID(update_pts_force)) {
1032 SEG_CALL_RET_VALID(tell_position, (p_ctx->segment_handle), pos, -1);
1033 if (pos != -1) {
1034 SEG_CALL(update_pts_force, (p_ctx->segment_handle, p_ctx->segment_info.duration, pos));
1035 }
1036 }
1037
1038 SEG_CALL_RET(tell_total_time, (p_ctx->segment_handle), p_ctx->segment_info.duration);
Pengfei Liuc181a982020-01-07 19:27:13 +08001039
Pengfei Liub4734232020-01-17 18:25:10 +08001040 /*Update segment info*/
1041 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
1042
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001043 SEG_CALL_RET(store_info, (p_ctx->segment_handle, p_info), ret);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +08001044 if (ret != DVR_SUCCESS)
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001045 goto end;
Pengfei Liub4734232020-01-17 18:25:10 +08001046
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001047 SEG_CALL(store_allInfo, (p_ctx->segment_handle, p_info));
hualing chenb9a02922021-12-14 11:29:47 +08001048
Wentao MA96f68962022-06-15 19:45:35 +08001049 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 +08001050 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
1051
Zhiqiang Han5c805cf2020-05-09 16:51:08 +08001052end:
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001053 SEG_CALL_RET(close, (p_ctx->segment_handle), ret);
hualing chencedcb862022-01-04 15:32:43 +08001054 p_ctx->segment_handle = NULL;
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001055 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001056
Pengfei Liub4734232020-01-17 18:25:10 +08001057 return DVR_SUCCESS;
1058}
Pengfei Liuc181a982020-01-07 19:27:13 +08001059
Pengfei Liub4734232020-01-17 18:25:10 +08001060int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
1061{
1062 DVR_RecordContext_t *p_ctx;
1063 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001064 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +08001065
1066 p_ctx = (DVR_RecordContext_t *)handle;
1067 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1068 if (p_ctx == &record_ctx[i])
1069 break;
Pengfei Liuc181a982020-01-07 19:27:13 +08001070 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +08001071 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1072 DVR_RETURN_IF_FALSE(params);
1073 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +08001074
Wentao MA96f68962022-06-15 19:45:35 +08001075 DVR_INFO("%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
pengfei.liuab5a2262020-02-14 17:33:40 +08001076 ret = dvr_record_start_segment(handle, params);
1077 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
1078
1079 p_ctx->segment_info.size = *p_resume_size;
1080
1081 return DVR_SUCCESS;
1082}
1083
1084int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
1085{
1086 DVR_RecordContext_t *p_ctx;
1087 int i;
1088
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;
1093 }
1094 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1095 DVR_RETURN_IF_FALSE(p_status);
1096
1097 //lock
1098 p_status->state = p_ctx->state;
1099 p_status->info.id = p_ctx->segment_info.id;
1100 p_status->info.duration = p_ctx->segment_info.duration;
1101 p_status->info.size = p_ctx->segment_info.size;
1102 p_status->info.nb_packets = p_ctx->segment_info.size/188;
1103
1104 return DVR_SUCCESS;
1105}
1106
1107int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
1108{
1109 DVR_RecordContext_t *p_ctx;
1110 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001111 int ret = DVR_SUCCESS;
pengfei.liuab5a2262020-02-14 17:33:40 +08001112 int has_pcr;
1113
1114 p_ctx = (DVR_RecordContext_t *)handle;
1115 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1116 if (p_ctx == &record_ctx[i])
1117 break;
1118 }
1119 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1120 DVR_RETURN_IF_FALSE(buffer);
1121 DVR_RETURN_IF_FALSE(len);
1122
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001123 SEG_CALL_INIT(&p_ctx->segment_ops);
1124
pengfei.liuab5a2262020-02-14 17:33:40 +08001125 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
1126 if (has_pcr == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001127 /* Pull VOD record should use PCR time index */
Wentao MA96f68962022-06-15 19:45:35 +08001128 DVR_INFO("%s has no pcr, can NOT do time index", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +08001129 }
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001130 SEG_CALL_RET(write, (p_ctx->segment_handle, buffer, len), ret);
hualing chen2932d372020-04-29 13:44:00 +08001131 if (ret != len) {
Wentao MA96f68962022-06-15 19:45:35 +08001132 DVR_INFO("%s write error ret:%d len:%d", __func__, ret, len);
hualing chen2932d372020-04-29 13:44:00 +08001133 }
pengfei.liuab5a2262020-02-14 17:33:40 +08001134 p_ctx->segment_info.size += len;
1135 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
1136
Pengfei Liuc181a982020-01-07 19:27:13 +08001137 return DVR_SUCCESS;
1138}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001139
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001140int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001141{
1142 DVR_RecordContext_t *p_ctx;
1143 uint32_t i;
1144
1145 p_ctx = (DVR_RecordContext_t *)handle;
1146 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1147 if (p_ctx == &record_ctx[i])
1148 break;
1149 }
1150 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1151 DVR_RETURN_IF_FALSE(func);
1152
Wentao MA96f68962022-06-15 19:45:35 +08001153 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001154 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
1155 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
1156
1157 p_ctx->enc_func = func;
1158 p_ctx->enc_userdata = userdata;
1159 return DVR_SUCCESS;
1160}
1161
1162int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
1163{
1164 DVR_RecordContext_t *p_ctx;
1165 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001166 int ret = DVR_SUCCESS;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001167
1168 p_ctx = (DVR_RecordContext_t *)handle;
1169 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1170 if (p_ctx == &record_ctx[i])
1171 break;
1172 }
1173 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1174 DVR_RETURN_IF_FALSE(p_secure_buf);
1175 DVR_RETURN_IF_FALSE(len);
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 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
1182 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
1183
1184 p_ctx->is_secure_mode = 1;
Yahui Han4577db82022-07-05 17:46:19 +08001185 p_ctx->secbuf_size = len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001186 return ret;
1187}
hualing chen4fe3bee2020-10-23 13:58:52 +08001188
1189int dvr_record_is_secure_mode(DVR_RecordHandle_t handle)
1190{
1191 DVR_RecordContext_t *p_ctx;
1192 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001193 int ret = DVR_SUCCESS;
hualing chen4fe3bee2020-10-23 13:58:52 +08001194
1195 p_ctx = (DVR_RecordContext_t *)handle;
1196 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1197 if (p_ctx == &record_ctx[i])
1198 break;
1199 }
hualing chen002e5b92022-02-23 17:51:21 +08001200
hualing chen4fe3bee2020-10-23 13:58:52 +08001201 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1202
1203 if (p_ctx->is_secure_mode == 1)
1204 ret = 1;
1205 else
1206 ret = 0;
1207 return ret;
Yahui Hance15e9c2020-12-08 18:08:32 +08001208}
Wentao MAf4072032022-06-30 13:50:45 +08001209
1210int dvr_record_discard_coming_data(DVR_RecordHandle_t handle, DVR_Bool_t discard)
1211{
1212 DVR_RecordContext_t *p_ctx;
1213 int i;
1214
1215 p_ctx = (DVR_RecordContext_t *)handle;
1216 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1217 if (p_ctx == &record_ctx[i])
1218 break;
1219 }
1220 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1221
1222 if (p_ctx->discard_coming_data != discard) {
1223 p_ctx->discard_coming_data = discard;
1224 if (discard) {
1225 DVR_WARN("%s, start discarding coming data. discard:%d",__func__,discard);
1226 } else {
1227 DVR_WARN("%s, finish discarding coming data. discard:%d",__func__,discard);
1228 }
1229 }
1230
1231 return DVR_TRUE;
1232}
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001233
1234int dvr_record_ioctl(DVR_RecordHandle_t handle, unsigned int cmd, void *data, size_t size)
1235{
1236 DVR_RecordContext_t *p_ctx;
1237 int ret = DVR_FAILURE;
1238 int i;
1239
1240 p_ctx = (DVR_RecordContext_t *)handle;
1241 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1242 if (p_ctx == &record_ctx[i])
1243 break;
1244 }
1245 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1246
1247 SEG_CALL_INIT(&p_ctx->segment_ops);
1248
1249 if (SEG_CALL_IS_VALID(ioctl)) {
1250 if (p_ctx->segment_handle) {
1251 SEG_CALL_RET(ioctl, (p_ctx->segment_handle, cmd, data, size), ret);
Zhiqiang Han267bf092024-07-15 15:33:46 +08001252 }
1253
1254 {
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001255 DVR_Control_t *ctrl = (DVR_Control_t *)calloc(1, sizeof(DVR_Control_t));
1256 if (ctrl) {
1257 ctrl->cmd = cmd;
1258 if (size) {
1259 void *pdata = malloc(size);
1260 if (pdata) {
1261 memcpy(pdata, data, size);
1262 ctrl->data = pdata;
1263 ctrl->size = size;
1264 } else {
1265 free(ctrl);
1266 ctrl = NULL;
1267 }
1268 }
1269 }
1270 if (ctrl) {
1271 list_add_tail(&ctrl->head, &p_ctx->segment_ctrls);
Zhiqiang Han267bf092024-07-15 15:33:46 +08001272 DVR_INFO("%s, save ctrl[cmd:%d]", __func__, ctrl->cmd);
Zhiqiang Han2f019af2023-08-31 11:12:02 +08001273 ret = DVR_SUCCESS;
1274 }
1275 }
1276 }
1277
1278 return ret;
1279}