blob: d2d09da67d8c72e5d1696d2bc161aa27c8178607 [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>
hualing chenb5cd42e2020-04-15 17:03:34 +080014#include <errno.h>
hualing chenb31a6c62020-01-13 17:27:00 +080015
hualing chenb31a6c62020-01-13 17:27:00 +080016#include "dvr_playback.h"
17
hualing chen4b7c15d2020-04-07 16:13:48 +080018#define DVR_PB_DG(_level, _fmt, ...) \
19 DVR_DEBUG(_level, "playback %-30.30s:%d " _fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
20
hualing chena540a7e2020-03-27 16:44:05 +080021
hualing chenb31a6c62020-01-13 17:27:00 +080022#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080023
24
25#define FF_SPEED (2.0f)
26#define FB_SPEED (-1.0f)
27#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
28#define IS_FB(_SPEED_) ((_SPEED_) < FB_SPEED)
29
30#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))
31#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
32
hualing chenb31a6c62020-01-13 17:27:00 +080033
hualing chenb5cd42e2020-04-15 17:03:34 +080034#define FFFB_SLEEP_TIME (1000)//500ms
hualing chen4b7c15d2020-04-07 16:13:48 +080035#define FB_DEFAULT_LEFT_TIME (10000)
hualing chen31140872020-03-25 12:29:26 +080036//if tsplayer delay time < 200 and no data can read, we will pause
37#define MIN_TSPLAYER_DELAY_TIME (200)
38
hualing chen041c4092020-04-05 15:11:50 +080039#define MAX_CACHE_TIME (30000)
40
hualing chena540a7e2020-03-27 16:44:05 +080041static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080042//
43static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chencc91e1c2020-02-28 13:26:17 +080044static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type);
45static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
46static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080047static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080048static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
49
hualing chenbcada022020-04-22 14:27:01 +080050
51static char* _cmd_toString(int cmd)
52{
53
54 char *string[DVR_PLAYBACK_CMD_NONE+1]={
55 "start",
56 "stop",
57 "vstart",
58 "astart",
59 "vstop",
60 "astop",
61 "vrestart",
62 "arestart",
63 "avrestart",
64 "vstopastart",
65 "astopvstart",
66 "vstoparestart",
67 "astopvrestart",
68 "vstartarestart",
69 "astartvrestart",
70 "pause",
71 "resume",
72 "seek",
73 "ff",
74 "fb",
75 "NONE"
76 };
77
78 if (cmd > DVR_PLAYBACK_CMD_NONE) {
79 return "unkown";
80 } else {
81 return string[cmd];
82 }
83}
84
85
hualing chen6d24aa92020-03-23 18:43:47 +080086static char* _dvr_playback_state_toString(int stat)
87{
88 char *string[DVR_PLAYBACK_STATE_FB+1]={
89 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080090 "stop",
hualing chen31140872020-03-25 12:29:26 +080091 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080092 "ff",
93 "fb"
94 };
95
96 if (stat > DVR_PLAYBACK_STATE_FB) {
97 return "unkown";
98 } else {
99 return string[stat];
100 }
101}
hualing chena540a7e2020-03-27 16:44:05 +0800102
103static DVR_Bool_t _dvr_support_speed(int speed) {
104
105 DVR_Bool_t ret = DVR_FALSE;
106
107 switch (speed) {
108 case PLAYBACK_SPEED_FBX2:
109 case PLAYBACK_SPEED_FBX4:
110 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800111 case PLAYBACK_SPEED_FBX16:
112 case PLAYBACK_SPEED_FBX12:
113 case PLAYBACK_SPEED_FBX32:
114 case PLAYBACK_SPEED_FBX48:
115 case PLAYBACK_SPEED_FBX64:
116 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800117 case PLAYBACK_SPEED_S2:
118 case PLAYBACK_SPEED_S4:
119 case PLAYBACK_SPEED_S8:
120 case PLAYBACK_SPEED_X1:
121 case PLAYBACK_SPEED_X2:
122 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800123 case PLAYBACK_SPEED_X3:
124 case PLAYBACK_SPEED_X5:
125 case PLAYBACK_SPEED_X6:
126 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800127 case PLAYBACK_SPEED_X8:
128 case PLAYBACK_SPEED_X12:
129 case PLAYBACK_SPEED_X16:
130 case PLAYBACK_SPEED_X32:
131 case PLAYBACK_SPEED_X48:
132 case PLAYBACK_SPEED_X64:
133 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800134 ret = DVR_TRUE;
135 break;
136 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800137 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800138 break;
139 }
140 return ret;
141}
hualing chen6e4bfa52020-03-13 14:37:11 +0800142void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
143{
hualing chen4b7c15d2020-04-07 16:13:48 +0800144 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800145 DVR_Playback_t *player = NULL;
146 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800147 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800148 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800149 }
150 switch (event->type) {
151 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
152 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800153 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800154 event->event.video_format.frame_width,
155 event->event.video_format.frame_height,
156 event->event.video_format.frame_rate);
157 break;
158 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800159 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
160 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800161 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800162 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800163 break;
164 }
165 default:
166 break;
167 }
168}
hualing chen2aba4022020-03-02 13:49:55 +0800169void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
170{
hualing chen6e4bfa52020-03-13 14:37:11 +0800171 DVR_Playback_t *player = NULL;
172 if (user_data != NULL) {
173 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800174 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800175 }
hualing chen2aba4022020-03-02 13:49:55 +0800176 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800177 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
178 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800179 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800180 event->event.video_format.frame_width,
181 event->event.video_format.frame_height,
182 event->event.video_format.frame_rate);
183 break;
184 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800185 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
186 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800187 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800188 if (player != NULL)
189 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800190 break;
191 }
192 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800193 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800194 break;
195 }
196 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800197 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800198 player->player_callback_func(player->player_callback_userdata, event);
199 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800200 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800201 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800202 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800203 }
204}
hualing chencc91e1c2020-02-28 13:26:17 +0800205
hualing chen5cbe1a62020-02-10 16:36:36 +0800206//convert video and audio fmt
207static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
208 int format = 0;
209 if (is_audio == DVR_FALSE) {
210 //for video fmt
211 switch (fmt)
212 {
213 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800214 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800215 break;
216 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800217 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800218 break;
219 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800220 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800221 break;
222 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800223 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800224 break;
hualing chena540a7e2020-03-27 16:44:05 +0800225 case DVR_VIDEO_FORMAT_VP9:
226 format = AV_VIDEO_CODEC_VP9;
227 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800228 }
229 } else {
230 //for audio fmt
231 switch (fmt)
232 {
233 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800234 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800235 break;
236 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800237 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800238 break;
239 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800240 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800241 break;
242 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800243 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800244 break;
hualing chena540a7e2020-03-27 16:44:05 +0800245 case DVR_AUDIO_FORMAT_AAC:
246 format = AV_AUDIO_CODEC_AAC;
247 break;
248 case DVR_AUDIO_FORMAT_LATM:
249 format = AV_AUDIO_CODEC_LATM;
250 break;
251 case DVR_AUDIO_FORMAT_PCM:
252 format = AV_AUDIO_CODEC_PCM;
253 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800254 }
255 }
256 return format;
257}
hualing chen040df222020-01-17 13:35:02 +0800258static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800259{
hualing chen040df222020-01-17 13:35:02 +0800260 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800261
hualing chena540a7e2020-03-27 16:44:05 +0800262 if (player == NULL || player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800263 return -1;
264
hualing chena540a7e2020-03-27 16:44:05 +0800265 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800266}
hualing chena540a7e2020-03-27 16:44:05 +0800267
hualing chen5cbe1a62020-02-10 16:36:36 +0800268//get sys time ms
269static int _dvr_time_getClock(void)
270{
271 struct timespec ts;
272 int ms;
273
274 clock_gettime(CLOCK_MONOTONIC, &ts);
275 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
276
277 return ms;
278}
hualing chen86e7d482020-01-16 15:13:33 +0800279
hualing chenb31a6c62020-01-13 17:27:00 +0800280
281//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800282static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800283{
hualing chen040df222020-01-17 13:35:02 +0800284 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800285
hualing chena540a7e2020-03-27 16:44:05 +0800286
287 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800288 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800289 return DVR_FAILURE;
290 }
291
hualing chen86e7d482020-01-16 15:13:33 +0800292 struct timespec ts;
293 clock_gettime(CLOCK_MONOTONIC, &ts);
294 //ms为毫秒,换算成秒
295 ts.tv_sec += ms/1000;
296 //在outtime的基础上,增加ms毫秒
297 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
298 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
299 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
300 //us的值有可能超过1秒,
301 ts.tv_sec += us / 1000000;
302 us = us % 1000000;
303 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800304 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
305 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800306}
hualing chen31140872020-03-25 12:29:26 +0800307//get tsplay delay time ms
308static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
309 DVR_Playback_t *player = (DVR_Playback_t *) handle;
310 int64_t cache = 0;
311 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800312 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800313 return 0;
314 }
315 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800316 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800317 return cache;
318}
hualing chenb31a6c62020-01-13 17:27:00 +0800319//send signal
hualing chen040df222020-01-17 13:35:02 +0800320static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800321{
hualing chen87072a82020-03-12 16:20:12 +0800322 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800323
324 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800325 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800326 return DVR_FAILURE;
327 }
328
hualing chen87072a82020-03-12 16:20:12 +0800329 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800330 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800331 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800332 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800333}
334
hualing chencc91e1c2020-02-28 13:26:17 +0800335//send playback event
336static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify) {
337
338 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800339
340 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800341 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800342 return DVR_FAILURE;
343 }
344
hualing chencc91e1c2020-02-28 13:26:17 +0800345 switch (evt) {
346 case DVR_PLAYBACK_EVENT_ERROR:
hualing chenb5cd42e2020-04-15 17:03:34 +0800347 dvr_playback_get_status(handle, &(notify->play_status));
hualing chencc91e1c2020-02-28 13:26:17 +0800348 break;
349 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
350 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800351 DVR_PB_DG(1, "trans ok EVENT");
hualing chencc91e1c2020-02-28 13:26:17 +0800352 dvr_playback_get_status(handle, &(notify->play_status));
353 break;
354 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
355 break;
356 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
357 break;
358 case DVR_PLAYBACK_EVENT_NO_KEY:
359 break;
360 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800361 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800362 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2aba4022020-03-02 13:49:55 +0800363 dvr_playback_get_status(handle, &(notify->play_status));
hualing chencc91e1c2020-02-28 13:26:17 +0800364 break;
365 case DVR_PLAYBACK_EVENT_REACHED_END:
366 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800367 DVR_PB_DG(1, "reached end EVENT");
hualing chencc91e1c2020-02-28 13:26:17 +0800368 dvr_playback_get_status(handle, &(notify->play_status));
369 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800370 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen6e4bfa52020-03-13 14:37:11 +0800371 dvr_playback_get_status(handle, &(notify->play_status));
372 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800373 default:
374 break;
375 }
376 if (player->openParams.event_fn != NULL)
377 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800378 return DVR_SUCCESS;
379}
380static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle)
381{
382 DVR_Play_Notify_t notify;
383 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
384 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
385 //get play statue not here
386 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify);
387 return DVR_SUCCESS;
388}
389
hualing chen6e4bfa52020-03-13 14:37:11 +0800390static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle)
391{
392 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800393
hualing chen4b7c15d2020-04-07 16:13:48 +0800394 if (1) {
395 return DVR_SUCCESS;
396 }
hualing chena540a7e2020-03-27 16:44:05 +0800397 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800398 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800399 return DVR_FAILURE;
400 }
401
hualing chen6e4bfa52020-03-13 14:37:11 +0800402 if (player->send_time ==0) {
403 player->send_time = _dvr_time_getClock() + 1000;
404 } else if (player->send_time > _dvr_time_getClock()) {
405 return DVR_SUCCESS;
406 }
407 player->send_time = _dvr_time_getClock() + 1000;
408 DVR_Play_Notify_t notify;
409 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
410 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
411 //get play statue not here
412 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify);
413 return DVR_SUCCESS;
414}
415
hualing chencc91e1c2020-02-28 13:26:17 +0800416//check is ongoing segment
417static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
418
419 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800420 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800421
422 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800423 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800424 return DVR_FAILURE;
425 }
hualing chen87072a82020-03-12 16:20:12 +0800426 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800427 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800428 return DVR_FALSE;
429 }
hualing chencc91e1c2020-02-28 13:26:17 +0800430 return DVR_TRUE;
431}
hualing chen4b7c15d2020-04-07 16:13:48 +0800432
433
434static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
435 DVR_Playback_t *player = (DVR_Playback_t *) handle;
436 player->fffb_start = _dvr_time_getClock();
437 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
438 player->fffb_current = player->fffb_start;
439 //get segment current time pos
440 player->fffb_start_pcr = _dvr_get_cur_time(handle);
441 //player->fffb_current = -1;
442 //player->fffb_start = -1;
443 //player->fffb_start_pcr = -1;
444 player->next_fffb_time = _dvr_time_getClock();
445
446 return DVR_SUCCESS;
447}
448
hualing chen2aba4022020-03-02 13:49:55 +0800449static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
450 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800451 player->fffb_start = _dvr_time_getClock();
452 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
453 player->fffb_current = player->fffb_start;
454 //get segment current time pos
455 player->fffb_start_pcr = _dvr_get_cur_time(handle);
456 //player->fffb_current = -1;
457 //player->fffb_start = -1;
458 //player->fffb_start_pcr = -1;
hualing chen2aba4022020-03-02 13:49:55 +0800459 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800460 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800461 return DVR_SUCCESS;
462}
hualing chencc91e1c2020-02-28 13:26:17 +0800463//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800464static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
465
466 DVR_Playback_t *player = (DVR_Playback_t *) handle;
467 DVR_PlaybackSegmentInfo_t *segment;
468 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
469
hualing chena540a7e2020-03-27 16:44:05 +0800470 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800471 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800472 return DVR_FAILURE;
473 }
474
hualing chen87072a82020-03-12 16:20:12 +0800475 int found = 0;
476 int found_eq_id = 0;
477 list_for_each_entry(segment, &player->segment_list, head)
478 {
479 if (player->segment_is_open == DVR_FALSE) {
480 //get first segment from list, case segment is not open
481 if (!IS_FB(player->speed))
482 found = 1;
483 } else if (segment->segment_id == segmentid) {
484 //find cur segment, we need get next one
485 found_eq_id = 1;
486 if (!IS_FB(player->speed)) {
487 found = 1;
488 continue;
489 } else {
490 //if is fb mode.we need used pre segment
491 if (pre_segment != NULL) {
492 found = 1;
493 } else {
494 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800495 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800496 return DVR_FAILURE;
497 }
498 }
499 }
500 if (found == 1) {
501 found = 2;
502 break;
503 }
504 }
505 if (found != 2) {
506 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800507 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800508 return DVR_FAILURE;
509 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800510 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800511 return DVR_SUCCESS;
512}
513
514//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800515static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800516
hualing chen040df222020-01-17 13:35:02 +0800517 DVR_Playback_t *player = (DVR_Playback_t *) handle;
518 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800519 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800520
hualing chena540a7e2020-03-27 16:44:05 +0800521 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800522 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800523 return DVR_FAILURE;
524 }
525
hualing chen86e7d482020-01-16 15:13:33 +0800526 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800527 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800528
hualing chen040df222020-01-17 13:35:02 +0800529 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800530 {
hualing chencc91e1c2020-02-28 13:26:17 +0800531 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800532 //get first segment from list, case segment is not open
533 if (!IS_FB(player->speed))
534 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800535 } else if (segment->segment_id == player->cur_segment_id) {
536 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800537 found_eq_id = 1;
538 if (!IS_FB(player->speed)) {
539 found = 1;
540 continue;
541 } else {
542 //if is fb mode.we need used pre segment
543 if (pre_segment != NULL) {
544 found = 1;
545 } else {
546 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800547 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800548 return DVR_FAILURE;
549 }
550 }
hualing chen86e7d482020-01-16 15:13:33 +0800551 }
552 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800553 if (IS_FB(player->speed)) {
554 //used pre segment
555 segment = pre_segment;
556 }
hualing chencc91e1c2020-02-28 13:26:17 +0800557 //save segment info
558 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800559 player->last_segment.segment_id = player->cur_segment.segment_id;
560 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800561 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
562 //pids
563 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
564
hualing chen5cbe1a62020-02-10 16:36:36 +0800565 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800566 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800567 player->cur_segment_id = segment->segment_id;
568 player->cur_segment.segment_id = segment->segment_id;
569 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800570 DVR_PB_DG(1, "set cur id 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 +0800571 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800572 //pids
hualing chen040df222020-01-17 13:35:02 +0800573 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800574 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800575 break;
hualing chen86e7d482020-01-16 15:13:33 +0800576 }
hualing chen2aba4022020-03-02 13:49:55 +0800577 pre_segment = segment;
578 }
579 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
580 //used the last one segment to open
581 //get segment info
582 player->segment_is_open = DVR_TRUE;
583 player->cur_segment_id = pre_segment->segment_id;
584 player->cur_segment.segment_id = pre_segment->segment_id;
585 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800586 DVR_PB_DG(1, "set cur id 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);
hualing chen2aba4022020-03-02 13:49:55 +0800587 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
588 //pids
589 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
590 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800591 }
592 if (found != 2) {
593 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800594 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800595 }
596 return DVR_SUCCESS;
597}
hualing chen040df222020-01-17 13:35:02 +0800598//open next segment to play,if reach list end return errro.
599static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800600{
hualing chen040df222020-01-17 13:35:02 +0800601 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800602 Segment_OpenParams_t params;
603 int ret = DVR_SUCCESS;
604
hualing chena540a7e2020-03-27 16:44:05 +0800605 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800606 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800607 return DVR_FAILURE;
608 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800609 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800610
611 ret = _dvr_get_next_segmentId(handle);
612 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800613 DVR_PB_DG(1, "not found segment info");
614 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800615 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800616 }
617
618 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800619 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800620 segment_close(player->r_handle);
621 player->r_handle = NULL;
622 }
623
624 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800625 //cp chur segment path to location
626 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800627 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800628 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800629 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
630
hualing chen86e7d482020-01-16 15:13:33 +0800631 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800632 if (ret == DVR_FAILURE) {
633 DVR_PB_DG(1, "open segment error");
634 }
hualing chen87072a82020-03-12 16:20:12 +0800635 pthread_mutex_unlock(&player->segment_lock);
636 int total = _dvr_get_end_time( handle);
637 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800638 if (IS_FB(player->speed)) {
639 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen266b9502020-04-04 17:39:39 +0800640 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800641 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800642 }
hualing chen87072a82020-03-12 16:20:12 +0800643 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800644 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800645 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800646 return ret;
647}
648
hualing chen5cbe1a62020-02-10 16:36:36 +0800649//open next segment to play,if reach list end return errro.
650static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
651{
652 DVR_Playback_t *player = (DVR_Playback_t *) handle;
653 Segment_OpenParams_t params;
654 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800655 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800656 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800657 return DVR_FAILURE;
658 }
hualing chencc91e1c2020-02-28 13:26:17 +0800659 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800660 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800661 }
hualing chencc91e1c2020-02-28 13:26:17 +0800662 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800663 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800664 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800665 return DVR_FAILURE;
666 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800667 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800668 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800669
670 DVR_PlaybackSegmentInfo_t *segment;
671
672 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800673
hualing chen5cbe1a62020-02-10 16:36:36 +0800674 list_for_each_entry(segment, &player->segment_list, head)
675 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800676 DVR_PB_DG(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 +0800677 if (segment->segment_id == segment_id) {
678 found = 1;
679 }
680 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800681 DVR_PB_DG(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 +0800682 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800683 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800684 player->cur_segment_id = segment->segment_id;
685 player->cur_segment.segment_id = segment->segment_id;
686 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800687 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800688 //pids
689 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800690 DVR_PB_DG(1, "cur found location [%s]id[%lld]flag[%x]", player->cur_segment.location, player->cur_segment.segment_id,player->cur_segment.flags);
hualing chencc91e1c2020-02-28 13:26:17 +0800691 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800692 }
693 }
hualing chencc91e1c2020-02-28 13:26:17 +0800694 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800695 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800696 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800697 return DVR_FAILURE;
698 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800699 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800700 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800701 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800702 params.segment_id = (uint64_t)player->cur_segment.segment_id;
703 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800704 DVR_PB_DG(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 +0800705 if (player->r_handle != NULL) {
706 segment_close(player->r_handle);
707 player->r_handle = NULL;
708 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800709 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800710 if (ret == DVR_FAILURE) {
711 DVR_PB_DG(1, "segment opne error");
712 }
hualing chen2aba4022020-03-02 13:49:55 +0800713 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800714 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800715
hualing chen4b7c15d2020-04-07 16:13:48 +0800716 DVR_PB_DG(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 +0800717 return ret;
718}
719
720
721//get play info by segment id
722static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
723 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800724 am_tsplayer_video_params *vparam,
725 am_tsplayer_audio_params *aparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800726
727 DVR_Playback_t *player = (DVR_Playback_t *) handle;
728 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800729 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800730 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800731 return DVR_FAILURE;
732 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800733
734 int found = 0;
735
736 list_for_each_entry(segment, &player->segment_list, head)
737 {
hualing chen87072a82020-03-12 16:20:12 +0800738 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800739 //get first segment from list
740 found = 1;
741 }
742 if (segment->segment_id == segment_id) {
743 found = 1;
744 }
745 if (found == 1) {
746 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800747 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800748 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800749 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800750 player->cur_segment.segment_id = segment->segment_id;
751 player->cur_segment.flags = segment->flags;
752 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800753 player->cur_segment.pids.video.pid = segment->pids.video.pid;
754 player->cur_segment.pids.video.format = segment->pids.video.format;
755 player->cur_segment.pids.video.type = segment->pids.video.type;
756 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
757 player->cur_segment.pids.audio.format = segment->pids.audio.format;
758 player->cur_segment.pids.audio.type = segment->pids.audio.type;
759 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
760 player->cur_segment.pids.ad.format = segment->pids.ad.format;
761 player->cur_segment.pids.ad.type = segment->pids.ad.type;
762 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800763 //
hualing chen2aba4022020-03-02 13:49:55 +0800764 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800765 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800766 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800767 aparam->pid = segment->pids.audio.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800768 DVR_PB_DG(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 +0800769 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800770 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800771 }
772 }
hualing chencc91e1c2020-02-28 13:26:17 +0800773 if (found != 2) {
774 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800775 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800776 return DVR_FAILURE;
777 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800778
779 return DVR_SUCCESS;
780}
hualing chencc91e1c2020-02-28 13:26:17 +0800781static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
782 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800783 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800784 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800785 return DVR_FAILURE;
786 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800787
hualing chencc91e1c2020-02-28 13:26:17 +0800788 //compare cur segment
789 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
790 {
791 //check video pids, stop or restart
792 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
793 //check audio pids stop or restart
hualing chen7a56cba2020-04-14 14:09:27 +0800794 DVR_PB_DG(1, ":last apid: %d set apid: %d", player->last_segment.pids.audio.pid,player->cur_segment.pids.audio.pid);
hualing chencc91e1c2020-02-28 13:26:17 +0800795 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
796 //check sub audio pids stop or restart
797 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
798 //check pcr pids stop or restart
799 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
800 }
hualing chena540a7e2020-03-27 16:44:05 +0800801 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800802}
hualing chen5cbe1a62020-02-10 16:36:36 +0800803
hualing chencc91e1c2020-02-28 13:26:17 +0800804static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
805{
806 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800807 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800808 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800809 return DVR_FAILURE;
810 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800811 DVR_PB_DG(1, "flag[0x%x]id[%lld]last[0x%x][%llu]", 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 +0800812 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
813 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800814 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800815 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800816 AmTsPlayer_showVideo(player->handle);
817 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800818 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
819 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800820 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800821 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800822 AmTsPlayer_hideVideo(player->handle);
823 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800824 }
825 return DVR_SUCCESS;
826}
hualing chena540a7e2020-03-27 16:44:05 +0800827static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
828 DVR_Playback_t *player = (DVR_Playback_t *) handle;
829 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800830 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800831 return DVR_TRUE;
832 }
hualing chen266b9502020-04-04 17:39:39 +0800833 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chena540a7e2020-03-27 16:44:05 +0800834 if (player->first_frame == 1) {
835 return DVR_TRUE;
836 } else {
837 return DVR_FALSE;
838 }
839 } else {
840 return DVR_TRUE;
841 }
842}
hualing chen86e7d482020-01-16 15:13:33 +0800843static void* _dvr_playback_thread(void *arg)
844{
hualing chen040df222020-01-17 13:35:02 +0800845 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800846 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800847 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800848 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800849 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800850
hualing chen6d24aa92020-03-23 18:43:47 +0800851 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800852 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800853 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800854 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800855 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
856
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800857 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800858 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800859 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800860
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800861 if (player->is_secure_mode) {
862 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800863 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800864 return NULL;
865 }
866 }
hualing chen86e7d482020-01-16 15:13:33 +0800867 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800868 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800869 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800870 return NULL;
871 }
hualing chen2aba4022020-03-02 13:49:55 +0800872 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
873 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800874
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800875 dec_bufs.buf_data = malloc(dec_buf_size);
876 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800877 DVR_PB_DG(1, "Malloc dec buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800878 return NULL;
879 }
880 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
881 dec_bufs.buf_size = dec_buf_size;
882
hualing chencc91e1c2020-02-28 13:26:17 +0800883 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800884 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
885 }
hualing chen86e7d482020-01-16 15:13:33 +0800886
hualing chen86e7d482020-01-16 15:13:33 +0800887 if (ret != DVR_SUCCESS) {
888 if (buf != NULL) {
889 free(buf);
890 buf = NULL;
891 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800892 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800893 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800894 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800895 }
hualing chencc91e1c2020-02-28 13:26:17 +0800896 //get play statue not here
897 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
898 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800899 //set video show
900 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800901
hualing chen86e7d482020-01-16 15:13:33 +0800902 int trick_stat = 0;
903 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800904
hualing chen86e7d482020-01-16 15:13:33 +0800905 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800906 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800907
hualing chen2aba4022020-03-02 13:49:55 +0800908 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
909 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800910 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800911 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen31140872020-03-25 12:29:26 +0800912 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800913 {
hualing chen2aba4022020-03-02 13:49:55 +0800914 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
915 if (trick_stat > 0) {
hualing chenbcada022020-04-22 14:27:01 +0800916 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]", player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +0800917 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 +0800918 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +0800919 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800920 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800921 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
922 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800923 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
924 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chenbcada022020-04-22 14:27:01 +0800925 DVR_PB_DG(1, "pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]", player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +0800926 //need change to pause state
927 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
928 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800929 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800930 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800931 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800932 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800933 AmTsPlayer_pauseVideoDecoding(player->handle);
934 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800935 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800936 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +0800937 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800938 }
939 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
940 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800941 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800942 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +0800943 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
944 DVR_PB_DG(1, "fffb pause state----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 +0800945 //used timeout wait need lock first,so we unlock and lock
946 //pthread_mutex_unlock(&player->lock);
947 //pthread_mutex_lock(&player->lock);
948 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
949 pthread_mutex_unlock(&player->lock);
950 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +0800951 } else if (_dvr_time_getClock() < player->next_fffb_time) {
952 DVR_PB_DG(1, "fffb timeout-to pause video---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);
953 //used timeout wait need lock first,so we unlock and lock
954 //pthread_mutex_unlock(&player->lock);
955 //pthread_mutex_lock(&player->lock);
956 AmTsPlayer_pauseVideoDecoding(player->handle);
957 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
958 pthread_mutex_unlock(&player->lock);
959 continue;
960
hualing chen2aba4022020-03-02 13:49:55 +0800961 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800962 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
hualing chen2aba4022020-03-02 13:49:55 +0800963 pthread_mutex_unlock(&player->lock);
964 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800965 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800966 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
967 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800968 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +0800969 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +0800970 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800971 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800972 }else if (player->fffb_play == DVR_TRUE){
973 //for first into fffb when reset speed
974 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
975 _dvr_time_getClock() < player->next_fffb_time) {
976 DVR_PB_DG(1, "fffb timeout-fffb play---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);
977 //used timeout wait need lock first,so we unlock and lock
978 //pthread_mutex_unlock(&player->lock);
979 //pthread_mutex_lock(&player->lock);
980 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
981 pthread_mutex_unlock(&player->lock);
982 continue;
983 }
hualing chenbcada022020-04-22 14:27:01 +0800984 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d][%s][%d]", player->speed, goto_rewrite, real_read, _dvr_playback_state_toString(player->state), player->cmd);
hualing chen4b7c15d2020-04-07 16:13:48 +0800985 pthread_mutex_unlock(&player->lock);
986 goto_rewrite = DVR_FALSE;
987 real_read = 0;
988 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
989 player->first_frame = 0;
990 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
991 pthread_mutex_lock(&player->lock);
992 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +0800993 }
hualing chenb31a6c62020-01-13 17:27:00 +0800994 }
hualing chen86e7d482020-01-16 15:13:33 +0800995
hualing chen87072a82020-03-12 16:20:12 +0800996 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800997 //check is need send time send end
998 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800999 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1000 pthread_mutex_unlock(&player->lock);
1001 continue;
1002 }
hualing chen266b9502020-04-04 17:39:39 +08001003 //when seek action is done. we need drop write timeout data.
1004 if (player->drop_ts == DVR_TRUE) {
1005 goto_rewrite = DVR_FALSE;
1006 real_read = 0;
1007 player->drop_ts = DVR_FALSE;
1008 }
hualing chen2aba4022020-03-02 13:49:55 +08001009 if (goto_rewrite == DVR_TRUE) {
1010 goto_rewrite = DVR_FALSE;
1011 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001012 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001013 goto rewrite;
1014 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001015 //.check is need send time send end
1016 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen4b7c15d2020-04-07 16:13:48 +08001017 pthread_mutex_lock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001018 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001019 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001020 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001021 if (read < 0 && errno == EIO) {
1022 //EIO ERROR, EXIT THRAD
1023 DVR_PB_DG(1, "read error.EIO error, exit thread");
1024 DVR_Play_Notify_t notify;
1025 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1026 notify.event = DVR_PLAYBACK_EVENT_ERROR;
1027 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify);
1028 goto end;
1029 } else if (read < 0) {
1030 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1031 }
hualing chen87072a82020-03-12 16:20:12 +08001032 //if on fb mode and read file end , we need calculate pos to retry read.
1033 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001034 DVR_PB_DG(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 +08001035 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
1036 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001037 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1038 pthread_mutex_unlock(&player->lock);
1039 continue;
1040 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001041 //DVR_PB_DG(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 +08001042 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001043 //file end.need to play next segment
hualing chen040df222020-01-17 13:35:02 +08001044 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001045 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001046 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001047
1048 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001049 //del delay time max check.
hualing chen041c4092020-04-05 15:11:50 +08001050 if (ret != DVR_SUCCESS &&
1051 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chenbcada022020-04-22 14:27:01 +08001052 /*delay > MAX_CACHE_TIME ||*/
hualing chen4b7c15d2020-04-07 16:13:48 +08001053 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen041c4092020-04-05 15:11:50 +08001054 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) {
hualing chena540a7e2020-03-27 16:44:05 +08001055 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001056 DVR_Play_Notify_t notify;
1057 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1058 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1059 //get play statue not here
1060 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen31140872020-03-25 12:29:26 +08001061 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify);
1062 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen4b7c15d2020-04-07 16:13:48 +08001063 DVR_PB_DG(1, "playback is send end delay:[%d]", delay);
hualing chen31140872020-03-25 12:29:26 +08001064 pthread_mutex_lock(&player->lock);
1065 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1066 pthread_mutex_unlock(&player->lock);
1067 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001068 } else if (ret != DVR_SUCCESS) {
1069 //not send event and pause,sleep and go to next time to recheck
hualing chen4b7c15d2020-04-07 16:13:48 +08001070 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001071 pthread_mutex_lock(&player->lock);
1072 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1073 pthread_mutex_unlock(&player->lock);
1074 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001075 }
hualing chen31140872020-03-25 12:29:26 +08001076 //change next segment success case
hualing chencc91e1c2020-02-28 13:26:17 +08001077 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
1078 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001079 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001080 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1081 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001082 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001083 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001084 }
1085 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001086 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001087 wbufs.buf_data = buf;
hualing chena540a7e2020-03-27 16:44:05 +08001088 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001089 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001090 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001091 real_read = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001092 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001093 }
hualing chen266b9502020-04-04 17:39:39 +08001094 //if need write whole block size, we need check read buf len is eq block size.
1095 if (b_writed_whole_block == DVR_TRUE) {
1096 //buf_len is block size value.
1097 if (real_read < buf_len) {
1098 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001099 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001100 pthread_mutex_lock(&player->lock);
1101 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1102 pthread_mutex_unlock(&player->lock);
1103 continue;
1104 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001105 DVR_PB_DG(1, "read buf len[%d] is > block size [%d],this error occur", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001106 }
1107 }
1108
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001109 if (player->dec_func) {
1110 DVR_CryptoParams_t crypto_params;
1111
1112 memset(&crypto_params, 0, sizeof(crypto_params));
1113 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1114 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1115 crypto_params.segment_id = player->cur_segment.segment_id;
1116 crypto_params.offset = segment_tell_position(player->r_handle);
1117
1118 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1119 crypto_params.input_buffer.addr = (size_t)buf;
1120 crypto_params.input_buffer.size = real_read;
1121
1122 if (player->is_secure_mode) {
1123 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1124 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1125 crypto_params.output_buffer.size = dec_buf_size;
1126 ret = player->dec_func(&crypto_params, player->dec_userdata);
1127 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001128 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001129 } else {
1130 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1131 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1132 crypto_params.output_buffer.size = dec_buf_size;
1133 ret = player->dec_func(&crypto_params, player->dec_userdata);
1134 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001135 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001136 }
1137 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001138 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001139 }
pengfei.liufda2a972020-04-09 14:47:15 +08001140 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001141 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001142rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001143 if (player->drop_ts == DVR_TRUE) {
1144 //need drop ts data when seek occur.we need read next loop,drop this ts data
1145 goto_rewrite = DVR_FALSE;
1146 real_read = 0;
1147 player->drop_ts = DVR_FALSE;
1148 continue;
1149 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001150 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1151 if (ret == AM_TSPLAYER_OK) {
hualing chena540a7e2020-03-27 16:44:05 +08001152 real_read = 0;
1153 write_success++;
1154 continue;
hualing chen87072a82020-03-12 16:20:12 +08001155 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001156 DVR_PB_DG(1, "write time out write_success:%d", write_success);
hualing chena540a7e2020-03-27 16:44:05 +08001157 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001158 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001159 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001160 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001161 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001162 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001163 break;
1164 }
hualing chen2aba4022020-03-02 13:49:55 +08001165 goto_rewrite = DVR_TRUE;
1166 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001167 }
1168 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001169end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001170 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001171 free(buf);
1172 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001173 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001174}
1175
1176
hualing chen040df222020-01-17 13:35:02 +08001177static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001178{
hualing chen040df222020-01-17 13:35:02 +08001179 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001180
1181 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001182 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001183 return DVR_FAILURE;
1184 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001185 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001186 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001187 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001188 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001189 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001190 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001191 if (rc < 0)
1192 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001193 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001194}
1195
1196
hualing chen040df222020-01-17 13:35:02 +08001197static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001198{
hualing chen040df222020-01-17 13:35:02 +08001199 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001200
1201 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001202 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001203 return DVR_FAILURE;
1204 }
1205
hualing chen4b7c15d2020-04-07 16:13:48 +08001206 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001207 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001208 {
1209 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001210 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001211 pthread_join(player->playback_thread, NULL);
1212 }
1213 if (player->r_handle) {
1214 segment_close(player->r_handle);
1215 player->r_handle = NULL;
1216 }
hualing chen7a56cba2020-04-14 14:09:27 +08001217 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001218 return 0;
1219}
1220
hualing chenb31a6c62020-01-13 17:27:00 +08001221/**\brief Open an dvr palyback
1222 * \param[out] p_handle dvr playback addr
1223 * \param[in] params dvr playback open parameters
1224 * \retval DVR_SUCCESS On success
1225 * \return Error code
1226 */
hualing chen040df222020-01-17 13:35:02 +08001227int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001228
hualing chen040df222020-01-17 13:35:02 +08001229 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001230 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001231
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001232 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001233
hualing chen86e7d482020-01-16 15:13:33 +08001234 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001235 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001236 pthread_condattr_init(&cattr);
1237 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1238 pthread_cond_init(&player->cond, &cattr);
1239 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001240
hualing chen5cbe1a62020-02-10 16:36:36 +08001241 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001242 INIT_LIST_HEAD(&player->segment_list);
1243 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1244 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001245 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001246 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001247 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001248 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001249 player->speed = 1.0f;
hualing chen2aba4022020-03-02 13:49:55 +08001250
hualing chen86e7d482020-01-16 15:13:33 +08001251 //store open params
hualing chen040df222020-01-17 13:35:02 +08001252 player->openParams.dmx_dev_id = params->dmx_dev_id;
1253 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001254 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001255 player->openParams.event_fn = params->event_fn;
1256 player->openParams.event_userdata = params->event_userdata;
1257
hualing chen5cbe1a62020-02-10 16:36:36 +08001258 player->has_pids = params->has_pids;
1259
hualing chen2aba4022020-03-02 13:49:55 +08001260 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001261
1262 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1263 //for test get callback
1264 if (0 && player->player_callback_func == NULL) {
1265 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1266 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001267 DVR_PB_DG(1, "playback open get callback[%p][%p][%p][%p]",player->player_callback_func, player->player_callback_userdata, _dvr_tsplayer_callback_test,player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001268 }
1269 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001270
hualing chen86e7d482020-01-16 15:13:33 +08001271 //init has audio and video
1272 player->has_video = DVR_FALSE;
1273 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001274 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001275 player->last_segment_id = 0LL;
1276 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001277
hualing chen5cbe1a62020-02-10 16:36:36 +08001278 //init ff fb time
1279 player->fffb_current = -1;
1280 player->fffb_start =-1;
1281 player->fffb_start_pcr = -1;
1282 //seek time
1283 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001284 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001285
1286 //init secure stuff
1287 player->dec_func = NULL;
1288 player->dec_userdata = NULL;
1289 player->is_secure_mode = 0;
1290 player->secure_buffer = NULL;
1291 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001292 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001293
hualing chen4b7c15d2020-04-07 16:13:48 +08001294 player->fffb_play = DVR_FALSE;
1295
1296 player->last_send_time_id = UINT64_MAX;
1297 player->last_cur_time = 0;
1298
hualing chen86e7d482020-01-16 15:13:33 +08001299 *p_handle = player;
1300 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001301}
1302
1303/**\brief Close an dvr palyback
1304 * \param[in] handle playback handle
1305 * \retval DVR_SUCCESS On success
1306 * \return Error code
1307 */
hualing chen040df222020-01-17 13:35:02 +08001308int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001309
hualing chen86e7d482020-01-16 15:13:33 +08001310 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001311 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001312 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001313 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001314 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001315 return DVR_FAILURE;
1316 }
1317
hualing chencc91e1c2020-02-28 13:26:17 +08001318 if (player->state != DVR_PLAYBACK_STATE_STOP)
1319 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001320 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001321 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001322 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1323 } else {
1324 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001325 }
hualing chen7a56cba2020-04-14 14:09:27 +08001326 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001327 pthread_mutex_destroy(&player->lock);
1328 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001329
1330 if (player) {
1331 free(player);
1332 player = NULL;
1333 }
hualing chen7a56cba2020-04-14 14:09:27 +08001334 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001335 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001336}
1337
hualing chenb31a6c62020-01-13 17:27:00 +08001338/**\brief Start play audio and video, used start auido api and start video api
1339 * \param[in] handle playback handle
1340 * \param[in] params audio playback params,contains fmt and pid...
1341 * \retval DVR_SUCCESS On success
1342 * \return Error code
1343 */
hualing chen040df222020-01-17 13:35:02 +08001344int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1345 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001346 am_tsplayer_video_params vparams;
1347 am_tsplayer_audio_params aparams;
hualing chena540a7e2020-03-27 16:44:05 +08001348
1349 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001350 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001351 return DVR_FAILURE;
1352 }
hualing chencc91e1c2020-02-28 13:26:17 +08001353 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001354 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001355
hualing chena540a7e2020-03-27 16:44:05 +08001356 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001357 //can used start api to resume playback
1358 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1359 return dvr_playback_resume(handle);
1360 }
hualing chen87072a82020-03-12 16:20:12 +08001361 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001362 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001363 return DVR_SUCCESS;
1364 }
hualing chen86e7d482020-01-16 15:13:33 +08001365 player->play_flag = flag;
hualing chen5cbe1a62020-02-10 16:36:36 +08001366 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001367 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001368 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001369 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001370 //start audio and video
1371 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1372 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001373 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001374 pthread_mutex_unlock(&player->lock);
1375 DVR_Play_Notify_t notify;
1376 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1377 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1378 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1379 notify.info.transition_failed_data.segment_id = segment_id;
1380 //get play statue not here
1381 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify);
hualing chen86e7d482020-01-16 15:13:33 +08001382 return -1;
1383 }
hualing chen31140872020-03-25 12:29:26 +08001384
hualing chencc91e1c2020-02-28 13:26:17 +08001385 {
hualing chen86e7d482020-01-16 15:13:33 +08001386 if (VALID_PID(vparams.pid)) {
1387 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001388 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001389 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001390 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001391 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1392 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001393 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001394 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001395 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001396 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001397 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001398 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001399 }
1400 AmTsPlayer_setVideoParams(player->handle, &vparams);
1401 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001402 }
hualing chena540a7e2020-03-27 16:44:05 +08001403
hualing chen4b7c15d2020-04-07 16:13:48 +08001404 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1405 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001406 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1407 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1408 player->cmd.state = DVR_PLAYBACK_STATE_START;
1409 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001410 } else {
1411 player->cmd.last_cmd = player->cmd.cur_cmd;
1412 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001413 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001414 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001415 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001416 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001417 } else {
1418 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001419 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08001420 player->has_audio = DVR_TRUE;
1421 AmTsPlayer_setAudioParams(player->handle, &aparams);
1422 AmTsPlayer_startAudioDecoding(player->handle);
1423 }
hualing chen31140872020-03-25 12:29:26 +08001424 }
hualing chencc91e1c2020-02-28 13:26:17 +08001425 player->cmd.state = DVR_PLAYBACK_STATE_START;
1426 player->state = DVR_PLAYBACK_STATE_START;
1427 }
hualing chen86e7d482020-01-16 15:13:33 +08001428 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001429 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001430 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001431 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001432 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001433}
hualing chen040df222020-01-17 13:35:02 +08001434/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001435 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001436 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001437 * \retval DVR_SUCCESS On success
1438 * \return Error code
1439 */
hualing chen040df222020-01-17 13:35:02 +08001440int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1441 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001442
hualing chena540a7e2020-03-27 16:44:05 +08001443 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001444 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001445 return DVR_FAILURE;
1446 }
1447
hualing chen4b7c15d2020-04-07 16:13:48 +08001448 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001449 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001450
hualing chen040df222020-01-17 13:35:02 +08001451 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1452 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001453
hualing chen86e7d482020-01-16 15:13:33 +08001454 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001455 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001456 //cp location
hualing chen040df222020-01-17 13:35:02 +08001457 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001458
hualing chen4b7c15d2020-04-07 16:13:48 +08001459 DVR_PB_DG(1, "add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001460 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001461
1462 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001463 segment->pids.video.pid = info->pids.video.pid;
1464 segment->pids.video.format = info->pids.video.format;
1465 segment->pids.video.type = info->pids.video.type;
1466
hualing chen2aba4022020-03-02 13:49:55 +08001467 segment->pids.audio.pid = info->pids.audio.pid;
1468 segment->pids.audio.format = info->pids.audio.format;
1469 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001470
hualing chen2aba4022020-03-02 13:49:55 +08001471 segment->pids.ad.pid = info->pids.ad.pid;
1472 segment->pids.ad.format = info->pids.ad.format;
1473 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001474
1475 segment->pids.pcr.pid = info->pids.pcr.pid;
1476
hualing chen4b7c15d2020-04-07 16:13:48 +08001477 DVR_PB_DG(1, "lock pid [0x%x][0x%x][0x%x][0x%x]", segment->pids.video.pid,segment->pids.audio.pid, info->pids.video.pid,info->pids.audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001478 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001479 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001480 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001481 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001482
hualing chen5cbe1a62020-02-10 16:36:36 +08001483 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001484}
hualing chen040df222020-01-17 13:35:02 +08001485/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001486 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001487 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001488 * \retval DVR_SUCCESS On success
1489 * \return Error code
1490 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001491int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001492 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001493 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001494 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001495 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001496 return DVR_FAILURE;
1497 }
1498
hualing chencc91e1c2020-02-28 13:26:17 +08001499 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001500 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001501 return DVR_FAILURE;
1502 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001503 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001504 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001505 DVR_PlaybackSegmentInfo_t *segment = NULL;
1506 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1507 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001508 {
hualing chen040df222020-01-17 13:35:02 +08001509 if (segment->segment_id == segment_id) {
1510 list_del(&segment->head);
1511 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001512 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001513 }
hualing chen86e7d482020-01-16 15:13:33 +08001514 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001515 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001516 pthread_mutex_unlock(&player->lock);
1517
1518 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001519}
hualing chen040df222020-01-17 13:35:02 +08001520/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001521 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001522 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001523 * \retval DVR_SUCCESS On success
1524 * \return Error code
1525 */
hualing chen040df222020-01-17 13:35:02 +08001526int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001527 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001528 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001529 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001530 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001531 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001532 return DVR_FAILURE;
1533 }
1534
hualing chen040df222020-01-17 13:35:02 +08001535 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001536 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001537 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001538 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001539 {
hualing chen040df222020-01-17 13:35:02 +08001540 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001541 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001542 }
hualing chen86e7d482020-01-16 15:13:33 +08001543 // if encramble to free, only set flag and return;
1544
1545 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001546 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001547 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1548 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001549 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001550 AmTsPlayer_hideVideo(player->handle);
1551 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001552 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1553 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001554 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001555 AmTsPlayer_showVideo(player->handle);
1556 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001557 } else {
1558 //do nothing
1559 }
1560 } else {
1561 //do nothing
1562 }
1563 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001564 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001565 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001566 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001567 pthread_mutex_unlock(&player->lock);
1568 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001569}
1570
1571
hualing chen5cbe1a62020-02-10 16:36:36 +08001572static 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 +08001573 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001574 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001575 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001576 return DVR_FAILURE;
1577 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001578 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001579 if (now_pid.pid == set_pid.pid) {
1580 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001581 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001582 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001583 if (VALID_PID(now_pid.pid)) {
1584 //stop now stream
1585 if (type == 0) {
1586 //stop vieo
hualing chen4b7c15d2020-04-07 16:13:48 +08001587 DVR_PB_DG(1, "stop video");
hualing chen2aba4022020-03-02 13:49:55 +08001588 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001589 player->has_video = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001590 } else if (type == 1) {
1591 //stop audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001592 DVR_PB_DG(1, "stop audio");
hualing chen2aba4022020-03-02 13:49:55 +08001593 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001594 player->has_audio = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001595 } else if (type == 2) {
1596 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001597 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001598 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001599 } else if (type == 3) {
1600 //pcr
1601 }
1602 }
1603 if (VALID_PID(set_pid.pid)) {
1604 //start
1605 if (type == 0) {
1606 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001607 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001608 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001609 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001610 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001611 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001612 AmTsPlayer_setVideoParams(player->handle, &vparams);
1613 AmTsPlayer_startVideoDecoding(player->handle);
1614 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001615 } else if (type == 1) {
1616 //start audio
hualing chen2aba4022020-03-02 13:49:55 +08001617 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001618 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001619 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001620 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001621 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001622 AmTsPlayer_setAudioParams(player->handle, &aparams);
1623 AmTsPlayer_startAudioDecoding(player->handle);
1624 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001625 } else if (type == 2) {
hualing chen2aba4022020-03-02 13:49:55 +08001626 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001627 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001628 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001629 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001630 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chena540a7e2020-03-27 16:44:05 +08001631 AmTsPlayer_setADParams(player->handle, &aparams);
1632 AmTsPlayer_enableADMix(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001633 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001634 } else if (type == 3) {
1635 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001636 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001637 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001638 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001639 //audio and video all close
1640 if (!player->has_audio && !player->has_video) {
1641 player->state = DVR_PLAYBACK_STATE_STOP;
1642 }
hualing chen86e7d482020-01-16 15:13:33 +08001643 }
1644 }
1645 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001646}
hualing chen5cbe1a62020-02-10 16:36:36 +08001647/**\brief dvr play back update segment pids
1648 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001649 * add pid stream and stop remove pid stream.
1650 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001651 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001652 * \retval DVR_SUCCESS On success
1653 * \return Error code
1654 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001655int 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 +08001656 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001657 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001658 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001659 return DVR_FAILURE;
1660 }
1661
hualing chen040df222020-01-17 13:35:02 +08001662 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001663 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001664 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001665 DVR_PB_DG(1, "get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001666
hualing chen040df222020-01-17 13:35:02 +08001667 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001668 {
hualing chen040df222020-01-17 13:35:02 +08001669 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001670
1671 if (player->cur_segment_id == segment_id) {
1672 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1673 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1674 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001675 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001676 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001677 return 0;
1678 }
1679
1680 //if segment is on going segment,we need stop start stream
1681 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001682 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001683 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001684 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001685 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001686 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001687 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001688 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001689 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001690 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1691 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001692 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1693 //if state is pause, we need process at resume api. we only record change info
1694 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1695 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1696 if (VALID_PID(segment->pids.video.pid)
1697 && VALID_PID(p_pids->video.pid)
1698 && segment->pids.video.pid != p_pids->video.pid) {
1699 //restart video
1700 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1701 }
1702 if (!VALID_PID(segment->pids.video.pid)
1703 && VALID_PID(p_pids->video.pid)
1704 && segment->pids.video.pid != p_pids->video.pid) {
1705 //start video
1706 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1707 }
1708 if (VALID_PID(segment->pids.video.pid)
1709 && !VALID_PID(p_pids->video.pid)
1710 && segment->pids.video.pid != p_pids->video.pid) {
1711 //stop video
1712 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1713 }
1714 if (VALID_PID(segment->pids.audio.pid)
1715 && VALID_PID(p_pids->audio.pid)
1716 && segment->pids.audio.pid != p_pids->audio.pid) {
1717 //restart audio
1718 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1719 }
1720 if (!VALID_PID(segment->pids.audio.pid)
1721 && VALID_PID(p_pids->audio.pid)
1722 && segment->pids.audio.pid != p_pids->audio.pid) {
1723 //start audio
1724 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1725 }
1726 if (VALID_PID(segment->pids.audio.pid)
1727 && !VALID_PID(p_pids->audio.pid)
1728 && segment->pids.audio.pid != p_pids->audio.pid) {
1729 //stop audio
1730 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1731 }
1732 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1733 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1734 //do nothing
1735 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1736 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1737 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1738 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1739 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1740 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1741 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1742 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1743 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1744 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1745 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1746 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1747 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1748 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1749 } else {
1750 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1751 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1752 }
1753
1754 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1755 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1756 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1757 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1758 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1759 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1760 //not occur this case
1761 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1762 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1763 } else {
1764 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1765 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1766 }
1767
1768 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1769 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1770 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1771 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1772 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1773 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1774 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1775 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1776 } else {
1777 //not occur this case
1778 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1779 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1780 }
1781 }
1782 }
hualing chene10666f2020-04-14 13:58:37 +08001783 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08001784 }
hualing chen86e7d482020-01-16 15:13:33 +08001785 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08001786 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08001787 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08001788 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001789 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001790 }
hualing chen86e7d482020-01-16 15:13:33 +08001791 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001792 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001793 pthread_mutex_unlock(&player->lock);
1794 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001795}
1796/**\brief Stop play, will stop video and audio
1797 * \param[in] handle playback handle
1798 * \param[in] clear is clear last frame
1799 * \retval DVR_SUCCESS On success
1800 * \return Error code
1801 */
hualing chen040df222020-01-17 13:35:02 +08001802int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1803 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001804
1805 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001806 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001807 return DVR_FAILURE;
1808 }
hualing chenb96aa2c2020-04-15 14:13:53 +08001809 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1810 DVR_PB_DG(1, ":playback is stoped");
1811 return DVR_SUCCESS;
1812 }
Ke Gong3c0caba2020-04-21 22:58:18 -07001813 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1814 DVR_PB_DG(1, ":playback is stoped");
1815 return DVR_SUCCESS;
1816 }
hualing chen7a56cba2020-04-14 14:09:27 +08001817 DVR_PB_DG(1, ":into");
hualing chen87072a82020-03-12 16:20:12 +08001818 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001819 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001820 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08001821 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08001822 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001823 if (player->has_video) {
1824 AmTsPlayer_resumeVideoDecoding(player->handle);
1825 }
1826 if (player->has_audio) {
1827 AmTsPlayer_resumeAudioDecoding(player->handle);
1828 }
hualing chen7a56cba2020-04-14 14:09:27 +08001829 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001830 if (player->has_video) {
1831 player->has_video = DVR_FALSE;
1832 AmTsPlayer_showVideo(player->handle);
1833 AmTsPlayer_stopVideoDecoding(player->handle);
1834 }
hualing chen7a56cba2020-04-14 14:09:27 +08001835 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001836 if (player->has_audio) {
1837 player->has_audio = DVR_FALSE;
1838 AmTsPlayer_stopAudioDecoding(player->handle);
1839 }
hualing chen7a56cba2020-04-14 14:09:27 +08001840 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001841
hualing chen86e7d482020-01-16 15:13:33 +08001842 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001843 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1844 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1845 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001846 player->cur_segment_id = UINT64_MAX;
1847 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001848 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08001849 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08001850 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001851 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001852}
1853/**\brief Start play audio
1854 * \param[in] handle playback handle
1855 * \param[in] params audio playback params,contains fmt and pid...
1856 * \retval DVR_SUCCESS On success
1857 * \return Error code
1858 */
hualing chen2aba4022020-03-02 13:49:55 +08001859
1860int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001861 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001862
1863 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001864 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001865 return DVR_FAILURE;
1866 }
hualing chen86e7d482020-01-16 15:13:33 +08001867 _start_playback_thread(handle);
1868 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001869 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001870 pthread_mutex_lock(&player->lock);
1871 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001872 AmTsPlayer_setAudioParams(player->handle, param);
1873 AmTsPlayer_startAudioDecoding(player->handle);
1874 //playback_device_audio_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001875 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001876 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1877 player->cmd.state = DVR_PLAYBACK_STATE_START;
1878 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001879 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001880 pthread_mutex_unlock(&player->lock);
1881 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001882}
1883/**\brief Stop play audio
1884 * \param[in] handle playback handle
1885 * \retval DVR_SUCCESS On success
1886 * \return Error code
1887 */
hualing chen040df222020-01-17 13:35:02 +08001888int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1889 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001890
1891 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001892 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001893 return DVR_FAILURE;
1894 }
1895
hualing chen2aba4022020-03-02 13:49:55 +08001896 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001897 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001898 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1899 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001900 //destory thread
1901 _stop_playback_thread(handle);
1902 } else {
1903 //do nothing.video is playing
1904 }
hualing chen7a56cba2020-04-14 14:09:27 +08001905 DVR_PB_DG(1, "lock");
1906 pthread_mutex_lock(&player->lock);
1907
hualing chen87072a82020-03-12 16:20:12 +08001908 player->has_audio = DVR_FALSE;
1909
1910 AmTsPlayer_stopAudioDecoding(player->handle);
1911 player->cmd.last_cmd = player->cmd.cur_cmd;
1912 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
1913
hualing chen4b7c15d2020-04-07 16:13:48 +08001914 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001915 pthread_mutex_unlock(&player->lock);
1916 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001917}
1918/**\brief Start play video
1919 * \param[in] handle playback handle
1920 * \param[in] params video playback params,contains fmt and pid...
1921 * \retval DVR_SUCCESS On success
1922 * \return Error code
1923 */
hualing chen2aba4022020-03-02 13:49:55 +08001924int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001925 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001926
1927 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001928 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001929 return DVR_FAILURE;
1930 }
1931
hualing chen86e7d482020-01-16 15:13:33 +08001932 _start_playback_thread(handle);
1933 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001934 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001935 pthread_mutex_lock(&player->lock);
1936 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001937 AmTsPlayer_setVideoParams(player->handle, param);
1938 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001939
1940 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001941 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08001942 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001943 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08001944 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1945 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08001946 }
1947 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001948 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
1949 player->cmd.state = DVR_PLAYBACK_STATE_START;
1950 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001951 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001952 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001953 return DVR_SUCCESS;
1954}
1955/**\brief Stop play video
1956 * \param[in] handle playback handle
1957 * \retval DVR_SUCCESS On success
1958 * \return Error code
1959 */
hualing chen040df222020-01-17 13:35:02 +08001960int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
1961 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001962
1963 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001964 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001965 return DVR_FAILURE;
1966 }
1967
hualing chen86e7d482020-01-16 15:13:33 +08001968 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001969 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1970 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001971 //destory thread
1972 _stop_playback_thread(handle);
1973 } else {
1974 //do nothing.audio is playing
1975 }
hualing chen7a56cba2020-04-14 14:09:27 +08001976
1977 DVR_PB_DG(1, "lock");
1978 pthread_mutex_lock(&player->lock);
1979
hualing chen87072a82020-03-12 16:20:12 +08001980 player->has_video = DVR_FALSE;
1981
1982 AmTsPlayer_stopVideoDecoding(player->handle);
1983 //playback_device_video_stop(player->handle);
1984
1985 player->cmd.last_cmd = player->cmd.cur_cmd;
1986 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
1987
hualing chen4b7c15d2020-04-07 16:13:48 +08001988 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001989 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001990 return DVR_SUCCESS;
1991}
1992/**\brief Pause play
1993 * \param[in] handle playback handle
1994 * \param[in] flush whether its internal buffers should be flushed
1995 * \retval DVR_SUCCESS On success
1996 * \return Error code
1997 */
hualing chen040df222020-01-17 13:35:02 +08001998int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
1999 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002000
2001 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002002 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002003 return DVR_FAILURE;
2004 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002005 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002006 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002007 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002008 if (player->has_video)
2009 AmTsPlayer_pauseVideoDecoding(player->handle);
2010 if (player->has_video)
2011 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002012
2013 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002014 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2015 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2016 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2017 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002018 } else {
2019 player->cmd.last_cmd = player->cmd.cur_cmd;
2020 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2021 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2022 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002023 }
hualing chen86e7d482020-01-16 15:13:33 +08002024 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002025 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002026
hualing chen86e7d482020-01-16 15:13:33 +08002027 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002028}
2029
hualing chen5cbe1a62020-02-10 16:36:36 +08002030//not add lock
2031static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2032{
2033 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2034
hualing chena540a7e2020-03-27 16:44:05 +08002035 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002036 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002037 return DVR_FAILURE;
2038 }
2039
hualing chen5cbe1a62020-02-10 16:36:36 +08002040 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002041 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002042 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002043 am_tsplayer_video_params vparams;
2044 am_tsplayer_audio_params aparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002045 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002046
2047 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002048 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002049 pthread_mutex_unlock(&player->lock);
2050
2051 switch (cmd) {
2052 case DVR_PLAYBACK_CMD_AVRESTART:
2053 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002054 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002055 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002056 break;
2057 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002058 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2059 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002060 break;
2061 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002062 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002063 break;
2064 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002065 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002066 break;
2067 case DVR_PLAYBACK_CMD_ARESTART:
2068 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002069 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2070 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002071 break;
2072 case DVR_PLAYBACK_CMD_ASTART:
hualing chen2aba4022020-03-02 13:49:55 +08002073 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002074 break;
2075 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002076 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002077 break;
2078 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002079 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2080 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2081 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002082 break;
2083 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002084 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2085 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002086 break;
2087 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002088 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2089 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2090 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002091 break;
2092 case DVR_PLAYBACK_CMD_STOP:
2093 break;
2094 case DVR_PLAYBACK_CMD_START:
2095 break;
2096 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002097 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2098 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
2099 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002100 break;
2101 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002102 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2103 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
2104 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002105 break;
2106 case DVR_PLAYBACK_CMD_FF:
2107 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002108 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002109 break;
2110 default:
2111 break;
2112 }
2113 return DVR_SUCCESS;
2114}
2115
2116/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002117 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002118 * \retval DVR_SUCCESS On success
2119 * \return Error code
2120 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002121int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2122 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2123
hualing chena540a7e2020-03-27 16:44:05 +08002124 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002125 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002126 return DVR_FAILURE;
2127 }
2128
hualing chen5cbe1a62020-02-10 16:36:36 +08002129 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002130 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002131 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002132 if (player->has_video) {
2133 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2134 AmTsPlayer_resumeVideoDecoding(player->handle);
2135 }
2136 if (player->has_audio) {
2137 AmTsPlayer_resumeAudioDecoding(player->handle);
2138 }
2139 //check is has audio param,if has audio .we need start audio,
2140 //we will stop audio when ff fb, if reach end, we will pause.so we need
2141 //start audio when resume play
2142
2143 am_tsplayer_video_params vparams;
2144 am_tsplayer_audio_params aparams;
2145 uint64_t segmentid = player->cur_segment_id;
2146 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
2147 //valid audio pid, start audio
2148 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid)) {
2149 player->has_audio = DVR_TRUE;
2150 AmTsPlayer_setAudioParams(player->handle, &aparams);
2151 AmTsPlayer_startAudioDecoding(player->handle);
2152 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002153 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d", aparams.pid, player->has_audio);
hualing chen266b9502020-04-04 17:39:39 +08002154 }
hualing chen87072a82020-03-12 16:20:12 +08002155 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2156 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2157 player->cmd.state = DVR_PLAYBACK_STATE_START;
2158 player->state = DVR_PLAYBACK_STATE_START;
2159 } else {
2160 player->cmd.last_cmd = player->cmd.cur_cmd;
2161 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2162 player->cmd.state = DVR_PLAYBACK_STATE_START;
2163 player->state = DVR_PLAYBACK_STATE_START;
2164 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002165 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002166 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002167 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
2168 if (player->has_video)
2169 AmTsPlayer_resumeVideoDecoding(player->handle);
2170 if (player->has_audio)
2171 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002172 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002173 player->cmd.state = DVR_PLAYBACK_STATE_START;
2174 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002175 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002176 } else {
2177 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2178 {
2179 pthread_mutex_lock(&player->lock);
2180 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002181 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002182 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2183 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2184 pthread_mutex_unlock(&player->lock);
2185 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002186 }
2187 return DVR_SUCCESS;
2188}
2189
hualing chena540a7e2020-03-27 16:44:05 +08002190static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2191
2192 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2193 DVR_PlaybackSegmentInfo_t *segment = NULL;
2194 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2195 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2196
2197 list_for_each_entry(segment, &player->segment_list, head)
2198 {
2199 if (segment->segment_id == segment_id) {
2200 cur_segment = segment;
2201 }
2202 if (segment->segment_id == set_seg_id) {
2203 set_segment = segment;
2204 }
2205 if (cur_segment != NULL && set_segment != NULL) {
2206 break;
2207 }
2208 }
2209 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002210 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002211 return DVR_TRUE;
2212 }
2213 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2214 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2215 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2216 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002217 DVR_PB_DG(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);
hualing chena540a7e2020-03-27 16:44:05 +08002218 return DVR_TRUE;
2219 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002220 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002221 return DVR_FALSE;
2222}
2223
hualing chen5cbe1a62020-02-10 16:36:36 +08002224/**\brief seek
2225 * \param[in] handle playback handle
2226 * \param[in] time_offset time offset base cur segment
2227 * \retval DVR_SUCCESS On success
2228 * \return Error code
2229 */
hualing chencc91e1c2020-02-28 13:26:17 +08002230int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002231 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002232
2233 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002234 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002235 return DVR_FAILURE;
2236 }
2237
hualing chen4b7c15d2020-04-07 16:13:48 +08002238 DVR_PB_DG(1, "lock segment_id %llu cur id %llu time_offset %u cur end: %d player->state:%d", segment_id,player->cur_segment_id, (uint32_t)time_offset, _dvr_get_end_time(handle), player->state);
hualing chen86e7d482020-01-16 15:13:33 +08002239 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002240
hualing chen86e7d482020-01-16 15:13:33 +08002241 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002242 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002243 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002244
hualing chen5cbe1a62020-02-10 16:36:36 +08002245 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002246 int ret = _dvr_open_segment(handle, segment_id);
2247 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002248 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002249 pthread_mutex_unlock(&player->lock);
2250 return DVR_FAILURE;
2251 }
2252 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2253 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002254 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002255 //pthread_mutex_unlock(&player->lock);
2256 //return DVR_SUCCESS;
2257 time_offset = _dvr_get_end_time(handle);
2258 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002259 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chen87072a82020-03-12 16:20:12 +08002260 pthread_mutex_unlock(&player->lock);
2261 return DVR_FAILURE;
2262 }
2263 }
2264
hualing chen4b7c15d2020-04-07 16:13:48 +08002265 DVR_PB_DG(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 +08002266 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002267 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2268 //forward playback.not seek end of file
2269 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2270 //default -2000ms
2271 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2272 }
hualing chen86e7d482020-01-16 15:13:33 +08002273 }
hualing chen2aba4022020-03-02 13:49:55 +08002274 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002275 player->drop_ts = DVR_TRUE;
2276 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002277 DVR_PB_DG(0, "seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08002278 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002279 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002280
hualing chen2aba4022020-03-02 13:49:55 +08002281 _dvr_get_end_time(handle);
2282 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002283 player->fffb_current = _dvr_time_getClock();
2284 player->fffb_start = player->fffb_current;
2285 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2286 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002287 //pause state if need to replayer false
2288 if (player->state == DVR_PLAYBACK_STATE_STOP ||
2289 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002290 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002291 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002292 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002293 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002294 }
hualing chen86e7d482020-01-16 15:13:33 +08002295 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002296 DVR_PB_DG(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 +08002297 if (player->has_video) {
2298 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002299 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002300 }
2301
2302 if (player->has_audio) {
2303 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002304 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002305 }
hualing chen86e7d482020-01-16 15:13:33 +08002306 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002307 am_tsplayer_video_params vparams;
2308 am_tsplayer_audio_params aparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002309
hualing chen040df222020-01-17 13:35:02 +08002310 player->cur_segment_id = segment_id;
2311
2312 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002313 //get segment info and audio video pid fmt ;
2314 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08002315 //start audio and video
2316 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2317 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002318 DVR_PB_DG(0, "unlock seek start dvr play back start error, not found audio and video info");
hualing chen86e7d482020-01-16 15:13:33 +08002319 pthread_mutex_unlock(&player->lock);
2320 return -1;
2321 }
2322 //add
hualing chen040df222020-01-17 13:35:02 +08002323 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002324 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002325 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002326 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chen31140872020-03-25 12:29:26 +08002327 player->speed > 1.0f||
2328 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002329 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002330 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002331 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002332 }
hualing chen2aba4022020-03-02 13:49:55 +08002333 AmTsPlayer_setVideoParams(player->handle, &vparams);
2334 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002335 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002336 }
hualing chen86e7d482020-01-16 15:13:33 +08002337 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002338 DVR_PB_DG(1, "start audio seek");
hualing chen2aba4022020-03-02 13:49:55 +08002339 AmTsPlayer_setAudioParams(player->handle, &aparams);
2340 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002341 player->has_audio = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002342 }
hualing chen86e7d482020-01-16 15:13:33 +08002343 }
hualing chen2aba4022020-03-02 13:49:55 +08002344 if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
2345 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2346 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2347 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
2348 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))) {
2349 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2350 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002351 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002352 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2353 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002354 player->speed > 1.0f||
2355 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002356 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002357 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002358 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002359 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002360 player->cmd.last_cmd = player->cmd.cur_cmd;
2361 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2362 player->cmd.state = DVR_PLAYBACK_STATE_START;
2363 player->state = DVR_PLAYBACK_STATE_START;
2364 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002365 player->last_send_time_id = UINT64_MAX;
2366 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002367 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002368
2369 return DVR_SUCCESS;
2370}
hualing chen5cbe1a62020-02-10 16:36:36 +08002371
hualing chen5cbe1a62020-02-10 16:36:36 +08002372static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2373 //get cur time of segment
2374 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002375
2376 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002377 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002378 return DVR_FAILURE;
2379 }
2380
hualing chen31140872020-03-25 12:29:26 +08002381 int64_t cache = 0;//defalut es buf cache 500ms
2382 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002383 pthread_mutex_lock(&player->segment_lock);
2384 uint64_t cur = segment_tell_current_time(player->r_handle);
2385 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002386 DVR_PB_DG(1, "get cur time [%lld] cache:%lld cur id [%lld]", cur, cache, player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002387 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2388 cache = 0;
2389 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002390 int cur_time = (int)(cur > cache ? cur - cache : 0);
2391 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002392}
2393
2394//get current segment current pcr time of read pos
2395static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2396 //get cur time of segment
2397 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002398
2399 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002400 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002401 return DVR_FAILURE;
2402 }
2403
hualing chen2aba4022020-03-02 13:49:55 +08002404 pthread_mutex_lock(&player->segment_lock);
2405 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002406 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002407 pthread_mutex_unlock(&player->segment_lock);
2408 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002409}
2410
hualing chen4b7c15d2020-04-07 16:13:48 +08002411#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002412//start replay
2413static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2414
2415 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2416 //calculate pcr seek time
2417 int t_diff = 0;
2418 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002419
2420 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002421 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002422 return DVR_FAILURE;
2423 }
2424
hualing chen5cbe1a62020-02-10 16:36:36 +08002425 if (player->fffb_start == -1) {
2426 //set fffb start time ms
2427 player->fffb_start = _dvr_time_getClock();
2428 player->fffb_current = player->fffb_start;
2429 //get segment current time pos
2430 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002431 DVR_PB_DG(1, "calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]", player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002432 t_diff = 0;
hualing chen2aba4022020-03-02 13:49:55 +08002433 //default first time 1ms seek
hualing chen87072a82020-03-12 16:20:12 +08002434 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002435 } else {
2436 player->fffb_current = _dvr_time_getClock();
2437 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002438 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002439 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002440 if (seek_time <= 0) {
2441 //need seek to pre one segment
2442 seek_time = 0;
2443 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002444 //seek segment pos
2445 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002446 pthread_mutex_lock(&player->segment_lock);
hualing chen041c4092020-04-05 15:11:50 +08002447 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2448 seek_time = 0;
2449 }
hualing chen2aba4022020-03-02 13:49:55 +08002450 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002451 } else {
2452 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002453 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002454 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002455 DVR_PB_DG(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 +08002456 }
hualing chen2aba4022020-03-02 13:49:55 +08002457 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002458}
2459
2460
2461//start replay
2462static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2463 //
2464 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002465
2466 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002467 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002468 return DVR_FAILURE;
2469 }
2470
hualing chen5cbe1a62020-02-10 16:36:36 +08002471 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002472 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002473 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002474 AmTsPlayer_stopVideoDecoding(player->handle);
2475 }
2476 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002477 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002478 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002479 AmTsPlayer_stopAudioDecoding(player->handle);
2480 }
2481
hualing chen5cbe1a62020-02-10 16:36:36 +08002482 //start video and audio
2483
hualing chen2aba4022020-03-02 13:49:55 +08002484 am_tsplayer_video_params vparams;
2485 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002486 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002487
2488 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002489 //pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002490 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2491 //start audio and video
2492 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2493 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002494 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002495 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002496 return -1;
2497 }
2498
2499 if (VALID_PID(vparams.pid)) {
2500 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002501 DVR_PB_DG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08002502 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002503 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2504 AmTsPlayer_setVideoParams(player->handle, &vparams);
2505 AmTsPlayer_startVideoDecoding(player->handle);
2506 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002507 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002508 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002509 }
hualing chena540a7e2020-03-27 16:44:05 +08002510 if (0 && VALID_PID(aparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002511 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002512 DVR_PB_DG(1, "fffb start audio");
hualing chen2aba4022020-03-02 13:49:55 +08002513 AmTsPlayer_setAudioParams(player->handle, &aparams);
2514 AmTsPlayer_startAudioDecoding(player->handle);
2515 //playback_device_audio_start(player->handle , &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002516 }
hualing chen31140872020-03-25 12:29:26 +08002517 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08002518 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002519 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002520 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002521 return 0;
2522}
2523
2524static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2525 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002526
2527 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002528 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002529 return DVR_FAILURE;
2530 }
2531
2532 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002533 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002534 pthread_mutex_lock(&player->lock);
2535
hualing chen2aba4022020-03-02 13:49:55 +08002536 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002537 DVR_PB_DG(1, "get lock speed [%f]id [%lld]seek_time[%d]", player->speed, player->cur_segment_id, seek_time);
hualing chen041c4092020-04-05 15:11:50 +08002538
hualing chen87072a82020-03-12 16:20:12 +08002539 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2540 //seek time set 0
2541 seek_time = 0;
2542 }
hualing chen041c4092020-04-05 15:11:50 +08002543 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002544 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2545 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002546 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002547 pthread_mutex_unlock(&player->lock);
2548 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002549 //send event here and pause
2550 DVR_Play_Notify_t notify;
2551 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002552 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002553 //get play statue not here
2554 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify);
hualing chen4b7c15d2020-04-07 16:13:48 +08002555 DVR_PB_DG(1, "*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08002556 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002557 return DVR_SUCCESS;
2558 }
hualing chen87072a82020-03-12 16:20:12 +08002559 _dvr_playback_sent_transition_ok(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002560 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002561 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002562 }
2563 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002564 _dvr_playback_fffb_replay(handle);
2565
2566 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002567 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002568
hualing chen5cbe1a62020-02-10 16:36:36 +08002569 return DVR_SUCCESS;
2570}
2571
hualing chen87072a82020-03-12 16:20:12 +08002572//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002573static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002574 //
2575 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002576
2577 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002578 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002579 return DVR_FAILURE;
2580 }
2581
hualing chen5cbe1a62020-02-10 16:36:36 +08002582 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002583 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002584 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002585 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002586 }
2587
2588 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002589 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002590 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002591 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002592 //start video and audio
2593
hualing chen2aba4022020-03-02 13:49:55 +08002594 am_tsplayer_video_params vparams;
2595 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002596 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002597
2598 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002599 DVR_PB_DG(1, "into");
hualing chen5cbe1a62020-02-10 16:36:36 +08002600 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2601 //start audio and video
2602 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002603 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002604 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002605 return -1;
2606 }
2607
2608 if (VALID_PID(vparams.pid)) {
2609 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002610 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002611 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002612 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002613 }
hualing chen266b9502020-04-04 17:39:39 +08002614 else {
hualing chen2aba4022020-03-02 13:49:55 +08002615 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002616 }
hualing chen2aba4022020-03-02 13:49:55 +08002617 AmTsPlayer_setVideoParams(player->handle, &vparams);
2618 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002619 }
hualing chena540a7e2020-03-27 16:44:05 +08002620
2621 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08002622 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08002623 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002624 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002625 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002626 if (VALID_PID(aparams.pid)) {
2627 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002628 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08002629 AmTsPlayer_startAudioDecoding(player->handle);
2630 AmTsPlayer_setAudioParams(player->handle, &aparams);
hualing chena540a7e2020-03-27 16:44:05 +08002631 }
hualing chen7a56cba2020-04-14 14:09:27 +08002632 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002633 AmTsPlayer_stopFast(player->handle);
2634 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2635 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2636 }
hualing chen2aba4022020-03-02 13:49:55 +08002637 player->cmd.last_cmd = player->cmd.cur_cmd;
2638 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002639 player->cmd.state = DVR_PLAYBACK_STATE_START;
2640 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002641 return 0;
2642}
2643
2644
hualing chenb31a6c62020-01-13 17:27:00 +08002645/**\brief Set play speed
2646 * \param[in] handle playback handle
2647 * \param[in] speed playback speed
2648 * \retval DVR_SUCCESS On success
2649 * \return Error code
2650 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002651int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2652
2653 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002654
2655 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002656 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002657 return DVR_FAILURE;
2658 }
2659
hualing chen4b7c15d2020-04-07 16:13:48 +08002660 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002661 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002662 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002663 return DVR_FAILURE;
2664 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002665 pthread_mutex_lock(&player->lock);
2666 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2667 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2668 player->cmd.last_cmd = player->cmd.cur_cmd;
2669 }
hualing chen31140872020-03-25 12:29:26 +08002670 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002671 IS_KERNEL_SPEED(speed.speed.speed)) {
2672 //case 1. cur speed is 100,set 200 50 25 12 .
2673 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2674 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002675 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002676 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2677 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002678 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002679 AmTsPlayer_stopFast(player->handle);
2680 pthread_mutex_unlock(&player->lock);
2681 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2682 pthread_mutex_lock(&player->lock);
2683 } else {
2684 //set play speed and if audio is start, stop audio.
2685 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002686 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002687 AmTsPlayer_stopAudioDecoding(player->handle);
2688 player->has_audio = DVR_FALSE;
2689 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002690 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002691 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002692 }
hualing chenbcada022020-04-22 14:27:01 +08002693 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08002694 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002695 player->cmd.speed.speed = speed.speed;
2696 player->speed = (float)speed.speed.speed/(float)100;
2697 pthread_mutex_unlock(&player->lock);
2698 return DVR_SUCCESS;
2699 }
2700 //case 2. not start play
2701 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2702 //only set speed.and return;
hualing chena540a7e2020-03-27 16:44:05 +08002703 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002704 player->cmd.speed.speed = speed.speed;
2705 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08002706 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002707 pthread_mutex_unlock(&player->lock);
2708 return DVR_SUCCESS;
hualing chen87072a82020-03-12 16:20:12 +08002709 }
hualing chen31140872020-03-25 12:29:26 +08002710 //case 3 fffb mode
2711 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2712 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2713 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002714 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002715 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002716 player->cmd.speed.speed = speed.speed;
2717 player->speed = (float)speed.speed.speed/(float)100;
2718 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08002719 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002720 pthread_mutex_unlock(&player->lock);
2721 return DVR_SUCCESS;
2722 }
2723 }
2724 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002725 IS_KERNEL_SPEED(speed.speed.speed)) {
2726 //case 1. cur speed is kernel support speed,set kernel speed.
2727 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002728 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002729 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2730 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002731 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002732 AmTsPlayer_stopFast(player->handle);
2733 pthread_mutex_unlock(&player->lock);
2734 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2735 pthread_mutex_lock(&player->lock);
2736 } else {
2737 //set play speed and if audio is start, stop audio.
2738 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002739 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002740 AmTsPlayer_stopAudioDecoding(player->handle);
2741 player->has_audio = DVR_FALSE;
2742 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002743 DVR_PB_DG(1, "start fast");
2744 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08002745 }
hualing chena540a7e2020-03-27 16:44:05 +08002746 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002747 player->cmd.speed.speed = speed.speed;
2748 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08002749 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002750 pthread_mutex_unlock(&player->lock);
2751 return DVR_SUCCESS;
2752 }
2753 //case 2 fffb mode
2754 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2755 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2756 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002757 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002758 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002759 player->cmd.speed.speed = speed.speed;
2760 player->speed = (float)speed.speed.speed/(float)100;
2761 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08002762 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002763 pthread_mutex_unlock(&player->lock);
2764 return DVR_SUCCESS;
2765 }
hualing chen31140872020-03-25 12:29:26 +08002766 }
hualing chena540a7e2020-03-27 16:44:05 +08002767 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2768 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08002769 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08002770 } else {
hualing chen31140872020-03-25 12:29:26 +08002771 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002772 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2773 else
2774 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08002775 player->fffb_play = DVR_TRUE;
2776 }
2777 DVR_Bool_t init_last_time = DVR_FALSE;
2778 if (player->speed > 0.0f && speed.speed.speed < 0) {
2779 init_last_time = DVR_TRUE;
2780 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
2781 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002782 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002783 player->cmd.speed.mode = speed.mode;
2784 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002785 player->speed = (float)speed.speed.speed/(float)100;
hualing chen4b7c15d2020-04-07 16:13:48 +08002786#if 0
2787 if (abs((int)(player->speed)) > 1) {
2788 //seek speed*1000 ms at fb mode
2789 pthread_mutex_lock(&player->segment_lock);
2790 uint64_t cur = segment_tell_current_time(player->r_handle);
2791 int diff = abs((int)(player->speed * 1000));
2792 DVR_PB_DG(1, " cur:%ull diff:%d", cur, diff);
2793 if (cur > diff)
2794 cur = cur - diff;
2795 else
2796 cur = 0;
2797 segment_seek(player->r_handle, cur, player->openParams.block_size);
2798 pthread_mutex_unlock(&player->segment_lock);
2799 }
2800#endif
hualing chen31140872020-03-25 12:29:26 +08002801 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08002802 _dvr_init_fffb_t(handle);
2803 if (init_last_time == DVR_TRUE)
2804 player->last_send_time_id = UINT64_MAX;
2805
hualing chen87072a82020-03-12 16:20:12 +08002806 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002807 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2808 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002809 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002810 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08002811 _dvr_playback_replay(handle, DVR_FALSE);
2812 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2813 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2814 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08002815 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08002816 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002817 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002818 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002819 return DVR_SUCCESS;
2820}
2821/**\brief Get playback status
2822 * \param[in] handle playback handle
2823 * \param[out] p_status playback status
2824 * \retval DVR_SUCCESS On success
2825 * \return Error code
2826 */
hualing chen040df222020-01-17 13:35:02 +08002827int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002828 DVR_PlaybackStatus_t *p_status) {
2829//
2830 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002831
2832 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002833 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002834 return DVR_FAILURE;
2835 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002836
2837 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002838 //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 +08002839 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2840 player->state == DVR_PLAYBACK_STATE_START) {
2841 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2842 }
hualing chen041c4092020-04-05 15:11:50 +08002843
hualing chencc91e1c2020-02-28 13:26:17 +08002844 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002845 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002846 if (player->last_send_time_id == UINT64_MAX) {
2847 player->last_send_time_id = player->cur_segment_id;
2848 player->last_cur_time = p_status->time_cur;
2849 }
2850 if (player->last_send_time_id == player->cur_segment_id) {
2851 if (player->speed > 0.0f ) {
2852 //ff
2853 if (p_status->time_cur < player->last_cur_time ) {
2854 DVR_PB_DG(1, "get ff time error last[%d]cur[%d]diff[%d]", player->last_cur_time, p_status->time_cur, player->last_cur_time - p_status->time_cur);
2855 p_status->time_cur = player->last_cur_time;
2856 } else {
2857 player->last_cur_time = p_status->time_cur;
2858 }
2859 } else if (player->speed < -1.0f){
2860 //fb
2861 if (p_status->time_cur > player->last_cur_time ) {
2862 DVR_PB_DG(1, "get fb time error last[%d]cur[%d]diff[%d]", player->last_cur_time, p_status->time_cur, p_status->time_cur - player->last_cur_time );
2863 p_status->time_cur = player->last_cur_time;
2864 } else {
2865 player->last_cur_time = p_status->time_cur;
2866 }
2867 }
2868 } else {
2869 player->last_cur_time = p_status->time_cur;
2870 }
2871 player->last_send_time_id = player->cur_segment_id;
hualing chen041c4092020-04-05 15:11:50 +08002872 p_status->segment_id = player->cur_segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08002873
hualing chen5cbe1a62020-02-10 16:36:36 +08002874 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08002875 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08002876 p_status->flags = player->cur_segment.flags;
hualing chenbcada022020-04-22 14:27:01 +08002877 DVR_PB_DG(1, "player real state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]",
hualing chen6d24aa92020-03-23 18:43:47 +08002878 _dvr_playback_state_toString(player->state),
2879 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08002880 p_status->time_cur, p_status->time_end,
2881 p_status->segment_id,player->play_flag,
2882 player->speed);
hualing chenb31a6c62020-01-13 17:27:00 +08002883 return DVR_SUCCESS;
2884}
2885
hualing chen040df222020-01-17 13:35:02 +08002886void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
2887 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002888 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
2889 DVR_PB_DG(1, "segment flag: %d", segment->flags);
2890 DVR_PB_DG(1, "segment location: [%s]", segment->location);
2891 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
2892 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
2893 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
2894 DVR_PB_DG(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 +08002895 }
hualing chenb31a6c62020-01-13 17:27:00 +08002896}
2897
hualing chen5cbe1a62020-02-10 16:36:36 +08002898int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002899 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08002900
hualing chena540a7e2020-03-27 16:44:05 +08002901 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002902 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002903 return DVR_FAILURE;
2904 }
2905
hualing chen040df222020-01-17 13:35:02 +08002906 DVR_PlaybackSegmentInfo_t *segment;
2907 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002908 {
hualing chen040df222020-01-17 13:35:02 +08002909 if (segment_id >= 0) {
2910 if (segment->segment_id == segment_id) {
2911 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002912 break;
2913 }
2914 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08002915 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08002916 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002917 }
2918 }
2919 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002920}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002921
pengfei.liu27cc4ec2020-04-03 16:28:16 +08002922int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002923{
2924 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2925 DVR_RETURN_IF_FALSE(player);
2926 DVR_RETURN_IF_FALSE(func);
2927
hualing chen4b7c15d2020-04-07 16:13:48 +08002928 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002929 pthread_mutex_lock(&player->lock);
2930
2931 player->dec_func = func;
2932 player->dec_userdata = userdata;
2933
2934 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002935 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002936 return DVR_SUCCESS;
2937}
2938
2939int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
2940{
2941 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2942 DVR_RETURN_IF_FALSE(player);
2943 DVR_RETURN_IF_FALSE(p_secure_buf);
2944 DVR_RETURN_IF_FALSE(len);
2945
hualing chen4b7c15d2020-04-07 16:13:48 +08002946 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002947 pthread_mutex_lock(&player->lock);
2948
2949 player->is_secure_mode = 1;
2950 player->secure_buffer = p_secure_buf;
2951 player->secure_buffer_size = len;
2952
2953 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002954 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002955 return DVR_SUCCESS;
2956}