blob: 5d4eadaa6c6b74a70b04b1830ba10a4e01cc6c6f [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>
Yahui Han1fbf3292021-11-08 18:17:19 +080013#include "am_crypt.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080014
hualing chend241c7a2021-06-22 13:34:27 +080015#define CONTROL_SPEED_ENABLE 0
16
hualing chen3092e1c2022-01-21 20:02:21 +080017#define CHECK_PTS_MAX_COUNT (20)
18
hualing chenc7aa4c82021-02-03 15:41:37 +080019//#define DEBUG_PERFORMANCE
Yahui Han10993892021-11-02 14:27:33 +080020#define MAX_DVR_RECORD_SESSION_COUNT 4
hualing chen266b9502020-04-04 17:39:39 +080021#define RECORD_BLOCK_SIZE (256 * 1024)
Yahui Hance15e9c2020-12-08 18:08:32 +080022#define NEW_DEVICE_RECORD_BLOCK_SIZE (1024 * 188)
pengfei.liuab5a2262020-02-14 17:33:40 +080023
24/**\brief DVR index file type*/
25typedef enum {
26 DVR_INDEX_TYPE_PCR, /**< DVR index file use pcr*/
27 DVR_INDEX_TYPE_LOCAL_CLOCK, /**< DVR index file use local clock*/
28 DVR_INDEX_TYPE_INVALID /**< DVR index file type invalid type*/
29} DVR_IndexType_t;
30
31/**\brief DVR VOD context*/
32typedef struct {
33 pthread_mutex_t mutex; /**< VOD mutex lock*/
34 pthread_cond_t cond; /**< VOD condition*/
35 void *buffer; /**< VOD buffer*/
36 uint32_t buf_len; /**< VOD buffer len*/
37} DVR_VodContext_t;
38
pengfei.liu07ddc8a2020-03-24 23:36:53 +080039/**\brief DVR record secure mode buffer*/
40typedef struct {
41 uint32_t addr; /**< Secure mode record buffer address*/
42 uint32_t len; /**< Secure mode record buffer length*/
43} DVR_SecureBuffer_t;
44
hualing chenf9867402020-09-23 17:06:20 +080045/**\brief DVR record new dmx secure mode buffer*/
46typedef struct {
47 uint32_t buf_start; /**< Secure mode record buffer address*/
48 uint32_t buf_end; /**< Secure mode record buffer length*/
49 uint32_t data_start; /**< Secure mode record buffer address*/
50 uint32_t data_end; /**< Secure mode record buffer length*/
51} DVR_NewDmxSecureBuffer_t;
52
Pengfei Liub4734232020-01-17 18:25:10 +080053/**\brief DVR record context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080054typedef struct {
Pengfei Liub4734232020-01-17 18:25:10 +080055 pthread_t thread; /**< DVR thread handle*/
56 Record_DeviceHandle_t dev_handle; /**< DVR device handle*/
57 Segment_Handle_t segment_handle; /**< DVR segment handle*/
58 DVR_RecordState_t state; /**< DVR record state*/
59 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
60 DVR_RecordSegmentStartParams_t segment_params; /**< DVR record start parameters*/
61 DVR_RecordSegmentInfo_t segment_info; /**< DVR record current segment info*/
Wentao MA270dc0f2022-08-23 13:17:26 +080062 size_t notification_size; /**< DVR record notification size*/
Pengfei Liub4734232020-01-17 18:25:10 +080063 DVR_RecordEventFunction_t event_notify_fn; /**< DVR record event notify function*/
64 void *event_userdata; /**< DVR record event userdata*/
pengfei.liuab5a2262020-02-14 17:33:40 +080065 //DVR_VodContext_t vod; /**< DVR record vod context*/
66 int is_vod; /**< Indicate current mode is VOD record mode*/
pengfei.liu27cc4ec2020-04-03 16:28:16 +080067 DVR_CryptoFunction_t enc_func; /**< Encrypt function*/
pengfei.liu07ddc8a2020-03-24 23:36:53 +080068 void *enc_userdata; /**< Encrypt userdata*/
69 int is_secure_mode; /**< Record session run in secure pipeline */
Yahui Han1fbf3292021-11-08 18:17:19 +080070 void *cryptor; /**< Cryptor for encrypted PVR on FTA.*/
hualing chen2615aa82020-04-02 21:32:51 +080071 size_t last_send_size; /**< Last send notify segment size */
pengfei.liufda2a972020-04-09 14:47:15 +080072 uint32_t block_size; /**< DVR record block size */
hualing chenf9867402020-09-23 17:06:20 +080073 DVR_Bool_t is_new_dmx; /**< DVR is used new dmx driver */
hualing chen40accc32021-04-21 15:58:09 +080074 int index_type; /**< DVR is used pcr or local time */
wentao.ma35a69d42022-03-10 18:08:40 +080075 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 +080076 uint64_t pts; /**< The newest pcr or local time */
hualing chen3092e1c2022-01-21 20:02:21 +080077 int check_pts_count; /**< The check count of pts */
hualing chen002e5b92022-02-23 17:51:21 +080078 int check_no_pts_count; /**< The check count of no pts */
Wentao MA270dc0f2022-08-23 13:17:26 +080079 int notification_time; /**< DVR record notification time*/
hualing chen002e5b92022-02-23 17:51:21 +080080 time_t last_send_time; /**< Last send notify segment duration */
Wentao MAeeffdb02022-06-27 16:34:35 +080081 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 +080082 size_t secbuf_size; /**< DVR record secure buffer length*/
Wentao MAf4072032022-06-30 13:50:45 +080083 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 +080084} DVR_RecordContext_t;
85
Gong Ke2a0ebbe2021-05-25 15:22:50 +080086extern ssize_t record_device_read_ext(Record_DeviceHandle_t handle, size_t *buf, size_t *len);
87
Pengfei Liuc181a982020-01-07 19:27:13 +080088static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
89 {
Pengfei Liub4734232020-01-17 18:25:10 +080090 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080091 },
92 {
Pengfei Liub4734232020-01-17 18:25:10 +080093 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080094 }
95};
96
Zhiqiang Han51646a02020-04-05 18:43:22 +080097static int record_is_valid_pid(DVR_RecordContext_t *p_ctx, int pid)
98{
99 int i;
100
101 for (i = 0; i < p_ctx->segment_info.nb_pids; i++) {
102 if (pid == p_ctx->segment_info.pids[i].pid)
103 return 1;
104 }
105 return 0;
106}
107
pengfei.liuab5a2262020-02-14 17:33:40 +0800108static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
109{
110 uint8_t *p = buf;
111 int len;
112 uint8_t afc;
113 uint64_t pcr = 0;
114 int has_pcr = 0;
115 int pid;
116 int adp_field_len;
117
118 pid = ((p[1] & 0x1f) << 8) | p[2];
Zhiqiang Han51646a02020-04-05 18:43:22 +0800119 if (pid == 0x1fff || !record_is_valid_pid(p_ctx, pid))
pengfei.liuab5a2262020-02-14 17:33:40 +0800120 return has_pcr;
121
122 //scramble = p[3] >> 6;
123 //cc = p[3] & 0x0f;
124 afc = (p[3] >> 4) & 0x03;
125
126 p += 4;
127 len = 184;
128
129 if (afc & 2) {
130 adp_field_len = p[0];
131 /* Skip adaptation len */
132 p++;
133 len--;
134 /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
hualing chen5605eed2020-05-26 18:18:06 +0800135 if (p[0] & 0x10 && len >= 6 && adp_field_len >= 6) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800136 /* get pcr value,pcr is 33bit value */
137 pcr = (((uint64_t)(p[1])) << 25)
138 | (((uint64_t)p[2]) << 17)
139 | (((uint64_t)(p[3])) << 9)
140 | (((uint64_t)p[4]) << 1)
141 | ((((uint64_t)p[5]) & 0x80) >> 7);
142 has_pcr = 1;
143 }
144
pengfei.liuab5a2262020-02-14 17:33:40 +0800145 len -= adp_field_len;
146
147 if (len < 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800148 DVR_INFO("parser pcr: illegal adaptation field length");
pengfei.liuab5a2262020-02-14 17:33:40 +0800149 return 0;
150 }
151 }
152
hualing chen40accc32021-04-21 15:58:09 +0800153 if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
hualing chen94d8dd22021-12-29 15:13:43 +0800154 //save newest pcr
hualing chen3092e1c2022-01-21 20:02:21 +0800155 if (p_ctx->pts == pcr/90 &&
156 p_ctx->check_pts_count < CHECK_PTS_MAX_COUNT) {
hualing chen3092e1c2022-01-21 20:02:21 +0800157 p_ctx->check_pts_count ++;
158 }
hualing chen94d8dd22021-12-29 15:13:43 +0800159 p_ctx->pts = pcr/90;
pengfei.liuab5a2262020-02-14 17:33:40 +0800160 segment_update_pts(p_ctx->segment_handle, pcr/90, pos);
161 }
162 return has_pcr;
163}
164
165static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
166{
167 uint8_t *p = buf;
168 int left = len;
169 loff_t pos;
170 int has_pcr = 0;
171
172 pos = segment_tell_position(p_ctx->segment_handle);
hualing chen3e0d3a42022-01-25 17:22:01 +0800173 if (pos >= len) {
174 pos = pos - len;
175 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800176 while (left >= 188) {
177 if (*p == 0x47) {
178 has_pcr |= record_save_pcr(p_ctx, p, pos);
179 p += 188;
180 left -= 188;
181 pos += 188;
182 } else {
183 p++;
184 left --;
185 pos++;
186 }
187 }
188 return has_pcr;
189}
190
pengfei.liu567d6d82020-04-17 16:48:59 +0800191static int get_diff_time(struct timeval start_tv, struct timeval end_tv)
192{
193 return end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000 - start_tv.tv_sec * 1000 - start_tv.tv_usec / 1000;
194}
195
Pengfei Liuc181a982020-01-07 19:27:13 +0800196void *record_thread(void *arg)
197{
198 DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
199 ssize_t len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800200 uint8_t *buf, *buf_out;
pengfei.liufda2a972020-04-09 14:47:15 +0800201 uint32_t block_size = p_ctx->block_size;
pengfei.liuab5a2262020-02-14 17:33:40 +0800202 loff_t pos = 0;
Wentao MA139fc612022-08-29 14:10:07 +0800203 int ret = DVR_SUCCESS;
Wentao MA270dc0f2022-08-23 13:17:26 +0800204 struct timespec start_ts, end_ts, start_no_pcr_ts, end_no_pcr_ts;
Pengfei Liub4734232020-01-17 18:25:10 +0800205 DVR_RecordStatus_t record_status;
pengfei.liuab5a2262020-02-14 17:33:40 +0800206 int has_pcr;
hualing chen3092e1c2022-01-21 20:02:21 +0800207 int pcr_rec_len = 0;
Wentao MAeeffdb02022-06-27 16:34:35 +0800208 DVR_Bool_t guarded_size_exceeded = DVR_FALSE;
hualing chen40accc32021-04-21 15:58:09 +0800209
hualing chen87072a82020-03-12 16:20:12 +0800210 time_t pre_time = 0;
hualing chen2932d372020-04-29 13:44:00 +0800211 #define DVR_STORE_INFO_TIME (400)
Wentao MA139fc612022-08-29 14:10:07 +0800212 DVR_SecureBuffer_t secure_buf = {0,0};
hualing chenf9867402020-09-23 17:06:20 +0800213 DVR_NewDmxSecureBuffer_t new_dmx_secure_buf;
hualing chena5f03222021-12-02 11:22:35 +0800214 int first_read = 0;
hualing chend241c7a2021-06-22 13:34:27 +0800215 if (CONTROL_SPEED_ENABLE == 0)
216 p_ctx->index_type = DVR_INDEX_TYPE_INVALID;
217 else
218 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
Pengfei Liuc181a982020-01-07 19:27:13 +0800219
wentao.ma35a69d42022-03-10 18:08:40 +0800220 // Force to use LOCAL_CLOCK as index type if force_sysclock is on. Please
221 // refer to SWPL-75327
222 if (p_ctx->force_sysclock)
223 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
Pengfei Liub4734232020-01-17 18:25:10 +0800224 buf = (uint8_t *)malloc(block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800225 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +0800226 DVR_INFO("%s, malloc failed", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800227 return NULL;
228 }
229
Yahui Han4577db82022-07-05 17:46:19 +0800230 if (p_ctx->is_secure_mode) {
231 buf_out = (uint8_t *)malloc(p_ctx->secbuf_size + 188);
232 } else {
233 buf_out = (uint8_t *)malloc(block_size + 188);
234 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800235 if (!buf_out) {
Wentao MA96f68962022-06-15 19:45:35 +0800236 DVR_INFO("%s, malloc failed", __func__);
Pengfei Liufaf38e42020-05-22 00:28:02 +0800237 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800238 return NULL;
239 }
240
hualing chen266b9502020-04-04 17:39:39 +0800241 memset(&record_status, 0, sizeof(record_status));
242 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800243 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800244 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800245 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
Wentao MA96f68962022-06-15 19:45:35 +0800246 DVR_INFO("%s line %d notify record status, state:%d id=%lld",
hualing chen4b7c15d2020-04-07 16:13:48 +0800247 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800248 }
Wentao MA96f68962022-06-15 19:45:35 +0800249 DVR_INFO("%s, --secure_mode:%d, block_size:%d, cryptor:%p",
hualing chen002e5b92022-02-23 17:51:21 +0800250 __func__, p_ctx->is_secure_mode,
251 block_size, p_ctx->cryptor);
Pengfei Liub4734232020-01-17 18:25:10 +0800252 clock_gettime(CLOCK_MONOTONIC, &start_ts);
hualing chen3092e1c2022-01-21 20:02:21 +0800253 p_ctx->check_pts_count = 0;
254 p_ctx->check_no_pts_count++;
hualing chen002e5b92022-02-23 17:51:21 +0800255 p_ctx->last_send_size = 0;
256 p_ctx->last_send_time = 0;
pengfei.liu567d6d82020-04-17 16:48:59 +0800257 struct timeval t1, t2, t3, t4, t5, t6, t7;
hualing chen03fd4942021-07-15 15:56:41 +0800258 while (p_ctx->state == DVR_RECORD_STATE_STARTED ||
259 p_ctx->state == DVR_RECORD_STATE_PAUSE) {
260
261 if (p_ctx->state == DVR_RECORD_STATE_PAUSE) {
262 //wait resume record
263 usleep(20*1000);
264 continue;
265 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800266 gettimeofday(&t1, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800267
pengfei.liuab5a2262020-02-14 17:33:40 +0800268 /* data from dmx, normal dvr case */
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800269 if (p_ctx->is_secure_mode) {
hualing chenf9867402020-09-23 17:06:20 +0800270 if (p_ctx->is_new_dmx) {
Yahui Hance15e9c2020-12-08 18:08:32 +0800271
272 /* We resolve the below invoke for dvbcore to be under safety status */
hualing chenf9867402020-09-23 17:06:20 +0800273 memset(&new_dmx_secure_buf, 0, sizeof(new_dmx_secure_buf));
Yahui Hance15e9c2020-12-08 18:08:32 +0800274 len = record_device_read(p_ctx->dev_handle, &new_dmx_secure_buf, sizeof(new_dmx_secure_buf), 10);
hualing chen002e5b92022-02-23 17:51:21 +0800275 if (len == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800276 DVR_INFO("handle[%p] ret:%d\n", p_ctx->dev_handle, ret);
hualing chen002e5b92022-02-23 17:51:21 +0800277 /*For the second recording, poll always failed which we should check
278 * dvbcore further. For now, Just ignore the fack poll fail, I think
Wentao MA270dc0f2022-08-23 13:17:26 +0800279 * it won't influence anything. But we need adjust the poll timeout
hualing chen002e5b92022-02-23 17:51:21 +0800280 * from 1000ms to 10ms.
281 */
282 //continue;
283 }
Yahui Hance15e9c2020-12-08 18:08:32 +0800284
hualing chen002e5b92022-02-23 17:51:21 +0800285 /* Read data from secure demux TA */
286 len = record_device_read_ext(p_ctx->dev_handle, &secure_buf.addr,
287 &secure_buf.len);
Yahui Hance15e9c2020-12-08 18:08:32 +0800288
hualing chenf9867402020-09-23 17:06:20 +0800289 } else {
290 memset(&secure_buf, 0, sizeof(secure_buf));
291 len = record_device_read(p_ctx->dev_handle, &secure_buf, sizeof(secure_buf), 1000);
292 }
293 if (len != DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800294 //DVR_INFO("%s, secure_buf:%#x, size:%#x", __func__, secure_buf.addr, secure_buf.len);
hualing chenf9867402020-09-23 17:06:20 +0800295 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800296 } else {
297 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
298 }
Pengfei Liub4734232020-01-17 18:25:10 +0800299 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800300 //usleep(10*1000);
Wentao MA96f68962022-06-15 19:45:35 +0800301 //DVR_INFO("%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800302 continue;
303 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800304 gettimeofday(&t2, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800305
Wentao MAeeffdb02022-06-27 16:34:35 +0800306 guarded_size_exceeded = DVR_FALSE;
307 if (p_ctx->segment_info.size+len >= p_ctx->guarded_segment_size) {
Wentao MAeeffdb02022-06-27 16:34:35 +0800308 guarded_size_exceeded = DVR_TRUE;
309 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800310 /* Got data from device, record it */
Wentao MAeeffdb02022-06-27 16:34:35 +0800311 if (guarded_size_exceeded) {
312 len = 0;
313 ret = 0;
Wentao MAf4072032022-06-30 13:50:45 +0800314 DVR_ERROR("Skip segment_write due to current segment size %u exceeding"
315 " guarded segment size", p_ctx->segment_info.size);
316 } else if (p_ctx->discard_coming_data) {
317 len = 0;
318 ret = 0;
319 DVR_ERROR("Skip segment_write due to total size exceeding max size too much");
Wentao MAeeffdb02022-06-27 16:34:35 +0800320 } else if (p_ctx->enc_func) {
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800321 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800322 DVR_CryptoParams_t crypto_params;
323
324 memset(&crypto_params, 0, sizeof(crypto_params));
325 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800326 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800327 crypto_params.segment_id = p_ctx->segment_info.id;
328 crypto_params.offset = p_ctx->segment_info.size;
329
330 if (p_ctx->is_secure_mode) {
331 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
Yahui Han1fbf3292021-11-08 18:17:19 +0800332 crypto_params.input_buffer.addr = secure_buf.addr;
333 crypto_params.input_buffer.size = secure_buf.len;
Yahui Hanaf03b142022-08-17 17:52:37 +0800334 crypto_params.output_buffer.size = p_ctx->secbuf_size + 188;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800335 } else {
336 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
337 crypto_params.input_buffer.addr = (size_t)buf;
338 crypto_params.input_buffer.size = len;
Yahui Hanaf03b142022-08-17 17:52:37 +0800339 crypto_params.output_buffer.size = block_size + 188;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800340 }
341
342 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
343 crypto_params.output_buffer.addr = (size_t)buf_out;
hualing chen9811b212020-10-29 11:21:44 +0800344
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800345 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800346 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800347 /* Out buffer length may not equal in buffer length */
hualing chenf9867402020-09-23 17:06:20 +0800348 if (crypto_params.output_size > 0) {
349 ret = segment_write(p_ctx->segment_handle, buf_out, crypto_params.output_size);
350 len = crypto_params.output_size;
hualing chenbafc62d2020-11-02 15:44:05 +0800351 } else {
352 len = 0;
hualing chenf9867402020-09-23 17:06:20 +0800353 }
Yahui Han1fbf3292021-11-08 18:17:19 +0800354 } else if (p_ctx->cryptor) {
355 /* Encrypt with clear key */
Yahui Han63b23b42021-12-07 15:37:46 +0800356 int crypt_len = len;
357 am_crypt_des_crypt(p_ctx->cryptor, buf_out, buf, &crypt_len, 0);
358 len = crypt_len;
Yahui Han1fbf3292021-11-08 18:17:19 +0800359 gettimeofday(&t3, NULL);
360 ret = segment_write(p_ctx->segment_handle, buf_out, len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800361 } else {
hualing chena5f03222021-12-02 11:22:35 +0800362 if (first_read == 0) {
363 first_read = 1;
Wentao MA96f68962022-06-15 19:45:35 +0800364 DVR_INFO("%s:%d,first read ts", __func__,__LINE__);
hualing chena5f03222021-12-02 11:22:35 +0800365 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800366 gettimeofday(&t3, NULL);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800367 ret = segment_write(p_ctx->segment_handle, buf, len);
368 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800369 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800370 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800371 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800372 //send write event
hualing chen9b434f02020-06-10 15:06:54 +0800373 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800374 memset(&record_status, 0, sizeof(record_status));
Wentao MAeeffdb02022-06-27 16:34:35 +0800375 DVR_INFO("%s:%d,send event write error", __func__,__LINE__);
hualing chen9ce7d942021-06-30 13:31:01 +0800376 record_status.info.id = p_ctx->segment_info.id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800377 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
378 }
Wentao MA96f68962022-06-15 19:45:35 +0800379 DVR_INFO("%s,write error %d", __func__,__LINE__);
hualing chen626204e2020-04-07 11:55:08 +0800380 goto end;
381 }
Wentao MAf4072032022-06-30 13:50:45 +0800382 if (len>0) {
383 /* Do time index */
384 uint8_t *index_buf = (p_ctx->enc_func || p_ctx->cryptor)? buf_out : buf;
385 pos = segment_tell_position(p_ctx->segment_handle);
386 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
387 if (has_pcr == 0 && p_ctx->index_type == DVR_INDEX_TYPE_INVALID) {
388 clock_gettime(CLOCK_MONOTONIC, &end_ts);
389 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
390 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800391 /* PCR interval threshold > 40 ms*/
Wentao MAf4072032022-06-30 13:50:45 +0800392 DVR_INFO("%s use local clock time index", __func__);
hualing chen3092e1c2022-01-21 20:02:21 +0800393 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
Wentao MAf4072032022-06-30 13:50:45 +0800394 }
395 } else if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_INVALID){
396 DVR_INFO("%s use pcr time index", __func__);
397 p_ctx->index_type = DVR_INDEX_TYPE_PCR;
398 record_do_pcr_index(p_ctx, index_buf, len);
399 }
400 gettimeofday(&t5, NULL);
401 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
402 if (has_pcr == 0) {
403 if (p_ctx->check_no_pts_count < 2 * CHECK_PTS_MAX_COUNT) {
404 if (p_ctx->check_no_pts_count == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800405 clock_gettime(CLOCK_MONOTONIC, &start_no_pcr_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800406 clock_gettime(CLOCK_MONOTONIC, &start_ts);
407 }
408 p_ctx->check_no_pts_count++;
409 }
410 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +0800411 clock_gettime(CLOCK_MONOTONIC, &start_no_pcr_ts);
Wentao MAf4072032022-06-30 13:50:45 +0800412 p_ctx->check_no_pts_count = 0;
413 }
414 }
415 /* Update segment i nfo */
416 p_ctx->segment_info.size += len;
Pengfei Liub4734232020-01-17 18:25:10 +0800417
Wentao MAf4072032022-06-30 13:50:45 +0800418 /*Duration need use pcr to calculate, todo...*/
419 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
hualing chenc94227e2022-02-17 09:48:43 +0800420 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Wentao MAf4072032022-06-30 13:50:45 +0800421 if (pre_time == 0)
422 pre_time = p_ctx->segment_info.duration;
423 } else if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
424 clock_gettime(CLOCK_MONOTONIC, &end_ts);
425 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
426 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) + pcr_rec_len;
427 if (pre_time == 0)
428 pre_time = p_ctx->segment_info.duration;
429 segment_update_pts(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
430 } else {
431 DVR_INFO("%s can NOT do time index", __func__);
432 }
433 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR &&
434 p_ctx->check_pts_count == CHECK_PTS_MAX_COUNT) {
435 DVR_INFO("%s change time from pcr to local time", __func__);
436 if (pcr_rec_len == 0)
437 pcr_rec_len = segment_tell_total_time(p_ctx->segment_handle);
438 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
439 if (pcr_rec_len == 0)
440 pcr_rec_len = segment_tell_total_time(p_ctx->segment_handle);
441 clock_gettime(CLOCK_MONOTONIC, &start_ts);
442 }
443
444 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR ) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800445 clock_gettime(CLOCK_MONOTONIC, &end_no_pcr_ts);
446 int diff = (int)(end_no_pcr_ts.tv_sec*1000 + end_no_pcr_ts.tv_nsec/1000000) -
447 (int)(start_no_pcr_ts.tv_sec*1000 + start_no_pcr_ts.tv_nsec/1000000);
Wentao MAf4072032022-06-30 13:50:45 +0800448 if (diff > 3000) {
449 DVR_INFO("%s no pcr change time from pcr to local time diff[%d]", __func__, diff);
450 if (pcr_rec_len == 0)
451 pcr_rec_len = segment_tell_total_time(p_ctx->segment_handle);
452 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
453 }
454 }
455 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
456
457 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
458 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
459 time_t duration = p_ctx->segment_info.duration;
460 if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK)
461 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
462 segment_store_info(p_ctx->segment_handle, &(p_ctx->segment_info));
463 p_ctx->segment_info.duration = duration;
464 }
465 } else {
466 gettimeofday(&t5, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800467 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800468 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800469 /*Event notification*/
Wentao MAf4072032022-06-30 13:50:45 +0800470 DVR_Bool_t condA1 = (p_ctx->notification_size > 0);
471 DVR_Bool_t condA2 = ((p_ctx->segment_info.size-p_ctx->last_send_size) >= p_ctx->notification_size);
472 DVR_Bool_t condA3 = (p_ctx->notification_time > 0);
473 DVR_Bool_t condA4 = ((p_ctx->segment_info.duration-p_ctx->last_send_time) >= p_ctx->notification_time);
474 DVR_Bool_t condA5 = (guarded_size_exceeded);
475 DVR_Bool_t condA6 = (p_ctx->discard_coming_data);
476 DVR_Bool_t condB = (p_ctx->event_notify_fn != NULL);
477 DVR_Bool_t condC = (p_ctx->segment_info.duration > 0);
478 DVR_Bool_t condD = (p_ctx->state == DVR_RECORD_STATE_STARTED);
479 if (((condA1 && condA2) || (condA3 && condA4) || condA5 || condA6)
480 && condB && condC && condD) {
Pengfei Liub4734232020-01-17 18:25:10 +0800481 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800482 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800483 p_ctx->last_send_size = p_ctx->segment_info.size;
hualing chen002e5b92022-02-23 17:51:21 +0800484 p_ctx->last_send_time = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800485 record_status.state = p_ctx->state;
486 record_status.info.id = p_ctx->segment_info.id;
hualing chenc94227e2022-02-17 09:48:43 +0800487 if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK)
488 record_status.info.duration = segment_tell_total_time(p_ctx->segment_handle);
489 else
490 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800491 record_status.info.size = p_ctx->segment_info.size;
492 record_status.info.nb_packets = p_ctx->segment_info.size/188;
493 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
Wentao MA96f68962022-06-15 19:45:35 +0800494 DVR_INFO("%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu loc[%s]",
hualing chen4fe3bee2020-10-23 13:58:52 +0800495 __func__, record_status.state,
496 record_status.info.id, record_status.info.duration,
497 record_status.info.size, p_ctx->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800498 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800499 gettimeofday(&t7, NULL);
500#ifdef DEBUG_PERFORMANCE
Wentao MA96f68962022-06-15 19:45:35 +0800501 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 +0800502 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 +0800503 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len,
504 p_ctx->notification_time,p_ctx->segment_info.duration -p_ctx->last_send_time);
pengfei.liu567d6d82020-04-17 16:48:59 +0800505#endif
Wentao MAf4072032022-06-30 13:50:45 +0800506 if (len == 0) {
507 usleep(20*1000);
508 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800509 }
hualing chen626204e2020-04-07 11:55:08 +0800510end:
Pengfei Liub4734232020-01-17 18:25:10 +0800511 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800512 free((void *)buf_out);
Wentao MA96f68962022-06-15 19:45:35 +0800513 DVR_INFO("exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800514 return NULL;
515}
516
517int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
518{
519 DVR_RecordContext_t *p_ctx;
520 Record_DeviceOpenParams_t dev_open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800521 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800522 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800523
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800524 DVR_RETURN_IF_FALSE(p_handle);
525 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800526
527 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800528 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800529 break;
530 }
531 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800532 DVR_RETURN_IF_FALSE(i < MAX_DVR_RECORD_SESSION_COUNT);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800533 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800534 p_ctx = &record_ctx[i];
Wentao MA96f68962022-06-15 19:45:35 +0800535 DVR_INFO("%s , current state:%d, dmx_id:%d, notification_size:%zu, flags:%d, keylen:%d ",
Yahui Han1fbf3292021-11-08 18:17:19 +0800536 __func__, p_ctx->state, params->dmx_dev_id,
hualing chen002e5b92022-02-23 17:51:21 +0800537 params->notification_size,
538 params->flags, params->keylen);
Pengfei Liuc181a982020-01-07 19:27:13 +0800539
Pengfei Liub4734232020-01-17 18:25:10 +0800540 /*Process event params*/
541 p_ctx->notification_size = params->notification_size;
hualing chen002e5b92022-02-23 17:51:21 +0800542 p_ctx->notification_time = params->notification_time;
543
Pengfei Liub4734232020-01-17 18:25:10 +0800544 p_ctx->event_notify_fn = params->event_fn;
545 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800546 p_ctx->last_send_size = 0;
hualing chen002e5b92022-02-23 17:51:21 +0800547 p_ctx->last_send_time = 0;
hualing chen94d8dd22021-12-29 15:13:43 +0800548 p_ctx->pts = ULLONG_MAX;
Yahui Han1fbf3292021-11-08 18:17:19 +0800549
550 if (params->keylen > 0) {
551 p_ctx->cryptor = am_crypt_des_open(params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +0800552 params->cleariv,
553 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +0800554 if (!p_ctx->cryptor)
Wentao MA96f68962022-06-15 19:45:35 +0800555 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +0800556 } else {
557 p_ctx->cryptor = NULL;
558 }
559
hualing chenf9867402020-09-23 17:06:20 +0800560 //check is new driver
561 p_ctx->is_new_dmx = dvr_check_dmx_isNew();
Pengfei Liub4734232020-01-17 18:25:10 +0800562 /*Process crypto params, todo*/
Pengfei Liub4734232020-01-17 18:25:10 +0800563 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800564 if (params->data_from_memory) {
565 /* data from memory, VOD case */
566 p_ctx->is_vod = 1;
567 } else {
568 p_ctx->is_vod = 0;
569 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800570 dev_open_params.dmx_dev_id = params->dmx_dev_id;
hualing chen157641d2022-02-22 17:54:52 +0800571 //set dvr flush size
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800572 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen157641d2022-02-22 17:54:52 +0800573 //set dvbcore ringbuf size
hualing chen03fd4942021-07-15 15:56:41 +0800574 dev_open_params.ringbuf_size = params->ringbuf_size;
hualing chen157641d2022-02-22 17:54:52 +0800575
pengfei.liuab5a2262020-02-14 17:33:40 +0800576 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
577 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +0800578 DVR_INFO("%s, open record devices failed", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800579 return DVR_FAILURE;
580 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800581 }
582
pengfei.liufda2a972020-04-09 14:47:15 +0800583 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen157641d2022-02-22 17:54:52 +0800584
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800585 p_ctx->enc_func = NULL;
586 p_ctx->enc_userdata = NULL;
587 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800588 p_ctx->state = DVR_RECORD_STATE_OPENED;
wentao.ma35a69d42022-03-10 18:08:40 +0800589 p_ctx->force_sysclock = params->force_sysclock;
Wentao MAeeffdb02022-06-27 16:34:35 +0800590 p_ctx->guarded_segment_size = params->guarded_segment_size;
Wentao MAf4072032022-06-30 13:50:45 +0800591 p_ctx->discard_coming_data = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +0800592 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 +0800593 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800594 return DVR_SUCCESS;
595}
596
597int dvr_record_close(DVR_RecordHandle_t handle)
598{
599 DVR_RecordContext_t *p_ctx;
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 Liu47ed6c92020-01-17 11:23:41 +0800603 p_ctx = (DVR_RecordContext_t *)handle;
604 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
605 if (p_ctx == &record_ctx[i])
606 break;
607 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800608 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800609
Wentao MA96f68962022-06-15 19:45:35 +0800610 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800611 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Yahui Han1fbf3292021-11-08 18:17:19 +0800612 if (p_ctx->cryptor) {
613 am_crypt_des_close(p_ctx->cryptor);
614 p_ctx->cryptor = NULL;
615 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800616 if (p_ctx->is_vod) {
617 ret = DVR_SUCCESS;
618 } else {
619 ret = record_device_close(p_ctx->dev_handle);
620 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +0800621 DVR_INFO("%s, failed", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800622 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800623 }
hualing chencedcb862022-01-04 15:32:43 +0800624 memset(p_ctx, 0, sizeof(DVR_RecordContext_t));
Pengfei Liub4734232020-01-17 18:25:10 +0800625 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800626 return ret;
627}
628
hualing chen03fd4942021-07-15 15:56:41 +0800629int dvr_record_pause(DVR_RecordHandle_t handle)
630{
631 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800632 int ret = DVR_SUCCESS;
hualing chen03fd4942021-07-15 15:56:41 +0800633 uint32_t i;
634
635 p_ctx = (DVR_RecordContext_t *)handle;
636 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
637 if (p_ctx == &record_ctx[i])
638 break;
639 }
640 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
641
Wentao MA96f68962022-06-15 19:45:35 +0800642 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
hualing chen03fd4942021-07-15 15:56:41 +0800643 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
644
645 if (p_ctx->is_vod) {
646 ret = DVR_SUCCESS;
647 }
648 //set pause state,will not store ts into segment
649 p_ctx->state = DVR_RECORD_STATE_PAUSE;
650 return ret;
651}
652
653int dvr_record_resume(DVR_RecordHandle_t handle)
654{
655 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800656 int ret = DVR_SUCCESS;
hualing chen03fd4942021-07-15 15:56:41 +0800657 uint32_t i;
658
659 p_ctx = (DVR_RecordContext_t *)handle;
660 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
661 if (p_ctx == &record_ctx[i])
662 break;
663 }
664 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
665
Wentao MA96f68962022-06-15 19:45:35 +0800666 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
hualing chen03fd4942021-07-15 15:56:41 +0800667 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
668
669 if (p_ctx->is_vod) {
670 ret = DVR_SUCCESS;
671 }
672 //set stated state,will resume store ts into segment
673 p_ctx->state = DVR_RECORD_STATE_STARTED;
674 return ret;
675}
676
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800677#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800678int dvr_record_register_encryption(DVR_RecordHandle_t handle,
679 DVR_CryptoFunction_t cb,
680 DVR_CryptoParams_t params,
681 void *userdata)
682{
683 return DVR_SUCCESS;
684}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800685#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800686
687int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
688{
689 DVR_RecordContext_t *p_ctx;
690 Segment_OpenParams_t open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800691 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800692 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800693
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800694 p_ctx = (DVR_RecordContext_t *)handle;
695 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
696 if (p_ctx == &record_ctx[i])
697 break;
698 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800699 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800700
Wentao MA96f68962022-06-15 19:45:35 +0800701 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 +0800702 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
703 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
704 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800705
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800706 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800707 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800708 memcpy(open_params.location, params->location, sizeof(params->location));
Pengfei Liuc181a982020-01-07 19:27:13 +0800709 open_params.segment_id = params->segment.segment_id;
710 open_params.mode = SEGMENT_MODE_WRITE;
wentao.ma35a69d42022-03-10 18:08:40 +0800711 open_params.force_sysclock = p_ctx->force_sysclock;
Pengfei Liuc181a982020-01-07 19:27:13 +0800712
713 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800714 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800715
Pengfei Liub4734232020-01-17 18:25:10 +0800716 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800717 {
hualing chen7a56cba2020-04-14 14:09:27 +0800718 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800719 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800720 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800721 /*save current segment info*/
722 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
723 p_ctx->segment_info.id = params->segment.segment_id;
724 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
725 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800726 }
727
pengfei.liuab5a2262020-02-14 17:33:40 +0800728 if (!p_ctx->is_vod) {
729 /* normal dvr case */
730 for (i = 0; i < params->segment.nb_pids; i++) {
731 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
732 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
733 }
734 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800735 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800736 }
737
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800738 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
wentao.maa210e5e2022-10-12 16:10:03 +0800739 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800740
Pengfei Liuc181a982020-01-07 19:27:13 +0800741 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800742 if (!p_ctx->is_vod)
743 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800744
Pengfei Liuc181a982020-01-07 19:27:13 +0800745 return DVR_SUCCESS;
746}
747
748int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
749{
750 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800751 Segment_OpenParams_t open_params;
Wentao MA139fc612022-08-29 14:10:07 +0800752 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800753 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800754 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800755
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800756 p_ctx = (DVR_RecordContext_t *)handle;
757 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
758 if (p_ctx == &record_ctx[i])
759 break;
760 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800761 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800762
Wentao MA96f68962022-06-15 19:45:35 +0800763 DVR_INFO("%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800764 DVR_RETURN_IF_FALSE(p_ctx->state == DVR_RECORD_STATE_STARTED);
765 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
766 DVR_RETURN_IF_FALSE(params);
767 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800768 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800769
770 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800771 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800772 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800773 p_ctx->state = DVR_RECORD_STATE_STOPPED;
774 pthread_join(p_ctx->thread, NULL);
775
hualing chen2932d372020-04-29 13:44:00 +0800776 //add index file store
777 pos = segment_tell_position(p_ctx->segment_handle);
778 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
779
780 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liub4734232020-01-17 18:25:10 +0800781 /*Update segment info*/
782 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
783
784 ret = segment_store_info(p_ctx->segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800785 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
wentao.maa210e5e2022-10-12 16:10:03 +0800786 segment_store_allInfo(p_ctx->segment_handle, p_info);
Wentao MA96f68962022-06-15 19:45:35 +0800787 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 +0800788 __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 +0800789
Pengfei Liub4734232020-01-17 18:25:10 +0800790 /*Close current segment*/
791 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800792 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800793 /*Open the new record segment*/
794 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800795 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800796 open_params.segment_id = params->segment.segment_id;
797 open_params.mode = SEGMENT_MODE_WRITE;
wentao.ma35a69d42022-03-10 18:08:40 +0800798 open_params.force_sysclock = p_ctx->force_sysclock;
Wentao MA96f68962022-06-15 19:45:35 +0800799 DVR_INFO("%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
hualing chen002e5b92022-02-23 17:51:21 +0800800 p_ctx->last_send_size = 0;
801 p_ctx->last_send_time = 0;
Pengfei Liub4734232020-01-17 18:25:10 +0800802 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800803 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800804 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800805 {
Pengfei Liub4734232020-01-17 18:25:10 +0800806 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800807 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800808 /*save current segment info*/
809 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
810 p_ctx->segment_info.id = params->segment.segment_id;
811 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800812 }
813
Pengfei Liub4734232020-01-17 18:25:10 +0800814 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800815 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800816 switch (params->segment.pid_action[i]) {
817 case DVR_RECORD_PID_CREATE:
Wentao MA96f68962022-06-15 19:45:35 +0800818 DVR_INFO("%s create pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800819 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
820 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800821 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800822 break;
823 case DVR_RECORD_PID_KEEP:
Wentao MA96f68962022-06-15 19:45:35 +0800824 DVR_INFO("%s keep pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800825 p_ctx->segment_info.nb_pids++;
826 break;
827 case DVR_RECORD_PID_CLOSE:
Wentao MA96f68962022-06-15 19:45:35 +0800828 DVR_INFO("%s close pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800829 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800830 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800831 break;
832 default:
Wentao MA96f68962022-06-15 19:45:35 +0800833 DVR_INFO("%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
Pengfei Liub4734232020-01-17 18:25:10 +0800834 return DVR_FAILURE;
835 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800836 }
837
Pengfei Liub4734232020-01-17 18:25:10 +0800838 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800839 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen4b7c15d2020-04-07 16:13:48 +0800840 /*Update segment info*/
841 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
wentao.maa210e5e2022-10-12 16:10:03 +0800842 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen94d8dd22021-12-29 15:13:43 +0800843 if (p_ctx->pts != ULLONG_MAX)
844 segment_update_pts(p_ctx->segment_handle, p_ctx->pts, 0);
Pengfei Liuc181a982020-01-07 19:27:13 +0800845
Pengfei Liuc181a982020-01-07 19:27:13 +0800846 p_ctx->state = DVR_RECORD_STATE_STARTED;
Zhiqiang Han0d60f2b2020-05-26 14:39:54 +0800847 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800848 return DVR_SUCCESS;
849}
850
851int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
852{
853 DVR_RecordContext_t *p_ctx;
Wentao MA139fc612022-08-29 14:10:07 +0800854 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800855 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800856 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800857
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800858 p_ctx = (DVR_RecordContext_t *)handle;
859 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
860 if (p_ctx == &record_ctx[i])
861 break;
862 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800863 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800864
Wentao MA96f68962022-06-15 19:45:35 +0800865 DVR_INFO("%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800866 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STOPPED);
867 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +0800868 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800869
Pengfei Liuc181a982020-01-07 19:27:13 +0800870 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800871 if (p_ctx->is_vod) {
pengfei.liu8b563292020-02-26 15:49:02 +0800872 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
pengfei.liuab5a2262020-02-14 17:33:40 +0800873 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
874 } else {
Chao Yin0e6cb602022-08-02 15:41:24 +0800875 pthread_join(p_ctx->thread, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +0800876 ret = record_device_stop(p_ctx->dev_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800877 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
878 if (ret != DVR_SUCCESS)
879 goto end;
pengfei.liuab5a2262020-02-14 17:33:40 +0800880 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800881 }
882
hualing chen2932d372020-04-29 13:44:00 +0800883 //add index file store
884 pos = segment_tell_position(p_ctx->segment_handle);
885 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
hualing chene41f4372020-06-06 16:29:17 +0800886 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800887
Pengfei Liub4734232020-01-17 18:25:10 +0800888 /*Update segment info*/
889 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
890
891 ret = segment_store_info(p_ctx->segment_handle, p_info);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800892 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
893 if (ret != DVR_SUCCESS)
894 goto end;
Pengfei Liub4734232020-01-17 18:25:10 +0800895
hualing chenb9a02922021-12-14 11:29:47 +0800896 segment_store_allInfo(p_ctx->segment_handle, p_info);
897
Wentao MA96f68962022-06-15 19:45:35 +0800898 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 +0800899 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
900
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800901end:
Pengfei Liuc181a982020-01-07 19:27:13 +0800902 ret = segment_close(p_ctx->segment_handle);
hualing chencedcb862022-01-04 15:32:43 +0800903 p_ctx->segment_handle = NULL;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800904 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800905 return DVR_SUCCESS;
906}
Pengfei Liuc181a982020-01-07 19:27:13 +0800907
Pengfei Liub4734232020-01-17 18:25:10 +0800908int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
909{
910 DVR_RecordContext_t *p_ctx;
911 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +0800912 int ret = DVR_SUCCESS;
Pengfei Liub4734232020-01-17 18:25:10 +0800913
914 p_ctx = (DVR_RecordContext_t *)handle;
915 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
916 if (p_ctx == &record_ctx[i])
917 break;
Pengfei Liuc181a982020-01-07 19:27:13 +0800918 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800919 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
920 DVR_RETURN_IF_FALSE(params);
921 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800922
Wentao MA96f68962022-06-15 19:45:35 +0800923 DVR_INFO("%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
pengfei.liuab5a2262020-02-14 17:33:40 +0800924 ret = dvr_record_start_segment(handle, params);
925 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
926
927 p_ctx->segment_info.size = *p_resume_size;
928
929 return DVR_SUCCESS;
930}
931
932int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
933{
934 DVR_RecordContext_t *p_ctx;
935 int i;
936
937 p_ctx = (DVR_RecordContext_t *)handle;
938 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
939 if (p_ctx == &record_ctx[i])
940 break;
941 }
942 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
943 DVR_RETURN_IF_FALSE(p_status);
944
945 //lock
946 p_status->state = p_ctx->state;
947 p_status->info.id = p_ctx->segment_info.id;
948 p_status->info.duration = p_ctx->segment_info.duration;
949 p_status->info.size = p_ctx->segment_info.size;
950 p_status->info.nb_packets = p_ctx->segment_info.size/188;
951
952 return DVR_SUCCESS;
953}
954
955int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
956{
957 DVR_RecordContext_t *p_ctx;
958 uint32_t i;
959 off_t pos = 0;
Wentao MA139fc612022-08-29 14:10:07 +0800960 int ret = DVR_SUCCESS;
pengfei.liuab5a2262020-02-14 17:33:40 +0800961 int has_pcr;
962
963 p_ctx = (DVR_RecordContext_t *)handle;
964 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
965 if (p_ctx == &record_ctx[i])
966 break;
967 }
968 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
969 DVR_RETURN_IF_FALSE(buffer);
970 DVR_RETURN_IF_FALSE(len);
971
972 pos = segment_tell_position(p_ctx->segment_handle);
973 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
974 if (has_pcr == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800975 /* Pull VOD record should use PCR time index */
Wentao MA96f68962022-06-15 19:45:35 +0800976 DVR_INFO("%s has no pcr, can NOT do time index", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800977 }
978 ret = segment_write(p_ctx->segment_handle, buffer, len);
hualing chen2932d372020-04-29 13:44:00 +0800979 if (ret != len) {
Wentao MA96f68962022-06-15 19:45:35 +0800980 DVR_INFO("%s write error ret:%d len:%d", __func__, ret, len);
hualing chen2932d372020-04-29 13:44:00 +0800981 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800982 p_ctx->segment_info.size += len;
983 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
984
Pengfei Liuc181a982020-01-07 19:27:13 +0800985 return DVR_SUCCESS;
986}
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800987
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800988int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800989{
990 DVR_RecordContext_t *p_ctx;
991 uint32_t i;
992
993 p_ctx = (DVR_RecordContext_t *)handle;
994 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
995 if (p_ctx == &record_ctx[i])
996 break;
997 }
998 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
999 DVR_RETURN_IF_FALSE(func);
1000
Wentao MA96f68962022-06-15 19:45:35 +08001001 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001002 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
1003 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
1004
1005 p_ctx->enc_func = func;
1006 p_ctx->enc_userdata = userdata;
1007 return DVR_SUCCESS;
1008}
1009
1010int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
1011{
1012 DVR_RecordContext_t *p_ctx;
1013 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001014 int ret = DVR_SUCCESS;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001015
1016 p_ctx = (DVR_RecordContext_t *)handle;
1017 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1018 if (p_ctx == &record_ctx[i])
1019 break;
1020 }
1021 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1022 DVR_RETURN_IF_FALSE(p_secure_buf);
1023 DVR_RETURN_IF_FALSE(len);
1024
Wentao MA96f68962022-06-15 19:45:35 +08001025 DVR_INFO("%s , current state:%d", __func__, p_ctx->state);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001026 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
1027 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
1028
1029 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
1030 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
1031
1032 p_ctx->is_secure_mode = 1;
Yahui Han4577db82022-07-05 17:46:19 +08001033 p_ctx->secbuf_size = len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001034 return ret;
1035}
hualing chen4fe3bee2020-10-23 13:58:52 +08001036
1037int dvr_record_is_secure_mode(DVR_RecordHandle_t handle)
1038{
1039 DVR_RecordContext_t *p_ctx;
1040 uint32_t i;
Wentao MA139fc612022-08-29 14:10:07 +08001041 int ret = DVR_SUCCESS;
hualing chen4fe3bee2020-10-23 13:58:52 +08001042
1043 p_ctx = (DVR_RecordContext_t *)handle;
1044 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1045 if (p_ctx == &record_ctx[i])
1046 break;
1047 }
hualing chen002e5b92022-02-23 17:51:21 +08001048
hualing chen4fe3bee2020-10-23 13:58:52 +08001049 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1050
1051 if (p_ctx->is_secure_mode == 1)
1052 ret = 1;
1053 else
1054 ret = 0;
1055 return ret;
Yahui Hance15e9c2020-12-08 18:08:32 +08001056}
Wentao MAf4072032022-06-30 13:50:45 +08001057
1058int dvr_record_discard_coming_data(DVR_RecordHandle_t handle, DVR_Bool_t discard)
1059{
1060 DVR_RecordContext_t *p_ctx;
1061 int i;
1062
1063 p_ctx = (DVR_RecordContext_t *)handle;
1064 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
1065 if (p_ctx == &record_ctx[i])
1066 break;
1067 }
1068 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
1069
1070 if (p_ctx->discard_coming_data != discard) {
1071 p_ctx->discard_coming_data = discard;
1072 if (discard) {
1073 DVR_WARN("%s, start discarding coming data. discard:%d",__func__,discard);
1074 } else {
1075 DVR_WARN("%s, finish discarding coming data. discard:%d",__func__,discard);
1076 }
1077 }
1078
1079 return DVR_TRUE;
1080}