blob: b920c7e599d9b79a2630a011239e693e6ed65d2e [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <poll.h>
11#include <errno.h>
12#include <signal.h>
13#include <pthread.h>
14
hualing chenb31a6c62020-01-13 17:27:00 +080015#include "dvr_playback.h"
16
hualing chena540a7e2020-03-27 16:44:05 +080017
hualing chenb31a6c62020-01-13 17:27:00 +080018#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080019
20
21#define FF_SPEED (2.0f)
22#define FB_SPEED (-1.0f)
23#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
24#define IS_FB(_SPEED_) ((_SPEED_) < FB_SPEED)
25
26#define IS_KERNEL_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_X1) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
27#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
28
hualing chenb31a6c62020-01-13 17:27:00 +080029
hualing chen041c4092020-04-05 15:11:50 +080030#define FFFB_SLEEP_TIME (500)//500ms
hualing chen2aba4022020-03-02 13:49:55 +080031#define FB_DEFAULT_LEFT_TIME (2000)
hualing chen31140872020-03-25 12:29:26 +080032//if tsplayer delay time < 200 and no data can read, we will pause
33#define MIN_TSPLAYER_DELAY_TIME (200)
34
hualing chen041c4092020-04-05 15:11:50 +080035//get current segment current pcr time of read pos
36static int g_cache_time = 0;
37#define MAX_CACHE_TIME (30000)
38
hualing chena540a7e2020-03-27 16:44:05 +080039static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080040//
41static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chencc91e1c2020-02-28 13:26:17 +080042static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type);
43static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
44static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080045static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080046static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
47
hualing chen6d24aa92020-03-23 18:43:47 +080048static char* _dvr_playback_state_toString(int stat)
49{
50 char *string[DVR_PLAYBACK_STATE_FB+1]={
51 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080052 "stop",
hualing chen31140872020-03-25 12:29:26 +080053 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080054 "ff",
55 "fb"
56 };
57
58 if (stat > DVR_PLAYBACK_STATE_FB) {
59 return "unkown";
60 } else {
61 return string[stat];
62 }
63}
hualing chena540a7e2020-03-27 16:44:05 +080064
65static DVR_Bool_t _dvr_support_speed(int speed) {
66
67 DVR_Bool_t ret = DVR_FALSE;
68
69 switch (speed) {
70 case PLAYBACK_SPEED_FBX2:
71 case PLAYBACK_SPEED_FBX4:
72 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +080073 case PLAYBACK_SPEED_FBX16:
74 case PLAYBACK_SPEED_FBX12:
75 case PLAYBACK_SPEED_FBX32:
76 case PLAYBACK_SPEED_FBX48:
77 case PLAYBACK_SPEED_FBX64:
78 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +080079 case PLAYBACK_SPEED_S2:
80 case PLAYBACK_SPEED_S4:
81 case PLAYBACK_SPEED_S8:
82 case PLAYBACK_SPEED_X1:
83 case PLAYBACK_SPEED_X2:
84 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +080085 case PLAYBACK_SPEED_X3:
86 case PLAYBACK_SPEED_X5:
87 case PLAYBACK_SPEED_X6:
88 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +080089 case PLAYBACK_SPEED_X8:
90 case PLAYBACK_SPEED_X12:
91 case PLAYBACK_SPEED_X16:
92 case PLAYBACK_SPEED_X32:
93 case PLAYBACK_SPEED_X48:
94 case PLAYBACK_SPEED_X64:
95 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +080096 ret = DVR_TRUE;
97 break;
98 default:
99 DVR_DEBUG(1, "not support speed is set [%d]", speed);
100 break;
101 }
102 return ret;
103}
hualing chen6e4bfa52020-03-13 14:37:11 +0800104void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
105{
106 DVR_DEBUG(1, "in callback test ");
107 DVR_Playback_t *player = NULL;
108 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800109 player = (DVR_Playback_t *) user_data;
110 DVR_DEBUG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800111 }
112 switch (event->type) {
113 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
114 {
115 DVR_DEBUG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
116 event->event.video_format.frame_width,
117 event->event.video_format.frame_height,
118 event->event.video_format.frame_rate);
119 break;
120 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800121 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
122 {
123 DVR_DEBUG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800124 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800125 break;
126 }
127 default:
128 break;
129 }
130}
hualing chen2aba4022020-03-02 13:49:55 +0800131void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
132{
hualing chen6e4bfa52020-03-13 14:37:11 +0800133 DVR_Playback_t *player = NULL;
134 if (user_data != NULL) {
135 player = (DVR_Playback_t *) user_data;
hualing chen31140872020-03-25 12:29:26 +0800136 DVR_DEBUG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800137 }
hualing chen2aba4022020-03-02 13:49:55 +0800138 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800139 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
140 {
141 DVR_DEBUG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
142 event->event.video_format.frame_width,
143 event->event.video_format.frame_height,
144 event->event.video_format.frame_rate);
145 break;
146 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800147 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
148 {
149 DVR_DEBUG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800150 if (player != NULL)
151 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800152 break;
153 }
154 default:
hualing chen6d24aa92020-03-23 18:43:47 +0800155 DVR_DEBUG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800156 break;
157 }
158 if (player&&player->player_callback_func) {
hualing chen6d24aa92020-03-23 18:43:47 +0800159 DVR_DEBUG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800160 player->player_callback_func(player->player_callback_userdata, event);
161 } else if (player == NULL){
162 DVR_DEBUG(1, "player is null, get userdata error\n");
163 } else {
164 DVR_DEBUG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800165 }
166}
hualing chencc91e1c2020-02-28 13:26:17 +0800167
hualing chen5cbe1a62020-02-10 16:36:36 +0800168//convert video and audio fmt
169static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
170 int format = 0;
171 if (is_audio == DVR_FALSE) {
172 //for video fmt
173 switch (fmt)
174 {
175 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800176 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800177 break;
178 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800179 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800180 break;
181 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800182 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800183 break;
184 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800185 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800186 break;
hualing chena540a7e2020-03-27 16:44:05 +0800187 case DVR_VIDEO_FORMAT_VP9:
188 format = AV_VIDEO_CODEC_VP9;
189 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800190 }
191 } else {
192 //for audio fmt
193 switch (fmt)
194 {
195 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800196 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800197 break;
198 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800199 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800200 break;
201 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800202 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800203 break;
204 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800205 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800206 break;
hualing chena540a7e2020-03-27 16:44:05 +0800207 case DVR_AUDIO_FORMAT_AAC:
208 format = AV_AUDIO_CODEC_AAC;
209 break;
210 case DVR_AUDIO_FORMAT_LATM:
211 format = AV_AUDIO_CODEC_LATM;
212 break;
213 case DVR_AUDIO_FORMAT_PCM:
214 format = AV_AUDIO_CODEC_PCM;
215 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800216 }
217 }
218 return format;
219}
hualing chen040df222020-01-17 13:35:02 +0800220static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800221{
hualing chen040df222020-01-17 13:35:02 +0800222 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800223
hualing chena540a7e2020-03-27 16:44:05 +0800224 if (player == NULL || player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800225 return -1;
226
hualing chena540a7e2020-03-27 16:44:05 +0800227 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800228}
hualing chena540a7e2020-03-27 16:44:05 +0800229
hualing chen5cbe1a62020-02-10 16:36:36 +0800230//get sys time ms
231static int _dvr_time_getClock(void)
232{
233 struct timespec ts;
234 int ms;
235
236 clock_gettime(CLOCK_MONOTONIC, &ts);
237 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
238
239 return ms;
240}
hualing chen86e7d482020-01-16 15:13:33 +0800241
hualing chenb31a6c62020-01-13 17:27:00 +0800242
243//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800244static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800245{
hualing chen040df222020-01-17 13:35:02 +0800246 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800247
hualing chena540a7e2020-03-27 16:44:05 +0800248
249 if (player == NULL) {
250 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
251 return DVR_FAILURE;
252 }
253
hualing chen86e7d482020-01-16 15:13:33 +0800254 struct timespec ts;
255 clock_gettime(CLOCK_MONOTONIC, &ts);
256 //ms为毫秒,换算成秒
257 ts.tv_sec += ms/1000;
258 //在outtime的基础上,增加ms毫秒
259 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
260 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
261 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
262 //us的值有可能超过1秒,
263 ts.tv_sec += us / 1000000;
264 us = us % 1000000;
265 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800266 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
267 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800268}
hualing chen31140872020-03-25 12:29:26 +0800269//get tsplay delay time ms
270static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
271 DVR_Playback_t *player = (DVR_Playback_t *) handle;
272 int64_t cache = 0;
273 if (player == NULL || player->handle == NULL) {
274 DVR_DEBUG(1, "tsplayer delay time error, handle is NULL");
275 return 0;
276 }
277 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chena540a7e2020-03-27 16:44:05 +0800278 DVR_DEBUG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800279 return cache;
280}
hualing chenb31a6c62020-01-13 17:27:00 +0800281//send signal
hualing chen040df222020-01-17 13:35:02 +0800282static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800283{
hualing chen87072a82020-03-12 16:20:12 +0800284 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800285
286 if (player == NULL) {
287 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
288 return DVR_FAILURE;
289 }
290
hualing chen87072a82020-03-12 16:20:12 +0800291 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800292 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800293 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800294 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800295}
296
hualing chencc91e1c2020-02-28 13:26:17 +0800297//send playback event
298static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify) {
299
300 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800301
302 if (player == NULL) {
303 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
304 return DVR_FAILURE;
305 }
306
hualing chencc91e1c2020-02-28 13:26:17 +0800307 switch (evt) {
308 case DVR_PLAYBACK_EVENT_ERROR:
309 break;
310 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
311 //GET STATE
312 DVR_DEBUG(1, "trans ok----");
313 dvr_playback_get_status(handle, &(notify->play_status));
314 break;
315 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
316 break;
317 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
318 break;
319 case DVR_PLAYBACK_EVENT_NO_KEY:
320 break;
321 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800322 //GET STATE
323 DVR_DEBUG(1, "reached begin---");
324 dvr_playback_get_status(handle, &(notify->play_status));
hualing chencc91e1c2020-02-28 13:26:17 +0800325 break;
326 case DVR_PLAYBACK_EVENT_REACHED_END:
327 //GET STATE
328 DVR_DEBUG(1, "reached end---");
329 dvr_playback_get_status(handle, &(notify->play_status));
330 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800331 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
332 //DVR_DEBUG(1, "send playtime---");
333 dvr_playback_get_status(handle, &(notify->play_status));
334 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800335 default:
336 break;
337 }
338 if (player->openParams.event_fn != NULL)
339 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800340 return DVR_SUCCESS;
341}
342static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle)
343{
344 DVR_Play_Notify_t notify;
345 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
346 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
347 //get play statue not here
348 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify);
349 return DVR_SUCCESS;
350}
351
hualing chen6e4bfa52020-03-13 14:37:11 +0800352static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle)
353{
354 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800355
356 if (player == NULL) {
357 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
358 return DVR_FAILURE;
359 }
360
hualing chen6e4bfa52020-03-13 14:37:11 +0800361 if (player->send_time ==0) {
362 player->send_time = _dvr_time_getClock() + 1000;
363 } else if (player->send_time > _dvr_time_getClock()) {
364 return DVR_SUCCESS;
365 }
366 player->send_time = _dvr_time_getClock() + 1000;
367 DVR_Play_Notify_t notify;
368 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
369 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
370 //get play statue not here
371 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify);
372 return DVR_SUCCESS;
373}
374
hualing chencc91e1c2020-02-28 13:26:17 +0800375//check is ongoing segment
376static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
377
378 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800379 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800380
381 if (player == NULL) {
382 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
383 return DVR_FAILURE;
384 }
hualing chen87072a82020-03-12 16:20:12 +0800385 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800386 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800387 return DVR_FALSE;
388 }
hualing chencc91e1c2020-02-28 13:26:17 +0800389 return DVR_TRUE;
390}
hualing chen2aba4022020-03-02 13:49:55 +0800391static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
392 DVR_Playback_t *player = (DVR_Playback_t *) handle;
393 player->fffb_current = -1;
394 player->fffb_start = -1;
395 player->fffb_start_pcr = -1;
396 player->next_fffb_time = _dvr_time_getClock();
397 return DVR_SUCCESS;
398}
hualing chencc91e1c2020-02-28 13:26:17 +0800399//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800400static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
401
402 DVR_Playback_t *player = (DVR_Playback_t *) handle;
403 DVR_PlaybackSegmentInfo_t *segment;
404 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
405
hualing chena540a7e2020-03-27 16:44:05 +0800406 if (player == NULL) {
407 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
408 return DVR_FAILURE;
409 }
410
hualing chen87072a82020-03-12 16:20:12 +0800411 int found = 0;
412 int found_eq_id = 0;
413 list_for_each_entry(segment, &player->segment_list, head)
414 {
415 if (player->segment_is_open == DVR_FALSE) {
416 //get first segment from list, case segment is not open
417 if (!IS_FB(player->speed))
418 found = 1;
419 } else if (segment->segment_id == segmentid) {
420 //find cur segment, we need get next one
421 found_eq_id = 1;
422 if (!IS_FB(player->speed)) {
423 found = 1;
424 continue;
425 } else {
426 //if is fb mode.we need used pre segment
427 if (pre_segment != NULL) {
428 found = 1;
429 } else {
430 //not find next id.
431 DVR_DEBUG(1, "not has find next segment on fb mode");
432 return DVR_FAILURE;
433 }
434 }
435 }
436 if (found == 1) {
437 found = 2;
438 break;
439 }
440 }
441 if (found != 2) {
442 //list is null or reache list end
443 DVR_DEBUG(1, "not found next segment return failure");
444 return DVR_FAILURE;
445 }
446 DVR_DEBUG(1, "found next segment return success");
447 return DVR_SUCCESS;
448}
449
450//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800451static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800452
hualing chen040df222020-01-17 13:35:02 +0800453 DVR_Playback_t *player = (DVR_Playback_t *) handle;
454 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800455 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800456
hualing chena540a7e2020-03-27 16:44:05 +0800457 if (player == NULL) {
458 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
459 return DVR_FAILURE;
460 }
461
hualing chen86e7d482020-01-16 15:13:33 +0800462 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800463 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800464
hualing chen040df222020-01-17 13:35:02 +0800465 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800466 {
hualing chencc91e1c2020-02-28 13:26:17 +0800467 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800468 //get first segment from list, case segment is not open
469 if (!IS_FB(player->speed))
470 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800471 } else if (segment->segment_id == player->cur_segment_id) {
472 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800473 found_eq_id = 1;
474 if (!IS_FB(player->speed)) {
475 found = 1;
476 continue;
477 } else {
478 //if is fb mode.we need used pre segment
479 if (pre_segment != NULL) {
480 found = 1;
481 } else {
482 //not find next id.
483 DVR_DEBUG(1, "not find next segment on fb mode");
484 return DVR_FAILURE;
485 }
486 }
hualing chen86e7d482020-01-16 15:13:33 +0800487 }
488 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800489 if (IS_FB(player->speed)) {
490 //used pre segment
491 segment = pre_segment;
492 }
hualing chencc91e1c2020-02-28 13:26:17 +0800493 //save segment info
494 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800495 player->last_segment.segment_id = player->cur_segment.segment_id;
496 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800497 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
498 //pids
499 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
500
hualing chen5cbe1a62020-02-10 16:36:36 +0800501 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800502 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800503 player->cur_segment_id = segment->segment_id;
504 player->cur_segment.segment_id = segment->segment_id;
505 player->cur_segment.flags = segment->flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800506 DVR_DEBUG(1, "cur flag[0x%x]segment->flags flag[0x%x] id [%lld]", player->cur_segment.flags, segment->flags, segment->segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800507 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800508 //pids
hualing chen040df222020-01-17 13:35:02 +0800509 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800510 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800511 break;
hualing chen86e7d482020-01-16 15:13:33 +0800512 }
hualing chen2aba4022020-03-02 13:49:55 +0800513 pre_segment = segment;
514 }
515 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
516 //used the last one segment to open
517 //get segment info
518 player->segment_is_open = DVR_TRUE;
519 player->cur_segment_id = pre_segment->segment_id;
520 player->cur_segment.segment_id = pre_segment->segment_id;
521 player->cur_segment.flags = pre_segment->flags;
522 DVR_DEBUG(1, "fb last one cur flag[0x%x]segment->flags flag[0x%x] id [%lld]", player->cur_segment.flags, pre_segment->flags, pre_segment->segment_id);
523 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
524 //pids
525 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
526 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800527 }
528 if (found != 2) {
529 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800530 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800531 }
532 return DVR_SUCCESS;
533}
hualing chen040df222020-01-17 13:35:02 +0800534//open next segment to play,if reach list end return errro.
535static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800536{
hualing chen040df222020-01-17 13:35:02 +0800537 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800538 Segment_OpenParams_t params;
539 int ret = DVR_SUCCESS;
540
hualing chena540a7e2020-03-27 16:44:05 +0800541 if (player == NULL) {
542 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
543 return DVR_FAILURE;
544 }
545
546 ret = _dvr_get_next_segmentId(handle);
547 if (ret == DVR_FAILURE) {
hualing chen040df222020-01-17 13:35:02 +0800548 DVR_DEBUG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800549 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800550 }
551
552 if (player->r_handle != NULL) {
553 segment_close(player->r_handle);
554 player->r_handle = NULL;
555 }
556
557 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800558 //cp chur segment path to location
559 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800560 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800561 params.mode = SEGMENT_MODE_READ;
hualing chencc91e1c2020-02-28 13:26:17 +0800562 DVR_DEBUG(1, "open segment info[%s][%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen2aba4022020-03-02 13:49:55 +0800563 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +0800564 ret = segment_open(&params, &(player->r_handle));
hualing chen87072a82020-03-12 16:20:12 +0800565 pthread_mutex_unlock(&player->segment_lock);
566 int total = _dvr_get_end_time( handle);
567 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800568 if (IS_FB(player->speed)) {
569 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen266b9502020-04-04 17:39:39 +0800570 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen2aba4022020-03-02 13:49:55 +0800571 }
hualing chen87072a82020-03-12 16:20:12 +0800572 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800573 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800574 DVR_DEBUG(1, "next player->dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800575 return ret;
576}
577
hualing chen5cbe1a62020-02-10 16:36:36 +0800578//open next segment to play,if reach list end return errro.
579static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
580{
581 DVR_Playback_t *player = (DVR_Playback_t *) handle;
582 Segment_OpenParams_t params;
583 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800584 if (player == NULL) {
585 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
586 return DVR_FAILURE;
587 }
hualing chencc91e1c2020-02-28 13:26:17 +0800588 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800589 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800590 }
hualing chencc91e1c2020-02-28 13:26:17 +0800591 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800592 if (id < 0) {
593 DVR_DEBUG(1, "not found segment info");
594 return DVR_FAILURE;
595 }
hualing chencc91e1c2020-02-28 13:26:17 +0800596 DVR_DEBUG(1, "start found segment[%lld][%lld] info", id,segment_id);
hualing chen2aba4022020-03-02 13:49:55 +0800597 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800598
599 DVR_PlaybackSegmentInfo_t *segment;
600
601 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800602
hualing chen5cbe1a62020-02-10 16:36:36 +0800603 list_for_each_entry(segment, &player->segment_list, head)
604 {
hualing chencc91e1c2020-02-28 13:26:17 +0800605 DVR_DEBUG(1, "see 1 location [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800606 if (segment->segment_id == segment_id) {
607 found = 1;
608 }
609 if (found == 1) {
hualing chencc91e1c2020-02-28 13:26:17 +0800610 DVR_DEBUG(1, "found [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800611 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800612 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800613 player->cur_segment_id = segment->segment_id;
614 player->cur_segment.segment_id = segment->segment_id;
615 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800616 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800617 //pids
618 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +0800619 DVR_DEBUG(1, "cur found location [%s]id[%lld]flag[%x]", player->cur_segment.location, player->cur_segment.segment_id,player->cur_segment.flags);
620 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800621 }
622 }
hualing chencc91e1c2020-02-28 13:26:17 +0800623 if (found == 0) {
624 DVR_DEBUG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800625 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800626 return DVR_FAILURE;
627 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800628 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800629 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800630 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800631 params.segment_id = (uint64_t)player->cur_segment.segment_id;
632 params.mode = SEGMENT_MODE_READ;
hualing chencc91e1c2020-02-28 13:26:17 +0800633 DVR_DEBUG(1, "open segment location[%s][%lld]cur flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen2aba4022020-03-02 13:49:55 +0800634 if (player->r_handle != NULL) {
635 segment_close(player->r_handle);
636 player->r_handle = NULL;
637 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800638 ret = segment_open(&params, &(player->r_handle));
hualing chen2aba4022020-03-02 13:49:55 +0800639 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800640 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800641
642 DVR_DEBUG(1, "player->dur [%d]cur id [%lld]cur flag [0x%x]\r\n", player->dur,player->cur_segment.segment_id, player->cur_segment.flags);
hualing chen5cbe1a62020-02-10 16:36:36 +0800643 return ret;
644}
645
646
647//get play info by segment id
648static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
649 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800650 am_tsplayer_video_params *vparam,
651 am_tsplayer_audio_params *aparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800652
653 DVR_Playback_t *player = (DVR_Playback_t *) handle;
654 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800655 if (player == NULL) {
656 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
657 return DVR_FAILURE;
658 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800659
660 int found = 0;
661
662 list_for_each_entry(segment, &player->segment_list, head)
663 {
hualing chen87072a82020-03-12 16:20:12 +0800664 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800665 //get first segment from list
666 found = 1;
667 }
668 if (segment->segment_id == segment_id) {
669 found = 1;
670 }
671 if (found == 1) {
672 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800673 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800674 player->cur_segment_id = segment->segment_id;
675 DVR_DEBUG(1, "get play info id [%lld]", player->cur_segment_id);
676 player->cur_segment.segment_id = segment->segment_id;
677 player->cur_segment.flags = segment->flags;
678 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800679 player->cur_segment.pids.video.pid = segment->pids.video.pid;
680 player->cur_segment.pids.video.format = segment->pids.video.format;
681 player->cur_segment.pids.video.type = segment->pids.video.type;
682 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
683 player->cur_segment.pids.audio.format = segment->pids.audio.format;
684 player->cur_segment.pids.audio.type = segment->pids.audio.type;
685 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
686 player->cur_segment.pids.ad.format = segment->pids.ad.format;
687 player->cur_segment.pids.ad.type = segment->pids.ad.type;
688 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800689 //
hualing chen2aba4022020-03-02 13:49:55 +0800690 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800691 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800692 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800693 aparam->pid = segment->pids.audio.pid;
hualing chena540a7e2020-03-27 16:44:05 +0800694 DVR_DEBUG(1, "get play info sucess[0x%x]apid[0x%x]vfmt[%d]afmt[%d]", vparam->pid, aparam->pid, vparam->codectype, aparam->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800695 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800696 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800697 }
698 }
hualing chencc91e1c2020-02-28 13:26:17 +0800699 if (found != 2) {
700 //list is null or reache list end
701 DVR_DEBUG(1, "get play info fail");
702 return DVR_FAILURE;
703 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800704
705 return DVR_SUCCESS;
706}
hualing chencc91e1c2020-02-28 13:26:17 +0800707static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
708 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800709 if (player == NULL) {
710 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
711 return DVR_FAILURE;
712 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800713
hualing chencc91e1c2020-02-28 13:26:17 +0800714 //compare cur segment
715 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
716 {
717 //check video pids, stop or restart
718 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
719 //check audio pids stop or restart
720 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
721 //check sub audio pids stop or restart
722 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
723 //check pcr pids stop or restart
724 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
725 }
hualing chena540a7e2020-03-27 16:44:05 +0800726 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800727}
hualing chen5cbe1a62020-02-10 16:36:36 +0800728
hualing chencc91e1c2020-02-28 13:26:17 +0800729static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
730{
731 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800732 if (player == NULL) {
733 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
734 return DVR_FAILURE;
735 }
736 DVR_DEBUG(1, "call %s flag[0x%x]id[%lld]last[0x%x][%llu]", __func__, player->cur_segment.flags, player->cur_segment.segment_id, player->last_segment.flags, player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800737 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
738 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800739 //enable display
hualing chen2aba4022020-03-02 13:49:55 +0800740 DVR_DEBUG(1, "call %s unmute", __func__);
741 AmTsPlayer_showVideo(player->handle);
742 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800743 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
744 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800745 //disable display
hualing chencc91e1c2020-02-28 13:26:17 +0800746 DVR_DEBUG(1, "call %s mute", __func__);
hualing chen2aba4022020-03-02 13:49:55 +0800747 AmTsPlayer_hideVideo(player->handle);
748 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800749 }
750 return DVR_SUCCESS;
751}
hualing chena540a7e2020-03-27 16:44:05 +0800752static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
753 DVR_Playback_t *player = (DVR_Playback_t *) handle;
754 if (player == NULL) {
755 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
756 return DVR_TRUE;
757 }
hualing chen266b9502020-04-04 17:39:39 +0800758 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chena540a7e2020-03-27 16:44:05 +0800759 if (player->first_frame == 1) {
760 return DVR_TRUE;
761 } else {
762 return DVR_FALSE;
763 }
764 } else {
765 return DVR_TRUE;
766 }
767}
hualing chen86e7d482020-01-16 15:13:33 +0800768static void* _dvr_playback_thread(void *arg)
769{
hualing chen040df222020-01-17 13:35:02 +0800770 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800771 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800772 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800773 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800774 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800775
hualing chen6d24aa92020-03-23 18:43:47 +0800776 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800777 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800778 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800779 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800780 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
781
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800782 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800783 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800784 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800785
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800786 if (player->is_secure_mode) {
787 if (dec_buf_size > player->secure_buffer_size) {
788 DVR_DEBUG(1, "%s, playback blocksize too large", __func__);
789 return NULL;
790 }
791 }
hualing chen86e7d482020-01-16 15:13:33 +0800792 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800793 if (!buf) {
794 DVR_DEBUG(1, "%s, Malloc buffer failed", __func__);
795 return NULL;
796 }
hualing chen2aba4022020-03-02 13:49:55 +0800797 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
798 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800799
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800800 dec_bufs.buf_data = malloc(dec_buf_size);
801 if (!dec_bufs.buf_data) {
802 DVR_DEBUG(1, "%s, Malloc dec buffer failed", __func__);
803 return NULL;
804 }
805 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
806 dec_bufs.buf_size = dec_buf_size;
807
hualing chencc91e1c2020-02-28 13:26:17 +0800808 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800809 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
810 }
hualing chen86e7d482020-01-16 15:13:33 +0800811
hualing chen86e7d482020-01-16 15:13:33 +0800812 if (ret != DVR_SUCCESS) {
813 if (buf != NULL) {
814 free(buf);
815 buf = NULL;
816 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800817 free(dec_bufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +0800818 DVR_DEBUG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800819 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800820 }
hualing chencc91e1c2020-02-28 13:26:17 +0800821 //get play statue not here
822 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
823 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800824 //set video show
825 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800826
hualing chen86e7d482020-01-16 15:13:33 +0800827 int trick_stat = 0;
828 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800829
hualing chen86e7d482020-01-16 15:13:33 +0800830 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800831 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800832
hualing chen2aba4022020-03-02 13:49:55 +0800833 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
834 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800835 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800836 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen31140872020-03-25 12:29:26 +0800837 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800838 {
hualing chen2aba4022020-03-02 13:49:55 +0800839 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
840 if (trick_stat > 0) {
841 DVR_DEBUG(1, "trick stat[%d] is > 0", trick_stat);
hualing chen87072a82020-03-12 16:20:12 +0800842 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK || (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen2aba4022020-03-02 13:49:55 +0800843 //check last cmd
844 if(player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800845 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800846 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
847 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800848 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
849 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
850 DVR_DEBUG(1, "pause play-------");
851 //need change to pause state
852 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
853 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800854 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800855 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800856 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800857 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800858 AmTsPlayer_pauseVideoDecoding(player->handle);
859 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800860 } else {
861 DVR_DEBUG(1, "clear first frame value-------");
862 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800863 }
864 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
865 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800866 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800867 //restart play stream if speed > 2
868 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
869 _dvr_time_getClock() < player->next_fffb_time) {
hualing chena540a7e2020-03-27 16:44:05 +0800870 DVR_DEBUG(1, "fffb timeout----speed[%f] fffb cur[%d] cur sys[%d] [%s] [%d]", player->speed, player->fffb_current,_dvr_time_getClock(),_dvr_playback_state_toString(player->state), player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +0800871 //used timeout wait need lock first,so we unlock and lock
872 //pthread_mutex_unlock(&player->lock);
873 //pthread_mutex_lock(&player->lock);
874 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
875 pthread_mutex_unlock(&player->lock);
876 continue;
877 }
hualing chen31140872020-03-25 12:29:26 +0800878 DVR_DEBUG(1, "fffb play-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
hualing chen2aba4022020-03-02 13:49:55 +0800879 pthread_mutex_unlock(&player->lock);
880 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800881 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800882 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
883 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800884 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
885 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800886 }
hualing chen2aba4022020-03-02 13:49:55 +0800887 }
hualing chenb31a6c62020-01-13 17:27:00 +0800888 }
hualing chen86e7d482020-01-16 15:13:33 +0800889
hualing chen87072a82020-03-12 16:20:12 +0800890 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800891 //check is need send time send end
892 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800893 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
894 pthread_mutex_unlock(&player->lock);
895 continue;
896 }
hualing chen266b9502020-04-04 17:39:39 +0800897 //when seek action is done. we need drop write timeout data.
898 if (player->drop_ts == DVR_TRUE) {
899 goto_rewrite = DVR_FALSE;
900 real_read = 0;
901 player->drop_ts = DVR_FALSE;
902 }
hualing chen2aba4022020-03-02 13:49:55 +0800903 if (goto_rewrite == DVR_TRUE) {
904 goto_rewrite = DVR_FALSE;
905 pthread_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +0800906 //DVR_DEBUG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +0800907 goto rewrite;
908 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800909 //.check is need send time send end
910 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800911
912 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
913 pthread_mutex_unlock(&player->lock);
914 //if on fb mode and read file end , we need calculate pos to retry read.
915 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chena540a7e2020-03-27 16:44:05 +0800916 DVR_DEBUG(1, "recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]", read,real_read, buf_len, player->speed,player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800917 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
918 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +0800919 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
920 pthread_mutex_unlock(&player->lock);
921 continue;
922 }
hualing chen31140872020-03-25 12:29:26 +0800923 //DVR_DEBUG(1, "read ts [%d]buf_len[%d]speed[%f]real_read:%d", read, buf_len, player->speed, real_read);
hualing chen86e7d482020-01-16 15:13:33 +0800924 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +0800925 //file end.need to play next segment
hualing chen040df222020-01-17 13:35:02 +0800926 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +0800927 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +0800928 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +0800929
930 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +0800931 if (ret != DVR_SUCCESS &&
932 (delay <= MIN_TSPLAYER_DELAY_TIME ||
933 delay > MAX_CACHE_TIME ||
934 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
935 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) &&
936 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) {
hualing chena540a7e2020-03-27 16:44:05 +0800937 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +0800938 DVR_Play_Notify_t notify;
939 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
940 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
941 //get play statue not here
942 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen31140872020-03-25 12:29:26 +0800943 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify);
944 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen041c4092020-04-05 15:11:50 +0800945 DVR_DEBUG(1, "playback is send end delay:[%d]", delay);
hualing chen31140872020-03-25 12:29:26 +0800946 pthread_mutex_lock(&player->lock);
947 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
948 pthread_mutex_unlock(&player->lock);
949 continue;
hualing chena540a7e2020-03-27 16:44:05 +0800950 } else if (ret != DVR_SUCCESS) {
951 //not send event and pause,sleep and go to next time to recheck
hualing chen041c4092020-04-05 15:11:50 +0800952 DVR_DEBUG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +0800953 pthread_mutex_lock(&player->lock);
954 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
955 pthread_mutex_unlock(&player->lock);
956 continue;
hualing chen86e7d482020-01-16 15:13:33 +0800957 }
hualing chen31140872020-03-25 12:29:26 +0800958 //change next segment success case
hualing chencc91e1c2020-02-28 13:26:17 +0800959 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
960 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +0800961 DVR_DEBUG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +0800962 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
hualing chena540a7e2020-03-27 16:44:05 +0800963 DVR_DEBUG(1, "_dvr_replay_changed_pid:end");
hualing chencc91e1c2020-02-28 13:26:17 +0800964 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +0800965 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +0800966 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800967 }
968 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +0800969 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +0800970 wbufs.buf_data = buf;
hualing chena540a7e2020-03-27 16:44:05 +0800971 //check read data len,iflen < 0, we need continue
972 if (wbufs.buf_size == 0 || wbufs.buf_data == NULL) {
973 DVR_DEBUG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +0800974 real_read = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +0800975 continue;
hualing chena540a7e2020-03-27 16:44:05 +0800976 }
hualing chen266b9502020-04-04 17:39:39 +0800977 //if need write whole block size, we need check read buf len is eq block size.
978 if (b_writed_whole_block == DVR_TRUE) {
979 //buf_len is block size value.
980 if (real_read < buf_len) {
981 //coontinue to read data from file
982 DVR_DEBUG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
983 pthread_mutex_lock(&player->lock);
984 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
985 pthread_mutex_unlock(&player->lock);
986 continue;
987 } else if (real_read > buf_len) {
988 DVR_DEBUG(1, "read buf len[%d] is > block size [%d],this error occur", real_read, buf_len);
989 }
990 }
991
pengfei.liu27cc4ec2020-04-03 16:28:16 +0800992 if (player->dec_func) {
993 DVR_CryptoParams_t crypto_params;
994
995 memset(&crypto_params, 0, sizeof(crypto_params));
996 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
997 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
998 crypto_params.segment_id = player->cur_segment.segment_id;
999 crypto_params.offset = segment_tell_position(player->r_handle);
1000
1001 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1002 crypto_params.input_buffer.addr = (size_t)buf;
1003 crypto_params.input_buffer.size = real_read;
1004
1005 if (player->is_secure_mode) {
1006 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1007 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1008 crypto_params.output_buffer.size = dec_buf_size;
1009 ret = player->dec_func(&crypto_params, player->dec_userdata);
1010 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001011 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001012 } else {
1013 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1014 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1015 crypto_params.output_buffer.size = dec_buf_size;
1016 ret = player->dec_func(&crypto_params, player->dec_userdata);
1017 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001018 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001019 }
1020 if (ret != DVR_SUCCESS) {
1021 DVR_DEBUG(1, "%s, decrypt failed", __func__);
1022 }
pengfei.liufda2a972020-04-09 14:47:15 +08001023 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001024 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001025rewrite:
hualing chen041c4092020-04-05 15:11:50 +08001026
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001027 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1028 if (ret == AM_TSPLAYER_OK) {
hualing chena540a7e2020-03-27 16:44:05 +08001029 real_read = 0;
1030 write_success++;
1031 continue;
hualing chen87072a82020-03-12 16:20:12 +08001032 } else {
hualing chena540a7e2020-03-27 16:44:05 +08001033 DVR_DEBUG(1, "write time out write_success:%d", write_success);
1034 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001035 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001036 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001037 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001038 if (!player->is_running) {
hualing chen2aba4022020-03-02 13:49:55 +08001039 DVR_DEBUG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001040 break;
1041 }
hualing chen2aba4022020-03-02 13:49:55 +08001042 goto_rewrite = DVR_TRUE;
1043 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001044 }
1045 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001046 DVR_DEBUG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001047 free(buf);
1048 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001049 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001050}
1051
1052
hualing chen040df222020-01-17 13:35:02 +08001053static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001054{
hualing chen040df222020-01-17 13:35:02 +08001055 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001056 DVR_DEBUG(1, "start thread------[%d]", player->is_running);
hualing chena540a7e2020-03-27 16:44:05 +08001057
1058 if (player == NULL) {
1059 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1060 return DVR_FAILURE;
1061 }
1062
hualing chencc91e1c2020-02-28 13:26:17 +08001063 if (player->is_running == DVR_TRUE) {
hualing chen86e7d482020-01-16 15:13:33 +08001064 return 0;
1065 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001066 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001067 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001068 if (rc < 0)
1069 player->is_running = DVR_FALSE;
hualing chencc91e1c2020-02-28 13:26:17 +08001070 DVR_DEBUG(1, "start thread------[%d] end", player->is_running);
hualing chen86e7d482020-01-16 15:13:33 +08001071 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001072}
1073
1074
hualing chen040df222020-01-17 13:35:02 +08001075static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001076{
hualing chen040df222020-01-17 13:35:02 +08001077 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001078
1079 if (player == NULL) {
1080 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1081 return DVR_FAILURE;
1082 }
1083
hualing chencc91e1c2020-02-28 13:26:17 +08001084 DVR_DEBUG(1, "stopthread------[%d]", player->is_running);
1085 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001086 {
1087 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001088 _dvr_playback_sendSignal(handle);
hualing chencc91e1c2020-02-28 13:26:17 +08001089 //pthread_cond_signal(&player->cond);
hualing chen86e7d482020-01-16 15:13:33 +08001090 pthread_join(player->playback_thread, NULL);
1091 }
1092 if (player->r_handle) {
1093 segment_close(player->r_handle);
1094 player->r_handle = NULL;
1095 }
hualing chen87072a82020-03-12 16:20:12 +08001096 DVR_DEBUG(1, "stopthread------[%d]", player->is_running);
hualing chen86e7d482020-01-16 15:13:33 +08001097 return 0;
1098}
1099
hualing chenb31a6c62020-01-13 17:27:00 +08001100/**\brief Open an dvr palyback
1101 * \param[out] p_handle dvr playback addr
1102 * \param[in] params dvr playback open parameters
1103 * \retval DVR_SUCCESS On success
1104 * \return Error code
1105 */
hualing chen040df222020-01-17 13:35:02 +08001106int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001107
hualing chen040df222020-01-17 13:35:02 +08001108 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001109 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001110
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001111 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001112
hualing chen86e7d482020-01-16 15:13:33 +08001113 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001114 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001115 pthread_condattr_init(&cattr);
1116 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1117 pthread_cond_init(&player->cond, &cattr);
1118 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001119
hualing chen5cbe1a62020-02-10 16:36:36 +08001120 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001121 INIT_LIST_HEAD(&player->segment_list);
1122 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1123 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001124 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001125 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001126 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001127 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001128 player->speed = 1.0f;
hualing chen2aba4022020-03-02 13:49:55 +08001129
hualing chen86e7d482020-01-16 15:13:33 +08001130 //store open params
hualing chen040df222020-01-17 13:35:02 +08001131 player->openParams.dmx_dev_id = params->dmx_dev_id;
1132 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001133 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001134 player->openParams.event_fn = params->event_fn;
1135 player->openParams.event_userdata = params->event_userdata;
1136
hualing chen5cbe1a62020-02-10 16:36:36 +08001137 player->has_pids = params->has_pids;
1138
hualing chen2aba4022020-03-02 13:49:55 +08001139 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001140
1141 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1142 //for test get callback
1143 if (0 && player->player_callback_func == NULL) {
1144 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1145 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1146 DVR_DEBUG(1, "playback open get callback[%p][%p][%p][%p]",player->player_callback_func, player->player_callback_userdata, _dvr_tsplayer_callback_test,player);
1147 }
1148 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001149
hualing chen86e7d482020-01-16 15:13:33 +08001150 //init has audio and video
1151 player->has_video = DVR_FALSE;
1152 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001153 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001154 player->last_segment_id = 0LL;
1155 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001156
hualing chen5cbe1a62020-02-10 16:36:36 +08001157 //init ff fb time
1158 player->fffb_current = -1;
1159 player->fffb_start =-1;
1160 player->fffb_start_pcr = -1;
1161 //seek time
1162 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001163 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001164
1165 //init secure stuff
1166 player->dec_func = NULL;
1167 player->dec_userdata = NULL;
1168 player->is_secure_mode = 0;
1169 player->secure_buffer = NULL;
1170 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001171 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001172
hualing chen86e7d482020-01-16 15:13:33 +08001173 *p_handle = player;
1174 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001175}
1176
1177/**\brief Close an dvr palyback
1178 * \param[in] handle playback handle
1179 * \retval DVR_SUCCESS On success
1180 * \return Error code
1181 */
hualing chen040df222020-01-17 13:35:02 +08001182int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001183
hualing chen86e7d482020-01-16 15:13:33 +08001184 DVR_ASSERT(handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001185
hualing chen040df222020-01-17 13:35:02 +08001186 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +08001187 DVR_DEBUG(1, "func: %s, will resume", __func__);
hualing chena540a7e2020-03-27 16:44:05 +08001188
1189 if (player == NULL) {
1190 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1191 return DVR_FAILURE;
1192 }
1193
hualing chencc91e1c2020-02-28 13:26:17 +08001194 if (player->state != DVR_PLAYBACK_STATE_STOP)
1195 {
1196 dvr_playback_stop(handle, DVR_TRUE);
1197 }
hualing chena540a7e2020-03-27 16:44:05 +08001198 //AmTsPlayer_resumeVideoDecoding(player->handle);
1199 //AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001200 pthread_mutex_destroy(&player->lock);
1201 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001202
1203 if (player) {
1204 free(player);
1205 player = NULL;
1206 }
hualing chen86e7d482020-01-16 15:13:33 +08001207 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001208}
1209
hualing chenb31a6c62020-01-13 17:27:00 +08001210/**\brief Start play audio and video, used start auido api and start video api
1211 * \param[in] handle playback handle
1212 * \param[in] params audio playback params,contains fmt and pid...
1213 * \retval DVR_SUCCESS On success
1214 * \return Error code
1215 */
hualing chen040df222020-01-17 13:35:02 +08001216int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1217 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001218 am_tsplayer_video_params vparams;
1219 am_tsplayer_audio_params aparams;
hualing chena540a7e2020-03-27 16:44:05 +08001220
1221 if (player == NULL) {
1222 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1223 return DVR_FAILURE;
1224 }
hualing chencc91e1c2020-02-28 13:26:17 +08001225 uint64_t segment_id = player->cur_segment_id;
1226 DVR_DEBUG(1, "[%s][%p]segment_id:[%lld]",__func__, handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001227
hualing chena540a7e2020-03-27 16:44:05 +08001228 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001229 //can used start api to resume playback
1230 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1231 return dvr_playback_resume(handle);
1232 }
hualing chen87072a82020-03-12 16:20:12 +08001233 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
1234 DVR_DEBUG(1, "stat is start, not need into start play");
1235 return DVR_SUCCESS;
1236 }
hualing chen86e7d482020-01-16 15:13:33 +08001237 player->play_flag = flag;
hualing chen5cbe1a62020-02-10 16:36:36 +08001238 //get segment info and audio video pid fmt ;
hualing chen31140872020-03-25 12:29:26 +08001239 DVR_DEBUG(1, "lock func: %s %p flag:0x%x", __func__, handle, flag);
hualing chen86e7d482020-01-16 15:13:33 +08001240 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001241 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001242 //start audio and video
1243 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1244 //audio abnd video pis is all invalid, return error.
1245 DVR_DEBUG(0, "dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001246 DVR_DEBUG(1, "unlock func: %s", __func__);
1247 pthread_mutex_unlock(&player->lock);
1248 DVR_Play_Notify_t notify;
1249 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1250 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1251 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1252 notify.info.transition_failed_data.segment_id = segment_id;
1253 //get play statue not here
1254 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify);
hualing chen86e7d482020-01-16 15:13:33 +08001255 return -1;
1256 }
hualing chen31140872020-03-25 12:29:26 +08001257
hualing chencc91e1c2020-02-28 13:26:17 +08001258 {
hualing chen86e7d482020-01-16 15:13:33 +08001259 if (VALID_PID(vparams.pid)) {
1260 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001261 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001262 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1263 DVR_DEBUG(1, "set trick mode -pauselive flag--");
1264 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1265 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001266 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen31140872020-03-25 12:29:26 +08001267 DVR_DEBUG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001268 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001269 } else {
1270 DVR_DEBUG(1, "set trick mode ---none");
1271 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001272 }
1273 AmTsPlayer_setVideoParams(player->handle, &vparams);
1274 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001275 }
hualing chena540a7e2020-03-27 16:44:05 +08001276
hualing chen6d24aa92020-03-23 18:43:47 +08001277 DVR_DEBUG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
hualing chencc91e1c2020-02-28 13:26:17 +08001278 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1279 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1280 player->cmd.state = DVR_PLAYBACK_STATE_START;
1281 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001282 } else {
1283 player->cmd.last_cmd = player->cmd.cur_cmd;
1284 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001285 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001286 //set fast play
1287 DVR_DEBUG(1, "dvr start fast mode");
1288 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001289 } else {
1290 if (VALID_PID(aparams.pid)) {
1291 DVR_DEBUG(1, "%s :start audio---", __func__);
1292 player->has_audio = DVR_TRUE;
1293 AmTsPlayer_setAudioParams(player->handle, &aparams);
1294 AmTsPlayer_startAudioDecoding(player->handle);
1295 }
hualing chen31140872020-03-25 12:29:26 +08001296 }
hualing chencc91e1c2020-02-28 13:26:17 +08001297 player->cmd.state = DVR_PLAYBACK_STATE_START;
1298 player->state = DVR_PLAYBACK_STATE_START;
1299 }
hualing chen86e7d482020-01-16 15:13:33 +08001300 }
hualing chencc91e1c2020-02-28 13:26:17 +08001301 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001302 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001303 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001304 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001305}
hualing chen040df222020-01-17 13:35:02 +08001306/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001307 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001308 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001309 * \retval DVR_SUCCESS On success
1310 * \return Error code
1311 */
hualing chen040df222020-01-17 13:35:02 +08001312int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1313 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001314 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001315
hualing chena540a7e2020-03-27 16:44:05 +08001316 if (player == NULL) {
1317 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1318 return DVR_FAILURE;
1319 }
1320
hualing chencc91e1c2020-02-28 13:26:17 +08001321 DVR_DEBUG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001322 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001323
hualing chen040df222020-01-17 13:35:02 +08001324 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1325 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001326
hualing chen86e7d482020-01-16 15:13:33 +08001327 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001328 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001329 //cp location
hualing chen040df222020-01-17 13:35:02 +08001330 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001331
1332 DVR_DEBUG(1, "add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001333 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001334
1335 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001336 segment->pids.video.pid = info->pids.video.pid;
1337 segment->pids.video.format = info->pids.video.format;
1338 segment->pids.video.type = info->pids.video.type;
1339
hualing chen2aba4022020-03-02 13:49:55 +08001340 segment->pids.audio.pid = info->pids.audio.pid;
1341 segment->pids.audio.format = info->pids.audio.format;
1342 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001343
hualing chen2aba4022020-03-02 13:49:55 +08001344 segment->pids.ad.pid = info->pids.ad.pid;
1345 segment->pids.ad.format = info->pids.ad.format;
1346 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001347
1348 segment->pids.pcr.pid = info->pids.pcr.pid;
1349
1350 DVR_DEBUG(1, "lock func: %s pid [0x%x][0x%x][0x%x][0x%x]", __func__,segment->pids.video.pid,segment->pids.audio.pid, info->pids.video.pid,info->pids.audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001351 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001352 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001353 pthread_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001354 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chenb31a6c62020-01-13 17:27:00 +08001355
hualing chen5cbe1a62020-02-10 16:36:36 +08001356 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001357}
hualing chen040df222020-01-17 13:35:02 +08001358/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001359 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001360 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001361 * \retval DVR_SUCCESS On success
1362 * \return Error code
1363 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001364int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001365 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen5cbe1a62020-02-10 16:36:36 +08001366 DVR_DEBUG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001367
1368 if (player == NULL) {
1369 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1370 return DVR_FAILURE;
1371 }
1372
hualing chencc91e1c2020-02-28 13:26:17 +08001373 if (segment_id == player->cur_segment_id) {
1374 DVR_DEBUG(1, "not suport remove curren segment id: %lld", segment_id);
1375 return DVR_FAILURE;
1376 }
1377 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001378 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001379 DVR_PlaybackSegmentInfo_t *segment = NULL;
1380 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1381 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001382 {
hualing chen040df222020-01-17 13:35:02 +08001383 if (segment->segment_id == segment_id) {
1384 list_del(&segment->head);
1385 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001386 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001387 }
hualing chen86e7d482020-01-16 15:13:33 +08001388 }
hualing chencc91e1c2020-02-28 13:26:17 +08001389 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001390 pthread_mutex_unlock(&player->lock);
1391
1392 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001393}
hualing chen040df222020-01-17 13:35:02 +08001394/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001395 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001396 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001397 * \retval DVR_SUCCESS On success
1398 * \return Error code
1399 */
hualing chen040df222020-01-17 13:35:02 +08001400int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001401 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001402 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen5cbe1a62020-02-10 16:36:36 +08001403 DVR_DEBUG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chenb31a6c62020-01-13 17:27:00 +08001404
hualing chena540a7e2020-03-27 16:44:05 +08001405 if (player == NULL) {
1406 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1407 return DVR_FAILURE;
1408 }
1409
hualing chen040df222020-01-17 13:35:02 +08001410 DVR_PlaybackSegmentInfo_t *segment;
hualing chencc91e1c2020-02-28 13:26:17 +08001411 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001412 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001413 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001414 {
hualing chen040df222020-01-17 13:35:02 +08001415 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001416 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001417 }
hualing chen86e7d482020-01-16 15:13:33 +08001418 // if encramble to free, only set flag and return;
1419
1420 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001421 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001422 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1423 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001424 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001425 AmTsPlayer_hideVideo(player->handle);
1426 AmTsPlayer_setAudioMute(player->handle, 1, 1);
1427 //playback_device_mute_audio(player->handle, 1);
1428 //playback_device_mute_video(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001429 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1430 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001431 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001432 AmTsPlayer_showVideo(player->handle);
1433 AmTsPlayer_setAudioMute(player->handle, 0, 0);
1434 //playback_device_mute_audio(player->handle, 0);
1435 //playback_device_mute_video(player->handle, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001436 } else {
1437 //do nothing
1438 }
1439 } else {
1440 //do nothing
1441 }
1442 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001443 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001444 }
hualing chencc91e1c2020-02-28 13:26:17 +08001445 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001446 pthread_mutex_unlock(&player->lock);
1447 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001448}
1449
1450
hualing chen5cbe1a62020-02-10 16:36:36 +08001451static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type) {
hualing chen040df222020-01-17 13:35:02 +08001452 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001453 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001454
hualing chena540a7e2020-03-27 16:44:05 +08001455 if (player == NULL) {
1456 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1457 return DVR_FAILURE;
1458 }
1459
hualing chen86e7d482020-01-16 15:13:33 +08001460 if (now_pid.pid == set_pid.pid) {
1461 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001462 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001463 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001464 if (VALID_PID(now_pid.pid)) {
1465 //stop now stream
1466 if (type == 0) {
1467 //stop vieo
hualing chena540a7e2020-03-27 16:44:05 +08001468 DVR_DEBUG(1, "[%s]stop video",__func__);
hualing chen2aba4022020-03-02 13:49:55 +08001469 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001470 player->has_video = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001471 } else if (type == 1) {
1472 //stop audio
hualing chena540a7e2020-03-27 16:44:05 +08001473 DVR_DEBUG(1, "[%s]stop audio",__func__);
hualing chen2aba4022020-03-02 13:49:55 +08001474 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001475 player->has_audio = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001476 } else if (type == 2) {
1477 //stop sub audio
hualing chena540a7e2020-03-27 16:44:05 +08001478 DVR_DEBUG(1, "[%s]stop ad",__func__);
1479 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001480 } else if (type == 3) {
1481 //pcr
1482 }
1483 }
1484 if (VALID_PID(set_pid.pid)) {
1485 //start
1486 if (type == 0) {
1487 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001488 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001489 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001490 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001491 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001492 DVR_DEBUG(1, "[%s]start video pid[%d]fmt[%d]",__func__,vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001493 AmTsPlayer_setVideoParams(player->handle, &vparams);
1494 AmTsPlayer_startVideoDecoding(player->handle);
1495 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001496 } else if (type == 1) {
1497 //start audio
hualing chen2aba4022020-03-02 13:49:55 +08001498 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001499 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001500 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001501 player->has_audio = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001502 DVR_DEBUG(1, "[%s]start audio pid[%d]fmt[%d]",__func__,aparams.pid, aparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001503 AmTsPlayer_setAudioParams(player->handle, &aparams);
1504 AmTsPlayer_startAudioDecoding(player->handle);
1505 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001506 } else if (type == 2) {
hualing chen2aba4022020-03-02 13:49:55 +08001507 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001508 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001509 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001510 player->has_audio = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001511 DVR_DEBUG(1, "[%s]start ad audio pid[%d]fmt[%d]",__func__,aparams.pid, aparams.codectype);
1512 AmTsPlayer_setADParams(player->handle, &aparams);
1513 AmTsPlayer_enableADMix(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001514 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001515 } else if (type == 3) {
1516 //pcr
hualing chena540a7e2020-03-27 16:44:05 +08001517 DVR_DEBUG(1, "[%s]start set pcr [%d]",__func__, set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001518 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001519 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001520 //audio and video all close
1521 if (!player->has_audio && !player->has_video) {
1522 player->state = DVR_PLAYBACK_STATE_STOP;
1523 }
hualing chen86e7d482020-01-16 15:13:33 +08001524 }
1525 }
1526 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001527}
hualing chen5cbe1a62020-02-10 16:36:36 +08001528/**\brief dvr play back update segment pids
1529 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001530 * add pid stream and stop remove pid stream.
1531 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001532 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001533 * \retval DVR_SUCCESS On success
1534 * \return Error code
1535 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001536int dvr_playback_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
hualing chen040df222020-01-17 13:35:02 +08001537 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001538 DVR_DEBUG(1, "update segment id: %lld", segment_id);
1539 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001540
hualing chena540a7e2020-03-27 16:44:05 +08001541 if (player == NULL) {
1542 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1543 return DVR_FAILURE;
1544 }
1545
hualing chen040df222020-01-17 13:35:02 +08001546 DVR_PlaybackSegmentInfo_t *segment;
hualing chencc91e1c2020-02-28 13:26:17 +08001547 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001548 pthread_mutex_lock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001549 DVR_DEBUG(1, "get lock [%p] update segment id: %lld cur id %lld",handle, segment_id, player->cur_segment_id);
1550
hualing chen040df222020-01-17 13:35:02 +08001551 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001552 {
hualing chen040df222020-01-17 13:35:02 +08001553 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001554
1555 if (player->cur_segment_id == segment_id) {
1556 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1557 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1558 //do nothing when ff fb
1559 DVR_DEBUG(1, "now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001560 DVR_DEBUG(1, "unlock func: %s", __func__);
1561 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001562 return 0;
1563 }
1564
1565 //if segment is on going segment,we need stop start stream
1566 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001567 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001568 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001569 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001570 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001571 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001572 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001573 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001574 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001575 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1576 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001577 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1578 //if state is pause, we need process at resume api. we only record change info
1579 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1580 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1581 if (VALID_PID(segment->pids.video.pid)
1582 && VALID_PID(p_pids->video.pid)
1583 && segment->pids.video.pid != p_pids->video.pid) {
1584 //restart video
1585 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1586 }
1587 if (!VALID_PID(segment->pids.video.pid)
1588 && VALID_PID(p_pids->video.pid)
1589 && segment->pids.video.pid != p_pids->video.pid) {
1590 //start video
1591 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1592 }
1593 if (VALID_PID(segment->pids.video.pid)
1594 && !VALID_PID(p_pids->video.pid)
1595 && segment->pids.video.pid != p_pids->video.pid) {
1596 //stop video
1597 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1598 }
1599 if (VALID_PID(segment->pids.audio.pid)
1600 && VALID_PID(p_pids->audio.pid)
1601 && segment->pids.audio.pid != p_pids->audio.pid) {
1602 //restart audio
1603 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1604 }
1605 if (!VALID_PID(segment->pids.audio.pid)
1606 && VALID_PID(p_pids->audio.pid)
1607 && segment->pids.audio.pid != p_pids->audio.pid) {
1608 //start audio
1609 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1610 }
1611 if (VALID_PID(segment->pids.audio.pid)
1612 && !VALID_PID(p_pids->audio.pid)
1613 && segment->pids.audio.pid != p_pids->audio.pid) {
1614 //stop audio
1615 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1616 }
1617 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1618 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1619 //do nothing
1620 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1621 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1622 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1623 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1624 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1625 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1626 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1627 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1628 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1629 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1630 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1631 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1632 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1633 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1634 } else {
1635 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1636 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1637 }
1638
1639 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1640 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1641 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1642 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1643 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1644 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1645 //not occur this case
1646 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1647 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1648 } else {
1649 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1650 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1651 }
1652
1653 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1654 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1655 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1656 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1657 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1658 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1659 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1660 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1661 } else {
1662 //not occur this case
1663 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1664 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1665 }
1666 }
1667 }
1668 }
hualing chen86e7d482020-01-16 15:13:33 +08001669 //save pids info
hualing chen040df222020-01-17 13:35:02 +08001670 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +08001671 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001672 }
hualing chen86e7d482020-01-16 15:13:33 +08001673 }
hualing chencc91e1c2020-02-28 13:26:17 +08001674 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001675 pthread_mutex_unlock(&player->lock);
1676 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001677}
1678/**\brief Stop play, will stop video and audio
1679 * \param[in] handle playback handle
1680 * \param[in] clear is clear last frame
1681 * \retval DVR_SUCCESS On success
1682 * \return Error code
1683 */
hualing chen040df222020-01-17 13:35:02 +08001684int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1685 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001686
1687 if (player == NULL) {
1688 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1689 return DVR_FAILURE;
1690 }
hualing chencc91e1c2020-02-28 13:26:17 +08001691 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen87072a82020-03-12 16:20:12 +08001692 _stop_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001693 pthread_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001694 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001695 if (player->has_video) {
1696 AmTsPlayer_resumeVideoDecoding(player->handle);
1697 }
1698 if (player->has_audio) {
1699 AmTsPlayer_resumeAudioDecoding(player->handle);
1700 }
1701 if (player->has_video) {
1702 player->has_video = DVR_FALSE;
1703 AmTsPlayer_showVideo(player->handle);
1704 AmTsPlayer_stopVideoDecoding(player->handle);
1705 }
1706 if (player->has_audio) {
1707 player->has_audio = DVR_FALSE;
1708 AmTsPlayer_stopAudioDecoding(player->handle);
1709 }
1710
hualing chen86e7d482020-01-16 15:13:33 +08001711 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001712 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1713 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1714 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001715 player->cur_segment_id = UINT64_MAX;
1716 player->segment_is_open = DVR_FALSE;
hualing chencc91e1c2020-02-28 13:26:17 +08001717 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001718 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001719 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001720}
1721/**\brief Start play audio
1722 * \param[in] handle playback handle
1723 * \param[in] params audio playback params,contains fmt and pid...
1724 * \retval DVR_SUCCESS On success
1725 * \return Error code
1726 */
hualing chen2aba4022020-03-02 13:49:55 +08001727
1728int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001729 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001730
1731 if (player == NULL) {
1732 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1733 return DVR_FAILURE;
1734 }
1735
hualing chencc91e1c2020-02-28 13:26:17 +08001736 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chen86e7d482020-01-16 15:13:33 +08001737 _start_playback_thread(handle);
1738 //start audio and video
hualing chencc91e1c2020-02-28 13:26:17 +08001739 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001740 pthread_mutex_lock(&player->lock);
1741 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001742 AmTsPlayer_setAudioParams(player->handle, param);
1743 AmTsPlayer_startAudioDecoding(player->handle);
1744 //playback_device_audio_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001745 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001746 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1747 player->cmd.state = DVR_PLAYBACK_STATE_START;
1748 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001749 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001750 pthread_mutex_unlock(&player->lock);
1751 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001752}
1753/**\brief Stop play audio
1754 * \param[in] handle playback handle
1755 * \retval DVR_SUCCESS On success
1756 * \return Error code
1757 */
hualing chen040df222020-01-17 13:35:02 +08001758int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1759 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001760
1761 if (player == NULL) {
1762 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1763 return DVR_FAILURE;
1764 }
1765
hualing chencc91e1c2020-02-28 13:26:17 +08001766 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001767 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001768
hualing chen2aba4022020-03-02 13:49:55 +08001769 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001770 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001771 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1772 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001773 //destory thread
1774 _stop_playback_thread(handle);
1775 } else {
1776 //do nothing.video is playing
1777 }
hualing chen87072a82020-03-12 16:20:12 +08001778 player->has_audio = DVR_FALSE;
1779
1780 AmTsPlayer_stopAudioDecoding(player->handle);
1781 player->cmd.last_cmd = player->cmd.cur_cmd;
1782 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
1783
hualing chencc91e1c2020-02-28 13:26:17 +08001784 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001785 pthread_mutex_unlock(&player->lock);
1786 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001787}
1788/**\brief Start play video
1789 * \param[in] handle playback handle
1790 * \param[in] params video playback params,contains fmt and pid...
1791 * \retval DVR_SUCCESS On success
1792 * \return Error code
1793 */
hualing chen2aba4022020-03-02 13:49:55 +08001794int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001795 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001796
1797 if (player == NULL) {
1798 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1799 return DVR_FAILURE;
1800 }
1801
hualing chen86e7d482020-01-16 15:13:33 +08001802 _start_playback_thread(handle);
1803 //start audio and video
hualing chencc91e1c2020-02-28 13:26:17 +08001804 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001805 pthread_mutex_lock(&player->lock);
1806 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001807 AmTsPlayer_setVideoParams(player->handle, param);
1808 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001809
1810 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001811 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08001812 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen87072a82020-03-12 16:20:12 +08001813 DVR_DEBUG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08001814 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1815 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08001816 }
1817 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001818 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
1819 player->cmd.state = DVR_PLAYBACK_STATE_START;
1820 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001821 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001822 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001823 return DVR_SUCCESS;
1824}
1825/**\brief Stop play video
1826 * \param[in] handle playback handle
1827 * \retval DVR_SUCCESS On success
1828 * \return Error code
1829 */
hualing chen040df222020-01-17 13:35:02 +08001830int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
1831 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001832
1833 if (player == NULL) {
1834 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1835 return DVR_FAILURE;
1836 }
1837
hualing chencc91e1c2020-02-28 13:26:17 +08001838 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001839 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001840
1841 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001842 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1843 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001844 //destory thread
1845 _stop_playback_thread(handle);
1846 } else {
1847 //do nothing.audio is playing
1848 }
hualing chen87072a82020-03-12 16:20:12 +08001849 player->has_video = DVR_FALSE;
1850
1851 AmTsPlayer_stopVideoDecoding(player->handle);
1852 //playback_device_video_stop(player->handle);
1853
1854 player->cmd.last_cmd = player->cmd.cur_cmd;
1855 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
1856
hualing chencc91e1c2020-02-28 13:26:17 +08001857 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001858 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001859 return DVR_SUCCESS;
1860}
1861/**\brief Pause play
1862 * \param[in] handle playback handle
1863 * \param[in] flush whether its internal buffers should be flushed
1864 * \retval DVR_SUCCESS On success
1865 * \return Error code
1866 */
hualing chen040df222020-01-17 13:35:02 +08001867int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
1868 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001869 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chena540a7e2020-03-27 16:44:05 +08001870
1871 if (player == NULL) {
1872 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1873 return DVR_FAILURE;
1874 }
1875
hualing chen86e7d482020-01-16 15:13:33 +08001876 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001877 DVR_DEBUG(1, "get lock func: %s", __func__);
hualing chen266b9502020-04-04 17:39:39 +08001878 if (player->has_video)
1879 AmTsPlayer_pauseVideoDecoding(player->handle);
1880 if (player->has_video)
1881 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001882
1883 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001884 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1885 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1886 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1887 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001888 } else {
1889 player->cmd.last_cmd = player->cmd.cur_cmd;
1890 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1891 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1892 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001893 }
hualing chen86e7d482020-01-16 15:13:33 +08001894 pthread_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001895 DVR_DEBUG(1, "unlock func: %s", __func__);
1896
hualing chen86e7d482020-01-16 15:13:33 +08001897 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001898}
1899
hualing chen5cbe1a62020-02-10 16:36:36 +08001900//not add lock
1901static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
1902{
1903 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1904
hualing chena540a7e2020-03-27 16:44:05 +08001905 if (player == NULL) {
1906 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1907 return DVR_FAILURE;
1908 }
1909
hualing chen5cbe1a62020-02-10 16:36:36 +08001910 //get video params and audio params
hualing chencc91e1c2020-02-28 13:26:17 +08001911 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08001912 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001913 am_tsplayer_video_params vparams;
1914 am_tsplayer_audio_params aparams;
hualing chencc91e1c2020-02-28 13:26:17 +08001915 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08001916
1917 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
hualing chen87072a82020-03-12 16:20:12 +08001918 DVR_DEBUG(1, "unlock func: %s cmd: %d", __func__, cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08001919 pthread_mutex_unlock(&player->lock);
1920
1921 switch (cmd) {
1922 case DVR_PLAYBACK_CMD_AVRESTART:
1923 //av restart
hualing chen87072a82020-03-12 16:20:12 +08001924 DVR_DEBUG(1, "do_cmd avrestart");
1925 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001926 break;
1927 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001928 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1929 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001930 break;
1931 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001932 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001933 break;
1934 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001935 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001936 break;
1937 case DVR_PLAYBACK_CMD_ARESTART:
1938 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08001939 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1940 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001941 break;
1942 case DVR_PLAYBACK_CMD_ASTART:
hualing chen2aba4022020-03-02 13:49:55 +08001943 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001944 break;
1945 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001946 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001947 break;
1948 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001949 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1950 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1951 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001952 break;
1953 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001954 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1955 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001956 break;
1957 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001958 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1959 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1960 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001961 break;
1962 case DVR_PLAYBACK_CMD_STOP:
1963 break;
1964 case DVR_PLAYBACK_CMD_START:
1965 break;
1966 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001967 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1968 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
1969 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001970 break;
1971 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001972 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1973 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
1974 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001975 break;
1976 case DVR_PLAYBACK_CMD_FF:
1977 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08001978 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001979 break;
1980 default:
1981 break;
1982 }
1983 return DVR_SUCCESS;
1984}
1985
1986/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08001987 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08001988 * \retval DVR_SUCCESS On success
1989 * \return Error code
1990 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001991int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
1992 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1993
hualing chena540a7e2020-03-27 16:44:05 +08001994 if (player == NULL) {
1995 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1996 return DVR_FAILURE;
1997 }
1998
hualing chen5cbe1a62020-02-10 16:36:36 +08001999 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002000 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002001 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002002 if (player->has_video) {
2003 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2004 AmTsPlayer_resumeVideoDecoding(player->handle);
2005 }
2006 if (player->has_audio) {
2007 AmTsPlayer_resumeAudioDecoding(player->handle);
2008 }
2009 //check is has audio param,if has audio .we need start audio,
2010 //we will stop audio when ff fb, if reach end, we will pause.so we need
2011 //start audio when resume play
2012
2013 am_tsplayer_video_params vparams;
2014 am_tsplayer_audio_params aparams;
2015 uint64_t segmentid = player->cur_segment_id;
2016 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
2017 //valid audio pid, start audio
2018 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid)) {
2019 player->has_audio = DVR_TRUE;
2020 AmTsPlayer_setAudioParams(player->handle, &aparams);
2021 AmTsPlayer_startAudioDecoding(player->handle);
2022 } else {
2023 DVR_DEBUG(1, "aparams.pid:%d player->has_audio:%d", aparams.pid, player->has_audio);
2024 }
hualing chen87072a82020-03-12 16:20:12 +08002025 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2026 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2027 player->cmd.state = DVR_PLAYBACK_STATE_START;
2028 player->state = DVR_PLAYBACK_STATE_START;
2029 } else {
2030 player->cmd.last_cmd = player->cmd.cur_cmd;
2031 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2032 player->cmd.state = DVR_PLAYBACK_STATE_START;
2033 player->state = DVR_PLAYBACK_STATE_START;
2034 }
hualing chencc91e1c2020-02-28 13:26:17 +08002035 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002036 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002037 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
2038 if (player->has_video)
2039 AmTsPlayer_resumeVideoDecoding(player->handle);
2040 if (player->has_audio)
2041 AmTsPlayer_resumeAudioDecoding(player->handle);
2042 DVR_DEBUG(1, "func: %s, set start state cur cmd[%d]", __func__, player->cmd.cur_cmd, player->state, player->cmd.state);
hualing chen2aba4022020-03-02 13:49:55 +08002043 player->cmd.state = DVR_PLAYBACK_STATE_START;
2044 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002045 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002046 } else {
2047 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2048 {
2049 pthread_mutex_lock(&player->lock);
2050 //clear flag
2051 DVR_DEBUG(1, "func: %s, clear pause live flag cur cmd[%d]", __func__, player->cmd.cur_cmd);
2052 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2053 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2054 pthread_mutex_unlock(&player->lock);
2055 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002056 }
2057 return DVR_SUCCESS;
2058}
2059
hualing chena540a7e2020-03-27 16:44:05 +08002060static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2061
2062 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2063 DVR_PlaybackSegmentInfo_t *segment = NULL;
2064 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2065 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2066
2067 list_for_each_entry(segment, &player->segment_list, head)
2068 {
2069 if (segment->segment_id == segment_id) {
2070 cur_segment = segment;
2071 }
2072 if (segment->segment_id == set_seg_id) {
2073 set_segment = segment;
2074 }
2075 if (cur_segment != NULL && set_segment != NULL) {
2076 break;
2077 }
2078 }
2079 if (cur_segment == NULL || set_segment == NULL) {
2080 DVR_DEBUG(1, "set segmen or cur segment is null");
2081 return DVR_TRUE;
2082 }
2083 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2084 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2085 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2086 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
2087 DVR_DEBUG(1, "cur v[%d]a[%d] set v[%d]a[%d]",cur_segment->pids.video.pid,cur_segment->pids.audio.pid,set_segment->pids.video.pid,set_segment->pids.audio.pid);
2088 return DVR_TRUE;
2089 }
2090 DVR_DEBUG(1, "%s:play info not change", __func__);
2091 return DVR_FALSE;
2092}
2093
hualing chen5cbe1a62020-02-10 16:36:36 +08002094/**\brief seek
2095 * \param[in] handle playback handle
2096 * \param[in] time_offset time offset base cur segment
2097 * \retval DVR_SUCCESS On success
2098 * \return Error code
2099 */
hualing chencc91e1c2020-02-28 13:26:17 +08002100int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002101 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002102
2103 if (player == NULL) {
2104 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2105 return DVR_FAILURE;
2106 }
2107
2108 DVR_DEBUG(1, "lock func: %s segment_id %llu cur id %llu time_offset %u cur end: %d", __func__, segment_id,player->cur_segment_id, (uint32_t)time_offset, _dvr_get_end_time(handle));
hualing chencc91e1c2020-02-28 13:26:17 +08002109 DVR_DEBUG(1, "[%s][%p]---player->state[%d]----",__func__, handle, player->state);
hualing chen86e7d482020-01-16 15:13:33 +08002110 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002111
hualing chen86e7d482020-01-16 15:13:33 +08002112 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002113 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
2114 DVR_DEBUG(1, "[%s][%p]---player->state[%d]-replay[%d]--get lock-",__func__, handle, player->state, replay);
2115
hualing chen5cbe1a62020-02-10 16:36:36 +08002116 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002117 int ret = _dvr_open_segment(handle, segment_id);
2118 if (ret ==DVR_FAILURE) {
2119 DVR_DEBUG(1, "seek error at open segment");
2120 pthread_mutex_unlock(&player->lock);
2121 return DVR_FAILURE;
2122 }
2123 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2124 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
2125 DVR_DEBUG(1, "is ongoing segment when seek end, need return success");
2126 //pthread_mutex_unlock(&player->lock);
2127 //return DVR_SUCCESS;
2128 time_offset = _dvr_get_end_time(handle);
2129 } else {
2130 DVR_DEBUG(1, "is not ongoing segment when seek end, return failure");
2131 pthread_mutex_unlock(&player->lock);
2132 return DVR_FAILURE;
2133 }
2134 }
2135
hualing chencc91e1c2020-02-28 13:26:17 +08002136 DVR_DEBUG(1, "seek open id[%lld]flag[0x%x] time_offset %u", player->cur_segment.segment_id, player->cur_segment.flags, time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08002137 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002138 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2139 //forward playback.not seek end of file
2140 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2141 //default -2000ms
2142 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2143 }
hualing chen86e7d482020-01-16 15:13:33 +08002144 }
hualing chen2aba4022020-03-02 13:49:55 +08002145 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002146 player->drop_ts = DVR_TRUE;
2147 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen2aba4022020-03-02 13:49:55 +08002148 DVR_DEBUG(0, "---seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
2149 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002150 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002151
hualing chen2aba4022020-03-02 13:49:55 +08002152 _dvr_get_end_time(handle);
2153 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002154 player->fffb_current = _dvr_time_getClock();
2155 player->fffb_start = player->fffb_current;
2156 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2157 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002158 //pause state if need to replayer false
2159 if (player->state == DVR_PLAYBACK_STATE_STOP ||
2160 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002161 //only seek file,not start
hualing chencc91e1c2020-02-28 13:26:17 +08002162 DVR_DEBUG(1, "unlock func: %s", __func__);
2163 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002164 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002165 }
hualing chen86e7d482020-01-16 15:13:33 +08002166 //stop play
hualing chen2aba4022020-03-02 13:49:55 +08002167 DVR_DEBUG(0, "seek stop play, not inject data has video[%d]audio[%d]", player->has_video, player->has_audio);
hualing chen266b9502020-04-04 17:39:39 +08002168 if (player->has_video) {
2169 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002170 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002171 }
2172
2173 if (player->has_audio) {
2174 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002175 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002176 }
hualing chen86e7d482020-01-16 15:13:33 +08002177 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002178 am_tsplayer_video_params vparams;
2179 am_tsplayer_audio_params aparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002180
hualing chen040df222020-01-17 13:35:02 +08002181 player->cur_segment_id = segment_id;
2182
2183 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002184 //get segment info and audio video pid fmt ;
2185 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08002186 //start audio and video
2187 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2188 //audio abnd video pis is all invalid, return error.
2189 DVR_DEBUG(0, "seek start dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002190 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08002191 pthread_mutex_unlock(&player->lock);
2192 return -1;
2193 }
2194 //add
hualing chen040df222020-01-17 13:35:02 +08002195 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002196 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002197 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002198 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chen31140872020-03-25 12:29:26 +08002199 player->speed > 1.0f||
2200 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002201 //if is pause state. we need set trick mode.
hualing chen31140872020-03-25 12:29:26 +08002202 DVR_DEBUG(1, "[%s]seek set trick mode player->speed [%f]", __func__, player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002203 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002204 }
hualing chen2aba4022020-03-02 13:49:55 +08002205 AmTsPlayer_setVideoParams(player->handle, &vparams);
2206 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002207 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002208 }
hualing chen86e7d482020-01-16 15:13:33 +08002209 if (VALID_PID(aparams.pid)) {
hualing chena540a7e2020-03-27 16:44:05 +08002210 DVR_DEBUG(1, " func: %s start audio seek", __func__);
hualing chen2aba4022020-03-02 13:49:55 +08002211 AmTsPlayer_setAudioParams(player->handle, &aparams);
2212 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002213 player->has_audio = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002214 }
hualing chen86e7d482020-01-16 15:13:33 +08002215 }
hualing chen2aba4022020-03-02 13:49:55 +08002216 if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
2217 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2218 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2219 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
2220 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))) {
2221 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2222 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen041c4092020-04-05 15:11:50 +08002223 DVR_DEBUG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002224 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2225 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002226 player->speed > 1.0f||
2227 player->speed <= -1.0f) {
hualing chen87072a82020-03-12 16:20:12 +08002228 DVR_DEBUG(1, "not set cmd to seek");
2229 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002230 } else {
hualing chen87072a82020-03-12 16:20:12 +08002231 DVR_DEBUG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002232 player->cmd.last_cmd = player->cmd.cur_cmd;
2233 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2234 player->cmd.state = DVR_PLAYBACK_STATE_START;
2235 player->state = DVR_PLAYBACK_STATE_START;
2236 }
hualing chencc91e1c2020-02-28 13:26:17 +08002237 DVR_DEBUG(1, "unlock func: %s ---", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08002238 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002239
2240 return DVR_SUCCESS;
2241}
hualing chen5cbe1a62020-02-10 16:36:36 +08002242
hualing chen5cbe1a62020-02-10 16:36:36 +08002243static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2244 //get cur time of segment
2245 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002246
2247 if (player == NULL || player->handle == NULL) {
2248 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2249 return DVR_FAILURE;
2250 }
2251
hualing chen31140872020-03-25 12:29:26 +08002252 int64_t cache = 0;//defalut es buf cache 500ms
2253 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002254 pthread_mutex_lock(&player->segment_lock);
2255 uint64_t cur = segment_tell_current_time(player->r_handle);
2256 pthread_mutex_unlock(&player->segment_lock);
hualing chen041c4092020-04-05 15:11:50 +08002257 DVR_DEBUG(1, "get cur time [%lld] cache:%lld cur id [%d]", cur, cache, player->cur_segment_id);
2258 if (cache > MAX_CACHE_TIME) {
2259 DVR_DEBUG(1, "get cache:%lld ERRRO", cache);
2260 cache = g_cache_time;
2261 } else {
2262 g_cache_time = cache;
2263 }
hualing chen87072a82020-03-12 16:20:12 +08002264 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2265 cache = 0;
2266 }
hualing chen31140872020-03-25 12:29:26 +08002267 return (int)(cur > cache ? cur - cache : 0);
hualing chencc91e1c2020-02-28 13:26:17 +08002268}
2269
2270//get current segment current pcr time of read pos
2271static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2272 //get cur time of segment
2273 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002274
2275 if (player == NULL) {
2276 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2277 return DVR_FAILURE;
2278 }
2279
hualing chen2aba4022020-03-02 13:49:55 +08002280 pthread_mutex_lock(&player->segment_lock);
2281 uint64_t end = segment_tell_total_time(player->r_handle);
2282 DVR_DEBUG(1, "get tatal time [%lld]", end);
2283 pthread_mutex_unlock(&player->segment_lock);
2284 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002285}
2286
hualing chen87072a82020-03-12 16:20:12 +08002287#define FB_MIX_SEEK_TIME 1000
hualing chen5cbe1a62020-02-10 16:36:36 +08002288//start replay
2289static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2290
2291 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2292 //calculate pcr seek time
2293 int t_diff = 0;
2294 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002295
2296 if (player == NULL) {
2297 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2298 return DVR_FAILURE;
2299 }
2300
hualing chen5cbe1a62020-02-10 16:36:36 +08002301 if (player->fffb_start == -1) {
2302 //set fffb start time ms
2303 player->fffb_start = _dvr_time_getClock();
2304 player->fffb_current = player->fffb_start;
2305 //get segment current time pos
2306 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen31140872020-03-25 12:29:26 +08002307 DVR_DEBUG(1, "calculate seek posplayer->fffb_start_pcr[%d]ms, speed[%f]", player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002308 t_diff = 0;
hualing chen2aba4022020-03-02 13:49:55 +08002309 //default first time 1ms seek
hualing chen87072a82020-03-12 16:20:12 +08002310 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002311 } else {
2312 player->fffb_current = _dvr_time_getClock();
2313 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002314 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002315 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002316 if (seek_time <= 0) {
2317 //need seek to pre one segment
2318 seek_time = 0;
2319 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002320 //seek segment pos
2321 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002322 pthread_mutex_lock(&player->segment_lock);
hualing chen041c4092020-04-05 15:11:50 +08002323 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2324 seek_time = 0;
2325 }
hualing chen2aba4022020-03-02 13:49:55 +08002326 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002327 } else {
2328 //
2329 DVR_DEBUG(1, "segment not open,can not seek");
2330 }
hualing chen31140872020-03-25 12:29:26 +08002331 DVR_DEBUG(1, "calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]", seek_time, player->speed,player->cur_segment_id, _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08002332 }
hualing chen2aba4022020-03-02 13:49:55 +08002333 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002334}
2335
2336
2337//start replay
2338static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2339 //
2340 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002341
2342 if (player == NULL) {
2343 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2344 return DVR_FAILURE;
2345 }
2346
hualing chen5cbe1a62020-02-10 16:36:36 +08002347 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002348 if (player->has_video) {
2349 DVR_DEBUG(1, "fffb stop video");
2350 AmTsPlayer_stopVideoDecoding(player->handle);
2351 }
2352 if (player->has_audio) {
2353 DVR_DEBUG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002354 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002355 AmTsPlayer_stopAudioDecoding(player->handle);
2356 }
2357
hualing chen5cbe1a62020-02-10 16:36:36 +08002358 //start video and audio
2359
hualing chen2aba4022020-03-02 13:49:55 +08002360 am_tsplayer_video_params vparams;
2361 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002362 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002363
2364 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002365 //pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002366 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2367 //start audio and video
2368 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2369 //audio abnd video pis is all invalid, return error.
2370 DVR_DEBUG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002371 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002372 return -1;
2373 }
2374
2375 if (VALID_PID(vparams.pid)) {
2376 player->has_video = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08002377 DVR_DEBUG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08002378 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002379 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2380 AmTsPlayer_setVideoParams(player->handle, &vparams);
2381 AmTsPlayer_startVideoDecoding(player->handle);
2382 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002383 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002384 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002385 }
hualing chena540a7e2020-03-27 16:44:05 +08002386 if (0 && VALID_PID(aparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002387 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08002388 DVR_DEBUG(1, "fffb start audio");
2389 AmTsPlayer_setAudioParams(player->handle, &aparams);
2390 AmTsPlayer_startAudioDecoding(player->handle);
2391 //playback_device_audio_start(player->handle , &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002392 }
hualing chen31140872020-03-25 12:29:26 +08002393 //fffb mode need stop fast;
2394 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002395
hualing chencc91e1c2020-02-28 13:26:17 +08002396 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002397 return 0;
2398}
2399
2400static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2401 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002402
2403 if (player == NULL) {
2404 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2405 return DVR_FAILURE;
2406 }
2407
2408 player->first_frame = 0;
hualing chen31140872020-03-25 12:29:26 +08002409 DVR_DEBUG(1, "lock func: %s speed [%f]", __func__, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002410 pthread_mutex_lock(&player->lock);
2411
hualing chen2aba4022020-03-02 13:49:55 +08002412 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen041c4092020-04-05 15:11:50 +08002413 DVR_DEBUG(1, "get lock func: %s speed [%f]id [%lld]seek_time[%d]", __func__, player->speed, player->cur_segment_id, seek_time);
2414
hualing chen87072a82020-03-12 16:20:12 +08002415 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2416 //seek time set 0
2417 seek_time = 0;
2418 }
hualing chen041c4092020-04-05 15:11:50 +08002419 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002420 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2421 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002422 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002423 pthread_mutex_unlock(&player->lock);
2424 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002425 //send event here and pause
2426 DVR_Play_Notify_t notify;
2427 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002428 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002429 //get play statue not here
2430 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify);
hualing chen31140872020-03-25 12:29:26 +08002431 DVR_DEBUG(1, "*******************send begin event func: %s speed [%f] cur [%d]", __func__, player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08002432 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002433 return DVR_SUCCESS;
2434 }
hualing chen87072a82020-03-12 16:20:12 +08002435 _dvr_playback_sent_transition_ok(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002436 _dvr_init_fffb_time(handle);
hualing chen31140872020-03-25 12:29:26 +08002437 DVR_DEBUG(1, "*******************send trans ok event func: %s speed [%f]", __func__, player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002438 }
2439 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002440 _dvr_playback_fffb_replay(handle);
2441
2442 pthread_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002443 DVR_DEBUG(1, "unlock func: %s", __func__);
2444
hualing chen5cbe1a62020-02-10 16:36:36 +08002445 return DVR_SUCCESS;
2446}
2447
hualing chen87072a82020-03-12 16:20:12 +08002448//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002449static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002450 //
2451 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002452
2453 if (player == NULL) {
2454 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2455 return DVR_FAILURE;
2456 }
2457
hualing chen5cbe1a62020-02-10 16:36:36 +08002458 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002459 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002460 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002461 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002462 }
2463
2464 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002465 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002466 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002467 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002468 //start video and audio
2469
hualing chen2aba4022020-03-02 13:49:55 +08002470 am_tsplayer_video_params vparams;
2471 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002472 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002473
2474 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002475 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002476 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2477 //start audio and video
2478 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002479 //audio and video pis is all invalid, return error.
hualing chen5cbe1a62020-02-10 16:36:36 +08002480 DVR_DEBUG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002481 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002482 return -1;
2483 }
2484
2485 if (VALID_PID(vparams.pid)) {
2486 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002487 if (trick == DVR_TRUE) {
2488 DVR_DEBUG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002489 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002490 }
hualing chen266b9502020-04-04 17:39:39 +08002491 else {
hualing chen2aba4022020-03-02 13:49:55 +08002492 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002493 }
hualing chen2aba4022020-03-02 13:49:55 +08002494 AmTsPlayer_setVideoParams(player->handle, &vparams);
2495 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002496 }
hualing chena540a7e2020-03-27 16:44:05 +08002497
2498 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002499 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002500 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002501 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002502 if (VALID_PID(aparams.pid)) {
2503 player->has_audio = DVR_TRUE;
2504 DVR_DEBUG(1, " func: %s start audio", __func__);
2505 AmTsPlayer_startAudioDecoding(player->handle);
2506 AmTsPlayer_setAudioParams(player->handle, &aparams);
hualing chena540a7e2020-03-27 16:44:05 +08002507 }
hualing chen31140872020-03-25 12:29:26 +08002508 AmTsPlayer_stopFast(player->handle);
2509 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2510 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2511 }
hualing chen2aba4022020-03-02 13:49:55 +08002512 player->cmd.last_cmd = player->cmd.cur_cmd;
2513 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002514 player->cmd.state = DVR_PLAYBACK_STATE_START;
2515 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08002516 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002517 return 0;
2518}
2519
2520
hualing chenb31a6c62020-01-13 17:27:00 +08002521/**\brief Set play speed
2522 * \param[in] handle playback handle
2523 * \param[in] speed playback speed
2524 * \retval DVR_SUCCESS On success
2525 * \return Error code
2526 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002527int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2528
2529 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002530
2531 if (player == NULL) {
2532 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2533 return DVR_FAILURE;
2534 }
2535
2536 DVR_DEBUG(1, "lock func: %s speed [%d]", __func__, speed.speed.speed);
2537 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
2538 DVR_DEBUG(1, " func: %s not support speed [%d]", __func__, speed.speed.speed);
2539 return DVR_FAILURE;
2540 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002541 pthread_mutex_lock(&player->lock);
2542 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2543 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2544 player->cmd.last_cmd = player->cmd.cur_cmd;
2545 }
hualing chen31140872020-03-25 12:29:26 +08002546 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002547 IS_KERNEL_SPEED(speed.speed.speed)) {
2548 //case 1. cur speed is 100,set 200 50 25 12 .
2549 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2550 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002551 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002552 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2553 // resume audio and stop fast play
2554 AmTsPlayer_stopFast(player->handle);
2555 pthread_mutex_unlock(&player->lock);
2556 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2557 pthread_mutex_lock(&player->lock);
2558 } else {
2559 //set play speed and if audio is start, stop audio.
2560 if (player->has_audio) {
2561 DVR_DEBUG(1, "fast play stop audio");
2562 AmTsPlayer_stopAudioDecoding(player->handle);
2563 player->has_audio = DVR_FALSE;
2564 }
2565 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002566 }
hualing chena540a7e2020-03-27 16:44:05 +08002567 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002568 player->cmd.speed.speed = speed.speed;
2569 player->speed = (float)speed.speed.speed/(float)100;
2570 pthread_mutex_unlock(&player->lock);
2571 return DVR_SUCCESS;
2572 }
2573 //case 2. not start play
2574 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2575 //only set speed.and return;
hualing chena540a7e2020-03-27 16:44:05 +08002576 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002577 player->cmd.speed.speed = speed.speed;
2578 player->speed = (float)speed.speed.speed/(float)100;
2579 pthread_mutex_unlock(&player->lock);
2580 return DVR_SUCCESS;
hualing chen87072a82020-03-12 16:20:12 +08002581 }
hualing chen31140872020-03-25 12:29:26 +08002582 //case 3 fffb mode
2583 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2584 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2585 //restart play at normal speed exit ff fb
2586 DVR_DEBUG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002587 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002588 player->cmd.speed.speed = speed.speed;
2589 player->speed = (float)speed.speed.speed/(float)100;
2590 _dvr_playback_replay(handle, DVR_FALSE);
2591 pthread_mutex_unlock(&player->lock);
2592 return DVR_SUCCESS;
2593 }
2594 }
2595 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002596 IS_KERNEL_SPEED(speed.speed.speed)) {
2597 //case 1. cur speed is kernel support speed,set kernel speed.
2598 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002599 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002600 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2601 // resume audio and stop fast play
2602 AmTsPlayer_stopFast(player->handle);
2603 pthread_mutex_unlock(&player->lock);
2604 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2605 pthread_mutex_lock(&player->lock);
2606 } else {
2607 //set play speed and if audio is start, stop audio.
2608 if (player->has_audio) {
2609 DVR_DEBUG(1, "fast play stop audio at pause");
2610 AmTsPlayer_stopAudioDecoding(player->handle);
2611 player->has_audio = DVR_FALSE;
2612 }
2613 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
2614 }
hualing chena540a7e2020-03-27 16:44:05 +08002615 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002616 player->cmd.speed.speed = speed.speed;
2617 player->speed = (float)speed.speed.speed/(float)100;
2618 pthread_mutex_unlock(&player->lock);
2619 return DVR_SUCCESS;
2620 }
2621 //case 2 fffb mode
2622 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2623 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2624 //restart play at normal speed exit ff fb
2625 DVR_DEBUG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002626 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002627 player->cmd.speed.speed = speed.speed;
2628 player->speed = (float)speed.speed.speed/(float)100;
2629 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2630 pthread_mutex_unlock(&player->lock);
2631 return DVR_SUCCESS;
2632 }
hualing chen31140872020-03-25 12:29:26 +08002633 }
hualing chena540a7e2020-03-27 16:44:05 +08002634 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2635 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chen87072a82020-03-12 16:20:12 +08002636 } else {
hualing chen31140872020-03-25 12:29:26 +08002637 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002638 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2639 else
2640 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
2641 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002642 player->cmd.speed.mode = speed.mode;
2643 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002644 player->speed = (float)speed.speed.speed/(float)100;
2645 //reset fffb time, if change speed value
2646 _dvr_init_fffb_time(handle);
hualing chen87072a82020-03-12 16:20:12 +08002647 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002648 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2649 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002650 //restart play at normal speed exit ff fb
2651 DVR_DEBUG(1, "set speed normal and replay playback");
2652 _dvr_playback_replay(handle, DVR_FALSE);
2653 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2654 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2655 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2656 DVR_DEBUG(1, "set speed normal at pause state ,set cur cmd");
2657 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002658 //need exit ff fb
hualing chen31140872020-03-25 12:29:26 +08002659 DVR_DEBUG(1, "unlock func: %s speed[%f]cmd[%d]", __func__, player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002660 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002661 return DVR_SUCCESS;
2662}
2663/**\brief Get playback status
2664 * \param[in] handle playback handle
2665 * \param[out] p_status playback status
2666 * \retval DVR_SUCCESS On success
2667 * \return Error code
2668 */
hualing chen040df222020-01-17 13:35:02 +08002669int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002670 DVR_PlaybackStatus_t *p_status) {
2671//
2672 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002673
2674 if (player == NULL) {
2675 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2676 return DVR_FAILURE;
2677 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002678
2679 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002680 //when got first frame we will change to pause state.this only from start play to got first frame
hualing chen87072a82020-03-12 16:20:12 +08002681 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2682 player->state == DVR_PLAYBACK_STATE_START) {
2683 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2684 }
hualing chen041c4092020-04-05 15:11:50 +08002685
hualing chencc91e1c2020-02-28 13:26:17 +08002686 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002687 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen041c4092020-04-05 15:11:50 +08002688 p_status->segment_id = player->cur_segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08002689
hualing chen5cbe1a62020-02-10 16:36:36 +08002690 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08002691 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08002692 p_status->flags = player->cur_segment.flags;
hualing chena540a7e2020-03-27 16:44:05 +08002693 DVR_DEBUG(1, "get stat end player state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]",
hualing chen6d24aa92020-03-23 18:43:47 +08002694 _dvr_playback_state_toString(player->state),
2695 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08002696 p_status->time_cur, p_status->time_end,
2697 p_status->segment_id,player->play_flag,
2698 player->speed);
hualing chenb31a6c62020-01-13 17:27:00 +08002699 return DVR_SUCCESS;
2700}
2701
hualing chen040df222020-01-17 13:35:02 +08002702void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
2703 if (segment != NULL) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002704 DVR_DEBUG(1, "segment id: %lld", segment->segment_id);
hualing chen040df222020-01-17 13:35:02 +08002705 DVR_DEBUG(1, "segment flag: %d", segment->flags);
2706 DVR_DEBUG(1, "segment location: [%s]", segment->location);
2707 DVR_DEBUG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
2708 DVR_DEBUG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
2709 DVR_DEBUG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
2710 DVR_DEBUG(1, "segment sub apid: 0x%x sub afmt:0x%x", segment->pids.ad.pid,segment->pids.ad.format);
hualing chen86e7d482020-01-16 15:13:33 +08002711 }
hualing chenb31a6c62020-01-13 17:27:00 +08002712}
2713
hualing chen5cbe1a62020-02-10 16:36:36 +08002714int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002715 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08002716
hualing chena540a7e2020-03-27 16:44:05 +08002717 if (player == NULL) {
2718 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2719 return DVR_FAILURE;
2720 }
2721
hualing chen040df222020-01-17 13:35:02 +08002722 DVR_PlaybackSegmentInfo_t *segment;
2723 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002724 {
hualing chen040df222020-01-17 13:35:02 +08002725 if (segment_id >= 0) {
2726 if (segment->segment_id == segment_id) {
2727 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002728 break;
2729 }
2730 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08002731 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08002732 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002733 }
2734 }
2735 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002736}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002737
pengfei.liu27cc4ec2020-04-03 16:28:16 +08002738int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002739{
2740 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2741 DVR_RETURN_IF_FALSE(player);
2742 DVR_RETURN_IF_FALSE(func);
2743
hualing chen266b9502020-04-04 17:39:39 +08002744 DVR_DEBUG(1, "in %s func:%#x", __func__, func);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002745 pthread_mutex_lock(&player->lock);
2746
2747 player->dec_func = func;
2748 player->dec_userdata = userdata;
2749
2750 pthread_mutex_unlock(&player->lock);
2751 DVR_DEBUG(1, "out %s", __func__);
2752 return DVR_SUCCESS;
2753}
2754
2755int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
2756{
2757 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2758 DVR_RETURN_IF_FALSE(player);
2759 DVR_RETURN_IF_FALSE(p_secure_buf);
2760 DVR_RETURN_IF_FALSE(len);
2761
2762 DVR_DEBUG(1, "in %s", __func__);
2763 pthread_mutex_lock(&player->lock);
2764
2765 player->is_secure_mode = 1;
2766 player->secure_buffer = p_secure_buf;
2767 player->secure_buffer_size = len;
2768
2769 pthread_mutex_unlock(&player->lock);
2770 DVR_DEBUG(1, "out %s", __func__);
2771 return DVR_SUCCESS;
2772}