blob: b62b72904c382c2a4a059908f7570403db701603 [file] [log] [blame]
Pengfei Liuc181a982020-01-07 19:27:13 +08001#include <stdio.h>
Pengfei Liub4734232020-01-17 18:25:10 +08002#include <unistd.h>
3#include <stdlib.h>
Pengfei Liuc181a982020-01-07 19:27:13 +08004#include <pthread.h>
Pengfei Liub4734232020-01-17 18:25:10 +08005#include <string.h>
Pengfei Liu47ed6c92020-01-17 11:23:41 +08006#include "dvr_types.h"
Pengfei Liuc181a982020-01-07 19:27:13 +08007#include "dvr_record.h"
8#include "dvr_crypto.h"
Gong Ke2a0ebbe2021-05-25 15:22:50 +08009#include "dvb_utils.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080010#include "record_device.h"
11#include "segment.h"
pengfei.liu567d6d82020-04-17 16:48:59 +080012#include <sys/time.h>
Yahui Han1fbf3292021-11-08 18:17:19 +080013#include "am_crypt.h"
Pengfei Liuc181a982020-01-07 19:27:13 +080014
hualing chend241c7a2021-06-22 13:34:27 +080015#define CONTROL_SPEED_ENABLE 0
16
hualing chenc7aa4c82021-02-03 15:41:37 +080017//#define DEBUG_PERFORMANCE
Yahui Han10993892021-11-02 14:27:33 +080018#define MAX_DVR_RECORD_SESSION_COUNT 4
hualing chen266b9502020-04-04 17:39:39 +080019#define RECORD_BLOCK_SIZE (256 * 1024)
Yahui Hance15e9c2020-12-08 18:08:32 +080020#define NEW_DEVICE_RECORD_BLOCK_SIZE (1024 * 188)
pengfei.liuab5a2262020-02-14 17:33:40 +080021
22/**\brief DVR index file type*/
23typedef enum {
24 DVR_INDEX_TYPE_PCR, /**< DVR index file use pcr*/
25 DVR_INDEX_TYPE_LOCAL_CLOCK, /**< DVR index file use local clock*/
26 DVR_INDEX_TYPE_INVALID /**< DVR index file type invalid type*/
27} DVR_IndexType_t;
28
29/**\brief DVR VOD context*/
30typedef struct {
31 pthread_mutex_t mutex; /**< VOD mutex lock*/
32 pthread_cond_t cond; /**< VOD condition*/
33 void *buffer; /**< VOD buffer*/
34 uint32_t buf_len; /**< VOD buffer len*/
35} DVR_VodContext_t;
36
pengfei.liu07ddc8a2020-03-24 23:36:53 +080037/**\brief DVR record secure mode buffer*/
38typedef struct {
39 uint32_t addr; /**< Secure mode record buffer address*/
40 uint32_t len; /**< Secure mode record buffer length*/
41} DVR_SecureBuffer_t;
42
hualing chenf9867402020-09-23 17:06:20 +080043/**\brief DVR record new dmx secure mode buffer*/
44typedef struct {
45 uint32_t buf_start; /**< Secure mode record buffer address*/
46 uint32_t buf_end; /**< Secure mode record buffer length*/
47 uint32_t data_start; /**< Secure mode record buffer address*/
48 uint32_t data_end; /**< Secure mode record buffer length*/
49} DVR_NewDmxSecureBuffer_t;
50
Pengfei Liub4734232020-01-17 18:25:10 +080051/**\brief DVR record context*/
Pengfei Liuc181a982020-01-07 19:27:13 +080052typedef struct {
Pengfei Liub4734232020-01-17 18:25:10 +080053 pthread_t thread; /**< DVR thread handle*/
54 Record_DeviceHandle_t dev_handle; /**< DVR device handle*/
55 Segment_Handle_t segment_handle; /**< DVR segment handle*/
56 DVR_RecordState_t state; /**< DVR record state*/
57 char location[DVR_MAX_LOCATION_SIZE]; /**< DVR record file location*/
58 DVR_RecordSegmentStartParams_t segment_params; /**< DVR record start parameters*/
59 DVR_RecordSegmentInfo_t segment_info; /**< DVR record current segment info*/
60 size_t notification_size; /**< DVR record nogification size*/
61 DVR_RecordEventFunction_t event_notify_fn; /**< DVR record event notify function*/
62 void *event_userdata; /**< DVR record event userdata*/
pengfei.liuab5a2262020-02-14 17:33:40 +080063 //DVR_VodContext_t vod; /**< DVR record vod context*/
64 int is_vod; /**< Indicate current mode is VOD record mode*/
pengfei.liu27cc4ec2020-04-03 16:28:16 +080065 DVR_CryptoFunction_t enc_func; /**< Encrypt function*/
pengfei.liu07ddc8a2020-03-24 23:36:53 +080066 void *enc_userdata; /**< Encrypt userdata*/
67 int is_secure_mode; /**< Record session run in secure pipeline */
Yahui Han1fbf3292021-11-08 18:17:19 +080068 void *cryptor; /**< Cryptor for encrypted PVR on FTA.*/
hualing chen2615aa82020-04-02 21:32:51 +080069 size_t last_send_size; /**< Last send notify segment size */
pengfei.liufda2a972020-04-09 14:47:15 +080070 uint32_t block_size; /**< DVR record block size */
hualing chenf9867402020-09-23 17:06:20 +080071 DVR_Bool_t is_new_dmx; /**< DVR is used new dmx driver */
hualing chen40accc32021-04-21 15:58:09 +080072 int index_type; /**< DVR is used pcr or local time */
hualing chen94d8dd22021-12-29 15:13:43 +080073 uint64_t pts; /**< The newest pcr or local time */
Pengfei Liuc181a982020-01-07 19:27:13 +080074} DVR_RecordContext_t;
75
Gong Ke2a0ebbe2021-05-25 15:22:50 +080076extern ssize_t record_device_read_ext(Record_DeviceHandle_t handle, size_t *buf, size_t *len);
77
Pengfei Liuc181a982020-01-07 19:27:13 +080078static DVR_RecordContext_t record_ctx[MAX_DVR_RECORD_SESSION_COUNT] = {
79 {
Pengfei Liub4734232020-01-17 18:25:10 +080080 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080081 },
82 {
Pengfei Liub4734232020-01-17 18:25:10 +080083 .state = DVR_RECORD_STATE_CLOSED
Pengfei Liuc181a982020-01-07 19:27:13 +080084 }
85};
86
Zhiqiang Han51646a02020-04-05 18:43:22 +080087static int record_is_valid_pid(DVR_RecordContext_t *p_ctx, int pid)
88{
89 int i;
90
91 for (i = 0; i < p_ctx->segment_info.nb_pids; i++) {
92 if (pid == p_ctx->segment_info.pids[i].pid)
93 return 1;
94 }
95 return 0;
96}
97
pengfei.liuab5a2262020-02-14 17:33:40 +080098static int record_save_pcr(DVR_RecordContext_t *p_ctx, uint8_t *buf, loff_t pos)
99{
100 uint8_t *p = buf;
101 int len;
102 uint8_t afc;
103 uint64_t pcr = 0;
104 int has_pcr = 0;
105 int pid;
106 int adp_field_len;
107
108 pid = ((p[1] & 0x1f) << 8) | p[2];
Zhiqiang Han51646a02020-04-05 18:43:22 +0800109 if (pid == 0x1fff || !record_is_valid_pid(p_ctx, pid))
pengfei.liuab5a2262020-02-14 17:33:40 +0800110 return has_pcr;
111
112 //scramble = p[3] >> 6;
113 //cc = p[3] & 0x0f;
114 afc = (p[3] >> 4) & 0x03;
115
116 p += 4;
117 len = 184;
118
119 if (afc & 2) {
120 adp_field_len = p[0];
121 /* Skip adaptation len */
122 p++;
123 len--;
124 /* Parse pcr field, see 13818 spec table I-2-6,adaptation_field */
hualing chen5605eed2020-05-26 18:18:06 +0800125 if (p[0] & 0x10 && len >= 6 && adp_field_len >= 6) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800126 /* get pcr value,pcr is 33bit value */
127 pcr = (((uint64_t)(p[1])) << 25)
128 | (((uint64_t)p[2]) << 17)
129 | (((uint64_t)(p[3])) << 9)
130 | (((uint64_t)p[4]) << 1)
131 | ((((uint64_t)p[5]) & 0x80) >> 7);
132 has_pcr = 1;
133 }
134
135 p += adp_field_len;
136 len -= adp_field_len;
137
138 if (len < 0) {
139 DVR_DEBUG(1, "parser pcr: illegal adaptation field length");
140 return 0;
141 }
142 }
143
hualing chen40accc32021-04-21 15:58:09 +0800144 if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
hualing chen94d8dd22021-12-29 15:13:43 +0800145 //save newest pcr
146 p_ctx->pts = pcr/90;
pengfei.liuab5a2262020-02-14 17:33:40 +0800147 segment_update_pts(p_ctx->segment_handle, pcr/90, pos);
148 }
149 return has_pcr;
150}
151
152static int record_do_pcr_index(DVR_RecordContext_t *p_ctx, uint8_t *buf, int len)
153{
154 uint8_t *p = buf;
155 int left = len;
156 loff_t pos;
157 int has_pcr = 0;
158
159 pos = segment_tell_position(p_ctx->segment_handle);
hualing chena5f03222021-12-02 11:22:35 +0800160
pengfei.liuab5a2262020-02-14 17:33:40 +0800161 while (left >= 188) {
162 if (*p == 0x47) {
163 has_pcr |= record_save_pcr(p_ctx, p, pos);
164 p += 188;
165 left -= 188;
166 pos += 188;
167 } else {
168 p++;
169 left --;
170 pos++;
171 }
172 }
173 return has_pcr;
174}
175
pengfei.liu567d6d82020-04-17 16:48:59 +0800176static int get_diff_time(struct timeval start_tv, struct timeval end_tv)
177{
178 return end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000 - start_tv.tv_sec * 1000 - start_tv.tv_usec / 1000;
179}
180
Pengfei Liuc181a982020-01-07 19:27:13 +0800181void *record_thread(void *arg)
182{
183 DVR_RecordContext_t *p_ctx = (DVR_RecordContext_t *)arg;
184 ssize_t len;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800185 uint8_t *buf, *buf_out;
pengfei.liufda2a972020-04-09 14:47:15 +0800186 uint32_t block_size = p_ctx->block_size;
pengfei.liuab5a2262020-02-14 17:33:40 +0800187 loff_t pos = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800188 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800189 struct timespec start_ts, end_ts;
190 DVR_RecordStatus_t record_status;
pengfei.liuab5a2262020-02-14 17:33:40 +0800191 int has_pcr;
hualing chen40accc32021-04-21 15:58:09 +0800192
hualing chen87072a82020-03-12 16:20:12 +0800193 time_t pre_time = 0;
hualing chen2932d372020-04-29 13:44:00 +0800194 #define DVR_STORE_INFO_TIME (400)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800195 DVR_SecureBuffer_t secure_buf;
hualing chenf9867402020-09-23 17:06:20 +0800196 DVR_NewDmxSecureBuffer_t new_dmx_secure_buf;
hualing chena5f03222021-12-02 11:22:35 +0800197 int first_read = 0;
hualing chend241c7a2021-06-22 13:34:27 +0800198 if (CONTROL_SPEED_ENABLE == 0)
199 p_ctx->index_type = DVR_INDEX_TYPE_INVALID;
200 else
201 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
Pengfei Liuc181a982020-01-07 19:27:13 +0800202
Pengfei Liub4734232020-01-17 18:25:10 +0800203 buf = (uint8_t *)malloc(block_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800204 if (!buf) {
205 DVR_DEBUG(1, "%s, malloc failed", __func__);
206 return NULL;
207 }
208
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800209 buf_out = (uint8_t *)malloc(block_size + 188);
210 if (!buf_out) {
211 DVR_DEBUG(1, "%s, malloc failed", __func__);
Pengfei Liufaf38e42020-05-22 00:28:02 +0800212 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800213 return NULL;
214 }
215
hualing chen266b9502020-04-04 17:39:39 +0800216 memset(&record_status, 0, sizeof(record_status));
217 record_status.state = DVR_RECORD_STATE_STARTED;
pengfei.liufda2a972020-04-09 14:47:15 +0800218 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800219 record_status.info.id = p_ctx->segment_info.id;
pengfei.liufda2a972020-04-09 14:47:15 +0800220 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +0800221 DVR_DEBUG(1, "%s line %d notify record status, state:%d id=%lld",
222 __func__,__LINE__, record_status.state, p_ctx->segment_info.id);
pengfei.liufda2a972020-04-09 14:47:15 +0800223 }
Yahui Han1fbf3292021-11-08 18:17:19 +0800224 DVR_DEBUG(1, "%s, secure_mode:%d, block_size:%d, cryptor:%p",
225 __func__, p_ctx->is_secure_mode,
226 block_size, p_ctx->cryptor);
Pengfei Liub4734232020-01-17 18:25:10 +0800227 clock_gettime(CLOCK_MONOTONIC, &start_ts);
pengfei.liu567d6d82020-04-17 16:48:59 +0800228
229 struct timeval t1, t2, t3, t4, t5, t6, t7;
hualing chen03fd4942021-07-15 15:56:41 +0800230 while (p_ctx->state == DVR_RECORD_STATE_STARTED ||
231 p_ctx->state == DVR_RECORD_STATE_PAUSE) {
232
233 if (p_ctx->state == DVR_RECORD_STATE_PAUSE) {
234 //wait resume record
235 usleep(20*1000);
236 continue;
237 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800238 gettimeofday(&t1, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800239
pengfei.liuab5a2262020-02-14 17:33:40 +0800240 /* data from dmx, normal dvr case */
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800241 if (p_ctx->is_secure_mode) {
hualing chenf9867402020-09-23 17:06:20 +0800242 if (p_ctx->is_new_dmx) {
Yahui Hance15e9c2020-12-08 18:08:32 +0800243
244 /* We resolve the below invoke for dvbcore to be under safety status */
hualing chenf9867402020-09-23 17:06:20 +0800245 memset(&new_dmx_secure_buf, 0, sizeof(new_dmx_secure_buf));
Yahui Hance15e9c2020-12-08 18:08:32 +0800246 len = record_device_read(p_ctx->dev_handle, &new_dmx_secure_buf, sizeof(new_dmx_secure_buf), 10);
247 if (len == DVR_FAILURE) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800248 DVR_DEBUG(1, "handle[%p] ret:%d\n", p_ctx->dev_handle, ret);
Yahui Hance15e9c2020-12-08 18:08:32 +0800249 /*For the second recording, poll always failed which we should check
250 * dvbcore further. For now, Just ignore the fack poll fail, I think
251 * it won't influce anything. But we need adjust the poll timeout
252 * from 1000ms to 10ms.
253 */
254 //continue;
255 }
256
257 /* Read data from secure demux TA */
258 len = record_device_read_ext(p_ctx->dev_handle, &secure_buf.addr,
259 &secure_buf.len);
260
hualing chenf9867402020-09-23 17:06:20 +0800261 } else {
262 memset(&secure_buf, 0, sizeof(secure_buf));
263 len = record_device_read(p_ctx->dev_handle, &secure_buf, sizeof(secure_buf), 1000);
264 }
265 if (len != DVR_FAILURE) {
hualing chen4fe3bee2020-10-23 13:58:52 +0800266 //DVR_DEBUG(1, "%s, secure_buf:%#x, size:%#x", __func__, secure_buf.addr, secure_buf.len);
hualing chenf9867402020-09-23 17:06:20 +0800267 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800268 } else {
269 len = record_device_read(p_ctx->dev_handle, buf, block_size, 1000);
270 }
Pengfei Liub4734232020-01-17 18:25:10 +0800271 if (len == DVR_FAILURE) {
hualing chen6c126382020-04-13 15:47:51 +0800272 //usleep(10*1000);
hualing chen2932d372020-04-29 13:44:00 +0800273 DVR_DEBUG(1, "%s, start_read error", __func__);
Pengfei Liub4734232020-01-17 18:25:10 +0800274 continue;
275 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800276 gettimeofday(&t2, NULL);
hualing chenc70a8df2020-05-12 19:23:11 +0800277
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800278 /* Got data from device, record it */
Yahui Han1fbf3292021-11-08 18:17:19 +0800279 if (p_ctx->is_secure_mode && p_ctx->enc_func) {
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800280 /* Encrypt record data */
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800281 DVR_CryptoParams_t crypto_params;
282
283 memset(&crypto_params, 0, sizeof(crypto_params));
284 crypto_params.type = DVR_CRYPTO_TYPE_ENCRYPT;
hualing chen7a56cba2020-04-14 14:09:27 +0800285 memcpy(crypto_params.location, p_ctx->location, sizeof(p_ctx->location));
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800286 crypto_params.segment_id = p_ctx->segment_info.id;
287 crypto_params.offset = p_ctx->segment_info.size;
288
289 if (p_ctx->is_secure_mode) {
290 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_SECURE;
Yahui Han1fbf3292021-11-08 18:17:19 +0800291 crypto_params.input_buffer.addr = secure_buf.addr;
292 crypto_params.input_buffer.size = secure_buf.len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800293 } else {
294 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
295 crypto_params.input_buffer.addr = (size_t)buf;
296 crypto_params.input_buffer.size = len;
297 }
298
299 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
300 crypto_params.output_buffer.addr = (size_t)buf_out;
301 crypto_params.output_buffer.size = block_size + 188;
hualing chen9811b212020-10-29 11:21:44 +0800302
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800303 p_ctx->enc_func(&crypto_params, p_ctx->enc_userdata);
pengfei.liu567d6d82020-04-17 16:48:59 +0800304 gettimeofday(&t3, NULL);
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800305 /* Out buffer length may not equal in buffer length */
hualing chenf9867402020-09-23 17:06:20 +0800306 if (crypto_params.output_size > 0) {
307 ret = segment_write(p_ctx->segment_handle, buf_out, crypto_params.output_size);
308 len = crypto_params.output_size;
hualing chenbafc62d2020-11-02 15:44:05 +0800309 } else {
310 len = 0;
hualing chenf9867402020-09-23 17:06:20 +0800311 }
Yahui Han1fbf3292021-11-08 18:17:19 +0800312 } else if (p_ctx->cryptor) {
313 /* Encrypt with clear key */
Yahui Han63b23b42021-12-07 15:37:46 +0800314 int crypt_len = len;
315 am_crypt_des_crypt(p_ctx->cryptor, buf_out, buf, &crypt_len, 0);
316 len = crypt_len;
Yahui Han1fbf3292021-11-08 18:17:19 +0800317 gettimeofday(&t3, NULL);
318 ret = segment_write(p_ctx->segment_handle, buf_out, len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800319 } else {
hualing chena5f03222021-12-02 11:22:35 +0800320 if (first_read == 0) {
321 first_read = 1;
322 DVR_DEBUG(1, "%s:%d,first read ts", __func__,__LINE__);
323 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800324 gettimeofday(&t3, NULL);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800325 ret = segment_write(p_ctx->segment_handle, buf, len);
326 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800327 gettimeofday(&t4, NULL);
hualing chen626204e2020-04-07 11:55:08 +0800328 //add DVR_RECORD_EVENT_WRITE_ERROR event if write error
pengfei.liufda2a972020-04-09 14:47:15 +0800329 if (ret == -1 && len > 0 && p_ctx->event_notify_fn) {
hualing chen626204e2020-04-07 11:55:08 +0800330 //send write event
hualing chen9b434f02020-06-10 15:06:54 +0800331 if (p_ctx->event_notify_fn) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800332 memset(&record_status, 0, sizeof(record_status));
hualing chen4fe3bee2020-10-23 13:58:52 +0800333 DVR_DEBUG(1, "%s:%d,send event write error", __func__,__LINE__);
hualing chen9ce7d942021-06-30 13:31:01 +0800334 record_status.info.id = p_ctx->segment_info.id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800335 p_ctx->event_notify_fn(DVR_RECORD_EVENT_WRITE_ERROR, &record_status, p_ctx->event_userdata);
336 }
hualing chenc70a8df2020-05-12 19:23:11 +0800337 DVR_DEBUG(1, "%s,write error %d", __func__,__LINE__);
hualing chen626204e2020-04-07 11:55:08 +0800338 goto end;
339 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800340 /* Do time index */
Yahui Han1fbf3292021-11-08 18:17:19 +0800341 uint8_t *index_buf = (p_ctx->enc_func || p_ctx->cryptor)? buf_out : buf;
pengfei.liuab5a2262020-02-14 17:33:40 +0800342 pos = segment_tell_position(p_ctx->segment_handle);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800343 has_pcr = record_do_pcr_index(p_ctx, index_buf, len);
hualing chen40accc32021-04-21 15:58:09 +0800344 if (has_pcr == 0 && p_ctx->index_type == DVR_INDEX_TYPE_INVALID) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800345 clock_gettime(CLOCK_MONOTONIC, &end_ts);
346 if ((end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
347 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000) > 40) {
348 /* PCR interval threshlod > 40 ms*/
349 DVR_DEBUG(1, "%s use local clock time index", __func__);
hualing chen40accc32021-04-21 15:58:09 +0800350 p_ctx->index_type = DVR_INDEX_TYPE_LOCAL_CLOCK;
pengfei.liuab5a2262020-02-14 17:33:40 +0800351 }
hualing chen40accc32021-04-21 15:58:09 +0800352 } else if (has_pcr && p_ctx->index_type == DVR_INDEX_TYPE_INVALID){
pengfei.liuab5a2262020-02-14 17:33:40 +0800353 DVR_DEBUG(1, "%s use pcr time index", __func__);
hualing chen40accc32021-04-21 15:58:09 +0800354 p_ctx->index_type = DVR_INDEX_TYPE_PCR;
Pengfei Liuc181a982020-01-07 19:27:13 +0800355 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800356 gettimeofday(&t5, NULL);
pengfei.liuab5a2262020-02-14 17:33:40 +0800357
358 /* Update segment info */
Pengfei Liub4734232020-01-17 18:25:10 +0800359 p_ctx->segment_info.size += len;
pengfei.liuab5a2262020-02-14 17:33:40 +0800360 /*Duration need use pcr to calculate, todo...*/
hualing chen40accc32021-04-21 15:58:09 +0800361 if (p_ctx->index_type == DVR_INDEX_TYPE_PCR) {
pengfei.liu8b563292020-02-26 15:49:02 +0800362 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
hualing chen87072a82020-03-12 16:20:12 +0800363 if (pre_time == 0)
364 pre_time = p_ctx->segment_info.duration;
hualing chen40accc32021-04-21 15:58:09 +0800365 } else if (p_ctx->index_type == DVR_INDEX_TYPE_LOCAL_CLOCK) {
pengfei.liuab5a2262020-02-14 17:33:40 +0800366 clock_gettime(CLOCK_MONOTONIC, &end_ts);
367 p_ctx->segment_info.duration = (end_ts.tv_sec*1000 + end_ts.tv_nsec/1000000) -
368 (start_ts.tv_sec*1000 + start_ts.tv_nsec/1000000);
hualing chen87072a82020-03-12 16:20:12 +0800369 if (pre_time == 0)
370 pre_time = p_ctx->segment_info.duration;
pengfei.liuab5a2262020-02-14 17:33:40 +0800371 segment_update_pts(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
372 } else {
373 DVR_DEBUG(1, "%s can NOT do time index", __func__);
374 }
375 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
Pengfei Liub4734232020-01-17 18:25:10 +0800376
hualing chen87072a82020-03-12 16:20:12 +0800377 if (p_ctx->segment_info.duration - pre_time > DVR_STORE_INFO_TIME) {
378 pre_time = p_ctx->segment_info.duration + DVR_STORE_INFO_TIME;
hualing chenf9867402020-09-23 17:06:20 +0800379 segment_store_info(p_ctx->segment_handle, &(p_ctx->segment_info));
hualing chen87072a82020-03-12 16:20:12 +0800380 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800381 gettimeofday(&t6, NULL);
hualing chen87072a82020-03-12 16:20:12 +0800382 /*Event notification*/
Pengfei Liub4734232020-01-17 18:25:10 +0800383 if (p_ctx->notification_size &&
384 p_ctx->event_notify_fn &&
hualing chen2615aa82020-04-02 21:32:51 +0800385 /*!(p_ctx->segment_info.size % p_ctx->notification_size)*/
386 (p_ctx->segment_info.size -p_ctx->last_send_size) >= p_ctx->notification_size&&
hualing chenbe68d642021-09-09 13:06:36 +0800387 p_ctx->segment_info.duration > 0 &&
388 p_ctx->state == DVR_RECORD_STATE_STARTED) {
Pengfei Liub4734232020-01-17 18:25:10 +0800389 memset(&record_status, 0, sizeof(record_status));
pengfei.liuab5a2262020-02-14 17:33:40 +0800390 //clock_gettime(CLOCK_MONOTONIC, &end_ts);
hualing chen2615aa82020-04-02 21:32:51 +0800391 p_ctx->last_send_size = p_ctx->segment_info.size;
Pengfei Liub4734232020-01-17 18:25:10 +0800392 record_status.state = p_ctx->state;
393 record_status.info.id = p_ctx->segment_info.id;
pengfei.liuab5a2262020-02-14 17:33:40 +0800394 record_status.info.duration = p_ctx->segment_info.duration;
Pengfei Liub4734232020-01-17 18:25:10 +0800395 record_status.info.size = p_ctx->segment_info.size;
396 record_status.info.nb_packets = p_ctx->segment_info.size/188;
397 p_ctx->event_notify_fn(DVR_RECORD_EVENT_STATUS, &record_status, p_ctx->event_userdata);
hualing chen4fe3bee2020-10-23 13:58:52 +0800398 DVR_DEBUG(1, "%s notify record status, state:%d, id:%lld, duration:%ld ms, size:%zu loc[%s]",
399 __func__, record_status.state,
400 record_status.info.id, record_status.info.duration,
401 record_status.info.size, p_ctx->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800402 }
pengfei.liu567d6d82020-04-17 16:48:59 +0800403 gettimeofday(&t7, NULL);
404#ifdef DEBUG_PERFORMANCE
hualing chen2932d372020-04-29 13:44:00 +0800405 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 +0800406 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 +0800407 get_diff_time(t5, t6), get_diff_time(t6, t7), get_diff_time(t1, t5), len);
pengfei.liu567d6d82020-04-17 16:48:59 +0800408#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800409 }
hualing chen626204e2020-04-07 11:55:08 +0800410end:
Pengfei Liub4734232020-01-17 18:25:10 +0800411 free((void *)buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800412 free((void *)buf_out);
Pengfei Liub4734232020-01-17 18:25:10 +0800413 DVR_DEBUG(1, "exit %s", __func__);
Pengfei Liuc181a982020-01-07 19:27:13 +0800414 return NULL;
415}
416
417int dvr_record_open(DVR_RecordHandle_t *p_handle, DVR_RecordOpenParams_t *params)
418{
419 DVR_RecordContext_t *p_ctx;
420 Record_DeviceOpenParams_t dev_open_params;
421 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800422 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800423
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800424 DVR_RETURN_IF_FALSE(p_handle);
425 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800426
427 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800428 if (record_ctx[i].state == DVR_RECORD_STATE_CLOSED) {
Pengfei Liuc181a982020-01-07 19:27:13 +0800429 break;
430 }
431 }
Pengfei Liufaf38e42020-05-22 00:28:02 +0800432 DVR_RETURN_IF_FALSE(i < MAX_DVR_RECORD_SESSION_COUNT);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800433 DVR_RETURN_IF_FALSE(record_ctx[i].state == DVR_RECORD_STATE_CLOSED);
Pengfei Liuc181a982020-01-07 19:27:13 +0800434 p_ctx = &record_ctx[i];
Yahui Han1fbf3292021-11-08 18:17:19 +0800435 DVR_DEBUG(1, "%s , current state:%d, dmx_id:%d, notification_size:%zu, flags:%d, keylen:%d ",
436 __func__, p_ctx->state, params->dmx_dev_id,
437 params->notification_size,
438 params->flags, params->keylen);
Pengfei Liuc181a982020-01-07 19:27:13 +0800439
Pengfei Liub4734232020-01-17 18:25:10 +0800440 /*Process event params*/
441 p_ctx->notification_size = params->notification_size;
442 p_ctx->event_notify_fn = params->event_fn;
443 p_ctx->event_userdata = params->event_userdata;
hualing chen2615aa82020-04-02 21:32:51 +0800444 p_ctx->last_send_size = 0;
hualing chen94d8dd22021-12-29 15:13:43 +0800445 p_ctx->pts = ULLONG_MAX;
Yahui Han1fbf3292021-11-08 18:17:19 +0800446
447 if (params->keylen > 0) {
448 p_ctx->cryptor = am_crypt_des_open(params->clearkey,
449 params->cleariv,
450 params->keylen * 8);
451 if (!p_ctx->cryptor)
452 DVR_DEBUG(1, "%s , open des cryptor failed!!!\n", __func__);
453 } else {
454 p_ctx->cryptor = NULL;
455 }
456
hualing chenf9867402020-09-23 17:06:20 +0800457 //check is new driver
458 p_ctx->is_new_dmx = dvr_check_dmx_isNew();
Pengfei Liub4734232020-01-17 18:25:10 +0800459 /*Process crypto params, todo*/
Pengfei Liub4734232020-01-17 18:25:10 +0800460 memset((void *)&dev_open_params, 0, sizeof(dev_open_params));
pengfei.liuab5a2262020-02-14 17:33:40 +0800461 if (params->data_from_memory) {
462 /* data from memory, VOD case */
463 p_ctx->is_vod = 1;
464 } else {
465 p_ctx->is_vod = 0;
466 /* data from dmx, normal dvr case */
hualing chen958fe4c2020-03-24 17:35:07 +0800467 dev_open_params.dmx_dev_id = params->dmx_dev_id;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800468 dev_open_params.buf_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen03fd4942021-07-15 15:56:41 +0800469 dev_open_params.ringbuf_size = params->ringbuf_size;
hualing chen9811b212020-10-29 11:21:44 +0800470 if (p_ctx->is_new_dmx)
hualing cheneceb37e2021-01-18 16:07:48 +0800471 dev_open_params.buf_size = NEW_DEVICE_RECORD_BLOCK_SIZE * 30;
pengfei.liuab5a2262020-02-14 17:33:40 +0800472 ret = record_device_open(&p_ctx->dev_handle, &dev_open_params);
473 if (ret != DVR_SUCCESS) {
474 DVR_DEBUG(1, "%s, open record devices failed", __func__);
475 return DVR_FAILURE;
476 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800477 }
478
pengfei.liufda2a972020-04-09 14:47:15 +0800479 p_ctx->block_size = (params->flush_size > 0 ? params->flush_size : RECORD_BLOCK_SIZE);
hualing chen9811b212020-10-29 11:21:44 +0800480 if (p_ctx->is_new_dmx)
Yahui Hance15e9c2020-12-08 18:08:32 +0800481 p_ctx->block_size = NEW_DEVICE_RECORD_BLOCK_SIZE * 30;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800482 p_ctx->enc_func = NULL;
483 p_ctx->enc_userdata = NULL;
484 p_ctx->is_secure_mode = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800485 p_ctx->state = DVR_RECORD_STATE_OPENED;
hualing chen9811b212020-10-29 11:21:44 +0800486 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 +0800487 *p_handle = p_ctx;
Pengfei Liuc181a982020-01-07 19:27:13 +0800488 return DVR_SUCCESS;
489}
490
491int dvr_record_close(DVR_RecordHandle_t handle)
492{
493 DVR_RecordContext_t *p_ctx;
494 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800495 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800496
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800497 p_ctx = (DVR_RecordContext_t *)handle;
498 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
499 if (p_ctx == &record_ctx[i])
500 break;
501 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800502 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800503
Pengfei Liub4734232020-01-17 18:25:10 +0800504 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800505 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Yahui Han1fbf3292021-11-08 18:17:19 +0800506 if (p_ctx->cryptor) {
507 am_crypt_des_close(p_ctx->cryptor);
508 p_ctx->cryptor = NULL;
509 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800510 if (p_ctx->is_vod) {
511 ret = DVR_SUCCESS;
512 } else {
513 ret = record_device_close(p_ctx->dev_handle);
514 if (ret != DVR_SUCCESS) {
515 DVR_DEBUG(1, "%s, failed", __func__);
516 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800517 }
hualing chencedcb862022-01-04 15:32:43 +0800518 memset(p_ctx, 0, sizeof(DVR_RecordContext_t));
Pengfei Liub4734232020-01-17 18:25:10 +0800519 p_ctx->state = DVR_RECORD_STATE_CLOSED;
Pengfei Liuc181a982020-01-07 19:27:13 +0800520 return ret;
521}
522
hualing chen03fd4942021-07-15 15:56:41 +0800523int dvr_record_pause(DVR_RecordHandle_t handle)
524{
525 DVR_RecordContext_t *p_ctx;
526 int ret;
527 uint32_t i;
528
529 p_ctx = (DVR_RecordContext_t *)handle;
530 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
531 if (p_ctx == &record_ctx[i])
532 break;
533 }
534 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
535
536 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
537 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
538
539 if (p_ctx->is_vod) {
540 ret = DVR_SUCCESS;
541 }
542 //set pause state,will not store ts into segment
543 p_ctx->state = DVR_RECORD_STATE_PAUSE;
544 return ret;
545}
546
547int dvr_record_resume(DVR_RecordHandle_t handle)
548{
549 DVR_RecordContext_t *p_ctx;
550 int ret;
551 uint32_t i;
552
553 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 }
558 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
559
560 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
561 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
562
563 if (p_ctx->is_vod) {
564 ret = DVR_SUCCESS;
565 }
566 //set stated state,will resume store ts into segment
567 p_ctx->state = DVR_RECORD_STATE_STARTED;
568 return ret;
569}
570
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800571#if 0
Pengfei Liuc181a982020-01-07 19:27:13 +0800572int dvr_record_register_encryption(DVR_RecordHandle_t handle,
573 DVR_CryptoFunction_t cb,
574 DVR_CryptoParams_t params,
575 void *userdata)
576{
577 return DVR_SUCCESS;
578}
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800579#endif
Pengfei Liuc181a982020-01-07 19:27:13 +0800580
581int dvr_record_start_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params)
582{
583 DVR_RecordContext_t *p_ctx;
584 Segment_OpenParams_t open_params;
585 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800586 uint32_t i;
Pengfei Liuc181a982020-01-07 19:27:13 +0800587
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800588 p_ctx = (DVR_RecordContext_t *)handle;
589 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
590 if (p_ctx == &record_ctx[i])
591 break;
592 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800593 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800594
hualing chen4fe3bee2020-10-23 13:58:52 +0800595 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 +0800596 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
597 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
598 DVR_RETURN_IF_FALSE(params);
Pengfei Liuc181a982020-01-07 19:27:13 +0800599
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800600 DVR_RETURN_IF_FALSE(strlen((const char *)params->location) < DVR_MAX_LOCATION_SIZE);
Pengfei Liuc181a982020-01-07 19:27:13 +0800601 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800602 memcpy(open_params.location, params->location, sizeof(params->location));
Pengfei Liuc181a982020-01-07 19:27:13 +0800603 open_params.segment_id = params->segment.segment_id;
604 open_params.mode = SEGMENT_MODE_WRITE;
605
606 ret = segment_open(&open_params, &p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800607 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800608
Pengfei Liub4734232020-01-17 18:25:10 +0800609 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800610 {
hualing chen7a56cba2020-04-14 14:09:27 +0800611 memcpy(p_ctx->location, params->location, sizeof(params->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800612 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800613 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800614 /*save current segment info*/
615 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
616 p_ctx->segment_info.id = params->segment.segment_id;
617 p_ctx->segment_info.nb_pids = params->segment.nb_pids;
618 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800619 }
620
pengfei.liuab5a2262020-02-14 17:33:40 +0800621 if (!p_ctx->is_vod) {
622 /* normal dvr case */
623 for (i = 0; i < params->segment.nb_pids; i++) {
624 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
625 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
626 }
627 ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800628 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800629 }
630
Zhiqiang Han5ebad992020-04-28 18:19:59 +0800631 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
632
Pengfei Liuc181a982020-01-07 19:27:13 +0800633 p_ctx->state = DVR_RECORD_STATE_STARTED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800634 if (!p_ctx->is_vod)
635 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liub4734232020-01-17 18:25:10 +0800636
Pengfei Liuc181a982020-01-07 19:27:13 +0800637 return DVR_SUCCESS;
638}
639
640int dvr_record_next_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, DVR_RecordSegmentInfo_t *p_info)
641{
642 DVR_RecordContext_t *p_ctx;
Pengfei Liub4734232020-01-17 18:25:10 +0800643 Segment_OpenParams_t open_params;
Pengfei Liuc181a982020-01-07 19:27:13 +0800644 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_STARTED);
657 //DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
658 DVR_RETURN_IF_FALSE(params);
659 DVR_RETURN_IF_FALSE(p_info);
pengfei.liuab5a2262020-02-14 17:33:40 +0800660 DVR_RETURN_IF_FALSE(!p_ctx->is_vod);
Pengfei Liuc181a982020-01-07 19:27:13 +0800661
662 /*Stop the on going record segment*/
Pengfei Liub4734232020-01-17 18:25:10 +0800663 //ret = record_device_stop(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800664 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liuc181a982020-01-07 19:27:13 +0800665 p_ctx->state = DVR_RECORD_STATE_STOPPED;
666 pthread_join(p_ctx->thread, NULL);
667
hualing chen2932d372020-04-29 13:44:00 +0800668 //add index file store
669 pos = segment_tell_position(p_ctx->segment_handle);
670 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
671
672 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liub4734232020-01-17 18:25:10 +0800673 /*Update segment info*/
674 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
675
676 ret = segment_store_info(p_ctx->segment_handle, p_info);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800677 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chenb9a02922021-12-14 11:29:47 +0800678 ret = segment_store_allInfo(p_ctx->segment_handle, p_info);
hualing chena540a7e2020-03-27 16:44:05 +0800679 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",
680 __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 +0800681
Pengfei Liub4734232020-01-17 18:25:10 +0800682 /*Close current segment*/
683 ret = segment_close(p_ctx->segment_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800684 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800685 /*Open the new record segment*/
686 memset(&open_params, 0, sizeof(open_params));
hualing chen7a56cba2020-04-14 14:09:27 +0800687 memcpy(open_params.location, p_ctx->location, sizeof(p_ctx->location));
Pengfei Liub4734232020-01-17 18:25:10 +0800688 open_params.segment_id = params->segment.segment_id;
689 open_params.mode = SEGMENT_MODE_WRITE;
hualing chen7a56cba2020-04-14 14:09:27 +0800690 DVR_DEBUG(1, "%s: p_ctx->location:%s params->location:%s", __func__, p_ctx->location,params->location);
Pengfei Liub4734232020-01-17 18:25:10 +0800691
692 ret = segment_open(&open_params, &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 /*process params*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800695 {
Pengfei Liub4734232020-01-17 18:25:10 +0800696 //need all params??
Pengfei Liuc181a982020-01-07 19:27:13 +0800697 memcpy(&p_ctx->segment_params, &params->segment, sizeof(params->segment));
Pengfei Liub4734232020-01-17 18:25:10 +0800698 /*save current segment info*/
699 memset(&p_ctx->segment_info, 0, sizeof(p_ctx->segment_info));
700 p_ctx->segment_info.id = params->segment.segment_id;
701 memcpy(p_ctx->segment_info.pids, params->segment.pids, params->segment.nb_pids*sizeof(DVR_StreamPid_t));
Pengfei Liuc181a982020-01-07 19:27:13 +0800702 }
703
Pengfei Liub4734232020-01-17 18:25:10 +0800704 p_ctx->segment_info.nb_pids = 0;
Pengfei Liuc181a982020-01-07 19:27:13 +0800705 for (i = 0; i < params->segment.nb_pids; i++) {
Pengfei Liub4734232020-01-17 18:25:10 +0800706 switch (params->segment.pid_action[i]) {
707 case DVR_RECORD_PID_CREATE:
708 DVR_DEBUG(1, "%s create pid:%d", __func__, params->segment.pids[i].pid);
709 ret = record_device_add_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
710 p_ctx->segment_info.nb_pids++;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800711 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800712 break;
713 case DVR_RECORD_PID_KEEP:
714 DVR_DEBUG(1, "%s keep pid:%d", __func__, params->segment.pids[i].pid);
715 p_ctx->segment_info.nb_pids++;
716 break;
717 case DVR_RECORD_PID_CLOSE:
718 DVR_DEBUG(1, "%s close pid:%d", __func__, params->segment.pids[i].pid);
719 ret = record_device_remove_pid(p_ctx->dev_handle, params->segment.pids[i].pid);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800720 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800721 break;
722 default:
723 DVR_DEBUG(1, "%s wrong action pid:%d", __func__, params->segment.pids[i].pid);
724 return DVR_FAILURE;
725 }
Pengfei Liuc181a982020-01-07 19:27:13 +0800726 }
727
Pengfei Liub4734232020-01-17 18:25:10 +0800728 //ret = record_device_start(p_ctx->dev_handle);
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800729 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
hualing chen4b7c15d2020-04-07 16:13:48 +0800730 /*Update segment info*/
731 ret = segment_store_info(p_ctx->segment_handle, &p_ctx->segment_info);
hualing chen94d8dd22021-12-29 15:13:43 +0800732 if (p_ctx->pts != ULLONG_MAX)
733 segment_update_pts(p_ctx->segment_handle, p_ctx->pts, 0);
Pengfei Liuc181a982020-01-07 19:27:13 +0800734
Pengfei Liuc181a982020-01-07 19:27:13 +0800735 p_ctx->state = DVR_RECORD_STATE_STARTED;
Zhiqiang Han0d60f2b2020-05-26 14:39:54 +0800736 pthread_create(&p_ctx->thread, NULL, record_thread, p_ctx);
Pengfei Liuc181a982020-01-07 19:27:13 +0800737 return DVR_SUCCESS;
738}
739
740int dvr_record_stop_segment(DVR_RecordHandle_t handle, DVR_RecordSegmentInfo_t *p_info)
741{
742 DVR_RecordContext_t *p_ctx;
743 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800744 uint32_t i;
hualing chen2932d372020-04-29 13:44:00 +0800745 loff_t pos;
Pengfei Liuc181a982020-01-07 19:27:13 +0800746
Pengfei Liu47ed6c92020-01-17 11:23:41 +0800747 p_ctx = (DVR_RecordContext_t *)handle;
748 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
749 if (p_ctx == &record_ctx[i])
750 break;
751 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800752 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
Pengfei Liuc181a982020-01-07 19:27:13 +0800753
hualing chen4fe3bee2020-10-23 13:58:52 +0800754 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 +0800755 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STOPPED);
756 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
Zhiqiang Han2d8cd822020-03-16 13:58:10 +0800757 DVR_RETURN_IF_FALSE(p_info);/*should support NULL*/
Pengfei Liuc181a982020-01-07 19:27:13 +0800758
Pengfei Liuc181a982020-01-07 19:27:13 +0800759 p_ctx->state = DVR_RECORD_STATE_STOPPED;
pengfei.liuab5a2262020-02-14 17:33:40 +0800760 if (p_ctx->is_vod) {
pengfei.liu8b563292020-02-26 15:49:02 +0800761 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
pengfei.liuab5a2262020-02-14 17:33:40 +0800762 p_ctx->segment_info.duration = 10*1000; //debug, should delete it
763 } else {
764 ret = record_device_stop(p_ctx->dev_handle);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800765 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
766 if (ret != DVR_SUCCESS)
767 goto end;
pengfei.liuab5a2262020-02-14 17:33:40 +0800768 //p_ctx->state = DVR_RECORD_STATE_STOPPED;
769 pthread_join(p_ctx->thread, NULL);
770 }
771
hualing chen2932d372020-04-29 13:44:00 +0800772 //add index file store
773 pos = segment_tell_position(p_ctx->segment_handle);
774 segment_update_pts_force(p_ctx->segment_handle, p_ctx->segment_info.duration, pos);
hualing chene41f4372020-06-06 16:29:17 +0800775 p_ctx->segment_info.duration = segment_tell_total_time(p_ctx->segment_handle);
Pengfei Liuc181a982020-01-07 19:27:13 +0800776
Pengfei Liub4734232020-01-17 18:25:10 +0800777 /*Update segment info*/
778 memcpy(p_info, &p_ctx->segment_info, sizeof(p_ctx->segment_info));
779
780 ret = segment_store_info(p_ctx->segment_handle, p_info);
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800781 //DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
782 if (ret != DVR_SUCCESS)
783 goto end;
Pengfei Liub4734232020-01-17 18:25:10 +0800784
hualing chenb9a02922021-12-14 11:29:47 +0800785 segment_store_allInfo(p_ctx->segment_handle, p_info);
786
Pengfei Liub4734232020-01-17 18:25:10 +0800787 DVR_DEBUG(1, "%s dump segment info, id:%lld, nb_pids:%d, duration:%ld ms, size:%zu, nb_packets:%d",
788 __func__, p_info->id, p_info->nb_pids, p_info->duration, p_info->size, p_info->nb_packets);
789
Zhiqiang Han5c805cf2020-05-09 16:51:08 +0800790end:
Pengfei Liuc181a982020-01-07 19:27:13 +0800791 ret = segment_close(p_ctx->segment_handle);
hualing chencedcb862022-01-04 15:32:43 +0800792 p_ctx->segment_handle = NULL;
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800793 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
Pengfei Liub4734232020-01-17 18:25:10 +0800794 return DVR_SUCCESS;
795}
Pengfei Liuc181a982020-01-07 19:27:13 +0800796
Pengfei Liub4734232020-01-17 18:25:10 +0800797int dvr_record_resume_segment(DVR_RecordHandle_t handle, DVR_RecordStartParams_t *params, uint64_t *p_resume_size)
798{
799 DVR_RecordContext_t *p_ctx;
800 uint32_t i;
pengfei.liuab5a2262020-02-14 17:33:40 +0800801 int ret;
Pengfei Liub4734232020-01-17 18:25:10 +0800802
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;
Pengfei Liuc181a982020-01-07 19:27:13 +0800807 }
Pengfei Liu3b1a8202020-02-12 23:04:21 +0800808 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
809 DVR_RETURN_IF_FALSE(params);
810 DVR_RETURN_IF_FALSE(p_resume_size);
Pengfei Liuc181a982020-01-07 19:27:13 +0800811
pengfei.liuab5a2262020-02-14 17:33:40 +0800812 DVR_DEBUG(1, "%s , current state:%d, resume size:%lld", __func__, p_ctx->state, *p_resume_size);
813 ret = dvr_record_start_segment(handle, params);
814 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
815
816 p_ctx->segment_info.size = *p_resume_size;
817
818 return DVR_SUCCESS;
819}
820
821int dvr_record_get_status(DVR_RecordHandle_t handle, DVR_RecordStatus_t *p_status)
822{
823 DVR_RecordContext_t *p_ctx;
824 int i;
825
826 p_ctx = (DVR_RecordContext_t *)handle;
827 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
828 if (p_ctx == &record_ctx[i])
829 break;
830 }
831 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
832 DVR_RETURN_IF_FALSE(p_status);
833
834 //lock
835 p_status->state = p_ctx->state;
836 p_status->info.id = p_ctx->segment_info.id;
837 p_status->info.duration = p_ctx->segment_info.duration;
838 p_status->info.size = p_ctx->segment_info.size;
839 p_status->info.nb_packets = p_ctx->segment_info.size/188;
840
841 return DVR_SUCCESS;
842}
843
844int dvr_record_write(DVR_RecordHandle_t handle, void *buffer, uint32_t len)
845{
846 DVR_RecordContext_t *p_ctx;
847 uint32_t i;
848 off_t pos = 0;
849 int ret;
850 int has_pcr;
851
852 p_ctx = (DVR_RecordContext_t *)handle;
853 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
854 if (p_ctx == &record_ctx[i])
855 break;
856 }
857 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
858 DVR_RETURN_IF_FALSE(buffer);
859 DVR_RETURN_IF_FALSE(len);
860
861 pos = segment_tell_position(p_ctx->segment_handle);
862 has_pcr = record_do_pcr_index(p_ctx, buffer, len);
863 if (has_pcr == 0) {
864 /* Pull VOD record shoud use PCR time index */
865 DVR_DEBUG(1, "%s has no pcr, can NOT do time index", __func__);
866 }
867 ret = segment_write(p_ctx->segment_handle, buffer, len);
hualing chen2932d372020-04-29 13:44:00 +0800868 if (ret != len) {
869 DVR_DEBUG(1, "%s write error ret:%d len:%d", __func__, ret, len);
870 }
pengfei.liuab5a2262020-02-14 17:33:40 +0800871 p_ctx->segment_info.size += len;
872 p_ctx->segment_info.nb_packets = p_ctx->segment_info.size/188;
873
Pengfei Liuc181a982020-01-07 19:27:13 +0800874 return DVR_SUCCESS;
875}
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800876
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800877int dvr_record_set_encrypt_callback(DVR_RecordHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800878{
879 DVR_RecordContext_t *p_ctx;
880 uint32_t i;
881
882 p_ctx = (DVR_RecordContext_t *)handle;
883 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
884 if (p_ctx == &record_ctx[i])
885 break;
886 }
887 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
888 DVR_RETURN_IF_FALSE(func);
889
890 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
891 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
892 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
893
894 p_ctx->enc_func = func;
895 p_ctx->enc_userdata = userdata;
896 return DVR_SUCCESS;
897}
898
899int dvr_record_set_secure_buffer(DVR_RecordHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
900{
901 DVR_RecordContext_t *p_ctx;
902 uint32_t i;
903 int ret;
904
905 p_ctx = (DVR_RecordContext_t *)handle;
906 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
907 if (p_ctx == &record_ctx[i])
908 break;
909 }
910 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
911 DVR_RETURN_IF_FALSE(p_secure_buf);
912 DVR_RETURN_IF_FALSE(len);
913
914 DVR_DEBUG(1, "%s , current state:%d", __func__, p_ctx->state);
915 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_STARTED);
916 DVR_RETURN_IF_FALSE(p_ctx->state != DVR_RECORD_STATE_CLOSED);
917
918 ret = record_device_set_secure_buffer(p_ctx->dev_handle, p_secure_buf, len);
919 DVR_RETURN_IF_FALSE(ret == DVR_SUCCESS);
920
921 p_ctx->is_secure_mode = 1;
922 return ret;
923}
hualing chen4fe3bee2020-10-23 13:58:52 +0800924
925int dvr_record_is_secure_mode(DVR_RecordHandle_t handle)
926{
927 DVR_RecordContext_t *p_ctx;
928 uint32_t i;
929 int ret;
930
931 p_ctx = (DVR_RecordContext_t *)handle;
932 for (i = 0; i < MAX_DVR_RECORD_SESSION_COUNT; i++) {
933 if (p_ctx == &record_ctx[i])
934 break;
935 }
936 DVR_RETURN_IF_FALSE(p_ctx == &record_ctx[i]);
937
938 if (p_ctx->is_secure_mode == 1)
939 ret = 1;
940 else
941 ret = 0;
942 return ret;
Yahui Hance15e9c2020-12-08 18:08:32 +0800943}