blob: 9f6d02df5ac9e59612d291a9d1911bac812fab7d [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 chenc7aa4c82021-02-03 15:41:37 +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)
Yahui Hance15e9c2020-12-08 18:08:32 +080016#define NEW_DEVICE_RECORD_BLOCK_SIZE (1024 * 188)
pengfei.liuab5a2262020-02-14 17:33:40 +080017
18/**\brief DVR index file type*/
19typedef enum {
20 DVR_INDEX_TYPE_PCR, /**< DVR index file use pcr*/
21 DVR_INDEX_TYPE_LOCAL_CLOCK, /**< DVR index file use local clock*/
22 DVR_INDEX_TYPE_INVALID /**< DVR index file type invalid type*/
23} DVR_IndexType_t;
24
25/**\brief DVR VOD context*/
26typedef struct {
27 pthread_mutex_t mutex; /**< VOD mutex lock*/
28 pthread_cond_t cond; /**< VOD condition*/
29 void *buffer; /**< VOD buffer*/
30 uint32_t buf_len; /**< VOD buffer len*/
31} DVR_VodContext_t;
32
pengfei.liu07ddc8a2020-03-24 23:36:53 +080033/**\brief DVR record secure mode buffer*/
34typedef struct {
35 uint32_t addr; /**< Secure mode record buffer address*/
36 uint32_t len; /**< Secure mode record buffer length*/
37} DVR_SecureBuffer_t;
38
hualing chenf9867402020-09-23 17:06:20 +080039/**\brief DVR record new dmx secure mode buffer*/
40typedef struct {
41 uint32_t buf_start; /**< Secure mode record buffer address*/
42 uint32_t buf_end; /**< Secure mode record buffer length*/
43 uint32_t data_start; /**< Secure mode record buffer address*/
44 uint32_t data_end; /**< Secure mode record buffer length*/
45} DVR_NewDmxSecureBuffer_t;
46
Pengfei Liub4734232020-01-17 18:25:10 +080047/**\brief DVR record context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080048typedef struct {
Pengfei Liub4734232020-01-17 18:25:10 +080049 pthread_t thread; /**< DVR thread handle*/
50 Record_DeviceHandle_t dev_handle; /**< DVR device handle*/
51 Segment_Handle_t segment_handle; /**< DVR segment handle*/
52 DVR_RecordState_t state; /**< DVR record state*/
53 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
54 DVR_RecordSegmentStartParams_t segment_params; /**< DVR record start parameters*/
55 DVR_RecordSegmentInfo_t segment_info; /**< DVR record current segment info*/
56 size_t notification_size; /**< DVR record nogification size*/
57 DVR_RecordEventFunction_t event_notify_fn; /**< DVR record event notify function*/
58 void *event_userdata; /**< DVR record event userdata*/
pengfei.liuab5a2262020-02-14 17:33:40 +080059 //DVR_VodContext_t vod; /**< DVR record vod context*/
60 int is_vod; /**< Indicate current mode is VOD record mode*/
pengfei.liu27cc4ec2020-04-03 16:28:16 +080061 DVR_CryptoFunction_t enc_func; /**< Encrypt function*/
pengfei.liu07ddc8a2020-03-24 23:36:53 +080062 void *enc_userdata; /**< Encrypt userdata*/
63 int is_secure_mode; /**< Record session run in secure pipeline */
hualing chen2615aa82020-04-02 21:32:51 +080064 size_t last_send_size; /**< Last send notify segment size */
pengfei.liufda2a972020-04-09 14:47:15 +080065 uint32_t block_size; /**< DVR record block size */
hualing chenf9867402020-09-23 17:06:20 +080066 DVR_Bool_t is_new_dmx; /**< DVR is used new dmx driver */
Pengfei Liuc181a982020-01-07 19:27:13 +080067} DVR_RecordContext_t;
68
69static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
70 {
Pengfei Liub4734232020-01-17 18:25:10 +080071 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080072 },
73 {
Pengfei Liub4734232020-01-17 18:25:10 +080074 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080075 }
76};
77
Zhiqiang Han51646a02020-04-05 18:43:22 +080078static int record_is_valid_pid(DVR_RecordContext_t *p_ctx, int pid)
79{
80 int i;
81
82 for (i = 0; i < p_ctx->segment_info.nb_pids; i++) {
83 if (pid == p_ctx->segment_info.pids[i].pid)
84 return 1;
85 }
86 return 0;
87}
88
pengfei.liuab5a2262020-02-14 17:33:40 +080089static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
90{
91 uint8_t *p = buf;
92 int len;
93 uint8_t afc;
94 uint64_t pcr = 0;
95 int has_pcr = 0;
96 int pid;
97 int adp_field_len;
98
99 pid = ((p[1] & 0x1f) << 8) | p[2];
Zhiqiang Han51646a02020-04-05 18:43:22 +0800100 if (pid == 0x1fff || !record_is_valid_pid(p_ctx, pid))
pengfei.liuab5a2262020-02-14 17:33:40 +0800101 return has_pcr;
102
103 //scramble = p[3] >> 6;
104 //cc = p[3] & 0x0f;
105 afc = (p[3] >> 4) & 0x03;
106
107 p += 4;
108 len = 184;
109
110 if (afc & 2) {
111 adp_field_len = p[0];
112 /* Skip adaptation len */
113 p++;
114 len--;
115 /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
hualing chen5605eed2020-05-26 18:18:06 +0800116 if (p[0] & 0x10 && len >= 6 && adp_field_len >= 6) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800117 /* get pcr value,pcr is 33bit value */
118 pcr = (((uint64_t)(p[1])) << 25)
119 | (((uint64_t)p[2]) << 17)
120 | (((uint64_t)(p[3])) << 9)
121 | (((uint64_t)p[4]) << 1)
122 | ((((uint64_t)p[5]) & 0x80) >> 7);
123 has_pcr = 1;
124 }
125
126 p += adp_field_len;
127 len -= adp_field_len;
128
129 if (len < 0) {
130 DVR_DEBUG(1, "parser pcr: illegal adaptation field length");
131 return 0;
132 }
133 }
134
135 if (has_pcr) {
136 segment_update_pts(p_ctx->segment_handle, pcr/90, pos);
137 }
138 return has_pcr;
139}
140
141static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
142{
143 uint8_t *p = buf;
144 int left = len;
145 loff_t pos;
146 int has_pcr = 0;
147
148 pos = segment_tell_position(p_ctx->segment_handle);
149 while (left >= 188) {
150 if (*p == 0x47) {
151 has_pcr |= record_save_pcr(p_ctx, p, pos);
152 p += 188;
153 left -= 188;
154 pos += 188;
155 } else {
156 p++;
157 left --;
158 pos++;
159 }
160 }
161 return has_pcr;
162}
163
pengfei.liu567d6d82020-04-17 16:48:59 +0800164static int get_diff_time(struct timeval start_tv, struct timeval end_tv)
165{
166 return end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000 - start_tv.tv_sec * 1000 - start_tv.tv_usec / 1000;
167}
168
Pengfei Liuc181a982020-01-07 19:27:13 +0800169void *record_thread(void *arg)
170{
171 DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
172 ssize_t len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800173 uint8_t *buf, *buf_out;
pengfei.liufda2a972020-04-09 14:47:15 +0800174 uint32_t block_size = p_ctx->block_size;
pengfei.liuab5a2262020-02-14 17:33:40 +0800175 loff_t pos = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800176 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800177 struct timespec start_ts, end_ts;
178 DVR_RecordStatus_t record_status;
pengfei.liuab5a2262020-02-14 17:33:40 +0800179 int has_pcr;
180 int index_type = DVR_INDEX_TYPE_INVALID;
hualing chen87072a82020-03-12 16:20:12 +0800181 time_t pre_time = 0;
hualing chen2932d372020-04-29 13:44:00 +0800182 #define DVR_STORE_INFO_TIME (400)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800183 DVR_SecureBuffer_t secure_buf;
hualing chenf9867402020-09-23 17:06:20 +0800184 DVR_NewDmxSecureBuffer_t new_dmx_secure_buf;
Pengfei Liuc181a982020-01-07 19:27:13 +0800185
Pengfei Liub4734232020-01-17 18:25:10 +0800186 buf = (uint8_t *)malloc(block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800187 if (!buf) {
188 DVR_DEBUG(1, "%s, malloc failed", __func__);
189 return NULL;
190 }
191
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800192 buf_out = (uint8_t *)malloc(block_size + 188);
193 if (!buf_out) {
194 DVR_DEBUG(1, "%s, malloc failed", __func__);
Pengfei Liufaf38e42020-05-22 00:28:02 +0800195 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800196 return NULL;
197 }
198
hualing chen266b9502020-04-04 17:39:39 +0800199 memset(&record_status, 0, sizeof(record_status));
200 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800201 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800202 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800203 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +0800204 DVR_DEBUG(1, "%s line %d notify record status, state:%d id=%lld",
205 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800206 }
207 DVR_DEBUG(1, "%s, secure_mode:%d, block_size:%d", __func__, p_ctx->is_secure_mode, block_size);
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) {
Yahui Hance15e9c2020-12-08 18:08:32 +0800217
218 /* We resolve the below invoke for dvbcore to be under safety status */
hualing chenf9867402020-09-23 17:06:20 +0800219 memset(&new_dmx_secure_buf, 0, sizeof(new_dmx_secure_buf));
Yahui Hance15e9c2020-12-08 18:08:32 +0800220 len = record_device_read(p_ctx->dev_handle, &new_dmx_secure_buf, sizeof(new_dmx_secure_buf), 10);
221 if (len == DVR_FAILURE) {
222 DVR_DEBUG(1, "handle[%#x] ret:%d\n", p_ctx->dev_handle, ret);
223 /*For the second recording, poll always failed which we should check
224 * dvbcore further. For now, Just ignore the fack poll fail, I think
225 * it won't influce anything. But we need adjust the poll timeout
226 * from 1000ms to 10ms.
227 */
228 //continue;
229 }
230
231 /* Read data from secure demux TA */
232 len = record_device_read_ext(p_ctx->dev_handle, &secure_buf.addr,
233 &secure_buf.len);
234
hualing chenf9867402020-09-23 17:06:20 +0800235 } else {
236 memset(&secure_buf, 0, sizeof(secure_buf));
237 len = record_device_read(p_ctx->dev_handle, &secure_buf, sizeof(secure_buf), 1000);
238 }
239 if (len != DVR_FAILURE) {
hualing chen4fe3bee2020-10-23 13:58:52 +0800240 //DVR_DEBUG(1, "%s, secure_buf:%#x, size:%#x", __func__, secure_buf.addr, secure_buf.len);
hualing chenf9867402020-09-23 17:06:20 +0800241 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800242 } else {
243 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
244 }
Pengfei Liub4734232020-01-17 18:25:10 +0800245 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800246 //usleep(10*1000);
hualing chen2932d372020-04-29 13:44:00 +0800247 DVR_DEBUG(1, "%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800248 continue;
249 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800250 gettimeofday(&t2, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800251
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800252 /* Got data from device, record it */
253 if (p_ctx->enc_func) {
254 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800255 DVR_CryptoParams_t crypto_params;
256
257 memset(&crypto_params, 0, sizeof(crypto_params));
258 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800259 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800260 crypto_params.segment_id = p_ctx->segment_info.id;
261 crypto_params.offset = p_ctx->segment_info.size;
262
263 if (p_ctx->is_secure_mode) {
264 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
Yahui Hance15e9c2020-12-08 18:08:32 +0800265#if 0
hualing chenf9867402020-09-23 17:06:20 +0800266 if (p_ctx->is_new_dmx) {
267 crypto_params.input_buffer.addr = new_dmx_secure_buf.data_start;
268 crypto_params.input_buffer.size = new_dmx_secure_buf.data_end - new_dmx_secure_buf.data_start;
Yahui Hance15e9c2020-12-08 18:08:32 +0800269 } else
270#endif
271 {
hualing chenf9867402020-09-23 17:06:20 +0800272 crypto_params.input_buffer.addr = secure_buf.addr;
273 crypto_params.input_buffer.size = secure_buf.len;
274 }
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800275 } else {
276 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
277 crypto_params.input_buffer.addr = (size_t)buf;
278 crypto_params.input_buffer.size = len;
279 }
280
281 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
282 crypto_params.output_buffer.addr = (size_t)buf_out;
283 crypto_params.output_buffer.size = block_size + 188;
hualing chen9811b212020-10-29 11:21:44 +0800284
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800285 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800286 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800287 /* Out buffer length may not equal in buffer length */
hualing chenf9867402020-09-23 17:06:20 +0800288 if (crypto_params.output_size > 0) {
289 ret = segment_write(p_ctx->segment_handle, buf_out, crypto_params.output_size);
290 len = crypto_params.output_size;
hualing chenbafc62d2020-11-02 15:44:05 +0800291 } else {
292 len = 0;
hualing chenf9867402020-09-23 17:06:20 +0800293 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800294 } else {
pengfei.liu567d6d82020-04-17 16:48:59 +0800295 gettimeofday(&t3, NULL);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800296 ret = segment_write(p_ctx->segment_handle, buf, len);
297 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800298 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800299 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800300 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800301 //send write event
hualing chen9b434f02020-06-10 15:06:54 +0800302 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800303 memset(&record_status, 0, sizeof(record_status));
hualing chen4fe3bee2020-10-23 13:58:52 +0800304 DVR_DEBUG(1, "%s:%d,send event write error", __func__,__LINE__);
hualing chen4b7c15d2020-04-07 16:13:48 +0800305 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
306 }
hualing chenc70a8df2020-05-12 19:23:11 +0800307 DVR_DEBUG(1, "%s,write error %d", __func__,__LINE__);
hualing chen626204e2020-04-07 11:55:08 +0800308 goto end;
309 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800310 /* Do time index */
311 uint8_t *index_buf = p_ctx->enc_func ? buf_out : buf;
pengfei.liuab5a2262020-02-14 17:33:40 +0800312 pos = segment_tell_position(p_ctx->segment_handle);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800313 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
pengfei.liuab5a2262020-02-14 17:33:40 +0800314 if (has_pcr == 0 && index_type == DVR_INDEX_TYPE_INVALID) {
315 clock_gettime(CLOCK_MONOTONIC, &end_ts);
316 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
317 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
318 /* PCR interval threshlod > 40 ms*/
319 DVR_DEBUG(1, "%s use local clock time index", __func__);
320 index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
321 }
322 } else if (has_pcr && index_type == DVR_INDEX_TYPE_INVALID){
323 DVR_DEBUG(1, "%s use pcr time index", __func__);
324 index_type = DVR_INDEX_TYPE_PCR;
Pengfei Liuc181a982020-01-07 19:27:13 +0800325 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800326 gettimeofday(&t5, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +0800327
328 /* Update segment info */
Pengfei Liub4734232020-01-17 18:25:10 +0800329 p_ctx->segment_info.size += len;
pengfei.liuab5a2262020-02-14 17:33:40 +0800330 /*Duration need use pcr to calculate, todo...*/
331 if (index_type == DVR_INDEX_TYPE_PCR) {
pengfei.liu8b563292020-02-26 15:49:02 +0800332 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
hualing chen87072a82020-03-12 16:20:12 +0800333 if (pre_time == 0)
334 pre_time = p_ctx->segment_info.duration;
pengfei.liuab5a2262020-02-14 17:33:40 +0800335 } else if (index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
336 clock_gettime(CLOCK_MONOTONIC, &end_ts);
337 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
338 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000);
hualing chen87072a82020-03-12 16:20:12 +0800339 if (pre_time == 0)
340 pre_time = p_ctx->segment_info.duration;
pengfei.liuab5a2262020-02-14 17:33:40 +0800341 segment_update_pts(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
342 } else {
343 DVR_DEBUG(1, "%s can NOT do time index", __func__);
344 }
345 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
Pengfei Liub4734232020-01-17 18:25:10 +0800346
hualing chen87072a82020-03-12 16:20:12 +0800347 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
348 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
hualing chenf9867402020-09-23 17:06:20 +0800349 segment_store_info(p_ctx->segment_handle, &(p_ctx->segment_info));
hualing chen87072a82020-03-12 16:20:12 +0800350 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800351 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800352 /*Event notification*/
Pengfei Liub4734232020-01-17 18:25:10 +0800353 if (p_ctx->notification_size &&
354 p_ctx->event_notify_fn &&
hualing chen2615aa82020-04-02 21:32:51 +0800355 /*!(p_ctx->segment_info.size % p_ctx->notification_size)*/
356 (p_ctx->segment_info.size -p_ctx->last_send_size) >= p_ctx->notification_size&&
pengfei.liuab5a2262020-02-14 17:33:40 +0800357 p_ctx->segment_info.duration > 0) {
Pengfei Liub4734232020-01-17 18:25:10 +0800358 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800359 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800360 p_ctx->last_send_size = p_ctx->segment_info.size;
Pengfei Liub4734232020-01-17 18:25:10 +0800361 record_status.state = p_ctx->state;
362 record_status.info.id = p_ctx->segment_info.id;
pengfei.liuab5a2262020-02-14 17:33:40 +0800363 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800364 record_status.info.size = p_ctx->segment_info.size;
365 record_status.info.nb_packets = p_ctx->segment_info.size/188;
366 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4fe3bee2020-10-23 13:58:52 +0800367 DVR_DEBUG(1, "%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu loc[%s]",
368 __func__, record_status.state,
369 record_status.info.id, record_status.info.duration,
370 record_status.info.size, p_ctx->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800371 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800372 gettimeofday(&t7, NULL);
373#ifdef DEBUG_PERFORMANCE
hualing chen2932d372020-04-29 13:44:00 +0800374 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 +0800375 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 +0800376 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len);
pengfei.liu567d6d82020-04-17 16:48:59 +0800377#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800378 }
hualing chen626204e2020-04-07 11:55:08 +0800379end:
Pengfei Liub4734232020-01-17 18:25:10 +0800380 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800381 free((void *)buf_out);
Pengfei Liub4734232020-01-17 18:25:10 +0800382 DVR_DEBUG(1, "exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800383 return NULL;
384}
385
386int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
387{
388 DVR_RecordContext_t *p_ctx;
389 Record_DeviceOpenParams_t dev_open_params;
390 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800391 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800392
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800393 DVR_RETURN_IF_FALSE(p_handle);
394 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800395
396 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800397 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800398 break;
399 }
400 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800401 DVR_RETURN_IF_FALSE(i < MAX_DVR_RECORD_SESSION_COUNT);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800402 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800403 p_ctx = &record_ctx[i];
hualing chenfbf8e022020-06-15 13:43:11 +0800404 DVR_DEBUG(1, "%s , current state:%d, dmx_id:%d, notification_size:%zu ", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800405 p_ctx->state, params->dmx_dev_id, params->notification_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800406
Pengfei Liub4734232020-01-17 18:25:10 +0800407 /*Process event params*/
408 p_ctx->notification_size = params->notification_size;
409 p_ctx->event_notify_fn = params->event_fn;
410 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800411 p_ctx->last_send_size = 0;
hualing chenf9867402020-09-23 17:06:20 +0800412 //check is new driver
413 p_ctx->is_new_dmx = dvr_check_dmx_isNew();
Pengfei Liub4734232020-01-17 18:25:10 +0800414 /*Process crypto params, todo*/
Pengfei Liub4734232020-01-17 18:25:10 +0800415 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800416 if (params->data_from_memory) {
417 /* data from memory, VOD case */
418 p_ctx->is_vod = 1;
419 } else {
420 p_ctx->is_vod = 0;
421 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800422 dev_open_params.dmx_dev_id = params->dmx_dev_id;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800423 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen9811b212020-10-29 11:21:44 +0800424 if (p_ctx->is_new_dmx)
hualing cheneceb37e2021-01-18 16:07:48 +0800425 dev_open_params.buf_size = NEW_DEVICE_RECORD_BLOCK_SIZE * 30;
pengfei.liuab5a2262020-02-14 17:33:40 +0800426 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
427 if (ret != DVR_SUCCESS) {
428 DVR_DEBUG(1, "%s, open record devices failed", __func__);
429 return DVR_FAILURE;
430 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800431 }
432
pengfei.liufda2a972020-04-09 14:47:15 +0800433 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen9811b212020-10-29 11:21:44 +0800434 if (p_ctx->is_new_dmx)
Yahui Hance15e9c2020-12-08 18:08:32 +0800435 p_ctx->block_size = NEW_DEVICE_RECORD_BLOCK_SIZE * 30;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800436 p_ctx->enc_func = NULL;
437 p_ctx->enc_userdata = NULL;
438 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800439 p_ctx->state = DVR_RECORD_STATE_OPENED;
hualing chen9811b212020-10-29 11:21:44 +0800440 DVR_DEBUG(1, "%s, block_size:%d is_new:%d", __func__, p_ctx->block_size, p_ctx->is_new_dmx);
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800441 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800442 return DVR_SUCCESS;
443}
444
445int dvr_record_close(DVR_RecordHandle_t handle)
446{
447 DVR_RecordContext_t *p_ctx;
448 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800449 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800450
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800451 p_ctx = (DVR_RecordContext_t *)handle;
452 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
453 if (p_ctx == &record_ctx[i])
454 break;
455 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800456 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800457
Pengfei Liub4734232020-01-17 18:25:10 +0800458 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800459 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800460
pengfei.liuab5a2262020-02-14 17:33:40 +0800461 if (p_ctx->is_vod) {
462 ret = DVR_SUCCESS;
463 } else {
464 ret = record_device_close(p_ctx->dev_handle);
465 if (ret != DVR_SUCCESS) {
466 DVR_DEBUG(1, "%s, failed", __func__);
467 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800468 }
469
Pengfei Liub4734232020-01-17 18:25:10 +0800470 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800471 return ret;
472}
473
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800474#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800475int dvr_record_register_encryption(DVR_RecordHandle_t handle,
476 DVR_CryptoFunction_t cb,
477 DVR_CryptoParams_t params,
478 void *userdata)
479{
480 return DVR_SUCCESS;
481}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800482#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800483
484int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
485{
486 DVR_RecordContext_t *p_ctx;
487 Segment_OpenParams_t open_params;
488 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800489 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800490
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800491 p_ctx = (DVR_RecordContext_t *)handle;
492 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
493 if (p_ctx == &record_ctx[i])
494 break;
495 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800496 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800497
hualing chen4fe3bee2020-10-23 13:58:52 +0800498 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 +0800499 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
500 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
501 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800502
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800503 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800504 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800505 memcpy(open_params.location, params->location, sizeof(params->location));
Pengfei Liuc181a982020-01-07 19:27:13 +0800506 open_params.segment_id = params->segment.segment_id;
507 open_params.mode = SEGMENT_MODE_WRITE;
508
509 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800510 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800511
Pengfei Liub4734232020-01-17 18:25:10 +0800512 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800513 {
hualing chen7a56cba2020-04-14 14:09:27 +0800514 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800515 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800516 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800517 /*save current segment info*/
518 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
519 p_ctx->segment_info.id = params->segment.segment_id;
520 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
521 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800522 }
523
pengfei.liuab5a2262020-02-14 17:33:40 +0800524 if (!p_ctx->is_vod) {
525 /* normal dvr case */
526 for (i = 0; i < params->segment.nb_pids; i++) {
527 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
528 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
529 }
530 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800531 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800532 }
533
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800534 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
535
Pengfei Liuc181a982020-01-07 19:27:13 +0800536 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800537 if (!p_ctx->is_vod)
538 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800539
Pengfei Liuc181a982020-01-07 19:27:13 +0800540 return DVR_SUCCESS;
541}
542
543int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
544{
545 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800546 Segment_OpenParams_t open_params;
Pengfei Liuc181a982020-01-07 19:27:13 +0800547 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800548 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800549 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800550
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800551 p_ctx = (DVR_RecordContext_t *)handle;
552 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
553 if (p_ctx == &record_ctx[i])
554 break;
555 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800556 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800557
hualing chen4fe3bee2020-10-23 13:58:52 +0800558 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 +0800559 DVR_RETURN_IF_FALSE(p_ctx->state == DVR_RECORD_STATE_STARTED);
560 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
561 DVR_RETURN_IF_FALSE(params);
562 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800563 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800564
565 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800566 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800567 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800568 p_ctx->state = DVR_RECORD_STATE_STOPPED;
569 pthread_join(p_ctx->thread, NULL);
570
hualing chen2932d372020-04-29 13:44:00 +0800571 //add index file store
572 pos = segment_tell_position(p_ctx->segment_handle);
573 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
574
575 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liub4734232020-01-17 18:25:10 +0800576 /*Update segment info*/
577 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
578
579 ret = segment_store_info(p_ctx->segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800580 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800581
hualing chena540a7e2020-03-27 16:44:05 +0800582 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",
583 __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 +0800584
Pengfei Liub4734232020-01-17 18:25:10 +0800585 /*Close current segment*/
586 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800587 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800588 /*Open the new record segment*/
589 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800590 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800591 open_params.segment_id = params->segment.segment_id;
592 open_params.mode = SEGMENT_MODE_WRITE;
hualing chen7a56cba2020-04-14 14:09:27 +0800593 DVR_DEBUG(1, "%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800594
595 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800596 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800597 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800598 {
Pengfei Liub4734232020-01-17 18:25:10 +0800599 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800600 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800601 /*save current segment info*/
602 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
603 p_ctx->segment_info.id = params->segment.segment_id;
604 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800605 }
606
Pengfei Liub4734232020-01-17 18:25:10 +0800607 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800608 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800609 switch (params->segment.pid_action[i]) {
610 case DVR_RECORD_PID_CREATE:
611 DVR_DEBUG(1, "%s create pid:%d", __func__, params->segment.pids[i].pid);
612 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
613 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800614 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800615 break;
616 case DVR_RECORD_PID_KEEP:
617 DVR_DEBUG(1, "%s keep pid:%d", __func__, params->segment.pids[i].pid);
618 p_ctx->segment_info.nb_pids++;
619 break;
620 case DVR_RECORD_PID_CLOSE:
621 DVR_DEBUG(1, "%s close pid:%d", __func__, params->segment.pids[i].pid);
622 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800623 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800624 break;
625 default:
626 DVR_DEBUG(1, "%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
627 return DVR_FAILURE;
628 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800629 }
630
Pengfei Liub4734232020-01-17 18:25:10 +0800631 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800632 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen4b7c15d2020-04-07 16:13:48 +0800633 /*Update segment info*/
634 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
Pengfei Liuc181a982020-01-07 19:27:13 +0800635
Pengfei Liuc181a982020-01-07 19:27:13 +0800636 p_ctx->state = DVR_RECORD_STATE_STARTED;
Zhiqiang Han0d60f2b2020-05-26 14:39:54 +0800637 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800638 return DVR_SUCCESS;
639}
640
641int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
642{
643 DVR_RecordContext_t *p_ctx;
644 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800645 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800646 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800647
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800648 p_ctx = (DVR_RecordContext_t *)handle;
649 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
650 if (p_ctx == &record_ctx[i])
651 break;
652 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800653 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800654
hualing chen4fe3bee2020-10-23 13:58:52 +0800655 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 +0800656 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STOPPED);
657 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +0800658 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800659
Pengfei Liuc181a982020-01-07 19:27:13 +0800660 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800661 if (p_ctx->is_vod) {
pengfei.liu8b563292020-02-26 15:49:02 +0800662 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
pengfei.liuab5a2262020-02-14 17:33:40 +0800663 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
664 } else {
665 ret = record_device_stop(p_ctx->dev_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800666 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
667 if (ret != DVR_SUCCESS)
668 goto end;
pengfei.liuab5a2262020-02-14 17:33:40 +0800669 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
670 pthread_join(p_ctx->thread, NULL);
671 }
672
hualing chen2932d372020-04-29 13:44:00 +0800673 //add index file store
674 pos = segment_tell_position(p_ctx->segment_handle);
675 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
hualing chene41f4372020-06-06 16:29:17 +0800676 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800677
Pengfei Liub4734232020-01-17 18:25:10 +0800678 /*Update segment info*/
679 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
680
681 ret = segment_store_info(p_ctx->segment_handle, p_info);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800682 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
683 if (ret != DVR_SUCCESS)
684 goto end;
Pengfei Liub4734232020-01-17 18:25:10 +0800685
686 DVR_DEBUG(1, "%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
687 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
688
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800689end:
Pengfei Liuc181a982020-01-07 19:27:13 +0800690 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800691 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800692 return DVR_SUCCESS;
693}
Pengfei Liuc181a982020-01-07 19:27:13 +0800694
Pengfei Liub4734232020-01-17 18:25:10 +0800695int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
696{
697 DVR_RecordContext_t *p_ctx;
698 uint32_t i;
pengfei.liuab5a2262020-02-14 17:33:40 +0800699 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800700
701 p_ctx = (DVR_RecordContext_t *)handle;
702 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
703 if (p_ctx == &record_ctx[i])
704 break;
Pengfei Liuc181a982020-01-07 19:27:13 +0800705 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800706 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
707 DVR_RETURN_IF_FALSE(params);
708 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800709
pengfei.liuab5a2262020-02-14 17:33:40 +0800710 DVR_DEBUG(1, "%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
711 ret = dvr_record_start_segment(handle, params);
712 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
713
714 p_ctx->segment_info.size = *p_resume_size;
715
716 return DVR_SUCCESS;
717}
718
719int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
720{
721 DVR_RecordContext_t *p_ctx;
722 int i;
723
724 p_ctx = (DVR_RecordContext_t *)handle;
725 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
726 if (p_ctx == &record_ctx[i])
727 break;
728 }
729 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
730 DVR_RETURN_IF_FALSE(p_status);
731
732 //lock
733 p_status->state = p_ctx->state;
734 p_status->info.id = p_ctx->segment_info.id;
735 p_status->info.duration = p_ctx->segment_info.duration;
736 p_status->info.size = p_ctx->segment_info.size;
737 p_status->info.nb_packets = p_ctx->segment_info.size/188;
738
739 return DVR_SUCCESS;
740}
741
742int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
743{
744 DVR_RecordContext_t *p_ctx;
745 uint32_t i;
746 off_t pos = 0;
747 int ret;
748 int has_pcr;
749
750 p_ctx = (DVR_RecordContext_t *)handle;
751 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
752 if (p_ctx == &record_ctx[i])
753 break;
754 }
755 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
756 DVR_RETURN_IF_FALSE(buffer);
757 DVR_RETURN_IF_FALSE(len);
758
759 pos = segment_tell_position(p_ctx->segment_handle);
760 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
761 if (has_pcr == 0) {
762 /* Pull VOD record shoud use PCR time index */
763 DVR_DEBUG(1, "%s has no pcr, can NOT do time index", __func__);
764 }
765 ret = segment_write(p_ctx->segment_handle, buffer, len);
hualing chen2932d372020-04-29 13:44:00 +0800766 if (ret != len) {
767 DVR_DEBUG(1, "%s write error ret:%d len:%d", __func__, ret, len);
768 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800769 p_ctx->segment_info.size += len;
770 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
771
Pengfei Liuc181a982020-01-07 19:27:13 +0800772 return DVR_SUCCESS;
773}
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800774
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800775int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800776{
777 DVR_RecordContext_t *p_ctx;
778 uint32_t i;
779
780 p_ctx = (DVR_RecordContext_t *)handle;
781 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
782 if (p_ctx == &record_ctx[i])
783 break;
784 }
785 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
786 DVR_RETURN_IF_FALSE(func);
787
788 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
789 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
790 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
791
792 p_ctx->enc_func = func;
793 p_ctx->enc_userdata = userdata;
794 return DVR_SUCCESS;
795}
796
797int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
798{
799 DVR_RecordContext_t *p_ctx;
800 uint32_t i;
801 int ret;
802
803 p_ctx = (DVR_RecordContext_t *)handle;
804 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
805 if (p_ctx == &record_ctx[i])
806 break;
807 }
808 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
809 DVR_RETURN_IF_FALSE(p_secure_buf);
810 DVR_RETURN_IF_FALSE(len);
811
812 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
813 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
814 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
815
816 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
817 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
818
819 p_ctx->is_secure_mode = 1;
820 return ret;
821}
hualing chen4fe3bee2020-10-23 13:58:52 +0800822
823int dvr_record_is_secure_mode(DVR_RecordHandle_t handle)
824{
825 DVR_RecordContext_t *p_ctx;
826 uint32_t i;
827 int ret;
828
829 p_ctx = (DVR_RecordContext_t *)handle;
830 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
831 if (p_ctx == &record_ctx[i])
832 break;
833 }
834 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
835
836 if (p_ctx->is_secure_mode == 1)
837 ret = 1;
838 else
839 ret = 0;
840 return ret;
Yahui Hance15e9c2020-12-08 18:08:32 +0800841}