blob: 3825cb7aa18b2bd7e104a397aacec028f0089bbf [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 chen5605eed2020-05-26 18:18:06 +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
hualing chenf9867402020-09-23 17:06:20 +080038/**\brief DVR record new dmx secure mode buffer*/
39typedef struct {
40 uint32_t buf_start; /**< Secure mode record buffer address*/
41 uint32_t buf_end; /**< Secure mode record buffer length*/
42 uint32_t data_start; /**< Secure mode record buffer address*/
43 uint32_t data_end; /**< Secure mode record buffer length*/
44} DVR_NewDmxSecureBuffer_t;
45
Pengfei Liub4734232020-01-17 18:25:10 +080046/**\brief DVR record context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080047typedef struct {
Pengfei Liub4734232020-01-17 18:25:10 +080048 pthread_t thread; /**< DVR thread handle*/
49 Record_DeviceHandle_t dev_handle; /**< DVR device handle*/
50 Segment_Handle_t segment_handle; /**< DVR segment handle*/
51 DVR_RecordState_t state; /**< DVR record state*/
52 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
53 DVR_RecordSegmentStartParams_t segment_params; /**< DVR record start parameters*/
54 DVR_RecordSegmentInfo_t segment_info; /**< DVR record current segment info*/
55 size_t notification_size; /**< DVR record nogification size*/
56 DVR_RecordEventFunction_t event_notify_fn; /**< DVR record event notify function*/
57 void *event_userdata; /**< DVR record event userdata*/
pengfei.liuab5a2262020-02-14 17:33:40 +080058 //DVR_VodContext_t vod; /**< DVR record vod context*/
59 int is_vod; /**< Indicate current mode is VOD record mode*/
pengfei.liu27cc4ec2020-04-03 16:28:16 +080060 DVR_CryptoFunction_t enc_func; /**< Encrypt function*/
pengfei.liu07ddc8a2020-03-24 23:36:53 +080061 void *enc_userdata; /**< Encrypt userdata*/
62 int is_secure_mode; /**< Record session run in secure pipeline */
hualing chen2615aa82020-04-02 21:32:51 +080063 size_t last_send_size; /**< Last send notify segment size */
pengfei.liufda2a972020-04-09 14:47:15 +080064 uint32_t block_size; /**< DVR record block size */
hualing chenf9867402020-09-23 17:06:20 +080065 DVR_Bool_t is_new_dmx; /**< DVR is used new dmx driver */
Pengfei Liuc181a982020-01-07 19:27:13 +080066} DVR_RecordContext_t;
67
68static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
69 {
Pengfei Liub4734232020-01-17 18:25:10 +080070 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080071 },
72 {
Pengfei Liub4734232020-01-17 18:25:10 +080073 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080074 }
75};
76
Zhiqiang Han51646a02020-04-05 18:43:22 +080077static int record_is_valid_pid(DVR_RecordContext_t *p_ctx, int pid)
78{
79 int i;
80
81 for (i = 0; i < p_ctx->segment_info.nb_pids; i++) {
82 if (pid == p_ctx->segment_info.pids[i].pid)
83 return 1;
84 }
85 return 0;
86}
87
pengfei.liuab5a2262020-02-14 17:33:40 +080088static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
89{
90 uint8_t *p = buf;
91 int len;
92 uint8_t afc;
93 uint64_t pcr = 0;
94 int has_pcr = 0;
95 int pid;
96 int adp_field_len;
97
98 pid = ((p[1] & 0x1f) << 8) | p[2];
Zhiqiang Han51646a02020-04-05 18:43:22 +080099 if (pid == 0x1fff || !record_is_valid_pid(p_ctx, pid))
pengfei.liuab5a2262020-02-14 17:33:40 +0800100 return has_pcr;
101
102 //scramble = p[3] >> 6;
103 //cc = p[3] & 0x0f;
104 afc = (p[3] >> 4) & 0x03;
105
106 p += 4;
107 len = 184;
108
109 if (afc & 2) {
110 adp_field_len = p[0];
111 /* Skip adaptation len */
112 p++;
113 len--;
114 /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
hualing chen5605eed2020-05-26 18:18:06 +0800115 if (p[0] & 0x10 && len >= 6 && adp_field_len >= 6) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800116 /* get pcr value,pcr is 33bit value */
117 pcr = (((uint64_t)(p[1])) << 25)
118 | (((uint64_t)p[2]) << 17)
119 | (((uint64_t)(p[3])) << 9)
120 | (((uint64_t)p[4]) << 1)
121 | ((((uint64_t)p[5]) & 0x80) >> 7);
122 has_pcr = 1;
123 }
124
125 p += adp_field_len;
126 len -= adp_field_len;
127
128 if (len < 0) {
129 DVR_DEBUG(1, "parser pcr: illegal adaptation field length");
130 return 0;
131 }
132 }
133
134 if (has_pcr) {
135 segment_update_pts(p_ctx->segment_handle, pcr/90, pos);
136 }
137 return has_pcr;
138}
139
140static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
141{
142 uint8_t *p = buf;
143 int left = len;
144 loff_t pos;
145 int has_pcr = 0;
146
147 pos = segment_tell_position(p_ctx->segment_handle);
148 while (left >= 188) {
149 if (*p == 0x47) {
150 has_pcr |= record_save_pcr(p_ctx, p, pos);
151 p += 188;
152 left -= 188;
153 pos += 188;
154 } else {
155 p++;
156 left --;
157 pos++;
158 }
159 }
160 return has_pcr;
161}
162
pengfei.liu567d6d82020-04-17 16:48:59 +0800163static int get_diff_time(struct timeval start_tv, struct timeval end_tv)
164{
165 return end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000 - start_tv.tv_sec * 1000 - start_tv.tv_usec / 1000;
166}
167
Pengfei Liuc181a982020-01-07 19:27:13 +0800168void *record_thread(void *arg)
169{
170 DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
171 ssize_t len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800172 uint8_t *buf, *buf_out;
pengfei.liufda2a972020-04-09 14:47:15 +0800173 uint32_t block_size = p_ctx->block_size;
pengfei.liuab5a2262020-02-14 17:33:40 +0800174 loff_t pos = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800175 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800176 struct timespec start_ts, end_ts;
177 DVR_RecordStatus_t record_status;
pengfei.liuab5a2262020-02-14 17:33:40 +0800178 int has_pcr;
179 int index_type = DVR_INDEX_TYPE_INVALID;
hualing chen87072a82020-03-12 16:20:12 +0800180 time_t pre_time = 0;
hualing chen2932d372020-04-29 13:44:00 +0800181 #define DVR_STORE_INFO_TIME (400)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800182 DVR_SecureBuffer_t secure_buf;
hualing chenf9867402020-09-23 17:06:20 +0800183 DVR_NewDmxSecureBuffer_t new_dmx_secure_buf;
Pengfei Liuc181a982020-01-07 19:27:13 +0800184
Pengfei Liub4734232020-01-17 18:25:10 +0800185 buf = (uint8_t *)malloc(block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800186 if (!buf) {
187 DVR_DEBUG(1, "%s, malloc failed", __func__);
188 return NULL;
189 }
190
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800191 buf_out = (uint8_t *)malloc(block_size + 188);
192 if (!buf_out) {
193 DVR_DEBUG(1, "%s, malloc failed", __func__);
Pengfei Liufaf38e42020-05-22 00:28:02 +0800194 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800195 return NULL;
196 }
197
hualing chen266b9502020-04-04 17:39:39 +0800198 memset(&record_status, 0, sizeof(record_status));
199 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800200 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800201 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800202 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +0800203 DVR_DEBUG(1, "%s line %d notify record status, state:%d id=%lld",
204 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800205 }
206 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 +0800207
Pengfei Liub4734232020-01-17 18:25:10 +0800208 clock_gettime(CLOCK_MONOTONIC, &start_ts);
pengfei.liu567d6d82020-04-17 16:48:59 +0800209
210 struct timeval t1, t2, t3, t4, t5, t6, t7;
Pengfei Liuc181a982020-01-07 19:27:13 +0800211 while (p_ctx->state == DVR_RECORD_STATE_STARTED) {
pengfei.liu567d6d82020-04-17 16:48:59 +0800212 gettimeofday(&t1, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800213
pengfei.liuab5a2262020-02-14 17:33:40 +0800214 /* data from dmx, normal dvr case */
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800215 if (p_ctx->is_secure_mode) {
hualing chenf9867402020-09-23 17:06:20 +0800216 if (p_ctx->is_new_dmx) {
217 memset(&new_dmx_secure_buf, 0, sizeof(new_dmx_secure_buf));
218 len = record_device_read(p_ctx->dev_handle, &new_dmx_secure_buf, sizeof(new_dmx_secure_buf), 1000);
219 } else {
220 memset(&secure_buf, 0, sizeof(secure_buf));
221 len = record_device_read(p_ctx->dev_handle, &secure_buf, sizeof(secure_buf), 1000);
222 }
223 if (len != DVR_FAILURE) {
hualing chen4fe3bee2020-10-23 13:58:52 +0800224 //DVR_DEBUG(1, "%s, secure_buf:%#x, size:%#x", __func__, secure_buf.addr, secure_buf.len);
hualing chenf9867402020-09-23 17:06:20 +0800225 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800226 } else {
227 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
228 }
Pengfei Liub4734232020-01-17 18:25:10 +0800229 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800230 //usleep(10*1000);
hualing chen2932d372020-04-29 13:44:00 +0800231 DVR_DEBUG(1, "%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800232 continue;
233 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800234 gettimeofday(&t2, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800235
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800236 /* Got data from device, record it */
237 if (p_ctx->enc_func) {
238 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800239 DVR_CryptoParams_t crypto_params;
240
241 memset(&crypto_params, 0, sizeof(crypto_params));
242 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800243 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800244 crypto_params.segment_id = p_ctx->segment_info.id;
245 crypto_params.offset = p_ctx->segment_info.size;
246
247 if (p_ctx->is_secure_mode) {
248 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
hualing chenf9867402020-09-23 17:06:20 +0800249 if (p_ctx->is_new_dmx) {
250 crypto_params.input_buffer.addr = new_dmx_secure_buf.data_start;
251 crypto_params.input_buffer.size = new_dmx_secure_buf.data_end - new_dmx_secure_buf.data_start;
252 } else {
253 crypto_params.input_buffer.addr = secure_buf.addr;
254 crypto_params.input_buffer.size = secure_buf.len;
255 }
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800256 } else {
257 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
258 crypto_params.input_buffer.addr = (size_t)buf;
259 crypto_params.input_buffer.size = len;
260 }
261
262 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
263 crypto_params.output_buffer.addr = (size_t)buf_out;
264 crypto_params.output_buffer.size = block_size + 188;
hualing chen4fe3bee2020-10-23 13:58:52 +0800265 if ((p_ctx->segment_info.size % (256 * 1024)) != 0) {
266 DVR_DEBUG(1, "%s:%d,offset is not 256k error", __func__,__LINE__);
267 }
268 if (p_ctx->segment_info.size == 0) {
269 DVR_DEBUG(1, "%s:%d,offset is 0k success", __func__,__LINE__);
270 }
271 if (p_ctx->is_secure_mode && secure_buf.len != (256 * 1024)) {
272 DVR_DEBUG(1, "%s:%d,secure buf len is not 256k [0x%x] continue", __func__,__LINE__, secure_buf.len);
273 continue;
274 } else {
275 DVR_DEBUG(1, "%s:%d,read is 256k success", __func__,__LINE__);
276 }
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800277 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800278 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800279 /* Out buffer length may not equal in buffer length */
hualing chenf9867402020-09-23 17:06:20 +0800280 if (crypto_params.output_size > 0) {
281 ret = segment_write(p_ctx->segment_handle, buf_out, crypto_params.output_size);
282 len = crypto_params.output_size;
283 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800284 } else {
pengfei.liu567d6d82020-04-17 16:48:59 +0800285 gettimeofday(&t3, NULL);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800286 ret = segment_write(p_ctx->segment_handle, buf, len);
287 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800288 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800289 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800290 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800291 //send write event
hualing chen9b434f02020-06-10 15:06:54 +0800292 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800293 memset(&record_status, 0, sizeof(record_status));
hualing chen4fe3bee2020-10-23 13:58:52 +0800294 DVR_DEBUG(1, "%s:%d,send event write error", __func__,__LINE__);
hualing chen4b7c15d2020-04-07 16:13:48 +0800295 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
296 }
hualing chenc70a8df2020-05-12 19:23:11 +0800297 DVR_DEBUG(1, "%s,write error %d", __func__,__LINE__);
hualing chen626204e2020-04-07 11:55:08 +0800298 goto end;
299 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800300 /* Do time index */
301 uint8_t *index_buf = p_ctx->enc_func ? buf_out : buf;
pengfei.liuab5a2262020-02-14 17:33:40 +0800302 pos = segment_tell_position(p_ctx->segment_handle);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800303 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
pengfei.liuab5a2262020-02-14 17:33:40 +0800304 if (has_pcr == 0 && index_type == DVR_INDEX_TYPE_INVALID) {
305 clock_gettime(CLOCK_MONOTONIC, &end_ts);
306 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
307 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
308 /* PCR interval threshlod > 40 ms*/
309 DVR_DEBUG(1, "%s use local clock time index", __func__);
310 index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
311 }
312 } else if (has_pcr && index_type == DVR_INDEX_TYPE_INVALID){
313 DVR_DEBUG(1, "%s use pcr time index", __func__);
314 index_type = DVR_INDEX_TYPE_PCR;
Pengfei Liuc181a982020-01-07 19:27:13 +0800315 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800316 gettimeofday(&t5, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +0800317
318 /* Update segment info */
Pengfei Liub4734232020-01-17 18:25:10 +0800319 p_ctx->segment_info.size += len;
pengfei.liuab5a2262020-02-14 17:33:40 +0800320 /*Duration need use pcr to calculate, todo...*/
321 if (index_type == DVR_INDEX_TYPE_PCR) {
pengfei.liu8b563292020-02-26 15:49:02 +0800322 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
hualing chen87072a82020-03-12 16:20:12 +0800323 if (pre_time == 0)
324 pre_time = p_ctx->segment_info.duration;
pengfei.liuab5a2262020-02-14 17:33:40 +0800325 } else if (index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
326 clock_gettime(CLOCK_MONOTONIC, &end_ts);
327 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
328 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000);
hualing chen87072a82020-03-12 16:20:12 +0800329 if (pre_time == 0)
330 pre_time = p_ctx->segment_info.duration;
pengfei.liuab5a2262020-02-14 17:33:40 +0800331 segment_update_pts(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
332 } else {
333 DVR_DEBUG(1, "%s can NOT do time index", __func__);
334 }
335 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
Pengfei Liub4734232020-01-17 18:25:10 +0800336
hualing chen87072a82020-03-12 16:20:12 +0800337 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
338 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
hualing chenf9867402020-09-23 17:06:20 +0800339 segment_store_info(p_ctx->segment_handle, &(p_ctx->segment_info));
hualing chen87072a82020-03-12 16:20:12 +0800340 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800341 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800342 /*Event notification*/
Pengfei Liub4734232020-01-17 18:25:10 +0800343 if (p_ctx->notification_size &&
344 p_ctx->event_notify_fn &&
hualing chen2615aa82020-04-02 21:32:51 +0800345 /*!(p_ctx->segment_info.size % p_ctx->notification_size)*/
346 (p_ctx->segment_info.size -p_ctx->last_send_size) >= p_ctx->notification_size&&
pengfei.liuab5a2262020-02-14 17:33:40 +0800347 p_ctx->segment_info.duration > 0) {
Pengfei Liub4734232020-01-17 18:25:10 +0800348 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800349 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800350 p_ctx->last_send_size = p_ctx->segment_info.size;
Pengfei Liub4734232020-01-17 18:25:10 +0800351 record_status.state = p_ctx->state;
352 record_status.info.id = p_ctx->segment_info.id;
pengfei.liuab5a2262020-02-14 17:33:40 +0800353 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800354 record_status.info.size = p_ctx->segment_info.size;
355 record_status.info.nb_packets = p_ctx->segment_info.size/188;
356 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4fe3bee2020-10-23 13:58:52 +0800357 DVR_DEBUG(1, "%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu loc[%s]",
358 __func__, record_status.state,
359 record_status.info.id, record_status.info.duration,
360 record_status.info.size, p_ctx->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800361 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800362 gettimeofday(&t7, NULL);
363#ifdef DEBUG_PERFORMANCE
hualing chen2932d372020-04-29 13:44:00 +0800364 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 +0800365 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 +0800366 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len);
pengfei.liu567d6d82020-04-17 16:48:59 +0800367#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800368 }
hualing chen626204e2020-04-07 11:55:08 +0800369end:
Pengfei Liub4734232020-01-17 18:25:10 +0800370 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800371 free((void *)buf_out);
Pengfei Liub4734232020-01-17 18:25:10 +0800372 DVR_DEBUG(1, "exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800373 return NULL;
374}
375
376int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
377{
378 DVR_RecordContext_t *p_ctx;
379 Record_DeviceOpenParams_t dev_open_params;
380 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800381 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800382
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800383 DVR_RETURN_IF_FALSE(p_handle);
384 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800385
386 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800387 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800388 break;
389 }
390 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800391 DVR_RETURN_IF_FALSE(i < MAX_DVR_RECORD_SESSION_COUNT);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800392 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800393 p_ctx = &record_ctx[i];
hualing chenfbf8e022020-06-15 13:43:11 +0800394 DVR_DEBUG(1, "%s , current state:%d, dmx_id:%d, notification_size:%zu ", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800395 p_ctx->state, params->dmx_dev_id, params->notification_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800396
Pengfei Liub4734232020-01-17 18:25:10 +0800397 /*Process event params*/
398 p_ctx->notification_size = params->notification_size;
399 p_ctx->event_notify_fn = params->event_fn;
400 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800401 p_ctx->last_send_size = 0;
hualing chenf9867402020-09-23 17:06:20 +0800402 //check is new driver
403 p_ctx->is_new_dmx = dvr_check_dmx_isNew();
Pengfei Liub4734232020-01-17 18:25:10 +0800404 /*Process crypto params, todo*/
Pengfei Liub4734232020-01-17 18:25:10 +0800405 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800406 if (params->data_from_memory) {
407 /* data from memory, VOD case */
408 p_ctx->is_vod = 1;
409 } else {
410 p_ctx->is_vod = 0;
411 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800412 dev_open_params.dmx_dev_id = params->dmx_dev_id;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800413 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
Pengfei Liub4734232020-01-17 18:25:10 +0800414
pengfei.liuab5a2262020-02-14 17:33:40 +0800415 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
416 if (ret != DVR_SUCCESS) {
417 DVR_DEBUG(1, "%s, open record devices failed", __func__);
418 return DVR_FAILURE;
419 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800420 }
421
pengfei.liufda2a972020-04-09 14:47:15 +0800422 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800423 p_ctx->enc_func = NULL;
424 p_ctx->enc_userdata = NULL;
425 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800426 p_ctx->state = DVR_RECORD_STATE_OPENED;
427
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800428 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800429 return DVR_SUCCESS;
430}
431
432int dvr_record_close(DVR_RecordHandle_t handle)
433{
434 DVR_RecordContext_t *p_ctx;
435 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800436 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800437
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800438 p_ctx = (DVR_RecordContext_t *)handle;
439 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
440 if (p_ctx == &record_ctx[i])
441 break;
442 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800443 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800444
Pengfei Liub4734232020-01-17 18:25:10 +0800445 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800446 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800447
pengfei.liuab5a2262020-02-14 17:33:40 +0800448 if (p_ctx->is_vod) {
449 ret = DVR_SUCCESS;
450 } else {
451 ret = record_device_close(p_ctx->dev_handle);
452 if (ret != DVR_SUCCESS) {
453 DVR_DEBUG(1, "%s, failed", __func__);
454 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800455 }
456
Pengfei Liub4734232020-01-17 18:25:10 +0800457 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800458 return ret;
459}
460
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800461#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800462int dvr_record_register_encryption(DVR_RecordHandle_t handle,
463 DVR_CryptoFunction_t cb,
464 DVR_CryptoParams_t params,
465 void *userdata)
466{
467 return DVR_SUCCESS;
468}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800469#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800470
471int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
472{
473 DVR_RecordContext_t *p_ctx;
474 Segment_OpenParams_t open_params;
475 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800476 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800477
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800478 p_ctx = (DVR_RecordContext_t *)handle;
479 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
480 if (p_ctx == &record_ctx[i])
481 break;
482 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800483 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800484
hualing chen4fe3bee2020-10-23 13:58:52 +0800485 DVR_DEBUG(1, "%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 +0800486 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
487 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
488 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800489
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800490 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800491 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800492 memcpy(open_params.location, params->location, sizeof(params->location));
Pengfei Liuc181a982020-01-07 19:27:13 +0800493 open_params.segment_id = params->segment.segment_id;
494 open_params.mode = SEGMENT_MODE_WRITE;
495
496 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800497 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800498
Pengfei Liub4734232020-01-17 18:25:10 +0800499 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800500 {
hualing chen7a56cba2020-04-14 14:09:27 +0800501 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800502 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800503 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800504 /*save current segment info*/
505 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
506 p_ctx->segment_info.id = params->segment.segment_id;
507 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
508 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800509 }
510
pengfei.liuab5a2262020-02-14 17:33:40 +0800511 if (!p_ctx->is_vod) {
512 /* normal dvr case */
513 for (i = 0; i < params->segment.nb_pids; i++) {
514 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
515 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
516 }
517 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800518 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800519 }
520
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800521 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
522
Pengfei Liuc181a982020-01-07 19:27:13 +0800523 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800524 if (!p_ctx->is_vod)
525 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800526
Pengfei Liuc181a982020-01-07 19:27:13 +0800527 return DVR_SUCCESS;
528}
529
530int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
531{
532 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800533 Segment_OpenParams_t open_params;
Pengfei Liuc181a982020-01-07 19:27:13 +0800534 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800535 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800536 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800537
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800538 p_ctx = (DVR_RecordContext_t *)handle;
539 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
540 if (p_ctx == &record_ctx[i])
541 break;
542 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800543 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800544
hualing chen4fe3bee2020-10-23 13:58:52 +0800545 DVR_DEBUG(1, "%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800546 DVR_RETURN_IF_FALSE(p_ctx->state == DVR_RECORD_STATE_STARTED);
547 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
548 DVR_RETURN_IF_FALSE(params);
549 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800550 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800551
552 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800553 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800554 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800555 p_ctx->state = DVR_RECORD_STATE_STOPPED;
556 pthread_join(p_ctx->thread, NULL);
557
hualing chen2932d372020-04-29 13:44:00 +0800558 //add index file store
559 pos = segment_tell_position(p_ctx->segment_handle);
560 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
561
562 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liub4734232020-01-17 18:25:10 +0800563 /*Update segment info*/
564 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
565
566 ret = segment_store_info(p_ctx->segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800567 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800568
hualing chena540a7e2020-03-27 16:44:05 +0800569 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",
570 __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 +0800571
Pengfei Liub4734232020-01-17 18:25:10 +0800572 /*Close current segment*/
573 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800574 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800575 /*Open the new record segment*/
576 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800577 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800578 open_params.segment_id = params->segment.segment_id;
579 open_params.mode = SEGMENT_MODE_WRITE;
hualing chen7a56cba2020-04-14 14:09:27 +0800580 DVR_DEBUG(1, "%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800581
582 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800583 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800584 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800585 {
Pengfei Liub4734232020-01-17 18:25:10 +0800586 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800587 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800588 /*save current segment info*/
589 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
590 p_ctx->segment_info.id = params->segment.segment_id;
591 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800592 }
593
Pengfei Liub4734232020-01-17 18:25:10 +0800594 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800595 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800596 switch (params->segment.pid_action[i]) {
597 case DVR_RECORD_PID_CREATE:
598 DVR_DEBUG(1, "%s create pid:%d", __func__, params->segment.pids[i].pid);
599 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
600 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800601 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800602 break;
603 case DVR_RECORD_PID_KEEP:
604 DVR_DEBUG(1, "%s keep pid:%d", __func__, params->segment.pids[i].pid);
605 p_ctx->segment_info.nb_pids++;
606 break;
607 case DVR_RECORD_PID_CLOSE:
608 DVR_DEBUG(1, "%s close pid:%d", __func__, params->segment.pids[i].pid);
609 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800610 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800611 break;
612 default:
613 DVR_DEBUG(1, "%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
614 return DVR_FAILURE;
615 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800616 }
617
Pengfei Liub4734232020-01-17 18:25:10 +0800618 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800619 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen4b7c15d2020-04-07 16:13:48 +0800620 /*Update segment info*/
621 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
Pengfei Liuc181a982020-01-07 19:27:13 +0800622
Pengfei Liuc181a982020-01-07 19:27:13 +0800623 p_ctx->state = DVR_RECORD_STATE_STARTED;
Zhiqiang Han0d60f2b2020-05-26 14:39:54 +0800624 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800625 return DVR_SUCCESS;
626}
627
628int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
629{
630 DVR_RecordContext_t *p_ctx;
631 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800632 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800633 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800634
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800635 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 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800640 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800641
hualing chen4fe3bee2020-10-23 13:58:52 +0800642 DVR_DEBUG(1, "%s , current state:%d p_ctx->location:%s", __func__, p_ctx->state, p_ctx->location);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800643 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STOPPED);
644 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +0800645 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800646
Pengfei Liuc181a982020-01-07 19:27:13 +0800647 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800648 if (p_ctx->is_vod) {
pengfei.liu8b563292020-02-26 15:49:02 +0800649 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
pengfei.liuab5a2262020-02-14 17:33:40 +0800650 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
651 } else {
652 ret = record_device_stop(p_ctx->dev_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800653 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
654 if (ret != DVR_SUCCESS)
655 goto end;
pengfei.liuab5a2262020-02-14 17:33:40 +0800656 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
657 pthread_join(p_ctx->thread, NULL);
658 }
659
hualing chen2932d372020-04-29 13:44:00 +0800660 //add index file store
661 pos = segment_tell_position(p_ctx->segment_handle);
662 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
hualing chene41f4372020-06-06 16:29:17 +0800663 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800664
Pengfei Liub4734232020-01-17 18:25:10 +0800665 /*Update segment info*/
666 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
667
668 ret = segment_store_info(p_ctx->segment_handle, p_info);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800669 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
670 if (ret != DVR_SUCCESS)
671 goto end;
Pengfei Liub4734232020-01-17 18:25:10 +0800672
673 DVR_DEBUG(1, "%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
674 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
675
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800676end:
Pengfei Liuc181a982020-01-07 19:27:13 +0800677 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800678 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800679 return DVR_SUCCESS;
680}
Pengfei Liuc181a982020-01-07 19:27:13 +0800681
Pengfei Liub4734232020-01-17 18:25:10 +0800682int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
683{
684 DVR_RecordContext_t *p_ctx;
685 uint32_t i;
pengfei.liuab5a2262020-02-14 17:33:40 +0800686 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800687
688 p_ctx = (DVR_RecordContext_t *)handle;
689 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
690 if (p_ctx == &record_ctx[i])
691 break;
Pengfei Liuc181a982020-01-07 19:27:13 +0800692 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800693 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
694 DVR_RETURN_IF_FALSE(params);
695 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800696
pengfei.liuab5a2262020-02-14 17:33:40 +0800697 DVR_DEBUG(1, "%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
698 ret = dvr_record_start_segment(handle, params);
699 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
700
701 p_ctx->segment_info.size = *p_resume_size;
702
703 return DVR_SUCCESS;
704}
705
706int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
707{
708 DVR_RecordContext_t *p_ctx;
709 int i;
710
711 p_ctx = (DVR_RecordContext_t *)handle;
712 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
713 if (p_ctx == &record_ctx[i])
714 break;
715 }
716 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
717 DVR_RETURN_IF_FALSE(p_status);
718
719 //lock
720 p_status->state = p_ctx->state;
721 p_status->info.id = p_ctx->segment_info.id;
722 p_status->info.duration = p_ctx->segment_info.duration;
723 p_status->info.size = p_ctx->segment_info.size;
724 p_status->info.nb_packets = p_ctx->segment_info.size/188;
725
726 return DVR_SUCCESS;
727}
728
729int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
730{
731 DVR_RecordContext_t *p_ctx;
732 uint32_t i;
733 off_t pos = 0;
734 int ret;
735 int has_pcr;
736
737 p_ctx = (DVR_RecordContext_t *)handle;
738 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
739 if (p_ctx == &record_ctx[i])
740 break;
741 }
742 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
743 DVR_RETURN_IF_FALSE(buffer);
744 DVR_RETURN_IF_FALSE(len);
745
746 pos = segment_tell_position(p_ctx->segment_handle);
747 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
748 if (has_pcr == 0) {
749 /* Pull VOD record shoud use PCR time index */
750 DVR_DEBUG(1, "%s has no pcr, can NOT do time index", __func__);
751 }
752 ret = segment_write(p_ctx->segment_handle, buffer, len);
hualing chen2932d372020-04-29 13:44:00 +0800753 if (ret != len) {
754 DVR_DEBUG(1, "%s write error ret:%d len:%d", __func__, ret, len);
755 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800756 p_ctx->segment_info.size += len;
757 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
758
Pengfei Liuc181a982020-01-07 19:27:13 +0800759 return DVR_SUCCESS;
760}
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800761
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800762int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800763{
764 DVR_RecordContext_t *p_ctx;
765 uint32_t i;
766
767 p_ctx = (DVR_RecordContext_t *)handle;
768 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
769 if (p_ctx == &record_ctx[i])
770 break;
771 }
772 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
773 DVR_RETURN_IF_FALSE(func);
774
775 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
776 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
777 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
778
779 p_ctx->enc_func = func;
780 p_ctx->enc_userdata = userdata;
781 return DVR_SUCCESS;
782}
783
784int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
785{
786 DVR_RecordContext_t *p_ctx;
787 uint32_t i;
788 int ret;
789
790 p_ctx = (DVR_RecordContext_t *)handle;
791 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
792 if (p_ctx == &record_ctx[i])
793 break;
794 }
795 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
796 DVR_RETURN_IF_FALSE(p_secure_buf);
797 DVR_RETURN_IF_FALSE(len);
798
799 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
800 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
801 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
802
803 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
804 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
805
806 p_ctx->is_secure_mode = 1;
807 return ret;
808}
hualing chen4fe3bee2020-10-23 13:58:52 +0800809
810int dvr_record_is_secure_mode(DVR_RecordHandle_t handle)
811{
812 DVR_RecordContext_t *p_ctx;
813 uint32_t i;
814 int ret;
815
816 p_ctx = (DVR_RecordContext_t *)handle;
817 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
818 if (p_ctx == &record_ctx[i])
819 break;
820 }
821 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
822
823 if (p_ctx->is_secure_mode == 1)
824 ret = 1;
825 else
826 ret = 0;
827 return ret;
828}