blob: 462ac756c57690c6e29f1285d61e5dd19c24a186 [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"
11#include "segment.h"
pengfei.liu567d6d82020-04-17 16:48:59 +080012#include <sys/time.h>
Wentao MA361eaac2023-03-21 13:12:28 +080013#include <sys/prctl.h>
Yahui Han1fbf3292021-11-08 18:17:19 +080014#include "am_crypt.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080015
hualing chen3092e1c2022-01-21 20:02:21 +080016#define CHECK_PTS_MAX_COUNT (20)
17
hualing chenc7aa4c82021-02-03 15:41:37 +080018//#define DEBUG_PERFORMANCE
Yahui Han10993892021-11-02 14:27:33 +080019#define MAX_DVR_RECORD_SESSION_COUNT 4
hualing chen266b9502020-04-04 17:39:39 +080020#define RECORD_BLOCK_SIZE (256 * 1024)
Yahui Hance15e9c2020-12-08 18:08:32 +080021#define NEW_DEVICE_RECORD_BLOCK_SIZE (1024 * 188)
pengfei.liuab5a2262020-02-14 17:33:40 +080022
23/**\brief DVR index file type*/
24typedef enum {
25 DVR_INDEX_TYPE_PCR, /**< DVR index file use pcr*/
26 DVR_INDEX_TYPE_LOCAL_CLOCK, /**< DVR index file use local clock*/
27 DVR_INDEX_TYPE_INVALID /**< DVR index file type invalid type*/
28} DVR_IndexType_t;
29
30/**\brief DVR VOD context*/
31typedef struct {
32 pthread_mutex_t mutex; /**< VOD mutex lock*/
33 pthread_cond_t cond; /**< VOD condition*/
34 void *buffer; /**< VOD buffer*/
35 uint32_t buf_len; /**< VOD buffer len*/
36} DVR_VodContext_t;
37
pengfei.liu07ddc8a2020-03-24 23:36:53 +080038/**\brief DVR record secure mode buffer*/
39typedef struct {
40 uint32_t addr; /**< Secure mode record buffer address*/
41 uint32_t len; /**< Secure mode record buffer length*/
42} DVR_SecureBuffer_t;
43
hualing chenf9867402020-09-23 17:06:20 +080044/**\brief DVR record new dmx secure mode buffer*/
45typedef struct {
46 uint32_t buf_start; /**< Secure mode record buffer address*/
47 uint32_t buf_end; /**< Secure mode record buffer length*/
48 uint32_t data_start; /**< Secure mode record buffer address*/
49 uint32_t data_end; /**< Secure mode record buffer length*/
50} DVR_NewDmxSecureBuffer_t;
51
Pengfei Liub4734232020-01-17 18:25:10 +080052/**\brief DVR record context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080053typedef struct {
Pengfei Liub4734232020-01-17 18:25:10 +080054 pthread_t thread; /**< DVR thread handle*/
55 Record_DeviceHandle_t dev_handle; /**< DVR device handle*/
56 Segment_Handle_t segment_handle; /**< DVR segment handle*/
57 DVR_RecordState_t state; /**< DVR record state*/
58 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
59 DVR_RecordSegmentStartParams_t segment_params; /**< DVR record start parameters*/
60 DVR_RecordSegmentInfo_t segment_info; /**< DVR record current segment info*/
Wentao MA270dc0f2022-08-23 13:17:26 +080061 size_t notification_size; /**< DVR record notification size*/
Pengfei Liub4734232020-01-17 18:25:10 +080062 DVR_RecordEventFunction_t event_notify_fn; /**< DVR record event notify function*/
63 void *event_userdata; /**< DVR record event userdata*/
pengfei.liuab5a2262020-02-14 17:33:40 +080064 //DVR_VodContext_t vod; /**< DVR record vod context*/
65 int is_vod; /**< Indicate current mode is VOD record mode*/
pengfei.liu27cc4ec2020-04-03 16:28:16 +080066 DVR_CryptoFunction_t enc_func; /**< Encrypt function*/
pengfei.liu07ddc8a2020-03-24 23:36:53 +080067 void *enc_userdata; /**< Encrypt userdata*/
68 int is_secure_mode; /**< Record session run in secure pipeline */
Yahui Han1fbf3292021-11-08 18:17:19 +080069 void *cryptor; /**< Cryptor for encrypted PVR on FTA.*/
hualing chen2615aa82020-04-02 21:32:51 +080070 size_t last_send_size; /**< Last send notify segment size */
pengfei.liufda2a972020-04-09 14:47:15 +080071 uint32_t block_size; /**< DVR record block size */
hualing chenf9867402020-09-23 17:06:20 +080072 DVR_Bool_t is_new_dmx; /**< DVR is used new dmx driver */
hualing chen40accc32021-04-21 15:58:09 +080073 int index_type; /**< DVR is used pcr or local time */
wentao.ma35a69d42022-03-10 18:08:40 +080074 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 +080075 uint64_t pts; /**< The newest pcr or local time */
hualing chen3092e1c2022-01-21 20:02:21 +080076 int check_pts_count; /**< The check count of pts */
hualing chen002e5b92022-02-23 17:51:21 +080077 int check_no_pts_count; /**< The check count of no pts */
Wentao MA270dc0f2022-08-23 13:17:26 +080078 int notification_time; /**< DVR record notification time*/
hualing chen002e5b92022-02-23 17:51:21 +080079 time_t last_send_time; /**< Last send notify segment duration */
Wentao MAeeffdb02022-06-27 16:34:35 +080080 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 +080081 size_t secbuf_size; /**< DVR record secure buffer length*/
Wentao MAf4072032022-06-30 13:50:45 +080082 DVR_Bool_t discard_coming_data; /**< Whether to discard subsequent recording data due to exceeding total size limit too much.*/
Pengfei Liuc181a982020-01-07 19:27:13 +080083} DVR_RecordContext_t;
84
Gong Ke2a0ebbe2021-05-25 15:22:50 +080085extern ssize_t record_device_read_ext(Record_DeviceHandle_t handle, size_t *buf, size_t *len);
86
Pengfei Liuc181a982020-01-07 19:27:13 +080087static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
88 {
Pengfei Liub4734232020-01-17 18:25:10 +080089 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080090 },
91 {
Pengfei Liub4734232020-01-17 18:25:10 +080092 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080093 }
94};
95
Zhiqiang Han51646a02020-04-05 18:43:22 +080096static int record_is_valid_pid(DVR_RecordContext_t *p_ctx, int pid)
97{
98 int i;
99
100 for (i = 0; i < p_ctx->segment_info.nb_pids; i++) {
101 if (pid == p_ctx->segment_info.pids[i].pid)
102 return 1;
103 }
104 return 0;
105}
106
pengfei.liuab5a2262020-02-14 17:33:40 +0800107static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
108{
109 uint8_t *p = buf;
110 int len;
111 uint8_t afc;
112 uint64_t pcr = 0;
113 int has_pcr = 0;
114 int pid;
115 int adp_field_len;
116
117 pid = ((p[1] & 0x1f) << 8) | p[2];
Zhiqiang Han51646a02020-04-05 18:43:22 +0800118 if (pid == 0x1fff || !record_is_valid_pid(p_ctx, pid))
pengfei.liuab5a2262020-02-14 17:33:40 +0800119 return has_pcr;
120
121 //scramble = p[3] >> 6;
122 //cc = p[3] & 0x0f;
123 afc = (p[3] >> 4) & 0x03;
124
125 p += 4;
126 len = 184;
127
128 if (afc & 2) {
129 adp_field_len = p[0];
130 /* Skip adaptation len */
131 p++;
132 len--;
133 /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
hualing chen5605eed2020-05-26 18:18:06 +0800134 if (p[0] & 0x10 && len >= 6 && adp_field_len >= 6) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800135 /* get pcr value,pcr is 33bit value */
136 pcr = (((uint64_t)(p[1])) << 25)
137 | (((uint64_t)p[2]) << 17)
138 | (((uint64_t)(p[3])) << 9)
139 | (((uint64_t)p[4]) << 1)
140 | ((((uint64_t)p[5]) & 0x80) >> 7);
141 has_pcr = 1;
142 }
143
pengfei.liuab5a2262020-02-14 17:33:40 +0800144 len -= adp_field_len;
145
146 if (len < 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800147 DVR_INFO("parser pcr: illegal adaptation field length");
pengfei.liuab5a2262020-02-14 17:33:40 +0800148 return 0;
149 }
150 }
151
hualing chen40accc32021-04-21 15:58:09 +0800152 if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
hualing chen94d8dd22021-12-29 15:13:43 +0800153 //save newest pcr
hualing chen3092e1c2022-01-21 20:02:21 +0800154 if (p_ctx->pts == pcr/90 &&
155 p_ctx->check_pts_count < CHECK_PTS_MAX_COUNT) {
hualing chen3092e1c2022-01-21 20:02:21 +0800156 p_ctx->check_pts_count ++;
157 }
hualing chen94d8dd22021-12-29 15:13:43 +0800158 p_ctx->pts = pcr/90;
pengfei.liuab5a2262020-02-14 17:33:40 +0800159 segment_update_pts(p_ctx->segment_handle, pcr/90, pos);
160 }
161 return has_pcr;
162}
163
164static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
165{
166 uint8_t *p = buf;
167 int left = len;
168 loff_t pos;
169 int has_pcr = 0;
170
171 pos = segment_tell_position(p_ctx->segment_handle);
hualing chen3e0d3a42022-01-25 17:22:01 +0800172 if (pos >= len) {
173 pos = pos - len;
174 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800175 while (left >= 188) {
176 if (*p == 0x47) {
177 has_pcr |= record_save_pcr(p_ctx, p, pos);
178 p += 188;
179 left -= 188;
180 pos += 188;
181 } else {
182 p++;
183 left --;
184 pos++;
185 }
186 }
187 return has_pcr;
188}
189
pengfei.liu567d6d82020-04-17 16:48:59 +0800190static int get_diff_time(struct timeval start_tv, struct timeval end_tv)
191{
192 return end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000 - start_tv.tv_sec * 1000 - start_tv.tv_usec / 1000;
193}
194
Pengfei Liuc181a982020-01-07 19:27:13 +0800195void *record_thread(void *arg)
196{
197 DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
198 ssize_t len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800199 uint8_t *buf, *buf_out;
pengfei.liufda2a972020-04-09 14:47:15 +0800200 uint32_t block_size = p_ctx->block_size;
pengfei.liuab5a2262020-02-14 17:33:40 +0800201 loff_t pos = 0;
Wentao MA139fc612022-08-29 14:10:07 +0800202 int ret = DVR_SUCCESS;
Wentao MA270dc0f2022-08-23 13:17:26 +0800203 struct timespec start_ts, end_ts, start_no_pcr_ts, end_no_pcr_ts;
Pengfei Liub4734232020-01-17 18:25:10 +0800204 DVR_RecordStatus_t record_status;
pengfei.liuab5a2262020-02-14 17:33:40 +0800205 int has_pcr;
hualing chen3092e1c2022-01-21 20:02:21 +0800206 int pcr_rec_len = 0;
Wentao MAeeffdb02022-06-27 16:34:35 +0800207 DVR_Bool_t guarded_size_exceeded = DVR_FALSE;
hualing chen40accc32021-04-21 15:58:09 +0800208
hualing chen87072a82020-03-12 16:20:12 +0800209 time_t pre_time = 0;
hualing chen2932d372020-04-29 13:44:00 +0800210 #define DVR_STORE_INFO_TIME (400)
Wentao MA139fc612022-08-29 14:10:07 +0800211 DVR_SecureBuffer_t secure_buf = {0,0};
hualing chenf9867402020-09-23 17:06:20 +0800212 DVR_NewDmxSecureBuffer_t new_dmx_secure_buf;
hualing chena5f03222021-12-02 11:22:35 +0800213 int first_read = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800214
Wentao MA361eaac2023-03-21 13:12:28 +0800215 prctl(PR_SET_NAME,"DvrRecording");
216
wentao.ma35a69d42022-03-10 18:08:40 +0800217 // Force to use LOCAL_CLOCK as index type if force_sysclock is on. Please
218 // refer to SWPL-75327
219 if (p_ctx->force_sysclock)
220 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
shenghui.gengbec6a462023-01-12 15:21:02 +0800221 else
222 p_ctx->index_type = DVR_INDEX_TYPE_INVALID;
Pengfei Liub4734232020-01-17 18:25:10 +0800223 buf = (uint8_t *)malloc(block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800224 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +0800225 DVR_INFO("%s, malloc failed", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800226 return NULL;
227 }
228
Yahui Han4577db82022-07-05 17:46:19 +0800229 if (p_ctx->is_secure_mode) {
230 buf_out = (uint8_t *)malloc(p_ctx->secbuf_size + 188);
231 } else {
232 buf_out = (uint8_t *)malloc(block_size + 188);
233 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800234 if (!buf_out) {
Wentao MA96f68962022-06-15 19:45:35 +0800235 DVR_INFO("%s, malloc failed", __func__);
Pengfei Liufaf38e42020-05-22 00:28:02 +0800236 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800237 return NULL;
238 }
239
hualing chen266b9502020-04-04 17:39:39 +0800240 memset(&record_status, 0, sizeof(record_status));
241 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800242 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800243 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800244 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
Wentao MA96f68962022-06-15 19:45:35 +0800245 DVR_INFO("%s line %d notify record status, state:%d id=%lld",
hualing chen4b7c15d2020-04-07 16:13:48 +0800246 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800247 }
Wentao MA96f68962022-06-15 19:45:35 +0800248 DVR_INFO("%s, --secure_mode:%d, block_size:%d, cryptor:%p",
hualing chen002e5b92022-02-23 17:51:21 +0800249 __func__, p_ctx->is_secure_mode,
250 block_size, p_ctx->cryptor);
Pengfei Liub4734232020-01-17 18:25:10 +0800251 clock_gettime(CLOCK_MONOTONIC, &start_ts);
hualing chen3092e1c2022-01-21 20:02:21 +0800252 p_ctx->check_pts_count = 0;
253 p_ctx->check_no_pts_count++;
hualing chen002e5b92022-02-23 17:51:21 +0800254 p_ctx->last_send_size = 0;
255 p_ctx->last_send_time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800256 struct timeval t1, t2, t3, t4, t5, t6, t7;
hualing chen03fd4942021-07-15 15:56:41 +0800257 while (p_ctx->state == DVR_RECORD_STATE_STARTED ||
258 p_ctx->state == DVR_RECORD_STATE_PAUSE) {
259
260 if (p_ctx->state == DVR_RECORD_STATE_PAUSE) {
261 //wait resume record
262 usleep(20*1000);
263 continue;
264 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800265 gettimeofday(&t1, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800266
pengfei.liuab5a2262020-02-14 17:33:40 +0800267 /* data from dmx, normal dvr case */
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800268 if (p_ctx->is_secure_mode) {
hualing chenf9867402020-09-23 17:06:20 +0800269 if (p_ctx->is_new_dmx) {
Wentao MA804bab12022-11-29 10:01:26 +0800270 /* We resolve the below invoke for dvbcore to be under safety status */
271 memset(&new_dmx_secure_buf, 0, sizeof(new_dmx_secure_buf));
272 len = record_device_read(p_ctx->dev_handle, &new_dmx_secure_buf,
273 sizeof(new_dmx_secure_buf), 10);
Yahui Hance15e9c2020-12-08 18:08:32 +0800274
Wentao MA804bab12022-11-29 10:01:26 +0800275 /* Read data from secure demux TA */
276 len = record_device_read_ext(p_ctx->dev_handle, &secure_buf.addr,
277 &secure_buf.len);
hualing chenf9867402020-09-23 17:06:20 +0800278 } else {
279 memset(&secure_buf, 0, sizeof(secure_buf));
Wentao MA804bab12022-11-29 10:01:26 +0800280 len = record_device_read(p_ctx->dev_handle, &secure_buf,
281 sizeof(secure_buf), 1000);
hualing chenf9867402020-09-23 17:06:20 +0800282 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800283 } else {
284 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
285 }
Pengfei Liub4734232020-01-17 18:25:10 +0800286 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800287 //usleep(10*1000);
Wentao MA96f68962022-06-15 19:45:35 +0800288 //DVR_INFO("%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800289 continue;
290 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800291 gettimeofday(&t2, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800292
Wentao MAeeffdb02022-06-27 16:34:35 +0800293 guarded_size_exceeded = DVR_FALSE;
wentao.mad08db842022-11-14 17:35:40 +0800294 if ( p_ctx->guarded_segment_size > 0 &&
295 p_ctx->segment_info.size+len >= p_ctx->guarded_segment_size) {
Wentao MAeeffdb02022-06-27 16:34:35 +0800296 guarded_size_exceeded = DVR_TRUE;
297 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800298 /* Got data from device, record it */
Wentao MAeeffdb02022-06-27 16:34:35 +0800299 if (guarded_size_exceeded) {
300 len = 0;
301 ret = 0;
Wentao MAf4072032022-06-30 13:50:45 +0800302 DVR_ERROR("Skip segment_write due to current segment size %u exceeding"
303 " guarded segment size", p_ctx->segment_info.size);
304 } else if (p_ctx->discard_coming_data) {
305 len = 0;
306 ret = 0;
307 DVR_ERROR("Skip segment_write due to total size exceeding max size too much");
Wentao MAeeffdb02022-06-27 16:34:35 +0800308 } else if (p_ctx->enc_func) {
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800309 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800310 DVR_CryptoParams_t crypto_params;
311
312 memset(&crypto_params, 0, sizeof(crypto_params));
313 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800314 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800315 crypto_params.segment_id = p_ctx->segment_info.id;
316 crypto_params.offset = p_ctx->segment_info.size;
317
318 if (p_ctx->is_secure_mode) {
319 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
Yahui Han1fbf3292021-11-08 18:17:19 +0800320 crypto_params.input_buffer.addr = secure_buf.addr;
321 crypto_params.input_buffer.size = secure_buf.len;
Yahui Hanaf03b142022-08-17 17:52:37 +0800322 crypto_params.output_buffer.size = p_ctx->secbuf_size + 188;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800323 } else {
324 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
325 crypto_params.input_buffer.addr = (size_t)buf;
326 crypto_params.input_buffer.size = len;
Yahui Hanaf03b142022-08-17 17:52:37 +0800327 crypto_params.output_buffer.size = block_size + 188;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800328 }
329
330 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
331 crypto_params.output_buffer.addr = (size_t)buf_out;
hualing chen9811b212020-10-29 11:21:44 +0800332
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800333 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800334 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800335 /* Out buffer length may not equal in buffer length */
hualing chenf9867402020-09-23 17:06:20 +0800336 if (crypto_params.output_size > 0) {
337 ret = segment_write(p_ctx->segment_handle, buf_out, crypto_params.output_size);
338 len = crypto_params.output_size;
hualing chenbafc62d2020-11-02 15:44:05 +0800339 } else {
340 len = 0;
hualing chenf9867402020-09-23 17:06:20 +0800341 }
Yahui Han1fbf3292021-11-08 18:17:19 +0800342 } else if (p_ctx->cryptor) {
343 /* Encrypt with clear key */
Yahui Han63b23b42021-12-07 15:37:46 +0800344 int crypt_len = len;
345 am_crypt_des_crypt(p_ctx->cryptor, buf_out, buf, &crypt_len, 0);
346 len = crypt_len;
Yahui Han1fbf3292021-11-08 18:17:19 +0800347 gettimeofday(&t3, NULL);
348 ret = segment_write(p_ctx->segment_handle, buf_out, len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800349 } else {
hualing chena5f03222021-12-02 11:22:35 +0800350 if (first_read == 0) {
351 first_read = 1;
Wentao MA96f68962022-06-15 19:45:35 +0800352 DVR_INFO("%s:%d,first read ts", __func__,__LINE__);
hualing chena5f03222021-12-02 11:22:35 +0800353 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800354 gettimeofday(&t3, NULL);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800355 ret = segment_write(p_ctx->segment_handle, buf, len);
356 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800357 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800358 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800359 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800360 //send write event
hualing chen9b434f02020-06-10 15:06:54 +0800361 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800362 memset(&record_status, 0, sizeof(record_status));
Wentao MAeeffdb02022-06-27 16:34:35 +0800363 DVR_INFO("%s:%d,send event write error", __func__,__LINE__);
hualing chen9ce7d942021-06-30 13:31:01 +0800364 record_status.info.id = p_ctx->segment_info.id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800365 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
366 }
Wentao MA96f68962022-06-15 19:45:35 +0800367 DVR_INFO("%s,write error %d", __func__,__LINE__);
hualing chen626204e2020-04-07 11:55:08 +0800368 goto end;
369 }
Wentao MAf4072032022-06-30 13:50:45 +0800370 if (len>0) {
371 /* Do time index */
372 uint8_t *index_buf = (p_ctx->enc_func || p_ctx->cryptor)? buf_out : buf;
373 pos = segment_tell_position(p_ctx->segment_handle);
374 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
375 if (has_pcr == 0 && p_ctx->index_type == DVR_INDEX_TYPE_INVALID) {
376 clock_gettime(CLOCK_MONOTONIC, &end_ts);
377 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
378 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800379 /* PCR interval threshold > 40 ms*/
Wentao MAf4072032022-06-30 13:50:45 +0800380 DVR_INFO("%s use local clock time index", __func__);
hualing chen3092e1c2022-01-21 20:02:21 +0800381 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
Wentao MAf4072032022-06-30 13:50:45 +0800382 }
383 } else if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_INVALID){
384 DVR_INFO("%s use pcr time index", __func__);
385 p_ctx->index_type = DVR_INDEX_TYPE_PCR;
386 record_do_pcr_index(p_ctx, index_buf, len);
387 }
388 gettimeofday(&t5, NULL);
389 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
390 if (has_pcr == 0) {
391 if (p_ctx->check_no_pts_count < 2 * CHECK_PTS_MAX_COUNT) {
392 if (p_ctx->check_no_pts_count == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800393 clock_gettime(CLOCK_MONOTONIC, &start_no_pcr_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800394 clock_gettime(CLOCK_MONOTONIC, &start_ts);
395 }
396 p_ctx->check_no_pts_count++;
397 }
398 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +0800399 clock_gettime(CLOCK_MONOTONIC, &start_no_pcr_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800400 p_ctx->check_no_pts_count = 0;
401 }
402 }
403 /* Update segment i nfo */
404 p_ctx->segment_info.size += len;
Pengfei Liub4734232020-01-17 18:25:10 +0800405
Wentao MAf4072032022-06-30 13:50:45 +0800406 /*Duration need use pcr to calculate, todo...*/
407 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
hualing chenc94227e2022-02-17 09:48:43 +0800408 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Wentao MAf4072032022-06-30 13:50:45 +0800409 if (pre_time == 0)
410 pre_time = p_ctx->segment_info.duration;
411 } else if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
412 clock_gettime(CLOCK_MONOTONIC, &end_ts);
413 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
414 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) + pcr_rec_len;
415 if (pre_time == 0)
416 pre_time = p_ctx->segment_info.duration;
417 segment_update_pts(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
418 } else {
419 DVR_INFO("%s can NOT do time index", __func__);
420 }
421 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR &&
422 p_ctx->check_pts_count == CHECK_PTS_MAX_COUNT) {
423 DVR_INFO("%s change time from pcr to local time", __func__);
424 if (pcr_rec_len == 0)
425 pcr_rec_len = segment_tell_total_time(p_ctx->segment_handle);
426 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
427 if (pcr_rec_len == 0)
428 pcr_rec_len = segment_tell_total_time(p_ctx->segment_handle);
429 clock_gettime(CLOCK_MONOTONIC, &start_ts);
430 }
431
432 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR ) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800433 clock_gettime(CLOCK_MONOTONIC, &end_no_pcr_ts);
434 int diff = (int)(end_no_pcr_ts.tv_sec*1000 + end_no_pcr_ts.tv_nsec/1000000) -
435 (int)(start_no_pcr_ts.tv_sec*1000 + start_no_pcr_ts.tv_nsec/1000000);
Wentao MAf4072032022-06-30 13:50:45 +0800436 if (diff > 3000) {
437 DVR_INFO("%s no pcr change time from pcr to local time diff[%d]", __func__, diff);
438 if (pcr_rec_len == 0)
439 pcr_rec_len = segment_tell_total_time(p_ctx->segment_handle);
440 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
441 }
442 }
443 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
444
445 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
446 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
447 time_t duration = p_ctx->segment_info.duration;
448 if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK)
449 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
450 segment_store_info(p_ctx->segment_handle, &(p_ctx->segment_info));
451 p_ctx->segment_info.duration = duration;
452 }
453 } else {
454 gettimeofday(&t5, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800455 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800456 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800457 /*Event notification*/
Wentao MAf4072032022-06-30 13:50:45 +0800458 DVR_Bool_t condA1 = (p_ctx->notification_size > 0);
459 DVR_Bool_t condA2 = ((p_ctx->segment_info.size-p_ctx->last_send_size) >= p_ctx->notification_size);
460 DVR_Bool_t condA3 = (p_ctx->notification_time > 0);
461 DVR_Bool_t condA4 = ((p_ctx->segment_info.duration-p_ctx->last_send_time) >= p_ctx->notification_time);
462 DVR_Bool_t condA5 = (guarded_size_exceeded);
463 DVR_Bool_t condA6 = (p_ctx->discard_coming_data);
464 DVR_Bool_t condB = (p_ctx->event_notify_fn != NULL);
465 DVR_Bool_t condC = (p_ctx->segment_info.duration > 0);
466 DVR_Bool_t condD = (p_ctx->state == DVR_RECORD_STATE_STARTED);
467 if (((condA1 && condA2) || (condA3 && condA4) || condA5 || condA6)
468 && condB && condC && condD) {
Pengfei Liub4734232020-01-17 18:25:10 +0800469 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800470 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800471 p_ctx->last_send_size = p_ctx->segment_info.size;
hualing chen002e5b92022-02-23 17:51:21 +0800472 p_ctx->last_send_time = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800473 record_status.state = p_ctx->state;
474 record_status.info.id = p_ctx->segment_info.id;
hualing chenc94227e2022-02-17 09:48:43 +0800475 if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK)
476 record_status.info.duration = segment_tell_total_time(p_ctx->segment_handle);
477 else
478 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800479 record_status.info.size = p_ctx->segment_info.size;
480 record_status.info.nb_packets = p_ctx->segment_info.size/188;
481 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
Wentao MA96f68962022-06-15 19:45:35 +0800482 DVR_INFO("%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu loc[%s]",
hualing chen4fe3bee2020-10-23 13:58:52 +0800483 __func__, record_status.state,
484 record_status.info.id, record_status.info.duration,
485 record_status.info.size, p_ctx->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800486 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800487 gettimeofday(&t7, NULL);
488#ifdef DEBUG_PERFORMANCE
Wentao MA96f68962022-06-15 19:45:35 +0800489 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 +0800490 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 +0800491 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len,
492 p_ctx->notification_time,p_ctx->segment_info.duration -p_ctx->last_send_time);
pengfei.liu567d6d82020-04-17 16:48:59 +0800493#endif
Wentao MAf4072032022-06-30 13:50:45 +0800494 if (len == 0) {
495 usleep(20*1000);
496 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800497 }
hualing chen626204e2020-04-07 11:55:08 +0800498end:
Pengfei Liub4734232020-01-17 18:25:10 +0800499 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800500 free((void *)buf_out);
Wentao MA96f68962022-06-15 19:45:35 +0800501 DVR_INFO("exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800502 return NULL;
503}
504
505int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
506{
507 DVR_RecordContext_t *p_ctx;
508 Record_DeviceOpenParams_t dev_open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800509 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800510 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800511
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800512 DVR_RETURN_IF_FALSE(p_handle);
513 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800514
515 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800516 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800517 break;
518 }
519 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800520 DVR_RETURN_IF_FALSE(i < MAX_DVR_RECORD_SESSION_COUNT);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800521 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800522 p_ctx = &record_ctx[i];
Wentao MA96f68962022-06-15 19:45:35 +0800523 DVR_INFO("%s , current state:%d, dmx_id:%d, notification_size:%zu, flags:%d, keylen:%d ",
Yahui Han1fbf3292021-11-08 18:17:19 +0800524 __func__, p_ctx->state, params->dmx_dev_id,
hualing chen002e5b92022-02-23 17:51:21 +0800525 params->notification_size,
526 params->flags, params->keylen);
Pengfei Liuc181a982020-01-07 19:27:13 +0800527
Pengfei Liub4734232020-01-17 18:25:10 +0800528 /*Process event params*/
529 p_ctx->notification_size = params->notification_size;
hualing chen002e5b92022-02-23 17:51:21 +0800530 p_ctx->notification_time = params->notification_time;
531
Pengfei Liub4734232020-01-17 18:25:10 +0800532 p_ctx->event_notify_fn = params->event_fn;
533 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800534 p_ctx->last_send_size = 0;
hualing chen002e5b92022-02-23 17:51:21 +0800535 p_ctx->last_send_time = 0;
hualing chen94d8dd22021-12-29 15:13:43 +0800536 p_ctx->pts = ULLONG_MAX;
Yahui Han1fbf3292021-11-08 18:17:19 +0800537
538 if (params->keylen > 0) {
539 p_ctx->cryptor = am_crypt_des_open(params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +0800540 params->cleariv,
541 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +0800542 if (!p_ctx->cryptor)
Wentao MA96f68962022-06-15 19:45:35 +0800543 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +0800544 } else {
545 p_ctx->cryptor = NULL;
546 }
547
hualing chenf9867402020-09-23 17:06:20 +0800548 //check is new driver
549 p_ctx->is_new_dmx = dvr_check_dmx_isNew();
Pengfei Liub4734232020-01-17 18:25:10 +0800550 /*Process crypto params, todo*/
Pengfei Liub4734232020-01-17 18:25:10 +0800551 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800552 if (params->data_from_memory) {
553 /* data from memory, VOD case */
554 p_ctx->is_vod = 1;
555 } else {
556 p_ctx->is_vod = 0;
557 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800558 dev_open_params.dmx_dev_id = params->dmx_dev_id;
hualing chen157641d2022-02-22 17:54:52 +0800559 //set dvr flush size
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800560 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen157641d2022-02-22 17:54:52 +0800561 //set dvbcore ringbuf size
hualing chen03fd4942021-07-15 15:56:41 +0800562 dev_open_params.ringbuf_size = params->ringbuf_size;
hualing chen157641d2022-02-22 17:54:52 +0800563
pengfei.liuab5a2262020-02-14 17:33:40 +0800564 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
565 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +0800566 DVR_INFO("%s, open record devices failed", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800567 return DVR_FAILURE;
568 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800569 }
570
pengfei.liufda2a972020-04-09 14:47:15 +0800571 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen157641d2022-02-22 17:54:52 +0800572
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800573 p_ctx->enc_func = NULL;
574 p_ctx->enc_userdata = NULL;
575 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800576 p_ctx->state = DVR_RECORD_STATE_OPENED;
wentao.ma35a69d42022-03-10 18:08:40 +0800577 p_ctx->force_sysclock = params->force_sysclock;
Wentao MAeeffdb02022-06-27 16:34:35 +0800578 p_ctx->guarded_segment_size = params->guarded_segment_size;
wentao.mad08db842022-11-14 17:35:40 +0800579 if (p_ctx->guarded_segment_size <= 0) {
580 DVR_WARN("Odd guarded_segment_size value %lld is given. Change it to"
581 " 0 to disable segment guarding mechanism.", p_ctx->guarded_segment_size);
582 p_ctx->guarded_segment_size = 0;
583 }
Wentao MAf4072032022-06-30 13:50:45 +0800584 p_ctx->discard_coming_data = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +0800585 DVR_INFO("%s, block_size:%d is_new:%d", __func__, p_ctx->block_size, p_ctx->is_new_dmx);
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800586 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800587 return DVR_SUCCESS;
588}
589
590int dvr_record_close(DVR_RecordHandle_t handle)
591{
592 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800593 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800594 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800595
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800596 p_ctx = (DVR_RecordContext_t *)handle;
597 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
598 if (p_ctx == &record_ctx[i])
599 break;
600 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800601 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800602
Wentao MA96f68962022-06-15 19:45:35 +0800603 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800604 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Yahui Han1fbf3292021-11-08 18:17:19 +0800605 if (p_ctx->cryptor) {
606 am_crypt_des_close(p_ctx->cryptor);
607 p_ctx->cryptor = NULL;
608 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800609 if (p_ctx->is_vod) {
610 ret = DVR_SUCCESS;
611 } else {
612 ret = record_device_close(p_ctx->dev_handle);
613 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +0800614 DVR_INFO("%s, failed", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800615 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800616 }
hualing chencedcb862022-01-04 15:32:43 +0800617 memset(p_ctx, 0, sizeof(DVR_RecordContext_t));
Pengfei Liub4734232020-01-17 18:25:10 +0800618 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800619 return ret;
620}
621
hualing chen03fd4942021-07-15 15:56:41 +0800622int dvr_record_pause(DVR_RecordHandle_t handle)
623{
624 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800625 int ret = DVR_SUCCESS;
hualing chen03fd4942021-07-15 15:56:41 +0800626 uint32_t i;
627
628 p_ctx = (DVR_RecordContext_t *)handle;
629 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
630 if (p_ctx == &record_ctx[i])
631 break;
632 }
633 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
634
Wentao MA96f68962022-06-15 19:45:35 +0800635 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
hualing chen03fd4942021-07-15 15:56:41 +0800636 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
637
638 if (p_ctx->is_vod) {
639 ret = DVR_SUCCESS;
640 }
641 //set pause state,will not store ts into segment
642 p_ctx->state = DVR_RECORD_STATE_PAUSE;
643 return ret;
644}
645
646int dvr_record_resume(DVR_RecordHandle_t handle)
647{
648 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800649 int ret = DVR_SUCCESS;
hualing chen03fd4942021-07-15 15:56:41 +0800650 uint32_t i;
651
652 p_ctx = (DVR_RecordContext_t *)handle;
653 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
654 if (p_ctx == &record_ctx[i])
655 break;
656 }
657 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
658
Wentao MA96f68962022-06-15 19:45:35 +0800659 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
hualing chen03fd4942021-07-15 15:56:41 +0800660 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
661
662 if (p_ctx->is_vod) {
663 ret = DVR_SUCCESS;
664 }
665 //set stated state,will resume store ts into segment
666 p_ctx->state = DVR_RECORD_STATE_STARTED;
667 return ret;
668}
669
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800670#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800671int dvr_record_register_encryption(DVR_RecordHandle_t handle,
672 DVR_CryptoFunction_t cb,
673 DVR_CryptoParams_t params,
674 void *userdata)
675{
676 return DVR_SUCCESS;
677}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800678#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800679
680int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
681{
682 DVR_RecordContext_t *p_ctx;
683 Segment_OpenParams_t open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800684 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800685 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800686
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800687 p_ctx = (DVR_RecordContext_t *)handle;
688 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
689 if (p_ctx == &record_ctx[i])
690 break;
691 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800692 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800693
Wentao MA96f68962022-06-15 19:45:35 +0800694 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 +0800695 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
696 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
697 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800698
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800699 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800700 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800701 memcpy(open_params.location, params->location, sizeof(params->location));
Pengfei Liuc181a982020-01-07 19:27:13 +0800702 open_params.segment_id = params->segment.segment_id;
703 open_params.mode = SEGMENT_MODE_WRITE;
wentao.ma35a69d42022-03-10 18:08:40 +0800704 open_params.force_sysclock = p_ctx->force_sysclock;
Pengfei Liuc181a982020-01-07 19:27:13 +0800705
706 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800707 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800708
Pengfei Liub4734232020-01-17 18:25:10 +0800709 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800710 {
hualing chen7a56cba2020-04-14 14:09:27 +0800711 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800712 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800713 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800714 /*save current segment info*/
715 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
716 p_ctx->segment_info.id = params->segment.segment_id;
717 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
718 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800719 }
720
pengfei.liuab5a2262020-02-14 17:33:40 +0800721 if (!p_ctx->is_vod) {
722 /* normal dvr case */
723 for (i = 0; i < params->segment.nb_pids; i++) {
724 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
725 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
726 }
727 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800728 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800729 }
730
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800731 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
wentao.maa210e5e2022-10-12 16:10:03 +0800732 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800733
Pengfei Liuc181a982020-01-07 19:27:13 +0800734 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800735 if (!p_ctx->is_vod)
736 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800737
Pengfei Liuc181a982020-01-07 19:27:13 +0800738 return DVR_SUCCESS;
739}
740
741int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
742{
743 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800744 Segment_OpenParams_t open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800745 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800746 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800747 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800748
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800749 p_ctx = (DVR_RecordContext_t *)handle;
750 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
751 if (p_ctx == &record_ctx[i])
752 break;
753 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800754 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800755
Wentao MA96f68962022-06-15 19:45:35 +0800756 DVR_INFO("%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800757 DVR_RETURN_IF_FALSE(p_ctx->state == DVR_RECORD_STATE_STARTED);
758 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
759 DVR_RETURN_IF_FALSE(params);
760 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800761 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800762
763 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800764 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800765 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800766 p_ctx->state = DVR_RECORD_STATE_STOPPED;
767 pthread_join(p_ctx->thread, NULL);
768
hualing chen2932d372020-04-29 13:44:00 +0800769 //add index file store
770 pos = segment_tell_position(p_ctx->segment_handle);
771 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
772
773 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liub4734232020-01-17 18:25:10 +0800774 /*Update segment info*/
775 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
776
777 ret = segment_store_info(p_ctx->segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800778 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
wentao.maa210e5e2022-10-12 16:10:03 +0800779 segment_store_allInfo(p_ctx->segment_handle, p_info);
Wentao MA96f68962022-06-15 19:45:35 +0800780 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 +0800781 __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 +0800782
Pengfei Liub4734232020-01-17 18:25:10 +0800783 /*Close current segment*/
784 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800785 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800786 /*Open the new record segment*/
787 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800788 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800789 open_params.segment_id = params->segment.segment_id;
790 open_params.mode = SEGMENT_MODE_WRITE;
wentao.ma35a69d42022-03-10 18:08:40 +0800791 open_params.force_sysclock = p_ctx->force_sysclock;
Wentao MA96f68962022-06-15 19:45:35 +0800792 DVR_INFO("%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
hualing chen002e5b92022-02-23 17:51:21 +0800793 p_ctx->last_send_size = 0;
794 p_ctx->last_send_time = 0;
Pengfei Liub4734232020-01-17 18:25:10 +0800795 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800796 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800797 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800798 {
Pengfei Liub4734232020-01-17 18:25:10 +0800799 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800800 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800801 /*save current segment info*/
802 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
803 p_ctx->segment_info.id = params->segment.segment_id;
804 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800805 }
806
Pengfei Liub4734232020-01-17 18:25:10 +0800807 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800808 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800809 switch (params->segment.pid_action[i]) {
810 case DVR_RECORD_PID_CREATE:
Wentao MA96f68962022-06-15 19:45:35 +0800811 DVR_INFO("%s create pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800812 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
813 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800814 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800815 break;
816 case DVR_RECORD_PID_KEEP:
Wentao MA96f68962022-06-15 19:45:35 +0800817 DVR_INFO("%s keep pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800818 p_ctx->segment_info.nb_pids++;
819 break;
820 case DVR_RECORD_PID_CLOSE:
Wentao MA96f68962022-06-15 19:45:35 +0800821 DVR_INFO("%s close pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800822 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800823 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800824 break;
825 default:
Wentao MA96f68962022-06-15 19:45:35 +0800826 DVR_INFO("%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800827 return DVR_FAILURE;
828 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800829 }
830
Pengfei Liub4734232020-01-17 18:25:10 +0800831 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800832 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen4b7c15d2020-04-07 16:13:48 +0800833 /*Update segment info*/
834 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
wentao.maa210e5e2022-10-12 16:10:03 +0800835 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen94d8dd22021-12-29 15:13:43 +0800836 if (p_ctx->pts != ULLONG_MAX)
837 segment_update_pts(p_ctx->segment_handle, p_ctx->pts, 0);
Pengfei Liuc181a982020-01-07 19:27:13 +0800838
Pengfei Liuc181a982020-01-07 19:27:13 +0800839 p_ctx->state = DVR_RECORD_STATE_STARTED;
Zhiqiang Han0d60f2b2020-05-26 14:39:54 +0800840 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800841 return DVR_SUCCESS;
842}
843
844int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
845{
846 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800847 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800848 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800849 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800850
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800851 p_ctx = (DVR_RecordContext_t *)handle;
852 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
853 if (p_ctx == &record_ctx[i])
854 break;
855 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800856 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800857
Wentao MAd71e2062023-02-15 10:10:49 +0800858 if (p_ctx->segment_handle == NULL) {
859 // It seems this stop function has been called twice on the same recording,
860 // so just return success.
861 return DVR_SUCCESS;
862 }
863
Wentao MA96f68962022-06-15 19:45:35 +0800864 DVR_INFO("%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800865 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STOPPED);
866 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +0800867 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800868
Pengfei Liuc181a982020-01-07 19:27:13 +0800869 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800870 if (p_ctx->is_vod) {
pengfei.liu8b563292020-02-26 15:49:02 +0800871 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
pengfei.liuab5a2262020-02-14 17:33:40 +0800872 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
873 } else {
Chao Yin0e6cb602022-08-02 15:41:24 +0800874 pthread_join(p_ctx->thread, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +0800875 ret = record_device_stop(p_ctx->dev_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800876 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
877 if (ret != DVR_SUCCESS)
878 goto end;
pengfei.liuab5a2262020-02-14 17:33:40 +0800879 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800880 }
881
hualing chen2932d372020-04-29 13:44:00 +0800882 //add index file store
883 pos = segment_tell_position(p_ctx->segment_handle);
884 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
hualing chene41f4372020-06-06 16:29:17 +0800885 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800886
Pengfei Liub4734232020-01-17 18:25:10 +0800887 /*Update segment info*/
888 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
889
890 ret = segment_store_info(p_ctx->segment_handle, p_info);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800891 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
892 if (ret != DVR_SUCCESS)
893 goto end;
Pengfei Liub4734232020-01-17 18:25:10 +0800894
hualing chenb9a02922021-12-14 11:29:47 +0800895 segment_store_allInfo(p_ctx->segment_handle, p_info);
896
Wentao MA96f68962022-06-15 19:45:35 +0800897 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 +0800898 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
899
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800900end:
Pengfei Liuc181a982020-01-07 19:27:13 +0800901 ret = segment_close(p_ctx->segment_handle);
hualing chencedcb862022-01-04 15:32:43 +0800902 p_ctx->segment_handle = NULL;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800903 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800904 return DVR_SUCCESS;
905}
Pengfei Liuc181a982020-01-07 19:27:13 +0800906
Pengfei Liub4734232020-01-17 18:25:10 +0800907int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
908{
909 DVR_RecordContext_t *p_ctx;
910 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +0800911 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800912
913 p_ctx = (DVR_RecordContext_t *)handle;
914 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
915 if (p_ctx == &record_ctx[i])
916 break;
Pengfei Liuc181a982020-01-07 19:27:13 +0800917 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800918 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
919 DVR_RETURN_IF_FALSE(params);
920 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800921
Wentao MA96f68962022-06-15 19:45:35 +0800922 DVR_INFO("%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
pengfei.liuab5a2262020-02-14 17:33:40 +0800923 ret = dvr_record_start_segment(handle, params);
924 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
925
926 p_ctx->segment_info.size = *p_resume_size;
927
928 return DVR_SUCCESS;
929}
930
931int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
932{
933 DVR_RecordContext_t *p_ctx;
934 int i;
935
936 p_ctx = (DVR_RecordContext_t *)handle;
937 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
938 if (p_ctx == &record_ctx[i])
939 break;
940 }
941 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
942 DVR_RETURN_IF_FALSE(p_status);
943
944 //lock
945 p_status->state = p_ctx->state;
946 p_status->info.id = p_ctx->segment_info.id;
947 p_status->info.duration = p_ctx->segment_info.duration;
948 p_status->info.size = p_ctx->segment_info.size;
949 p_status->info.nb_packets = p_ctx->segment_info.size/188;
950
951 return DVR_SUCCESS;
952}
953
954int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
955{
956 DVR_RecordContext_t *p_ctx;
957 uint32_t i;
958 off_t pos = 0;
Wentao MA139fc612022-08-29 14:10:07 +0800959 int ret = DVR_SUCCESS;
pengfei.liuab5a2262020-02-14 17:33:40 +0800960 int has_pcr;
961
962 p_ctx = (DVR_RecordContext_t *)handle;
963 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
964 if (p_ctx == &record_ctx[i])
965 break;
966 }
967 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
968 DVR_RETURN_IF_FALSE(buffer);
969 DVR_RETURN_IF_FALSE(len);
970
971 pos = segment_tell_position(p_ctx->segment_handle);
972 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
973 if (has_pcr == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800974 /* Pull VOD record should use PCR time index */
Wentao MA96f68962022-06-15 19:45:35 +0800975 DVR_INFO("%s has no pcr, can NOT do time index", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800976 }
977 ret = segment_write(p_ctx->segment_handle, buffer, len);
hualing chen2932d372020-04-29 13:44:00 +0800978 if (ret != len) {
Wentao MA96f68962022-06-15 19:45:35 +0800979 DVR_INFO("%s write error ret:%d len:%d", __func__, ret, len);
hualing chen2932d372020-04-29 13:44:00 +0800980 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800981 p_ctx->segment_info.size += len;
982 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
983
Pengfei Liuc181a982020-01-07 19:27:13 +0800984 return DVR_SUCCESS;
985}
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800986
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800987int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800988{
989 DVR_RecordContext_t *p_ctx;
990 uint32_t i;
991
992 p_ctx = (DVR_RecordContext_t *)handle;
993 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
994 if (p_ctx == &record_ctx[i])
995 break;
996 }
997 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
998 DVR_RETURN_IF_FALSE(func);
999
Wentao MA96f68962022-06-15 19:45:35 +08001000 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001001 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
1002 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
1003
1004 p_ctx->enc_func = func;
1005 p_ctx->enc_userdata = userdata;
1006 return DVR_SUCCESS;
1007}
1008
1009int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
1010{
1011 DVR_RecordContext_t *p_ctx;
1012 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001013 int ret = DVR_SUCCESS;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001014
1015 p_ctx = (DVR_RecordContext_t *)handle;
1016 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1017 if (p_ctx == &record_ctx[i])
1018 break;
1019 }
1020 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1021 DVR_RETURN_IF_FALSE(p_secure_buf);
1022 DVR_RETURN_IF_FALSE(len);
1023
Wentao MA96f68962022-06-15 19:45:35 +08001024 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001025 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
1026 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
1027
1028 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
1029 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
1030
1031 p_ctx->is_secure_mode = 1;
Yahui Han4577db82022-07-05 17:46:19 +08001032 p_ctx->secbuf_size = len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001033 return ret;
1034}
hualing chen4fe3bee2020-10-23 13:58:52 +08001035
1036int dvr_record_is_secure_mode(DVR_RecordHandle_t handle)
1037{
1038 DVR_RecordContext_t *p_ctx;
1039 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001040 int ret = DVR_SUCCESS;
hualing chen4fe3bee2020-10-23 13:58:52 +08001041
1042 p_ctx = (DVR_RecordContext_t *)handle;
1043 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1044 if (p_ctx == &record_ctx[i])
1045 break;
1046 }
hualing chen002e5b92022-02-23 17:51:21 +08001047
hualing chen4fe3bee2020-10-23 13:58:52 +08001048 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1049
1050 if (p_ctx->is_secure_mode == 1)
1051 ret = 1;
1052 else
1053 ret = 0;
1054 return ret;
Yahui Hance15e9c2020-12-08 18:08:32 +08001055}
Wentao MAf4072032022-06-30 13:50:45 +08001056
1057int dvr_record_discard_coming_data(DVR_RecordHandle_t handle, DVR_Bool_t discard)
1058{
1059 DVR_RecordContext_t *p_ctx;
1060 int i;
1061
1062 p_ctx = (DVR_RecordContext_t *)handle;
1063 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1064 if (p_ctx == &record_ctx[i])
1065 break;
1066 }
1067 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1068
1069 if (p_ctx->discard_coming_data != discard) {
1070 p_ctx->discard_coming_data = discard;
1071 if (discard) {
1072 DVR_WARN("%s, start discarding coming data. discard:%d",__func__,discard);
1073 } else {
1074 DVR_WARN("%s, finish discarding coming data. discard:%d",__func__,discard);
1075 }
1076 }
1077
1078 return DVR_TRUE;
1079}