blob: e0ad60e3c06f31c0caad11e10b72a64a7e9acf02 [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"
9#include "record_device.h"
10#include "segment.h"
pengfei.liu567d6d82020-04-17 16:48:59 +080011#include <sys/time.h>
Pengfei Liuc181a982020-01-07 19:27:13 +080012
hualing chen2932d372020-04-29 13:44:00 +080013#define DEBUG_PERFORMANCE
Pengfei Liuc181a982020-01-07 19:27:13 +080014#define MAX_DVR_RECORD_SESSION_COUNT 2
hualing chen266b9502020-04-04 17:39:39 +080015#define RECORD_BLOCK_SIZE (256 * 1024)
pengfei.liuab5a2262020-02-14 17:33:40 +080016
17/**\brief DVR index file type*/
18typedef enum {
19 DVR_INDEX_TYPE_PCR, /**< DVR index file use pcr*/
20 DVR_INDEX_TYPE_LOCAL_CLOCK, /**< DVR index file use local clock*/
21 DVR_INDEX_TYPE_INVALID /**< DVR index file type invalid type*/
22} DVR_IndexType_t;
23
24/**\brief DVR VOD context*/
25typedef struct {
26 pthread_mutex_t mutex; /**< VOD mutex lock*/
27 pthread_cond_t cond; /**< VOD condition*/
28 void *buffer; /**< VOD buffer*/
29 uint32_t buf_len; /**< VOD buffer len*/
30} DVR_VodContext_t;
31
pengfei.liu07ddc8a2020-03-24 23:36:53 +080032/**\brief DVR record secure mode buffer*/
33typedef struct {
34 uint32_t addr; /**< Secure mode record buffer address*/
35 uint32_t len; /**< Secure mode record buffer length*/
36} DVR_SecureBuffer_t;
37
Pengfei Liub4734232020-01-17 18:25:10 +080038/**\brief DVR record context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080039typedef struct {
Pengfei Liub4734232020-01-17 18:25:10 +080040 pthread_t thread; /**< DVR thread handle*/
41 Record_DeviceHandle_t dev_handle; /**< DVR device handle*/
42 Segment_Handle_t segment_handle; /**< DVR segment handle*/
43 DVR_RecordState_t state; /**< DVR record state*/
44 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
45 DVR_RecordSegmentStartParams_t segment_params; /**< DVR record start parameters*/
46 DVR_RecordSegmentInfo_t segment_info; /**< DVR record current segment info*/
47 size_t notification_size; /**< DVR record nogification size*/
48 DVR_RecordEventFunction_t event_notify_fn; /**< DVR record event notify function*/
49 void *event_userdata; /**< DVR record event userdata*/
pengfei.liuab5a2262020-02-14 17:33:40 +080050 //DVR_VodContext_t vod; /**< DVR record vod context*/
51 int is_vod; /**< Indicate current mode is VOD record mode*/
pengfei.liu27cc4ec2020-04-03 16:28:16 +080052 DVR_CryptoFunction_t enc_func; /**< Encrypt function*/
pengfei.liu07ddc8a2020-03-24 23:36:53 +080053 void *enc_userdata; /**< Encrypt userdata*/
54 int is_secure_mode; /**< Record session run in secure pipeline */
hualing chen2615aa82020-04-02 21:32:51 +080055 size_t last_send_size; /**< Last send notify segment size */
pengfei.liufda2a972020-04-09 14:47:15 +080056 uint32_t block_size; /**< DVR record block size */
Pengfei Liuc181a982020-01-07 19:27:13 +080057} DVR_RecordContext_t;
58
59static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
60 {
Pengfei Liub4734232020-01-17 18:25:10 +080061 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080062 },
63 {
Pengfei Liub4734232020-01-17 18:25:10 +080064 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080065 }
66};
67
Zhiqiang Han51646a02020-04-05 18:43:22 +080068static int record_is_valid_pid(DVR_RecordContext_t *p_ctx, int pid)
69{
70 int i;
71
72 for (i = 0; i < p_ctx->segment_info.nb_pids; i++) {
73 if (pid == p_ctx->segment_info.pids[i].pid)
74 return 1;
75 }
76 return 0;
77}
78
pengfei.liuab5a2262020-02-14 17:33:40 +080079static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
80{
81 uint8_t *p = buf;
82 int len;
83 uint8_t afc;
84 uint64_t pcr = 0;
85 int has_pcr = 0;
86 int pid;
87 int adp_field_len;
88
89 pid = ((p[1] & 0x1f) << 8) | p[2];
Zhiqiang Han51646a02020-04-05 18:43:22 +080090 if (pid == 0x1fff || !record_is_valid_pid(p_ctx, pid))
pengfei.liuab5a2262020-02-14 17:33:40 +080091 return has_pcr;
92
93 //scramble = p[3] >> 6;
94 //cc = p[3] & 0x0f;
95 afc = (p[3] >> 4) & 0x03;
96
97 p += 4;
98 len = 184;
99
100 if (afc & 2) {
101 adp_field_len = p[0];
102 /* Skip adaptation len */
103 p++;
104 len--;
105 /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
106 if (p[0] & 0x10 && len >= 6) {
107 /* get pcr value,pcr is 33bit value */
108 pcr = (((uint64_t)(p[1])) << 25)
109 | (((uint64_t)p[2]) << 17)
110 | (((uint64_t)(p[3])) << 9)
111 | (((uint64_t)p[4]) << 1)
112 | ((((uint64_t)p[5]) & 0x80) >> 7);
113 has_pcr = 1;
114 }
115
116 p += adp_field_len;
117 len -= adp_field_len;
118
119 if (len < 0) {
120 DVR_DEBUG(1, "parser pcr: illegal adaptation field length");
121 return 0;
122 }
123 }
124
125 if (has_pcr) {
126 segment_update_pts(p_ctx->segment_handle, pcr/90, pos);
127 }
128 return has_pcr;
129}
130
131static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
132{
133 uint8_t *p = buf;
134 int left = len;
135 loff_t pos;
136 int has_pcr = 0;
137
138 pos = segment_tell_position(p_ctx->segment_handle);
139 while (left >= 188) {
140 if (*p == 0x47) {
141 has_pcr |= record_save_pcr(p_ctx, p, pos);
142 p += 188;
143 left -= 188;
144 pos += 188;
145 } else {
146 p++;
147 left --;
148 pos++;
149 }
150 }
151 return has_pcr;
152}
153
pengfei.liu567d6d82020-04-17 16:48:59 +0800154static int get_diff_time(struct timeval start_tv, struct timeval end_tv)
155{
156 return end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000 - start_tv.tv_sec * 1000 - start_tv.tv_usec / 1000;
157}
158
Pengfei Liuc181a982020-01-07 19:27:13 +0800159void *record_thread(void *arg)
160{
161 DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
162 ssize_t len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800163 uint8_t *buf, *buf_out;
pengfei.liufda2a972020-04-09 14:47:15 +0800164 uint32_t block_size = p_ctx->block_size;
pengfei.liuab5a2262020-02-14 17:33:40 +0800165 loff_t pos = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800166 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800167 struct timespec start_ts, end_ts;
168 DVR_RecordStatus_t record_status;
pengfei.liuab5a2262020-02-14 17:33:40 +0800169 int has_pcr;
170 int index_type = DVR_INDEX_TYPE_INVALID;
hualing chen87072a82020-03-12 16:20:12 +0800171 time_t pre_time = 0;
hualing chen2932d372020-04-29 13:44:00 +0800172 #define DVR_STORE_INFO_TIME (400)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800173 DVR_SecureBuffer_t secure_buf;
Pengfei Liuc181a982020-01-07 19:27:13 +0800174
Pengfei Liub4734232020-01-17 18:25:10 +0800175 buf = (uint8_t *)malloc(block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800176 if (!buf) {
177 DVR_DEBUG(1, "%s, malloc failed", __func__);
178 return NULL;
179 }
180
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800181 buf_out = (uint8_t *)malloc(block_size + 188);
182 if (!buf_out) {
183 DVR_DEBUG(1, "%s, malloc failed", __func__);
184 return NULL;
185 }
186
hualing chen266b9502020-04-04 17:39:39 +0800187 memset(&record_status, 0, sizeof(record_status));
188 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800189 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800190 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800191 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +0800192 DVR_DEBUG(1, "%s line %d notify record status, state:%d id=%lld",
193 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800194 }
195 DVR_DEBUG(1, "%s, secure_mode:%d, block_size:%d", __func__, p_ctx->is_secure_mode, block_size);
hualing chen266b9502020-04-04 17:39:39 +0800196
Pengfei Liub4734232020-01-17 18:25:10 +0800197 clock_gettime(CLOCK_MONOTONIC, &start_ts);
pengfei.liu567d6d82020-04-17 16:48:59 +0800198
199 struct timeval t1, t2, t3, t4, t5, t6, t7;
Pengfei Liuc181a982020-01-07 19:27:13 +0800200 while (p_ctx->state == DVR_RECORD_STATE_STARTED) {
pengfei.liu567d6d82020-04-17 16:48:59 +0800201 gettimeofday(&t1, NULL);
hualing chen2932d372020-04-29 13:44:00 +0800202 DVR_DEBUG(1, "%s, start_read", __func__);
pengfei.liuab5a2262020-02-14 17:33:40 +0800203 /* data from dmx, normal dvr case */
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800204 if (p_ctx->is_secure_mode) {
205 memset(&secure_buf, 0, sizeof(secure_buf));
206 len = record_device_read(p_ctx->dev_handle, &secure_buf, sizeof(secure_buf), 1000);
hualing chen266b9502020-04-04 17:39:39 +0800207 if (len != DVR_FAILURE) {
208 DVR_DEBUG(1, "%s, secure_buf:%#x, size:%#x", __func__, secure_buf.addr, secure_buf.len);
209 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800210 } else {
211 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
212 }
Pengfei Liub4734232020-01-17 18:25:10 +0800213 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800214 //usleep(10*1000);
hualing chen2932d372020-04-29 13:44:00 +0800215 DVR_DEBUG(1, "%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800216 continue;
217 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800218
pengfei.liu567d6d82020-04-17 16:48:59 +0800219 gettimeofday(&t2, NULL);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800220 /* Got data from device, record it */
221 if (p_ctx->enc_func) {
222 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800223 DVR_CryptoParams_t crypto_params;
224
225 memset(&crypto_params, 0, sizeof(crypto_params));
226 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800227 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800228 crypto_params.segment_id = p_ctx->segment_info.id;
229 crypto_params.offset = p_ctx->segment_info.size;
230
231 if (p_ctx->is_secure_mode) {
232 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
233 crypto_params.input_buffer.addr = secure_buf.addr;
234 crypto_params.input_buffer.size = secure_buf.len;
235 } else {
236 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
237 crypto_params.input_buffer.addr = (size_t)buf;
238 crypto_params.input_buffer.size = len;
239 }
240
241 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
242 crypto_params.output_buffer.addr = (size_t)buf_out;
243 crypto_params.output_buffer.size = block_size + 188;
244
245 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800246 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800247 /* Out buffer length may not equal in buffer length */
248 ret = segment_write(p_ctx->segment_handle, buf_out, crypto_params.output_size);
249 len = crypto_params.output_size;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800250 } else {
pengfei.liu567d6d82020-04-17 16:48:59 +0800251 gettimeofday(&t3, NULL);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800252 ret = segment_write(p_ctx->segment_handle, buf, len);
253 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800254 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800255 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800256 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800257 //send write event
hualing chen4b7c15d2020-04-07 16:13:48 +0800258 if (p_ctx->notification_size &&
259 p_ctx->event_notify_fn) {
260 memset(&record_status, 0, sizeof(record_status));
261 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
262 }
hualing chen626204e2020-04-07 11:55:08 +0800263 goto end;
264 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800265 /* Do time index */
266 uint8_t *index_buf = p_ctx->enc_func ? buf_out : buf;
pengfei.liuab5a2262020-02-14 17:33:40 +0800267 pos = segment_tell_position(p_ctx->segment_handle);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800268 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
pengfei.liuab5a2262020-02-14 17:33:40 +0800269 if (has_pcr == 0 && index_type == DVR_INDEX_TYPE_INVALID) {
270 clock_gettime(CLOCK_MONOTONIC, &end_ts);
271 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
272 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
273 /* PCR interval threshlod > 40 ms*/
274 DVR_DEBUG(1, "%s use local clock time index", __func__);
275 index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
276 }
277 } else if (has_pcr && index_type == DVR_INDEX_TYPE_INVALID){
278 DVR_DEBUG(1, "%s use pcr time index", __func__);
279 index_type = DVR_INDEX_TYPE_PCR;
Pengfei Liuc181a982020-01-07 19:27:13 +0800280 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800281 gettimeofday(&t5, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +0800282
283 /* Update segment info */
Pengfei Liub4734232020-01-17 18:25:10 +0800284 p_ctx->segment_info.size += len;
pengfei.liuab5a2262020-02-14 17:33:40 +0800285 /*Duration need use pcr to calculate, todo...*/
286 if (index_type == DVR_INDEX_TYPE_PCR) {
pengfei.liu8b563292020-02-26 15:49:02 +0800287 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
hualing chen87072a82020-03-12 16:20:12 +0800288 if (pre_time == 0)
289 pre_time = p_ctx->segment_info.duration;
pengfei.liuab5a2262020-02-14 17:33:40 +0800290 } else if (index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
291 clock_gettime(CLOCK_MONOTONIC, &end_ts);
292 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
293 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000);
hualing chen87072a82020-03-12 16:20:12 +0800294 if (pre_time == 0)
295 pre_time = p_ctx->segment_info.duration;
pengfei.liuab5a2262020-02-14 17:33:40 +0800296 segment_update_pts(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
297 } else {
298 DVR_DEBUG(1, "%s can NOT do time index", __func__);
299 }
300 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
Pengfei Liub4734232020-01-17 18:25:10 +0800301
hualing chen87072a82020-03-12 16:20:12 +0800302 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
303 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
304 segment_store_info(p_ctx->segment_handle, &(p_ctx->segment_info));
305 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800306 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800307 /*Event notification*/
Pengfei Liub4734232020-01-17 18:25:10 +0800308 if (p_ctx->notification_size &&
309 p_ctx->event_notify_fn &&
hualing chen2615aa82020-04-02 21:32:51 +0800310 /*!(p_ctx->segment_info.size % p_ctx->notification_size)*/
311 (p_ctx->segment_info.size -p_ctx->last_send_size) >= p_ctx->notification_size&&
pengfei.liuab5a2262020-02-14 17:33:40 +0800312 p_ctx->segment_info.duration > 0) {
Pengfei Liub4734232020-01-17 18:25:10 +0800313 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800314 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800315 p_ctx->last_send_size = p_ctx->segment_info.size;
Pengfei Liub4734232020-01-17 18:25:10 +0800316 record_status.state = p_ctx->state;
317 record_status.info.id = p_ctx->segment_info.id;
pengfei.liuab5a2262020-02-14 17:33:40 +0800318 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800319 record_status.info.size = p_ctx->segment_info.size;
320 record_status.info.nb_packets = p_ctx->segment_info.size/188;
321 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
322 DVR_DEBUG(1, "%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu",
323 __func__, record_status.state, record_status.info.id, record_status.info.duration, record_status.info.size);
324 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800325 gettimeofday(&t7, NULL);
326#ifdef DEBUG_PERFORMANCE
hualing chen2932d372020-04-29 13:44:00 +0800327 DVR_DEBUG(1, "record count, read:%dms, encrypt:%dms, write:%dms, index:%dms, store:%dms, notify:%dms total:%dms read len:%zd ",
pengfei.liu567d6d82020-04-17 16:48:59 +0800328 get_diff_time(t1, t2), get_diff_time(t2, t3), get_diff_time(t3, t4), get_diff_time(t4, t5),
hualing chen2932d372020-04-29 13:44:00 +0800329 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len);
pengfei.liu567d6d82020-04-17 16:48:59 +0800330#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800331 }
hualing chen626204e2020-04-07 11:55:08 +0800332end:
Pengfei Liub4734232020-01-17 18:25:10 +0800333 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800334 free((void *)buf_out);
Pengfei Liub4734232020-01-17 18:25:10 +0800335 DVR_DEBUG(1, "exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800336 return NULL;
337}
338
339int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
340{
341 DVR_RecordContext_t *p_ctx;
342 Record_DeviceOpenParams_t dev_open_params;
343 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800344 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800345
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800346 DVR_RETURN_IF_FALSE(p_handle);
347 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800348
349 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800350 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800351 break;
352 }
353 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800354 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800355 p_ctx = &record_ctx[i];
Pengfei Liub4734232020-01-17 18:25:10 +0800356 DVR_DEBUG(1, "%s , current state:%d, dmx_id:%d, notification_size:%zu", __func__,
357 p_ctx->state, params->dmx_dev_id, params->notification_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800358
Pengfei Liub4734232020-01-17 18:25:10 +0800359 /*Process event params*/
360 p_ctx->notification_size = params->notification_size;
361 p_ctx->event_notify_fn = params->event_fn;
362 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800363 p_ctx->last_send_size = 0;
Pengfei Liub4734232020-01-17 18:25:10 +0800364 /*Process crypto params, todo*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800365
Pengfei Liub4734232020-01-17 18:25:10 +0800366 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800367 if (params->data_from_memory) {
368 /* data from memory, VOD case */
369 p_ctx->is_vod = 1;
370 } else {
371 p_ctx->is_vod = 0;
372 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800373 dev_open_params.dmx_dev_id = params->dmx_dev_id;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800374 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
Pengfei Liub4734232020-01-17 18:25:10 +0800375
pengfei.liuab5a2262020-02-14 17:33:40 +0800376 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
377 if (ret != DVR_SUCCESS) {
378 DVR_DEBUG(1, "%s, open record devices failed", __func__);
379 return DVR_FAILURE;
380 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800381 }
382
pengfei.liufda2a972020-04-09 14:47:15 +0800383 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800384 p_ctx->enc_func = NULL;
385 p_ctx->enc_userdata = NULL;
386 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800387 p_ctx->state = DVR_RECORD_STATE_OPENED;
388
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800389 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800390 return DVR_SUCCESS;
391}
392
393int dvr_record_close(DVR_RecordHandle_t handle)
394{
395 DVR_RecordContext_t *p_ctx;
396 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800397 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800398
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800399 p_ctx = (DVR_RecordContext_t *)handle;
400 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
401 if (p_ctx == &record_ctx[i])
402 break;
403 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800404 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800405
Pengfei Liub4734232020-01-17 18:25:10 +0800406 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800407 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800408
pengfei.liuab5a2262020-02-14 17:33:40 +0800409 if (p_ctx->is_vod) {
410 ret = DVR_SUCCESS;
411 } else {
412 ret = record_device_close(p_ctx->dev_handle);
413 if (ret != DVR_SUCCESS) {
414 DVR_DEBUG(1, "%s, failed", __func__);
415 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800416 }
417
Pengfei Liub4734232020-01-17 18:25:10 +0800418 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800419 return ret;
420}
421
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800422#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800423int dvr_record_register_encryption(DVR_RecordHandle_t handle,
424 DVR_CryptoFunction_t cb,
425 DVR_CryptoParams_t params,
426 void *userdata)
427{
428 return DVR_SUCCESS;
429}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800430#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800431
432int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
433{
434 DVR_RecordContext_t *p_ctx;
435 Segment_OpenParams_t open_params;
436 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800437 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800438
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800439 p_ctx = (DVR_RecordContext_t *)handle;
440 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
441 if (p_ctx == &record_ctx[i])
442 break;
443 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800444 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800445
Pengfei Liub4734232020-01-17 18:25:10 +0800446 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800447 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
448 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
449 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800450
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800451 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800452 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800453 memcpy(open_params.location, params->location, sizeof(params->location));
Pengfei Liuc181a982020-01-07 19:27:13 +0800454 open_params.segment_id = params->segment.segment_id;
455 open_params.mode = SEGMENT_MODE_WRITE;
456
457 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800458 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800459
Pengfei Liub4734232020-01-17 18:25:10 +0800460 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800461 {
hualing chen7a56cba2020-04-14 14:09:27 +0800462 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800463 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800464 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800465 /*save current segment info*/
466 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
467 p_ctx->segment_info.id = params->segment.segment_id;
468 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
469 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800470 }
471
pengfei.liuab5a2262020-02-14 17:33:40 +0800472 if (!p_ctx->is_vod) {
473 /* normal dvr case */
474 for (i = 0; i < params->segment.nb_pids; i++) {
475 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
476 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
477 }
478 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800479 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800480 }
481
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800482 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
483
Pengfei Liuc181a982020-01-07 19:27:13 +0800484 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800485 if (!p_ctx->is_vod)
486 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800487
Pengfei Liuc181a982020-01-07 19:27:13 +0800488 return DVR_SUCCESS;
489}
490
491int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
492{
493 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800494 Segment_OpenParams_t open_params;
Pengfei Liuc181a982020-01-07 19:27:13 +0800495 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800496 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800497 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800498
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800499 p_ctx = (DVR_RecordContext_t *)handle;
500 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
501 if (p_ctx == &record_ctx[i])
502 break;
503 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800504 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800505
Pengfei Liub4734232020-01-17 18:25:10 +0800506 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800507 DVR_RETURN_IF_FALSE(p_ctx->state == DVR_RECORD_STATE_STARTED);
508 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
509 DVR_RETURN_IF_FALSE(params);
510 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800511 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800512
513 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800514 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800515 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800516 p_ctx->state = DVR_RECORD_STATE_STOPPED;
517 pthread_join(p_ctx->thread, NULL);
518
hualing chen2932d372020-04-29 13:44:00 +0800519 //add index file store
520 pos = segment_tell_position(p_ctx->segment_handle);
521 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
522
523 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liub4734232020-01-17 18:25:10 +0800524 /*Update segment info*/
525 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
526
527 ret = segment_store_info(p_ctx->segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800528 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800529
hualing chena540a7e2020-03-27 16:44:05 +0800530 DVR_DEBUG(1, "%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d params->segment.nb_pids:%d",
531 __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 +0800532
Pengfei Liub4734232020-01-17 18:25:10 +0800533 /*Close current segment*/
534 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800535 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800536 /*Open the new record segment*/
537 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800538 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800539 open_params.segment_id = params->segment.segment_id;
540 open_params.mode = SEGMENT_MODE_WRITE;
hualing chen7a56cba2020-04-14 14:09:27 +0800541 DVR_DEBUG(1, "%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800542
543 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800544 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800545 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800546 {
Pengfei Liub4734232020-01-17 18:25:10 +0800547 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800548 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800549 /*save current segment info*/
550 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
551 p_ctx->segment_info.id = params->segment.segment_id;
552 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800553 }
554
Pengfei Liub4734232020-01-17 18:25:10 +0800555 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800556 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800557 switch (params->segment.pid_action[i]) {
558 case DVR_RECORD_PID_CREATE:
559 DVR_DEBUG(1, "%s create pid:%d", __func__, params->segment.pids[i].pid);
560 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
561 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800562 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800563 break;
564 case DVR_RECORD_PID_KEEP:
565 DVR_DEBUG(1, "%s keep pid:%d", __func__, params->segment.pids[i].pid);
566 p_ctx->segment_info.nb_pids++;
567 break;
568 case DVR_RECORD_PID_CLOSE:
569 DVR_DEBUG(1, "%s close pid:%d", __func__, params->segment.pids[i].pid);
570 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800571 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800572 break;
573 default:
574 DVR_DEBUG(1, "%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
575 return DVR_FAILURE;
576 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800577 }
578
Pengfei Liub4734232020-01-17 18:25:10 +0800579 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800580 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen4b7c15d2020-04-07 16:13:48 +0800581 /*Update segment info*/
582 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
Pengfei Liuc181a982020-01-07 19:27:13 +0800583
584 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
585 p_ctx->state = DVR_RECORD_STATE_STARTED;
586 return DVR_SUCCESS;
587}
588
589int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
590{
591 DVR_RecordContext_t *p_ctx;
592 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800593 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800594 loff_t pos;
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
Pengfei Liub4734232020-01-17 18:25:10 +0800603 DVR_DEBUG(1, "%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_STOPPED);
605 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +0800606 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800607
Pengfei Liuc181a982020-01-07 19:27:13 +0800608 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800609 if (p_ctx->is_vod) {
pengfei.liu8b563292020-02-26 15:49:02 +0800610 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
pengfei.liuab5a2262020-02-14 17:33:40 +0800611 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
612 } else {
613 ret = record_device_stop(p_ctx->dev_handle);
614 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
615 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
616 pthread_join(p_ctx->thread, NULL);
617 }
618
hualing chen2932d372020-04-29 13:44:00 +0800619 //add index file store
620 pos = segment_tell_position(p_ctx->segment_handle);
621 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
Pengfei Liuc181a982020-01-07 19:27:13 +0800622
Pengfei Liub4734232020-01-17 18:25:10 +0800623 /*Update segment info*/
624 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
625
626 ret = segment_store_info(p_ctx->segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800627 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800628
629 DVR_DEBUG(1, "%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
630 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
631
Pengfei Liuc181a982020-01-07 19:27:13 +0800632 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800633 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800634 return DVR_SUCCESS;
635}
Pengfei Liuc181a982020-01-07 19:27:13 +0800636
Pengfei Liub4734232020-01-17 18:25:10 +0800637int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
638{
639 DVR_RecordContext_t *p_ctx;
640 uint32_t i;
pengfei.liuab5a2262020-02-14 17:33:40 +0800641 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800642
643 p_ctx = (DVR_RecordContext_t *)handle;
644 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
645 if (p_ctx == &record_ctx[i])
646 break;
Pengfei Liuc181a982020-01-07 19:27:13 +0800647 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800648 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
649 DVR_RETURN_IF_FALSE(params);
650 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800651
pengfei.liuab5a2262020-02-14 17:33:40 +0800652 DVR_DEBUG(1, "%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
653 ret = dvr_record_start_segment(handle, params);
654 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
655
656 p_ctx->segment_info.size = *p_resume_size;
657
658 return DVR_SUCCESS;
659}
660
661int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
662{
663 DVR_RecordContext_t *p_ctx;
664 int i;
665
666 p_ctx = (DVR_RecordContext_t *)handle;
667 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
668 if (p_ctx == &record_ctx[i])
669 break;
670 }
671 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
672 DVR_RETURN_IF_FALSE(p_status);
673
674 //lock
675 p_status->state = p_ctx->state;
676 p_status->info.id = p_ctx->segment_info.id;
677 p_status->info.duration = p_ctx->segment_info.duration;
678 p_status->info.size = p_ctx->segment_info.size;
679 p_status->info.nb_packets = p_ctx->segment_info.size/188;
680
681 return DVR_SUCCESS;
682}
683
684int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
685{
686 DVR_RecordContext_t *p_ctx;
687 uint32_t i;
688 off_t pos = 0;
689 int ret;
690 int has_pcr;
691
692 p_ctx = (DVR_RecordContext_t *)handle;
693 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
694 if (p_ctx == &record_ctx[i])
695 break;
696 }
697 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
698 DVR_RETURN_IF_FALSE(buffer);
699 DVR_RETURN_IF_FALSE(len);
700
701 pos = segment_tell_position(p_ctx->segment_handle);
702 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
703 if (has_pcr == 0) {
704 /* Pull VOD record shoud use PCR time index */
705 DVR_DEBUG(1, "%s has no pcr, can NOT do time index", __func__);
706 }
707 ret = segment_write(p_ctx->segment_handle, buffer, len);
hualing chen2932d372020-04-29 13:44:00 +0800708 if (ret != len) {
709 DVR_DEBUG(1, "%s write error ret:%d len:%d", __func__, ret, len);
710 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800711 p_ctx->segment_info.size += len;
712 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
713
Pengfei Liuc181a982020-01-07 19:27:13 +0800714 return DVR_SUCCESS;
715}
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800716
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800717int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800718{
719 DVR_RecordContext_t *p_ctx;
720 uint32_t i;
721
722 p_ctx = (DVR_RecordContext_t *)handle;
723 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
724 if (p_ctx == &record_ctx[i])
725 break;
726 }
727 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
728 DVR_RETURN_IF_FALSE(func);
729
730 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
731 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
732 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
733
734 p_ctx->enc_func = func;
735 p_ctx->enc_userdata = userdata;
736 return DVR_SUCCESS;
737}
738
739int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
740{
741 DVR_RecordContext_t *p_ctx;
742 uint32_t i;
743 int ret;
744
745 p_ctx = (DVR_RecordContext_t *)handle;
746 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
747 if (p_ctx == &record_ctx[i])
748 break;
749 }
750 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
751 DVR_RETURN_IF_FALSE(p_secure_buf);
752 DVR_RETURN_IF_FALSE(len);
753
754 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
755 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
756 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
757
758 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
759 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
760
761 p_ctx->is_secure_mode = 1;
762 return ret;
763}