blob: 79c44671a9cfc23970ab8fdc30721072686abc47 [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 */
hualing chen40accc32021-04-21 15:58:09 +080067 int index_type; /**< DVR is used pcr or local time */
Pengfei Liuc181a982020-01-07 19:27:13 +080068} DVR_RecordContext_t;
69
70static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
71 {
Pengfei Liub4734232020-01-17 18:25:10 +080072 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080073 },
74 {
Pengfei Liub4734232020-01-17 18:25:10 +080075 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080076 }
77};
78
Zhiqiang Han51646a02020-04-05 18:43:22 +080079static int record_is_valid_pid(DVR_RecordContext_t *p_ctx, int pid)
80{
81 int i;
82
83 for (i = 0; i < p_ctx->segment_info.nb_pids; i++) {
84 if (pid == p_ctx->segment_info.pids[i].pid)
85 return 1;
86 }
87 return 0;
88}
89
pengfei.liuab5a2262020-02-14 17:33:40 +080090static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
91{
92 uint8_t *p = buf;
93 int len;
94 uint8_t afc;
95 uint64_t pcr = 0;
96 int has_pcr = 0;
97 int pid;
98 int adp_field_len;
99
100 pid = ((p[1] & 0x1f) << 8) | p[2];
Zhiqiang Han51646a02020-04-05 18:43:22 +0800101 if (pid == 0x1fff || !record_is_valid_pid(p_ctx, pid))
pengfei.liuab5a2262020-02-14 17:33:40 +0800102 return has_pcr;
103
104 //scramble = p[3] >> 6;
105 //cc = p[3] & 0x0f;
106 afc = (p[3] >> 4) & 0x03;
107
108 p += 4;
109 len = 184;
110
111 if (afc & 2) {
112 adp_field_len = p[0];
113 /* Skip adaptation len */
114 p++;
115 len--;
116 /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
hualing chen5605eed2020-05-26 18:18:06 +0800117 if (p[0] & 0x10 && len >= 6 && adp_field_len >= 6) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800118 /* get pcr value,pcr is 33bit value */
119 pcr = (((uint64_t)(p[1])) << 25)
120 | (((uint64_t)p[2]) << 17)
121 | (((uint64_t)(p[3])) << 9)
122 | (((uint64_t)p[4]) << 1)
123 | ((((uint64_t)p[5]) & 0x80) >> 7);
124 has_pcr = 1;
125 }
126
127 p += adp_field_len;
128 len -= adp_field_len;
129
130 if (len < 0) {
131 DVR_DEBUG(1, "parser pcr: illegal adaptation field length");
132 return 0;
133 }
134 }
135
hualing chen40accc32021-04-21 15:58:09 +0800136 if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800137 segment_update_pts(p_ctx->segment_handle, pcr/90, pos);
138 }
139 return has_pcr;
140}
141
142static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
143{
144 uint8_t *p = buf;
145 int left = len;
146 loff_t pos;
147 int has_pcr = 0;
148
149 pos = segment_tell_position(p_ctx->segment_handle);
150 while (left >= 188) {
151 if (*p == 0x47) {
152 has_pcr |= record_save_pcr(p_ctx, p, pos);
153 p += 188;
154 left -= 188;
155 pos += 188;
156 } else {
157 p++;
158 left --;
159 pos++;
160 }
161 }
162 return has_pcr;
163}
164
pengfei.liu567d6d82020-04-17 16:48:59 +0800165static int get_diff_time(struct timeval start_tv, struct timeval end_tv)
166{
167 return end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000 - start_tv.tv_sec * 1000 - start_tv.tv_usec / 1000;
168}
169
Pengfei Liuc181a982020-01-07 19:27:13 +0800170void *record_thread(void *arg)
171{
172 DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
173 ssize_t len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800174 uint8_t *buf, *buf_out;
pengfei.liufda2a972020-04-09 14:47:15 +0800175 uint32_t block_size = p_ctx->block_size;
pengfei.liuab5a2262020-02-14 17:33:40 +0800176 loff_t pos = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800177 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800178 struct timespec start_ts, end_ts;
179 DVR_RecordStatus_t record_status;
pengfei.liuab5a2262020-02-14 17:33:40 +0800180 int has_pcr;
hualing chen40accc32021-04-21 15:58:09 +0800181
hualing chen87072a82020-03-12 16:20:12 +0800182 time_t pre_time = 0;
hualing chen2932d372020-04-29 13:44:00 +0800183 #define DVR_STORE_INFO_TIME (400)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800184 DVR_SecureBuffer_t secure_buf;
hualing chenf9867402020-09-23 17:06:20 +0800185 DVR_NewDmxSecureBuffer_t new_dmx_secure_buf;
hualing chen40accc32021-04-21 15:58:09 +0800186 p_ctx->index_type == DVR_INDEX_TYPE_INVALID;
Pengfei Liuc181a982020-01-07 19:27:13 +0800187
Pengfei Liub4734232020-01-17 18:25:10 +0800188 buf = (uint8_t *)malloc(block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800189 if (!buf) {
190 DVR_DEBUG(1, "%s, malloc failed", __func__);
191 return NULL;
192 }
193
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800194 buf_out = (uint8_t *)malloc(block_size + 188);
195 if (!buf_out) {
196 DVR_DEBUG(1, "%s, malloc failed", __func__);
Pengfei Liufaf38e42020-05-22 00:28:02 +0800197 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800198 return NULL;
199 }
200
hualing chen266b9502020-04-04 17:39:39 +0800201 memset(&record_status, 0, sizeof(record_status));
202 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800203 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800204 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800205 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +0800206 DVR_DEBUG(1, "%s line %d notify record status, state:%d id=%lld",
207 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800208 }
209 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 +0800210 clock_gettime(CLOCK_MONOTONIC, &start_ts);
pengfei.liu567d6d82020-04-17 16:48:59 +0800211
212 struct timeval t1, t2, t3, t4, t5, t6, t7;
Pengfei Liuc181a982020-01-07 19:27:13 +0800213 while (p_ctx->state == DVR_RECORD_STATE_STARTED) {
pengfei.liu567d6d82020-04-17 16:48:59 +0800214 gettimeofday(&t1, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800215
pengfei.liuab5a2262020-02-14 17:33:40 +0800216 /* data from dmx, normal dvr case */
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800217 if (p_ctx->is_secure_mode) {
hualing chenf9867402020-09-23 17:06:20 +0800218 if (p_ctx->is_new_dmx) {
Yahui Hance15e9c2020-12-08 18:08:32 +0800219
220 /* We resolve the below invoke for dvbcore to be under safety status */
hualing chenf9867402020-09-23 17:06:20 +0800221 memset(&new_dmx_secure_buf, 0, sizeof(new_dmx_secure_buf));
Yahui Hance15e9c2020-12-08 18:08:32 +0800222 len = record_device_read(p_ctx->dev_handle, &new_dmx_secure_buf, sizeof(new_dmx_secure_buf), 10);
223 if (len == DVR_FAILURE) {
224 DVR_DEBUG(1, "handle[%#x] ret:%d\n", p_ctx->dev_handle, ret);
225 /*For the second recording, poll always failed which we should check
226 * dvbcore further. For now, Just ignore the fack poll fail, I think
227 * it won't influce anything. But we need adjust the poll timeout
228 * from 1000ms to 10ms.
229 */
230 //continue;
231 }
232
233 /* Read data from secure demux TA */
234 len = record_device_read_ext(p_ctx->dev_handle, &secure_buf.addr,
235 &secure_buf.len);
236
hualing chenf9867402020-09-23 17:06:20 +0800237 } else {
238 memset(&secure_buf, 0, sizeof(secure_buf));
239 len = record_device_read(p_ctx->dev_handle, &secure_buf, sizeof(secure_buf), 1000);
240 }
241 if (len != DVR_FAILURE) {
hualing chen4fe3bee2020-10-23 13:58:52 +0800242 //DVR_DEBUG(1, "%s, secure_buf:%#x, size:%#x", __func__, secure_buf.addr, secure_buf.len);
hualing chenf9867402020-09-23 17:06:20 +0800243 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800244 } else {
245 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
246 }
Pengfei Liub4734232020-01-17 18:25:10 +0800247 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800248 //usleep(10*1000);
hualing chen2932d372020-04-29 13:44:00 +0800249 DVR_DEBUG(1, "%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800250 continue;
251 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800252 gettimeofday(&t2, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800253
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800254 /* Got data from device, record it */
255 if (p_ctx->enc_func) {
256 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800257 DVR_CryptoParams_t crypto_params;
258
259 memset(&crypto_params, 0, sizeof(crypto_params));
260 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800261 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800262 crypto_params.segment_id = p_ctx->segment_info.id;
263 crypto_params.offset = p_ctx->segment_info.size;
264
265 if (p_ctx->is_secure_mode) {
266 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
Yahui Hance15e9c2020-12-08 18:08:32 +0800267#if 0
hualing chenf9867402020-09-23 17:06:20 +0800268 if (p_ctx->is_new_dmx) {
269 crypto_params.input_buffer.addr = new_dmx_secure_buf.data_start;
270 crypto_params.input_buffer.size = new_dmx_secure_buf.data_end - new_dmx_secure_buf.data_start;
Yahui Hance15e9c2020-12-08 18:08:32 +0800271 } else
272#endif
273 {
hualing chenf9867402020-09-23 17:06:20 +0800274 crypto_params.input_buffer.addr = secure_buf.addr;
275 crypto_params.input_buffer.size = secure_buf.len;
276 }
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800277 } else {
278 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
279 crypto_params.input_buffer.addr = (size_t)buf;
280 crypto_params.input_buffer.size = len;
281 }
282
283 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
284 crypto_params.output_buffer.addr = (size_t)buf_out;
285 crypto_params.output_buffer.size = block_size + 188;
hualing chen9811b212020-10-29 11:21:44 +0800286
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800287 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800288 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800289 /* Out buffer length may not equal in buffer length */
hualing chenf9867402020-09-23 17:06:20 +0800290 if (crypto_params.output_size > 0) {
291 ret = segment_write(p_ctx->segment_handle, buf_out, crypto_params.output_size);
292 len = crypto_params.output_size;
hualing chenbafc62d2020-11-02 15:44:05 +0800293 } else {
294 len = 0;
hualing chenf9867402020-09-23 17:06:20 +0800295 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800296 } else {
pengfei.liu567d6d82020-04-17 16:48:59 +0800297 gettimeofday(&t3, NULL);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800298 ret = segment_write(p_ctx->segment_handle, buf, len);
299 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800300 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800301 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800302 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800303 //send write event
hualing chen9b434f02020-06-10 15:06:54 +0800304 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800305 memset(&record_status, 0, sizeof(record_status));
hualing chen4fe3bee2020-10-23 13:58:52 +0800306 DVR_DEBUG(1, "%s:%d,send event write error", __func__,__LINE__);
hualing chen4b7c15d2020-04-07 16:13:48 +0800307 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
308 }
hualing chenc70a8df2020-05-12 19:23:11 +0800309 DVR_DEBUG(1, "%s,write error %d", __func__,__LINE__);
hualing chen626204e2020-04-07 11:55:08 +0800310 goto end;
311 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800312 /* Do time index */
313 uint8_t *index_buf = p_ctx->enc_func ? buf_out : buf;
pengfei.liuab5a2262020-02-14 17:33:40 +0800314 pos = segment_tell_position(p_ctx->segment_handle);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800315 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
hualing chen40accc32021-04-21 15:58:09 +0800316 if (has_pcr == 0 && p_ctx->index_type == DVR_INDEX_TYPE_INVALID) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800317 clock_gettime(CLOCK_MONOTONIC, &end_ts);
318 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
319 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
320 /* PCR interval threshlod > 40 ms*/
321 DVR_DEBUG(1, "%s use local clock time index", __func__);
hualing chen40accc32021-04-21 15:58:09 +0800322 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
pengfei.liuab5a2262020-02-14 17:33:40 +0800323 }
hualing chen40accc32021-04-21 15:58:09 +0800324 } else if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_INVALID){
pengfei.liuab5a2262020-02-14 17:33:40 +0800325 DVR_DEBUG(1, "%s use pcr time index", __func__);
hualing chen40accc32021-04-21 15:58:09 +0800326 p_ctx->index_type = DVR_INDEX_TYPE_PCR;
Pengfei Liuc181a982020-01-07 19:27:13 +0800327 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800328 gettimeofday(&t5, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +0800329
330 /* Update segment info */
Pengfei Liub4734232020-01-17 18:25:10 +0800331 p_ctx->segment_info.size += len;
pengfei.liuab5a2262020-02-14 17:33:40 +0800332 /*Duration need use pcr to calculate, todo...*/
hualing chen40accc32021-04-21 15:58:09 +0800333 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
pengfei.liu8b563292020-02-26 15:49:02 +0800334 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
hualing chen87072a82020-03-12 16:20:12 +0800335 if (pre_time == 0)
336 pre_time = p_ctx->segment_info.duration;
hualing chen40accc32021-04-21 15:58:09 +0800337 } else if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800338 clock_gettime(CLOCK_MONOTONIC, &end_ts);
339 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
340 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000);
hualing chen87072a82020-03-12 16:20:12 +0800341 if (pre_time == 0)
342 pre_time = p_ctx->segment_info.duration;
pengfei.liuab5a2262020-02-14 17:33:40 +0800343 segment_update_pts(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
344 } else {
345 DVR_DEBUG(1, "%s can NOT do time index", __func__);
346 }
347 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
Pengfei Liub4734232020-01-17 18:25:10 +0800348
hualing chen87072a82020-03-12 16:20:12 +0800349 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
350 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
hualing chenf9867402020-09-23 17:06:20 +0800351 segment_store_info(p_ctx->segment_handle, &(p_ctx->segment_info));
hualing chen87072a82020-03-12 16:20:12 +0800352 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800353 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800354 /*Event notification*/
Pengfei Liub4734232020-01-17 18:25:10 +0800355 if (p_ctx->notification_size &&
356 p_ctx->event_notify_fn &&
hualing chen2615aa82020-04-02 21:32:51 +0800357 /*!(p_ctx->segment_info.size % p_ctx->notification_size)*/
358 (p_ctx->segment_info.size -p_ctx->last_send_size) >= p_ctx->notification_size&&
pengfei.liuab5a2262020-02-14 17:33:40 +0800359 p_ctx->segment_info.duration > 0) {
Pengfei Liub4734232020-01-17 18:25:10 +0800360 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800361 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800362 p_ctx->last_send_size = p_ctx->segment_info.size;
Pengfei Liub4734232020-01-17 18:25:10 +0800363 record_status.state = p_ctx->state;
364 record_status.info.id = p_ctx->segment_info.id;
pengfei.liuab5a2262020-02-14 17:33:40 +0800365 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800366 record_status.info.size = p_ctx->segment_info.size;
367 record_status.info.nb_packets = p_ctx->segment_info.size/188;
368 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4fe3bee2020-10-23 13:58:52 +0800369 DVR_DEBUG(1, "%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu loc[%s]",
370 __func__, record_status.state,
371 record_status.info.id, record_status.info.duration,
372 record_status.info.size, p_ctx->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800373 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800374 gettimeofday(&t7, NULL);
375#ifdef DEBUG_PERFORMANCE
hualing chen2932d372020-04-29 13:44:00 +0800376 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 +0800377 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 +0800378 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len);
pengfei.liu567d6d82020-04-17 16:48:59 +0800379#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800380 }
hualing chen626204e2020-04-07 11:55:08 +0800381end:
Pengfei Liub4734232020-01-17 18:25:10 +0800382 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800383 free((void *)buf_out);
Pengfei Liub4734232020-01-17 18:25:10 +0800384 DVR_DEBUG(1, "exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800385 return NULL;
386}
387
388int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
389{
390 DVR_RecordContext_t *p_ctx;
391 Record_DeviceOpenParams_t dev_open_params;
392 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800393 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800394
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800395 DVR_RETURN_IF_FALSE(p_handle);
396 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800397
398 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800399 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800400 break;
401 }
402 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800403 DVR_RETURN_IF_FALSE(i < MAX_DVR_RECORD_SESSION_COUNT);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800404 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800405 p_ctx = &record_ctx[i];
hualing chenfbf8e022020-06-15 13:43:11 +0800406 DVR_DEBUG(1, "%s , current state:%d, dmx_id:%d, notification_size:%zu ", __func__,
Pengfei Liub4734232020-01-17 18:25:10 +0800407 p_ctx->state, params->dmx_dev_id, params->notification_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800408
Pengfei Liub4734232020-01-17 18:25:10 +0800409 /*Process event params*/
410 p_ctx->notification_size = params->notification_size;
411 p_ctx->event_notify_fn = params->event_fn;
412 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800413 p_ctx->last_send_size = 0;
hualing chenf9867402020-09-23 17:06:20 +0800414 //check is new driver
415 p_ctx->is_new_dmx = dvr_check_dmx_isNew();
Pengfei Liub4734232020-01-17 18:25:10 +0800416 /*Process crypto params, todo*/
Pengfei Liub4734232020-01-17 18:25:10 +0800417 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800418 if (params->data_from_memory) {
419 /* data from memory, VOD case */
420 p_ctx->is_vod = 1;
421 } else {
422 p_ctx->is_vod = 0;
423 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800424 dev_open_params.dmx_dev_id = params->dmx_dev_id;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800425 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen9811b212020-10-29 11:21:44 +0800426 if (p_ctx->is_new_dmx)
hualing cheneceb37e2021-01-18 16:07:48 +0800427 dev_open_params.buf_size = NEW_DEVICE_RECORD_BLOCK_SIZE * 30;
pengfei.liuab5a2262020-02-14 17:33:40 +0800428 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
429 if (ret != DVR_SUCCESS) {
430 DVR_DEBUG(1, "%s, open record devices failed", __func__);
431 return DVR_FAILURE;
432 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800433 }
434
pengfei.liufda2a972020-04-09 14:47:15 +0800435 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen9811b212020-10-29 11:21:44 +0800436 if (p_ctx->is_new_dmx)
Yahui Hance15e9c2020-12-08 18:08:32 +0800437 p_ctx->block_size = NEW_DEVICE_RECORD_BLOCK_SIZE * 30;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800438 p_ctx->enc_func = NULL;
439 p_ctx->enc_userdata = NULL;
440 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800441 p_ctx->state = DVR_RECORD_STATE_OPENED;
hualing chen9811b212020-10-29 11:21:44 +0800442 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 +0800443 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800444 return DVR_SUCCESS;
445}
446
447int dvr_record_close(DVR_RecordHandle_t handle)
448{
449 DVR_RecordContext_t *p_ctx;
450 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800451 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800452
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800453 p_ctx = (DVR_RecordContext_t *)handle;
454 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
455 if (p_ctx == &record_ctx[i])
456 break;
457 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800458 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800459
Pengfei Liub4734232020-01-17 18:25:10 +0800460 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800461 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800462
pengfei.liuab5a2262020-02-14 17:33:40 +0800463 if (p_ctx->is_vod) {
464 ret = DVR_SUCCESS;
465 } else {
466 ret = record_device_close(p_ctx->dev_handle);
467 if (ret != DVR_SUCCESS) {
468 DVR_DEBUG(1, "%s, failed", __func__);
469 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800470 }
471
Pengfei Liub4734232020-01-17 18:25:10 +0800472 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800473 return ret;
474}
475
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800476#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800477int dvr_record_register_encryption(DVR_RecordHandle_t handle,
478 DVR_CryptoFunction_t cb,
479 DVR_CryptoParams_t params,
480 void *userdata)
481{
482 return DVR_SUCCESS;
483}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800484#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800485
486int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
487{
488 DVR_RecordContext_t *p_ctx;
489 Segment_OpenParams_t open_params;
490 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800491 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800492
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800493 p_ctx = (DVR_RecordContext_t *)handle;
494 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
495 if (p_ctx == &record_ctx[i])
496 break;
497 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800498 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800499
hualing chen4fe3bee2020-10-23 13:58:52 +0800500 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 +0800501 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
502 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
503 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800504
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800505 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800506 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800507 memcpy(open_params.location, params->location, sizeof(params->location));
Pengfei Liuc181a982020-01-07 19:27:13 +0800508 open_params.segment_id = params->segment.segment_id;
509 open_params.mode = SEGMENT_MODE_WRITE;
510
511 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800512 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800513
Pengfei Liub4734232020-01-17 18:25:10 +0800514 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800515 {
hualing chen7a56cba2020-04-14 14:09:27 +0800516 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800517 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800518 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800519 /*save current segment info*/
520 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
521 p_ctx->segment_info.id = params->segment.segment_id;
522 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
523 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800524 }
525
pengfei.liuab5a2262020-02-14 17:33:40 +0800526 if (!p_ctx->is_vod) {
527 /* normal dvr case */
528 for (i = 0; i < params->segment.nb_pids; i++) {
529 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
530 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
531 }
532 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800533 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800534 }
535
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800536 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
537
Pengfei Liuc181a982020-01-07 19:27:13 +0800538 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800539 if (!p_ctx->is_vod)
540 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800541
Pengfei Liuc181a982020-01-07 19:27:13 +0800542 return DVR_SUCCESS;
543}
544
545int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
546{
547 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800548 Segment_OpenParams_t open_params;
Pengfei Liuc181a982020-01-07 19:27:13 +0800549 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800550 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800551 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800552
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800553 p_ctx = (DVR_RecordContext_t *)handle;
554 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
555 if (p_ctx == &record_ctx[i])
556 break;
557 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800558 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800559
hualing chen4fe3bee2020-10-23 13:58:52 +0800560 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 +0800561 DVR_RETURN_IF_FALSE(p_ctx->state == DVR_RECORD_STATE_STARTED);
562 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
563 DVR_RETURN_IF_FALSE(params);
564 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800565 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800566
567 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800568 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800569 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800570 p_ctx->state = DVR_RECORD_STATE_STOPPED;
571 pthread_join(p_ctx->thread, NULL);
572
hualing chen2932d372020-04-29 13:44:00 +0800573 //add index file store
574 pos = segment_tell_position(p_ctx->segment_handle);
575 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
576
577 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liub4734232020-01-17 18:25:10 +0800578 /*Update segment info*/
579 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
580
581 ret = segment_store_info(p_ctx->segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800582 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800583
hualing chena540a7e2020-03-27 16:44:05 +0800584 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",
585 __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 +0800586
Pengfei Liub4734232020-01-17 18:25:10 +0800587 /*Close current segment*/
588 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800589 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800590 /*Open the new record segment*/
591 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800592 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800593 open_params.segment_id = params->segment.segment_id;
594 open_params.mode = SEGMENT_MODE_WRITE;
hualing chen7a56cba2020-04-14 14:09:27 +0800595 DVR_DEBUG(1, "%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800596
597 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800598 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800599 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800600 {
Pengfei Liub4734232020-01-17 18:25:10 +0800601 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800602 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800603 /*save current segment info*/
604 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
605 p_ctx->segment_info.id = params->segment.segment_id;
606 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800607 }
608
Pengfei Liub4734232020-01-17 18:25:10 +0800609 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800610 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800611 switch (params->segment.pid_action[i]) {
612 case DVR_RECORD_PID_CREATE:
613 DVR_DEBUG(1, "%s create pid:%d", __func__, params->segment.pids[i].pid);
614 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
615 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800616 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800617 break;
618 case DVR_RECORD_PID_KEEP:
619 DVR_DEBUG(1, "%s keep pid:%d", __func__, params->segment.pids[i].pid);
620 p_ctx->segment_info.nb_pids++;
621 break;
622 case DVR_RECORD_PID_CLOSE:
623 DVR_DEBUG(1, "%s close pid:%d", __func__, params->segment.pids[i].pid);
624 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800625 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800626 break;
627 default:
628 DVR_DEBUG(1, "%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
629 return DVR_FAILURE;
630 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800631 }
632
Pengfei Liub4734232020-01-17 18:25:10 +0800633 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800634 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen4b7c15d2020-04-07 16:13:48 +0800635 /*Update segment info*/
636 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
Pengfei Liuc181a982020-01-07 19:27:13 +0800637
Pengfei Liuc181a982020-01-07 19:27:13 +0800638 p_ctx->state = DVR_RECORD_STATE_STARTED;
Zhiqiang Han0d60f2b2020-05-26 14:39:54 +0800639 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800640 return DVR_SUCCESS;
641}
642
643int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
644{
645 DVR_RecordContext_t *p_ctx;
646 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800647 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800648 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800649
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800650 p_ctx = (DVR_RecordContext_t *)handle;
651 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
652 if (p_ctx == &record_ctx[i])
653 break;
654 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800655 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800656
hualing chen4fe3bee2020-10-23 13:58:52 +0800657 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 +0800658 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STOPPED);
659 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +0800660 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800661
Pengfei Liuc181a982020-01-07 19:27:13 +0800662 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800663 if (p_ctx->is_vod) {
pengfei.liu8b563292020-02-26 15:49:02 +0800664 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
pengfei.liuab5a2262020-02-14 17:33:40 +0800665 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
666 } else {
667 ret = record_device_stop(p_ctx->dev_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800668 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
669 if (ret != DVR_SUCCESS)
670 goto end;
pengfei.liuab5a2262020-02-14 17:33:40 +0800671 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
672 pthread_join(p_ctx->thread, NULL);
673 }
674
hualing chen2932d372020-04-29 13:44:00 +0800675 //add index file store
676 pos = segment_tell_position(p_ctx->segment_handle);
677 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
hualing chene41f4372020-06-06 16:29:17 +0800678 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800679
Pengfei Liub4734232020-01-17 18:25:10 +0800680 /*Update segment info*/
681 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
682
683 ret = segment_store_info(p_ctx->segment_handle, p_info);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800684 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
685 if (ret != DVR_SUCCESS)
686 goto end;
Pengfei Liub4734232020-01-17 18:25:10 +0800687
688 DVR_DEBUG(1, "%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
689 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
690
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800691end:
Pengfei Liuc181a982020-01-07 19:27:13 +0800692 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800693 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800694 return DVR_SUCCESS;
695}
Pengfei Liuc181a982020-01-07 19:27:13 +0800696
Pengfei Liub4734232020-01-17 18:25:10 +0800697int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
698{
699 DVR_RecordContext_t *p_ctx;
700 uint32_t i;
pengfei.liuab5a2262020-02-14 17:33:40 +0800701 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800702
703 p_ctx = (DVR_RecordContext_t *)handle;
704 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
705 if (p_ctx == &record_ctx[i])
706 break;
Pengfei Liuc181a982020-01-07 19:27:13 +0800707 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800708 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
709 DVR_RETURN_IF_FALSE(params);
710 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800711
pengfei.liuab5a2262020-02-14 17:33:40 +0800712 DVR_DEBUG(1, "%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
713 ret = dvr_record_start_segment(handle, params);
714 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
715
716 p_ctx->segment_info.size = *p_resume_size;
717
718 return DVR_SUCCESS;
719}
720
721int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
722{
723 DVR_RecordContext_t *p_ctx;
724 int i;
725
726 p_ctx = (DVR_RecordContext_t *)handle;
727 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
728 if (p_ctx == &record_ctx[i])
729 break;
730 }
731 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
732 DVR_RETURN_IF_FALSE(p_status);
733
734 //lock
735 p_status->state = p_ctx->state;
736 p_status->info.id = p_ctx->segment_info.id;
737 p_status->info.duration = p_ctx->segment_info.duration;
738 p_status->info.size = p_ctx->segment_info.size;
739 p_status->info.nb_packets = p_ctx->segment_info.size/188;
740
741 return DVR_SUCCESS;
742}
743
744int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
745{
746 DVR_RecordContext_t *p_ctx;
747 uint32_t i;
748 off_t pos = 0;
749 int ret;
750 int has_pcr;
751
752 p_ctx = (DVR_RecordContext_t *)handle;
753 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
754 if (p_ctx == &record_ctx[i])
755 break;
756 }
757 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
758 DVR_RETURN_IF_FALSE(buffer);
759 DVR_RETURN_IF_FALSE(len);
760
761 pos = segment_tell_position(p_ctx->segment_handle);
762 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
763 if (has_pcr == 0) {
764 /* Pull VOD record shoud use PCR time index */
765 DVR_DEBUG(1, "%s has no pcr, can NOT do time index", __func__);
766 }
767 ret = segment_write(p_ctx->segment_handle, buffer, len);
hualing chen2932d372020-04-29 13:44:00 +0800768 if (ret != len) {
769 DVR_DEBUG(1, "%s write error ret:%d len:%d", __func__, ret, len);
770 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800771 p_ctx->segment_info.size += len;
772 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
773
Pengfei Liuc181a982020-01-07 19:27:13 +0800774 return DVR_SUCCESS;
775}
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800776
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800777int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800778{
779 DVR_RecordContext_t *p_ctx;
780 uint32_t i;
781
782 p_ctx = (DVR_RecordContext_t *)handle;
783 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
784 if (p_ctx == &record_ctx[i])
785 break;
786 }
787 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
788 DVR_RETURN_IF_FALSE(func);
789
790 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
791 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
792 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
793
794 p_ctx->enc_func = func;
795 p_ctx->enc_userdata = userdata;
796 return DVR_SUCCESS;
797}
798
799int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
800{
801 DVR_RecordContext_t *p_ctx;
802 uint32_t i;
803 int ret;
804
805 p_ctx = (DVR_RecordContext_t *)handle;
806 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
807 if (p_ctx == &record_ctx[i])
808 break;
809 }
810 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
811 DVR_RETURN_IF_FALSE(p_secure_buf);
812 DVR_RETURN_IF_FALSE(len);
813
814 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
815 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
816 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
817
818 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
819 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
820
821 p_ctx->is_secure_mode = 1;
822 return ret;
823}
hualing chen4fe3bee2020-10-23 13:58:52 +0800824
825int dvr_record_is_secure_mode(DVR_RecordHandle_t handle)
826{
827 DVR_RecordContext_t *p_ctx;
828 uint32_t i;
829 int ret;
830
831 p_ctx = (DVR_RecordContext_t *)handle;
832 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
833 if (p_ctx == &record_ctx[i])
834 break;
835 }
836 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
837
838 if (p_ctx->is_secure_mode == 1)
839 ret = 1;
840 else
841 ret = 0;
842 return ret;
Yahui Hance15e9c2020-12-08 18:08:32 +0800843}