blob: b950c4c20be948322f25c1f6df3eb6760624d4fd [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
Gong Ke2a0ebbe2021-05-25 15:22:50 +080018#define DVR_PB_DG(_level, _fmt...) \
19 DVR_DEBUG_FL(_level, "playback", _fmt)
hualing chena540a7e2020-03-27 16:44:05 +080020
hualing chenb31a6c62020-01-13 17:27:00 +080021#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080022
hualing chend241c7a2021-06-22 13:34:27 +080023#define CONTROL_SPEED_ENABLE 0
hualing chena540a7e2020-03-27 16:44:05 +080024
25#define FF_SPEED (2.0f)
26#define FB_SPEED (-1.0f)
27#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080028#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080029
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 chene41f4372020-06-06 16:29:17 +080035#define FB_DEFAULT_LEFT_TIME (3000)
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 chen275379e2021-06-15 17:57:21 +080044static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_PlaybackPids_t pids, int type);
hualing chencc91e1c2020-02-28 13:26:17 +080045static 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) ;
hualing chen2932d372020-04-29 13:44:00 +080049static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
50 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080051static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen87072a82020-03-12 16:20:12 +080052
hualing chenbcada022020-04-22 14:27:01 +080053
54static char* _cmd_toString(int cmd)
55{
56
57 char *string[DVR_PLAYBACK_CMD_NONE+1]={
58 "start",
59 "stop",
60 "vstart",
61 "astart",
62 "vstop",
63 "astop",
64 "vrestart",
65 "arestart",
66 "avrestart",
67 "vstopastart",
68 "astopvstart",
69 "vstoparestart",
70 "astopvrestart",
71 "vstartarestart",
72 "astartvrestart",
73 "pause",
74 "resume",
75 "seek",
76 "ff",
77 "fb",
78 "NONE"
79 };
80
81 if (cmd > DVR_PLAYBACK_CMD_NONE) {
82 return "unkown";
83 } else {
84 return string[cmd];
85 }
86}
87
88
hualing chen6d24aa92020-03-23 18:43:47 +080089static char* _dvr_playback_state_toString(int stat)
90{
91 char *string[DVR_PLAYBACK_STATE_FB+1]={
92 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080093 "stop",
hualing chen31140872020-03-25 12:29:26 +080094 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080095 "ff",
96 "fb"
97 };
98
99 if (stat > DVR_PLAYBACK_STATE_FB) {
100 return "unkown";
101 } else {
102 return string[stat];
103 }
104}
hualing chena540a7e2020-03-27 16:44:05 +0800105
106static DVR_Bool_t _dvr_support_speed(int speed) {
107
108 DVR_Bool_t ret = DVR_FALSE;
109
110 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800111 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800112 case PLAYBACK_SPEED_FBX2:
113 case PLAYBACK_SPEED_FBX4:
114 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800115 case PLAYBACK_SPEED_FBX16:
116 case PLAYBACK_SPEED_FBX12:
117 case PLAYBACK_SPEED_FBX32:
118 case PLAYBACK_SPEED_FBX48:
119 case PLAYBACK_SPEED_FBX64:
120 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800121 case PLAYBACK_SPEED_S2:
122 case PLAYBACK_SPEED_S4:
123 case PLAYBACK_SPEED_S8:
124 case PLAYBACK_SPEED_X1:
125 case PLAYBACK_SPEED_X2:
126 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800127 case PLAYBACK_SPEED_X3:
128 case PLAYBACK_SPEED_X5:
129 case PLAYBACK_SPEED_X6:
130 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800131 case PLAYBACK_SPEED_X8:
132 case PLAYBACK_SPEED_X12:
133 case PLAYBACK_SPEED_X16:
134 case PLAYBACK_SPEED_X32:
135 case PLAYBACK_SPEED_X48:
136 case PLAYBACK_SPEED_X64:
137 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800138 ret = DVR_TRUE;
139 break;
140 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800141 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800142 break;
143 }
144 return ret;
145}
hualing chen6e4bfa52020-03-13 14:37:11 +0800146void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
147{
hualing chen4b7c15d2020-04-07 16:13:48 +0800148 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800149 DVR_Playback_t *player = NULL;
150 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800151 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800152 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800153 }
154 switch (event->type) {
155 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
156 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800157 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800158 event->event.video_format.frame_width,
159 event->event.video_format.frame_height,
160 event->event.video_format.frame_rate);
161 break;
162 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800163 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
164 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800165 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800166 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800167 break;
168 }
169 default:
170 break;
171 }
172}
hualing chen2aba4022020-03-02 13:49:55 +0800173void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
174{
hualing chen6e4bfa52020-03-13 14:37:11 +0800175 DVR_Playback_t *player = NULL;
176 if (user_data != NULL) {
177 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800178 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800179 }
hualing chen2aba4022020-03-02 13:49:55 +0800180 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800181 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
182 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800183 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800184 event->event.video_format.frame_width,
185 event->event.video_format.frame_height,
186 event->event.video_format.frame_rate);
187 break;
188 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800189 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
190 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800191 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chene41f4372020-06-06 16:29:17 +0800192 if (player->first_trans_ok == DVR_FALSE) {
193 player->first_trans_ok = DVR_TRUE;
194 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
195 }
hualing chen30423862021-04-16 14:39:12 +0800196 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800197 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800198 player->seek_pause = DVR_FALSE;
199 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800200 break;
201 }
hualing chen487ae6d2020-07-22 10:34:11 +0800202 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
203 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
204 player->first_trans_ok = DVR_TRUE;
205 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
206 }
207 if (player != NULL && player->has_video == DVR_FALSE) {
208 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
209 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800210 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800211 }
212 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800213 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800214 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800215 break;
216 }
217 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800218 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800219 player->player_callback_func(player->player_callback_userdata, event);
220 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800221 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800222 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800223 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800224 }
225}
hualing chencc91e1c2020-02-28 13:26:17 +0800226
hualing chen5cbe1a62020-02-10 16:36:36 +0800227//convert video and audio fmt
228static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
229 int format = 0;
230 if (is_audio == DVR_FALSE) {
231 //for video fmt
232 switch (fmt)
233 {
234 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800235 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800236 break;
237 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800238 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800239 break;
240 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800241 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800242 break;
243 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800244 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800245 break;
hualing chena540a7e2020-03-27 16:44:05 +0800246 case DVR_VIDEO_FORMAT_VP9:
247 format = AV_VIDEO_CODEC_VP9;
248 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800249 }
250 } else {
251 //for audio fmt
252 switch (fmt)
253 {
254 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800255 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800256 break;
257 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800258 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800259 break;
260 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800261 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800262 break;
263 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800264 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800265 break;
hualing chena540a7e2020-03-27 16:44:05 +0800266 case DVR_AUDIO_FORMAT_AAC:
267 format = AV_AUDIO_CODEC_AAC;
268 break;
269 case DVR_AUDIO_FORMAT_LATM:
270 format = AV_AUDIO_CODEC_LATM;
271 break;
272 case DVR_AUDIO_FORMAT_PCM:
273 format = AV_AUDIO_CODEC_PCM;
274 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800275 case DVR_AUDIO_FORMAT_AC4:
276 format = AV_AUDIO_CODEC_AC4;
277 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800278 }
279 }
280 return format;
281}
hualing chen040df222020-01-17 13:35:02 +0800282static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800283{
hualing chen040df222020-01-17 13:35:02 +0800284 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800285
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800286 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800287 return -1;
288
hualing chena540a7e2020-03-27 16:44:05 +0800289 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800290}
hualing chena540a7e2020-03-27 16:44:05 +0800291
hualing chen5cbe1a62020-02-10 16:36:36 +0800292//get sys time ms
293static int _dvr_time_getClock(void)
294{
295 struct timespec ts;
296 int ms;
297
298 clock_gettime(CLOCK_MONOTONIC, &ts);
299 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
300
301 return ms;
302}
hualing chen86e7d482020-01-16 15:13:33 +0800303
hualing chenb31a6c62020-01-13 17:27:00 +0800304
305//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800306static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800307{
hualing chen040df222020-01-17 13:35:02 +0800308 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800309
hualing chena540a7e2020-03-27 16:44:05 +0800310
311 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800312 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800313 return DVR_FAILURE;
314 }
315
hualing chen86e7d482020-01-16 15:13:33 +0800316 struct timespec ts;
317 clock_gettime(CLOCK_MONOTONIC, &ts);
318 //ms为毫秒,换算成秒
319 ts.tv_sec += ms/1000;
320 //在outtime的基础上,增加ms毫秒
321 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
322 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
323 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
324 //us的值有可能超过1秒,
325 ts.tv_sec += us / 1000000;
326 us = us % 1000000;
327 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800328 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
329 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800330}
hualing chen31140872020-03-25 12:29:26 +0800331//get tsplay delay time ms
332static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
333 DVR_Playback_t *player = (DVR_Playback_t *) handle;
334 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800335 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800336 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800337 return 0;
338 }
339 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800340 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800341 return cache;
342}
hualing chenb31a6c62020-01-13 17:27:00 +0800343//send signal
hualing chen040df222020-01-17 13:35:02 +0800344static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800345{
hualing chen87072a82020-03-12 16:20:12 +0800346 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800347
348 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800349 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800350 return DVR_FAILURE;
351 }
352
hualing chen87072a82020-03-12 16:20:12 +0800353 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800354 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800355 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800356 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800357}
358
hualing chen2932d372020-04-29 13:44:00 +0800359//send playback event, need check is need lock first
360static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify, DVR_Bool_t is_lock) {
hualing chencc91e1c2020-02-28 13:26:17 +0800361
362 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800363
364 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800365 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800366 return DVR_FAILURE;
367 }
368
hualing chencc91e1c2020-02-28 13:26:17 +0800369 switch (evt) {
370 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800371 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800372 break;
373 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
374 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800375 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800376 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800377 break;
378 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
379 break;
380 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
381 break;
382 case DVR_PLAYBACK_EVENT_NO_KEY:
383 break;
384 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800385 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800386 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800387 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800388 break;
389 case DVR_PLAYBACK_EVENT_REACHED_END:
390 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800391 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800392 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800393 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800394 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800395 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800396 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800397 default:
398 break;
399 }
400 if (player->openParams.event_fn != NULL)
401 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800402 return DVR_SUCCESS;
403}
hualing chen2932d372020-04-29 13:44:00 +0800404static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800405{
406 DVR_Play_Notify_t notify;
407 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
408 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
409 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800410 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800411 return DVR_SUCCESS;
412}
413
hualing chen2932d372020-04-29 13:44:00 +0800414static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800415{
416 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800417
hualing chene3797f02021-01-13 14:53:28 +0800418 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800419 if (CONTROL_SPEED_ENABLE == 0)
420 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800421 }
hualing chena540a7e2020-03-27 16:44:05 +0800422 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 }
426
hualing chen6e4bfa52020-03-13 14:37:11 +0800427 if (player->send_time ==0) {
hualing chend241c7a2021-06-22 13:34:27 +0800428 if (CONTROL_SPEED_ENABLE == 0)
429 player->send_time = _dvr_time_getClock() + 500;
430 else
431 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800432 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800433 return DVR_SUCCESS;
434 }
hualing chend241c7a2021-06-22 13:34:27 +0800435 if (CONTROL_SPEED_ENABLE == 0)
436 player->send_time = _dvr_time_getClock() + 500;
437 else
438 player->send_time = _dvr_time_getClock() + 20;
439
hualing chen6e4bfa52020-03-13 14:37:11 +0800440 DVR_Play_Notify_t notify;
441 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
442 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
443 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800444 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800445 return DVR_SUCCESS;
446}
447
hualing chencc91e1c2020-02-28 13:26:17 +0800448//check is ongoing segment
449static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
450
451 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800452 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800453
454 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800455 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800456 return DVR_FAILURE;
457 }
hualing chen87072a82020-03-12 16:20:12 +0800458 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800459 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800460 return DVR_FALSE;
461 }
hualing chencc91e1c2020-02-28 13:26:17 +0800462 return DVR_TRUE;
463}
hualing chen4b7c15d2020-04-07 16:13:48 +0800464
465
466static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
467 DVR_Playback_t *player = (DVR_Playback_t *) handle;
468 player->fffb_start = _dvr_time_getClock();
469 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
470 player->fffb_current = player->fffb_start;
471 //get segment current time pos
472 player->fffb_start_pcr = _dvr_get_cur_time(handle);
473 //player->fffb_current = -1;
474 //player->fffb_start = -1;
475 //player->fffb_start_pcr = -1;
476 player->next_fffb_time = _dvr_time_getClock();
477
478 return DVR_SUCCESS;
479}
480
hualing chen2aba4022020-03-02 13:49:55 +0800481static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
482 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800483 player->fffb_start = _dvr_time_getClock();
484 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
485 player->fffb_current = player->fffb_start;
486 //get segment current time pos
487 player->fffb_start_pcr = _dvr_get_cur_time(handle);
488 //player->fffb_current = -1;
489 //player->fffb_start = -1;
490 //player->fffb_start_pcr = -1;
hualing chen2aba4022020-03-02 13:49:55 +0800491 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800492 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800493 return DVR_SUCCESS;
494}
hualing chencc91e1c2020-02-28 13:26:17 +0800495//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800496static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
497
498 DVR_Playback_t *player = (DVR_Playback_t *) handle;
499 DVR_PlaybackSegmentInfo_t *segment;
500 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
501
hualing chena540a7e2020-03-27 16:44:05 +0800502 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800503 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800504 return DVR_FAILURE;
505 }
506
hualing chen87072a82020-03-12 16:20:12 +0800507 int found = 0;
508 int found_eq_id = 0;
509 list_for_each_entry(segment, &player->segment_list, head)
510 {
511 if (player->segment_is_open == DVR_FALSE) {
512 //get first segment from list, case segment is not open
513 if (!IS_FB(player->speed))
514 found = 1;
515 } else if (segment->segment_id == segmentid) {
516 //find cur segment, we need get next one
517 found_eq_id = 1;
518 if (!IS_FB(player->speed)) {
519 found = 1;
520 continue;
521 } else {
522 //if is fb mode.we need used pre segment
523 if (pre_segment != NULL) {
524 found = 1;
525 } else {
526 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800527 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800528 return DVR_FAILURE;
529 }
530 }
531 }
532 if (found == 1) {
533 found = 2;
534 break;
535 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800536 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800537 }
538 if (found != 2) {
539 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800540 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800541 return DVR_FAILURE;
542 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800543 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800544 return DVR_SUCCESS;
545}
546
547//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800548static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800549
hualing chen040df222020-01-17 13:35:02 +0800550 DVR_Playback_t *player = (DVR_Playback_t *) handle;
551 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800552 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chend241c7a2021-06-22 13:34:27 +0800553
hualing chena540a7e2020-03-27 16:44:05 +0800554 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800555 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800556 return DVR_FAILURE;
557 }
558
hualing chen86e7d482020-01-16 15:13:33 +0800559 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800560 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800561
hualing chen040df222020-01-17 13:35:02 +0800562 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800563 {
hualing chencc91e1c2020-02-28 13:26:17 +0800564 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800565 //get first segment from list, case segment is not open
566 if (!IS_FB(player->speed))
567 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800568 } else if (segment->segment_id == player->cur_segment_id) {
569 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800570 found_eq_id = 1;
571 if (!IS_FB(player->speed)) {
572 found = 1;
573 continue;
574 } else {
575 //if is fb mode.we need used pre segment
576 if (pre_segment != NULL) {
577 found = 1;
578 } else {
579 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800580 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800581 return DVR_FAILURE;
582 }
583 }
hualing chen86e7d482020-01-16 15:13:33 +0800584 }
585 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800586 if (IS_FB(player->speed)) {
587 //used pre segment
588 segment = pre_segment;
589 }
hualing chencc91e1c2020-02-28 13:26:17 +0800590 //save segment info
591 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800592 if (player->r_handle)
593 player->last_segment_tatol = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800594 player->last_segment.segment_id = player->cur_segment.segment_id;
595 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800596 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
597 //pids
598 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
599
hualing chen5cbe1a62020-02-10 16:36:36 +0800600 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800601 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800602 player->cur_segment_id = segment->segment_id;
603 player->cur_segment.segment_id = segment->segment_id;
604 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800605 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 +0800606 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800607 //pids
hualing chen040df222020-01-17 13:35:02 +0800608 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800609 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800610 break;
hualing chen86e7d482020-01-16 15:13:33 +0800611 }
hualing chen2aba4022020-03-02 13:49:55 +0800612 pre_segment = segment;
613 }
614 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
615 //used the last one segment to open
616 //get segment info
617 player->segment_is_open = DVR_TRUE;
618 player->cur_segment_id = pre_segment->segment_id;
619 player->cur_segment.segment_id = pre_segment->segment_id;
620 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800621 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 +0800622 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
623 //pids
624 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
625 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800626 }
627 if (found != 2) {
628 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800629 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800630 }
631 return DVR_SUCCESS;
632}
hualing chen040df222020-01-17 13:35:02 +0800633//open next segment to play,if reach list end return errro.
634static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800635{
hualing chen040df222020-01-17 13:35:02 +0800636 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800637 Segment_OpenParams_t params;
638 int ret = DVR_SUCCESS;
639
hualing chena540a7e2020-03-27 16:44:05 +0800640 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800641 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800642 return DVR_FAILURE;
643 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800644 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800645
646 ret = _dvr_get_next_segmentId(handle);
647 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800648 DVR_PB_DG(1, "not found segment info");
649 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800650 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800651 }
652
653 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800654 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800655 segment_close(player->r_handle);
656 player->r_handle = NULL;
657 }
658
659 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800660 //cp chur segment path to location
661 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800662 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800663 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800664 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
665
hualing chen86e7d482020-01-16 15:13:33 +0800666 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800667 if (ret == DVR_FAILURE) {
668 DVR_PB_DG(1, "open segment error");
669 }
hualing chen87072a82020-03-12 16:20:12 +0800670 pthread_mutex_unlock(&player->segment_lock);
671 int total = _dvr_get_end_time( handle);
672 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800673 if (IS_FB(player->speed)) {
674 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800675 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800676 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800677 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800678 }
hualing chen87072a82020-03-12 16:20:12 +0800679 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800680 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800681 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800682 return ret;
683}
684
hualing chen5cbe1a62020-02-10 16:36:36 +0800685//open next segment to play,if reach list end return errro.
686static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
687{
688 DVR_Playback_t *player = (DVR_Playback_t *) handle;
689 Segment_OpenParams_t params;
690 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800691 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800692 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800693 return DVR_FAILURE;
694 }
hualing chencc91e1c2020-02-28 13:26:17 +0800695 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800696 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800697 }
hualing chencc91e1c2020-02-28 13:26:17 +0800698 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800699 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800700 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800701 return DVR_FAILURE;
702 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800703 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800704 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800705
706 DVR_PlaybackSegmentInfo_t *segment;
707
708 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800709
hualing chen5cbe1a62020-02-10 16:36:36 +0800710 list_for_each_entry(segment, &player->segment_list, head)
711 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800712 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 +0800713 if (segment->segment_id == segment_id) {
714 found = 1;
715 }
716 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800717 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 +0800718 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800719 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800720 player->cur_segment_id = segment->segment_id;
721 player->cur_segment.segment_id = segment->segment_id;
722 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800723 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800724 //pids
725 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800726 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 +0800727 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800728 }
729 }
hualing chencc91e1c2020-02-28 13:26:17 +0800730 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800731 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800732 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800733 return DVR_FAILURE;
734 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800735 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800736 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800737 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800738 params.segment_id = (uint64_t)player->cur_segment.segment_id;
739 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800740 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 +0800741 if (player->r_handle != NULL) {
742 segment_close(player->r_handle);
743 player->r_handle = NULL;
744 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800745 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800746 if (ret == DVR_FAILURE) {
747 DVR_PB_DG(1, "segment opne error");
748 }
hualing chen2aba4022020-03-02 13:49:55 +0800749 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800750 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800751
hualing chen4b7c15d2020-04-07 16:13:48 +0800752 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 +0800753 return ret;
754}
755
756
757//get play info by segment id
758static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
759 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800760 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800761 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800762
763 DVR_Playback_t *player = (DVR_Playback_t *) handle;
764 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800765 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800766 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800767 return DVR_FAILURE;
768 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800769
770 int found = 0;
771
772 list_for_each_entry(segment, &player->segment_list, head)
773 {
hualing chen87072a82020-03-12 16:20:12 +0800774 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800775 //get first segment from list
776 found = 1;
777 }
778 if (segment->segment_id == segment_id) {
779 found = 1;
780 }
781 if (found == 1) {
782 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800783 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800784 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800785 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800786 player->cur_segment.segment_id = segment->segment_id;
787 player->cur_segment.flags = segment->flags;
788 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800789 player->cur_segment.pids.video.pid = segment->pids.video.pid;
790 player->cur_segment.pids.video.format = segment->pids.video.format;
791 player->cur_segment.pids.video.type = segment->pids.video.type;
792 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
793 player->cur_segment.pids.audio.format = segment->pids.audio.format;
794 player->cur_segment.pids.audio.type = segment->pids.audio.type;
795 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
796 player->cur_segment.pids.ad.format = segment->pids.ad.format;
797 player->cur_segment.pids.ad.type = segment->pids.ad.type;
798 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800799 //
hualing chen2aba4022020-03-02 13:49:55 +0800800 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800801 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800802 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800803 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800804 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
805 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800806 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 +0800807 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800808 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800809 }
810 }
hualing chencc91e1c2020-02-28 13:26:17 +0800811 if (found != 2) {
812 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800813 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800814 return DVR_FAILURE;
815 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800816
817 return DVR_SUCCESS;
818}
hualing chencc91e1c2020-02-28 13:26:17 +0800819static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
820 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800821 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800822 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800823 return DVR_FAILURE;
824 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800825
hualing chencc91e1c2020-02-28 13:26:17 +0800826 //compare cur segment
827 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
828 {
829 //check video pids, stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800830 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800831 //check sub audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800832 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800833 //check audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800834 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids, 1);
hualing chene3797f02021-01-13 14:53:28 +0800835 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 +0800836 //check pcr pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800837 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800838 }
hualing chena540a7e2020-03-27 16:44:05 +0800839 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800840}
hualing chen5cbe1a62020-02-10 16:36:36 +0800841
hualing chend241c7a2021-06-22 13:34:27 +0800842static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
843{
844 DVR_Playback_t *player = (DVR_Playback_t *) handle;
845 if (player == NULL) {
846 DVR_PB_DG(1, "player is NULL");
847 return DVR_TRUE;
848 }
849 char buf[10];
850 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
851 DVR_PB_DG(1, "player get prop[%d][%s]", atoi(buf), buf);
852
853 if (atoi(buf) != 1) {
854 //return DVR_TRUE;
855 }
856
857 DVR_PB_DG(1, ":play speed: %f \n ply dur: %d \n sys_dur: %d", player->speed,
858 player->con_spe.ply_dur,
859 player->con_spe.sys_dur);
860
861 if (player->speed != 1.0f)
862 return DVR_TRUE;
863
864 if (player->con_spe.ply_dur > 0
865 && 2*player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
866 return DVR_FALSE;
867
868 return DVR_TRUE;
869}
870
hualing chencc91e1c2020-02-28 13:26:17 +0800871static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
872{
873 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800874 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800875 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800876 return DVR_FAILURE;
877 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800878 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
879 DVR_PB_DG(1, "vendor is amlogic. no used segment flag to hide or show av");
880 return DVR_SUCCESS;
881 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800882 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 +0800883 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
884 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800885 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800886 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800887 AmTsPlayer_showVideo(player->handle);
888 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800889 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
890 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800891 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800892 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800893 AmTsPlayer_hideVideo(player->handle);
894 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800895 }
896 return DVR_SUCCESS;
897}
hualing chene3797f02021-01-13 14:53:28 +0800898/*
899if decodec sucess first time.
900sucess: return true
901fail: return false
902*/
hualing chena540a7e2020-03-27 16:44:05 +0800903static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
904 DVR_Playback_t *player = (DVR_Playback_t *) handle;
905 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800906 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800907 return DVR_TRUE;
908 }
hualing chene3797f02021-01-13 14:53:28 +0800909 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800910 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800911 } else {
912 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800913 }
914}
hualing chen86e7d482020-01-16 15:13:33 +0800915static void* _dvr_playback_thread(void *arg)
916{
hualing chen040df222020-01-17 13:35:02 +0800917 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800918 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800919 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800920 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800921 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800922
hualing chen39628212020-05-14 10:35:13 +0800923 #define MAX_REACHEND_TIMEOUT (3000)
924 int reach_end_timeout = 0;//ms
925 int cache_time = 0;
hualing chen6d24aa92020-03-23 18:43:47 +0800926 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800927 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800928 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800929 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800930 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
931
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800932 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800933 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800934 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chene41f4372020-06-06 16:29:17 +0800935 int retry_open_seg = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800936 if (player->is_secure_mode) {
937 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800938 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800939 return NULL;
940 }
941 }
hualing chen86e7d482020-01-16 15:13:33 +0800942 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800943 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800944 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800945 return NULL;
946 }
hualing chen2aba4022020-03-02 13:49:55 +0800947 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
948 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800949
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800950 dec_bufs.buf_data = malloc(dec_buf_size);
951 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800952 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800953 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800954 return NULL;
955 }
956 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
957 dec_bufs.buf_size = dec_buf_size;
958
hualing chencc91e1c2020-02-28 13:26:17 +0800959 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800960 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
961 }
hualing chen86e7d482020-01-16 15:13:33 +0800962
hualing chen86e7d482020-01-16 15:13:33 +0800963 if (ret != DVR_SUCCESS) {
964 if (buf != NULL) {
965 free(buf);
966 buf = NULL;
967 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800968 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800969 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800970 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800971 }
hualing chen4fe3bee2020-10-23 13:58:52 +0800972 DVR_PB_DG(1, "player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
973 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +0800974 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
975 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
976 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
977 player->first_trans_ok = DVR_TRUE;
978 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
979 }
hualing chencc91e1c2020-02-28 13:26:17 +0800980 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800981 //set video show
982 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800983
hualing chen86e7d482020-01-16 15:13:33 +0800984 int trick_stat = 0;
985 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800986
hualing chen86e7d482020-01-16 15:13:33 +0800987 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800988 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800989
hualing chen2aba4022020-03-02 13:49:55 +0800990 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
991 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800992 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800993 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +0800994 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +0800995 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800996 {
hualing chen2aba4022020-03-02 13:49:55 +0800997 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
998 if (trick_stat > 0) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800999 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]", trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001000 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 +08001001 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001002 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001003 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001004 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
1005 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +08001006 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
1007 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chenbcada022020-04-22 14:27:01 +08001008 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 +08001009 //need change to pause state
1010 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1011 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +08001012 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001013 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001014 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001015 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001016 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001017 AmTsPlayer_pauseVideoDecoding(player->handle);
1018 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001019 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001020 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001021 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001022 }
1023 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1024 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001025 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001026 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001027 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
1028 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 +08001029 //used timeout wait need lock first,so we unlock and lock
1030 //pthread_mutex_unlock(&player->lock);
1031 //pthread_mutex_lock(&player->lock);
1032 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1033 pthread_mutex_unlock(&player->lock);
1034 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001035 } else if (_dvr_time_getClock() < player->next_fffb_time) {
1036 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);
1037 //used timeout wait need lock first,so we unlock and lock
1038 //pthread_mutex_unlock(&player->lock);
1039 //pthread_mutex_lock(&player->lock);
1040 AmTsPlayer_pauseVideoDecoding(player->handle);
1041 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1042 pthread_mutex_unlock(&player->lock);
1043 continue;
1044
hualing chen2aba4022020-03-02 13:49:55 +08001045 }
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001046 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d][%s][%d]", player->speed, goto_rewrite, real_read, _dvr_playback_state_toString(player->state), player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001047 pthread_mutex_unlock(&player->lock);
1048 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001049 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001050 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1051 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001052 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001053 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001054 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001055 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001056 }else if (player->fffb_play == DVR_TRUE){
1057 //for first into fffb when reset speed
1058 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1059 _dvr_time_getClock() < player->next_fffb_time) {
1060 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);
1061 //used timeout wait need lock first,so we unlock and lock
1062 //pthread_mutex_unlock(&player->lock);
1063 //pthread_mutex_lock(&player->lock);
1064 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1065 pthread_mutex_unlock(&player->lock);
1066 continue;
1067 }
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001068 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]", player->speed, goto_rewrite, real_read, _dvr_playback_state_toString(player->state), player->cmd.cur_cmd, player->fffb_play);
hualing chen4b7c15d2020-04-07 16:13:48 +08001069 pthread_mutex_unlock(&player->lock);
1070 goto_rewrite = DVR_FALSE;
1071 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001072 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001073 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1074 player->first_frame = 0;
1075 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1076 pthread_mutex_lock(&player->lock);
1077 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001078 }
hualing chenb31a6c62020-01-13 17:27:00 +08001079 }
hualing chen86e7d482020-01-16 15:13:33 +08001080
hualing chen30423862021-04-16 14:39:12 +08001081 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1082 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001083 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001084 DVR_PB_DG(1, "pause, continue");
hualing chen2932d372020-04-29 13:44:00 +08001085 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen87072a82020-03-12 16:20:12 +08001086 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1087 pthread_mutex_unlock(&player->lock);
1088 continue;
1089 }
hualing chen266b9502020-04-04 17:39:39 +08001090 //when seek action is done. we need drop write timeout data.
1091 if (player->drop_ts == DVR_TRUE) {
1092 goto_rewrite = DVR_FALSE;
1093 real_read = 0;
1094 player->drop_ts = DVR_FALSE;
1095 }
hualing chen2aba4022020-03-02 13:49:55 +08001096 if (goto_rewrite == DVR_TRUE) {
1097 goto_rewrite = DVR_FALSE;
1098 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001099 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001100 goto rewrite;
1101 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001102 //.check is need send time send end
hualing chen2932d372020-04-29 13:44:00 +08001103 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001104 pthread_mutex_lock(&player->segment_lock);
hualing chene41f4372020-06-06 16:29:17 +08001105 //DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001106 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chenfbf8e022020-06-15 13:43:11 +08001107 //DVR_PB_DG(1, "start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001108 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001109 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001110 if (read < 0 && errno == EIO) {
1111 //EIO ERROR, EXIT THRAD
1112 DVR_PB_DG(1, "read error.EIO error, exit thread");
1113 DVR_Play_Notify_t notify;
1114 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1115 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001116 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001117 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001118 goto end;
1119 } else if (read < 0) {
1120 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1121 }
hualing chen87072a82020-03-12 16:20:12 +08001122 //if on fb mode and read file end , we need calculate pos to retry read.
1123 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001124 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 +08001125 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
1126 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001127 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1128 pthread_mutex_unlock(&player->lock);
1129 continue;
1130 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001131 //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 +08001132 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001133 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001134 #define MIN_CACHE_TIME (3000)
1135 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001136 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001137 if (_cache_time > MIN_CACHE_TIME) {
hualing chene41f4372020-06-06 16:29:17 +08001138 pthread_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001139 /*if cache time > 20s , we think get time is error,*/
1140 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
1141 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1142 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1143 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1144 }
1145 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
hualing chene41f4372020-06-06 16:29:17 +08001146 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001147 DVR_PB_DG(1, "read end but cache time is %d > %d, to sleep end and continue", _cache_time, MIN_CACHE_TIME);
hualing chene41f4372020-06-06 16:29:17 +08001148 //continue;
1149 }
hualing chen969fe7b2021-05-26 15:13:17 +08001150
hualing chen040df222020-01-17 13:35:02 +08001151 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001152 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001153 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001154
1155 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chene3797f02021-01-13 14:53:28 +08001156 if (ret != DVR_SUCCESS) {
1157 player->noData++;
1158 DVR_PB_DG(1, "playback is sleep:[%d]ms nodata[%d]", timeout, player->noData);
1159 if (player->noData == 4) {
1160 DVR_PB_DG(1, "playback send nodata event nodata[%d]", player->noData);
1161 //send event here and pause
1162 DVR_Play_Notify_t notify;
1163 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1164 notify.event = DVR_PLAYBACK_EVENT_NODATA;
1165 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_NODATA");
1166 //get play statue not here
1167 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1168 }
1169 }
1170 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001171 if ((ret != DVR_SUCCESS &&
hualing chen90b3ae62021-03-30 10:49:28 +08001172 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001173 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001174 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001175 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1176 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001177 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001178 DVR_Play_Notify_t notify;
1179 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1180 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1181 //get play statue not here
1182 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001183 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001184 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001185 DVR_PB_DG(1, "playback is send end delay:[%d]reach_end_timeout[%d]ms", delay, reach_end_timeout);
hualing chen31140872020-03-25 12:29:26 +08001186 pthread_mutex_lock(&player->lock);
1187 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1188 pthread_mutex_unlock(&player->lock);
1189 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001190 } else if (ret != DVR_SUCCESS) {
1191 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001192 if (delay < cache_time) {
1193 //delay time is changed and then has data to play, so not start timeout
1194 } else {
1195 reach_end_timeout = reach_end_timeout + timeout;
1196 }
1197 cache_time = delay;
hualing chen4b7c15d2020-04-07 16:13:48 +08001198 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001199 pthread_mutex_lock(&player->lock);
1200 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1201 pthread_mutex_unlock(&player->lock);
1202 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001203 }
hualing chen39628212020-05-14 10:35:13 +08001204 reach_end_timeout = 0;
1205 cache_time = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001206 pthread_mutex_lock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001207 //change next segment success case
1208 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001209 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001210 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1211 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001212 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001213 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001214 }//read len 0 check end
1215 if (player->noData > 0) {
1216 player->noData = 0;
1217 DVR_PB_DG(1, "playback send data event resume[%d]", player->noData);
1218 //send event here and pause
1219 DVR_Play_Notify_t notify;
1220 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1221 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
1222 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_DATARESUME");
1223 //get play statue not here
1224 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001225 }
hualing chen39628212020-05-14 10:35:13 +08001226 reach_end_timeout = 0;
hualing chen86e7d482020-01-16 15:13:33 +08001227 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001228 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001229 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001230
hualing chena540a7e2020-03-27 16:44:05 +08001231 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001232 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001233 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001234 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001235 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001236 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001237 }
hualing chen266b9502020-04-04 17:39:39 +08001238 //if need write whole block size, we need check read buf len is eq block size.
1239 if (b_writed_whole_block == DVR_TRUE) {
1240 //buf_len is block size value.
1241 if (real_read < buf_len) {
1242 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001243 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001244 pthread_mutex_lock(&player->lock);
1245 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1246 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001247 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001248 continue;
1249 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001250 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 +08001251 }
1252 }
1253
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001254 if (player->dec_func) {
1255 DVR_CryptoParams_t crypto_params;
1256
1257 memset(&crypto_params, 0, sizeof(crypto_params));
1258 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1259 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1260 crypto_params.segment_id = player->cur_segment.segment_id;
hualing chen1f26ffa2020-11-03 10:39:20 +08001261 crypto_params.offset = segment_tell_position(player->r_handle) - wbufs.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001262 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
1263 DVR_PB_DG(1, "offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001264 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1265 crypto_params.input_buffer.addr = (size_t)buf;
1266 crypto_params.input_buffer.size = real_read;
1267
1268 if (player->is_secure_mode) {
1269 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1270 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1271 crypto_params.output_buffer.size = dec_buf_size;
1272 ret = player->dec_func(&crypto_params, player->dec_userdata);
1273 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001274 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001275 } else {
1276 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1277 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1278 crypto_params.output_buffer.size = dec_buf_size;
1279 ret = player->dec_func(&crypto_params, player->dec_userdata);
1280 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001281 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001282 }
1283 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001284 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001285 }
pengfei.liufda2a972020-04-09 14:47:15 +08001286 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001287 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001288rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001289 if (player->drop_ts == DVR_TRUE) {
1290 //need drop ts data when seek occur.we need read next loop,drop this ts data
1291 goto_rewrite = DVR_FALSE;
1292 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001293 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001294 player->drop_ts = DVR_FALSE;
1295 continue;
1296 }
hualing chen5605eed2020-05-26 18:18:06 +08001297 player->ts_cache_len = real_read;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001298 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1299 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001300 player->ts_cache_len = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001301 real_read = 0;
1302 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001303 if (CONTROL_SPEED_ENABLE == 1) {
1304check0:
1305 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1306 pthread_mutex_lock(&player->lock);
1307 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1308 pthread_mutex_unlock(&player->lock);
1309 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1310 goto check0;
1311 }
1312 }
hualing chen5605eed2020-05-26 18:18:06 +08001313 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001314 continue;
hualing chen87072a82020-03-12 16:20:12 +08001315 } else {
hualing chen2932d372020-04-29 13:44:00 +08001316 DVR_PB_DG(1, "write time out write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001317 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001318 if (CONTROL_SPEED_ENABLE == 1) {
1319check1:
1320 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1321 pthread_mutex_lock(&player->lock);
1322 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1323 pthread_mutex_unlock(&player->lock);
1324 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1325 goto check1;
1326 }
1327 }
hualing chencc91e1c2020-02-28 13:26:17 +08001328 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001329 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001330 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001331 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001332 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001333 break;
1334 }
hualing chen2aba4022020-03-02 13:49:55 +08001335 goto_rewrite = DVR_TRUE;
1336 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001337 }
1338 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001339end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001340 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001341 free(buf);
1342 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001343 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001344}
1345
1346
hualing chen040df222020-01-17 13:35:02 +08001347static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001348{
hualing chen040df222020-01-17 13:35:02 +08001349 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001350
1351 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001352 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001353 return DVR_FAILURE;
1354 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001355 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001356 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001357 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001358 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001359 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001360 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001361 if (rc < 0)
1362 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001363 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001364}
1365
1366
hualing chen040df222020-01-17 13:35:02 +08001367static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001368{
hualing chen040df222020-01-17 13:35:02 +08001369 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001370
1371 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001372 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001373 return DVR_FAILURE;
1374 }
1375
hualing chen4b7c15d2020-04-07 16:13:48 +08001376 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001377 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001378 {
1379 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001380 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001381 pthread_join(player->playback_thread, NULL);
1382 }
1383 if (player->r_handle) {
1384 segment_close(player->r_handle);
1385 player->r_handle = NULL;
1386 }
hualing chen7a56cba2020-04-14 14:09:27 +08001387 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001388 return 0;
1389}
1390
hualing chenb31a6c62020-01-13 17:27:00 +08001391/**\brief Open an dvr palyback
1392 * \param[out] p_handle dvr playback addr
1393 * \param[in] params dvr playback open parameters
1394 * \retval DVR_SUCCESS On success
1395 * \return Error code
1396 */
hualing chen040df222020-01-17 13:35:02 +08001397int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001398
hualing chen040df222020-01-17 13:35:02 +08001399 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001400 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001401
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001402 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001403
hualing chen86e7d482020-01-16 15:13:33 +08001404 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001405 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001406 pthread_condattr_init(&cattr);
1407 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1408 pthread_cond_init(&player->cond, &cattr);
1409 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001410
hualing chen5cbe1a62020-02-10 16:36:36 +08001411 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001412 INIT_LIST_HEAD(&player->segment_list);
1413 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1414 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001415 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001416 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001417 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001418 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001419 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001420 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001421
hualing chen86e7d482020-01-16 15:13:33 +08001422 //store open params
hualing chen040df222020-01-17 13:35:02 +08001423 player->openParams.dmx_dev_id = params->dmx_dev_id;
1424 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001425 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001426 player->openParams.event_fn = params->event_fn;
1427 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001428 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001429 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001430
hualing chen5cbe1a62020-02-10 16:36:36 +08001431 player->has_pids = params->has_pids;
1432
hualing chen2aba4022020-03-02 13:49:55 +08001433 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001434
1435 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1436 //for test get callback
1437 if (0 && player->player_callback_func == NULL) {
1438 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1439 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001440 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 +08001441 }
1442 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001443
hualing chen86e7d482020-01-16 15:13:33 +08001444 //init has audio and video
1445 player->has_video = DVR_FALSE;
1446 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001447 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001448 player->last_segment_id = 0LL;
1449 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001450
hualing chen5cbe1a62020-02-10 16:36:36 +08001451 //init ff fb time
1452 player->fffb_current = -1;
1453 player->fffb_start =-1;
1454 player->fffb_start_pcr = -1;
1455 //seek time
1456 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001457 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001458
1459 //init secure stuff
1460 player->dec_func = NULL;
1461 player->dec_userdata = NULL;
1462 player->is_secure_mode = 0;
1463 player->secure_buffer = NULL;
1464 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001465 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001466
hualing chen4b7c15d2020-04-07 16:13:48 +08001467 player->fffb_play = DVR_FALSE;
1468
1469 player->last_send_time_id = UINT64_MAX;
1470 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001471 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001472
hualing chend241c7a2021-06-22 13:34:27 +08001473 //speed con init
1474 if (CONTROL_SPEED_ENABLE == 1) {
1475 player->con_spe.ply_dur = 0;
1476 player->con_spe.ply_sta = -1;
1477 player->con_spe.sys_dur = 0;
1478 player->con_spe.sys_sta = 0;
1479 }
1480
hualing chen86e7d482020-01-16 15:13:33 +08001481 *p_handle = player;
1482 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001483}
1484
1485/**\brief Close an dvr palyback
1486 * \param[in] handle playback handle
1487 * \retval DVR_SUCCESS On success
1488 * \return Error code
1489 */
hualing chen040df222020-01-17 13:35:02 +08001490int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001491
hualing chen86e7d482020-01-16 15:13:33 +08001492 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001493 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001494 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001495 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001496 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001497 return DVR_FAILURE;
1498 }
1499
hualing chencc91e1c2020-02-28 13:26:17 +08001500 if (player->state != DVR_PLAYBACK_STATE_STOP)
1501 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001502 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001503 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001504 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1505 } else {
1506 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001507 }
hualing chen7a56cba2020-04-14 14:09:27 +08001508 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001509 pthread_mutex_destroy(&player->lock);
1510 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001511
1512 if (player) {
1513 free(player);
1514 player = NULL;
1515 }
hualing chen7a56cba2020-04-14 14:09:27 +08001516 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001517 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001518}
1519
hualing chenb31a6c62020-01-13 17:27:00 +08001520/**\brief Start play audio and video, used start auido api and start video api
1521 * \param[in] handle playback handle
1522 * \param[in] params audio playback params,contains fmt and pid...
1523 * \retval DVR_SUCCESS On success
1524 * \return Error code
1525 */
hualing chen040df222020-01-17 13:35:02 +08001526int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1527 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001528 am_tsplayer_video_params vparams;
1529 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001530 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001531
1532 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001533 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001534 return DVR_FAILURE;
1535 }
hualing chencc91e1c2020-02-28 13:26:17 +08001536 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001537 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001538
hualing chena540a7e2020-03-27 16:44:05 +08001539 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001540 //can used start api to resume playback
1541 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1542 return dvr_playback_resume(handle);
1543 }
hualing chen87072a82020-03-12 16:20:12 +08001544 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001545 //if flag is puased and not decodec first frame. if user resume, we need
1546 //clear flag and set trickmode none
1547 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1548 DVR_PB_DG(1, "[%p]clear pause live flag and clear trick mode", handle);
1549 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1550 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1551 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001552 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001553 return DVR_SUCCESS;
1554 }
hualing chen86e7d482020-01-16 15:13:33 +08001555 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001556 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001557 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001558 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001559 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001560 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001561 //start audio and video
Zhiqiang Hana9d261b2020-11-11 18:38:10 +08001562 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001563 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001564 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001565 pthread_mutex_unlock(&player->lock);
1566 DVR_Play_Notify_t notify;
1567 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1568 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1569 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1570 notify.info.transition_failed_data.segment_id = segment_id;
1571 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001572 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001573 return -1;
1574 }
hualing chen31140872020-03-25 12:29:26 +08001575
hualing chencc91e1c2020-02-28 13:26:17 +08001576 {
hualing chen86e7d482020-01-16 15:13:33 +08001577 if (VALID_PID(vparams.pid)) {
1578 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001579 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001580 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001581 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001582 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1583 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001584 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001585 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001586 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001587 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001588 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001589 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001590 }
hualing chena93bbbc2020-12-22 17:23:42 +08001591 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001592 AmTsPlayer_setVideoParams(player->handle, &vparams);
1593 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001594 }
hualing chena540a7e2020-03-27 16:44:05 +08001595
hualing chen4b7c15d2020-04-07 16:13:48 +08001596 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1597 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001598 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1599 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1600 player->cmd.state = DVR_PLAYBACK_STATE_START;
1601 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001602 } else {
1603 player->cmd.last_cmd = player->cmd.cur_cmd;
1604 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001605 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001606 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001607 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001608 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001609 } else {
hualing chendf118dd2020-05-21 15:49:11 +08001610 if (VALID_PID(adparams.pid)) {
1611 player->has_ad_audio = DVR_TRUE;
1612 DVR_PB_DG(1, "start ad audio");
1613 AmTsPlayer_setADParams(player->handle, &adparams);
1614 AmTsPlayer_enableADMix(player->handle);
1615 }
hualing chen969fe7b2021-05-26 15:13:17 +08001616 if (VALID_PID(aparams.pid)) {
1617 DVR_PB_DG(1, "start audio");
1618 player->has_audio = DVR_TRUE;
1619 AmTsPlayer_setAudioParams(player->handle, &aparams);
1620 AmTsPlayer_startAudioDecoding(player->handle);
1621 }
hualing chen31140872020-03-25 12:29:26 +08001622 }
hualing chencc91e1c2020-02-28 13:26:17 +08001623 player->cmd.state = DVR_PLAYBACK_STATE_START;
1624 player->state = DVR_PLAYBACK_STATE_START;
1625 }
hualing chen86e7d482020-01-16 15:13:33 +08001626 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001627 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001628 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001629 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001630 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001631}
hualing chen040df222020-01-17 13:35:02 +08001632/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001633 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001634 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001635 * \retval DVR_SUCCESS On success
1636 * \return Error code
1637 */
hualing chen040df222020-01-17 13:35:02 +08001638int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1639 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001640
hualing chena540a7e2020-03-27 16:44:05 +08001641 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001642 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001643 return DVR_FAILURE;
1644 }
1645
hualing chen4b7c15d2020-04-07 16:13:48 +08001646 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001647 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001648
hualing chen040df222020-01-17 13:35:02 +08001649 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1650 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001651
hualing chen86e7d482020-01-16 15:13:33 +08001652 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001653 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001654 //cp location
hualing chen040df222020-01-17 13:35:02 +08001655 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001656
hualing chen4b7c15d2020-04-07 16:13:48 +08001657 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 +08001658 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001659
1660 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001661 segment->pids.video.pid = info->pids.video.pid;
1662 segment->pids.video.format = info->pids.video.format;
1663 segment->pids.video.type = info->pids.video.type;
1664
hualing chen2aba4022020-03-02 13:49:55 +08001665 segment->pids.audio.pid = info->pids.audio.pid;
1666 segment->pids.audio.format = info->pids.audio.format;
1667 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001668
hualing chen2aba4022020-03-02 13:49:55 +08001669 segment->pids.ad.pid = info->pids.ad.pid;
1670 segment->pids.ad.format = info->pids.ad.format;
1671 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001672
1673 segment->pids.pcr.pid = info->pids.pcr.pid;
1674
hualing chen4b7c15d2020-04-07 16:13:48 +08001675 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 +08001676 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001677 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001678 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001679 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001680
hualing chen5cbe1a62020-02-10 16:36:36 +08001681 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001682}
hualing chen040df222020-01-17 13:35:02 +08001683/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001684 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001685 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001686 * \retval DVR_SUCCESS On success
1687 * \return Error code
1688 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001689int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001690 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001691 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001692 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001693 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001694 return DVR_FAILURE;
1695 }
1696
hualing chencc91e1c2020-02-28 13:26:17 +08001697 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001698 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001699 return DVR_FAILURE;
1700 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001701 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001702 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001703 DVR_PlaybackSegmentInfo_t *segment = NULL;
1704 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1705 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001706 {
hualing chen040df222020-01-17 13:35:02 +08001707 if (segment->segment_id == segment_id) {
1708 list_del(&segment->head);
1709 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001710 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001711 }
hualing chen86e7d482020-01-16 15:13:33 +08001712 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001713 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001714 pthread_mutex_unlock(&player->lock);
1715
1716 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001717}
hualing chen040df222020-01-17 13:35:02 +08001718/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001719 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001720 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001721 * \retval DVR_SUCCESS On success
1722 * \return Error code
1723 */
hualing chen040df222020-01-17 13:35:02 +08001724int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001725 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001726 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001727 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001728 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001729 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001730 return DVR_FAILURE;
1731 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001732 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
1733 DVR_PB_DG(1, "vendor is amlogic. not hide or show av and update segment");
1734 return DVR_SUCCESS;
1735 }
hualing chena540a7e2020-03-27 16:44:05 +08001736
hualing chen040df222020-01-17 13:35:02 +08001737 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001738 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001739 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001740 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001741 {
hualing chen040df222020-01-17 13:35:02 +08001742 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001743 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001744 }
hualing chen86e7d482020-01-16 15:13:33 +08001745 // if encramble to free, only set flag and return;
1746
1747 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001748 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001749 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1750 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001751 //disable display, mute
hualing chen703f3572021-01-06 12:51:34 +08001752 DVR_PB_DG(1, "mute av");
hualing chen2aba4022020-03-02 13:49:55 +08001753 AmTsPlayer_hideVideo(player->handle);
1754 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001755 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1756 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001757 //enable display, unmute
hualing chen703f3572021-01-06 12:51:34 +08001758 DVR_PB_DG(1, "unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08001759 AmTsPlayer_showVideo(player->handle);
1760 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001761 } else {
1762 //do nothing
1763 }
1764 } else {
1765 //do nothing
1766 }
1767 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001768 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001769 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001770 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001771 pthread_mutex_unlock(&player->lock);
1772 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001773}
1774
1775
hualing chen275379e2021-06-15 17:57:21 +08001776static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_PlaybackPids_t set_pids, int type) {
hualing chen040df222020-01-17 13:35:02 +08001777 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08001778 DVR_StreamInfo_t set_pid;
1779
1780 if (type == 0) {
1781 set_pid = set_pids.video;
1782 } else if (type == 1) {
1783 set_pid = set_pids.audio;
1784 } else if (type == 2) {
1785 set_pid = set_pids.ad;
1786 } else {
1787 set_pid = set_pids.pcr;
1788 }
1789
hualing chena540a7e2020-03-27 16:44:05 +08001790 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001791 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001792 return DVR_FAILURE;
1793 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001794 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001795 if (now_pid.pid == set_pid.pid) {
1796 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001797 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001798 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001799 if (VALID_PID(now_pid.pid)) {
1800 //stop now stream
1801 if (type == 0) {
1802 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001803 if (player->has_video == DVR_TRUE) {
1804 DVR_PB_DG(1, "stop video");
1805 AmTsPlayer_stopVideoDecoding(player->handle);
1806 player->has_video = DVR_FALSE;
1807 }
hualing chen86e7d482020-01-16 15:13:33 +08001808 } else if (type == 1) {
1809 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08001810 if (player->has_audio == DVR_TRUE) {
1811 DVR_PB_DG(1, "stop audio");
1812 AmTsPlayer_stopAudioDecoding(player->handle);
1813 player->has_audio = DVR_FALSE;
1814 }
hualing chen86e7d482020-01-16 15:13:33 +08001815 } else if (type == 2) {
1816 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001817 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001818 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001819 } else if (type == 3) {
1820 //pcr
1821 }
1822 }
1823 if (VALID_PID(set_pid.pid)) {
1824 //start
1825 if (type == 0) {
1826 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001827 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001828 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001829 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001830 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001831 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001832 AmTsPlayer_setVideoParams(player->handle, &vparams);
1833 AmTsPlayer_startVideoDecoding(player->handle);
1834 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001835 } else if (type == 1) {
1836 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001837 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08001838 if (VALID_PID(set_pids.ad.pid)) {
1839 am_tsplayer_audio_params adparams;
1840 adparams.pid = set_pids.ad.pid;
1841 adparams.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
1842 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",adparams.pid, adparams.codectype);
1843 AmTsPlayer_setADParams(player->handle, &adparams);
1844 AmTsPlayer_enableADMix(player->handle);
1845 }
1846
hualing chenc70a8df2020-05-12 19:23:11 +08001847 am_tsplayer_audio_params aparams;
1848 aparams.pid = set_pid.pid;
1849 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1850 player->has_audio = DVR_TRUE;
1851 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1852 AmTsPlayer_setAudioParams(player->handle, &aparams);
1853 AmTsPlayer_startAudioDecoding(player->handle);
1854 //playback_device_audio_start(player->handle,&aparams);
1855 }
hualing chen86e7d482020-01-16 15:13:33 +08001856 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001857 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chenc70a8df2020-05-12 19:23:11 +08001858 am_tsplayer_audio_params aparams;
1859 aparams.pid = set_pid.pid;
1860 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1861 player->has_audio = DVR_TRUE;
1862 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1863 AmTsPlayer_setADParams(player->handle, &aparams);
1864 AmTsPlayer_enableADMix(player->handle);
1865 //playback_device_audio_start(player->handle,&aparams);
1866 }
hualing chen86e7d482020-01-16 15:13:33 +08001867 } else if (type == 3) {
1868 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001869 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001870 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001871 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001872 //audio and video all close
1873 if (!player->has_audio && !player->has_video) {
1874 player->state = DVR_PLAYBACK_STATE_STOP;
1875 }
hualing chen86e7d482020-01-16 15:13:33 +08001876 }
1877 }
1878 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001879}
hualing chen5cbe1a62020-02-10 16:36:36 +08001880/**\brief dvr play back update segment pids
1881 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001882 * add pid stream and stop remove pid stream.
1883 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001884 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001885 * \retval DVR_SUCCESS On success
1886 * \return Error code
1887 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001888int 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 +08001889 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001890 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001891 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001892 return DVR_FAILURE;
1893 }
1894
hualing chen040df222020-01-17 13:35:02 +08001895 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001896 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001897 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001898 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 +08001899
hualing chen040df222020-01-17 13:35:02 +08001900 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001901 {
hualing chen040df222020-01-17 13:35:02 +08001902 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001903
1904 if (player->cur_segment_id == segment_id) {
1905 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1906 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1907 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001908 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001909 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001910 return 0;
1911 }
1912
1913 //if segment is on going segment,we need stop start stream
1914 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001915 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001916 //check video pids, stop or restart
hualing chen275379e2021-06-15 17:57:21 +08001917 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, *p_pids, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001918 //check sub audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08001919 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, *p_pids, 2);
jianchuan.pinge5f8c5a2021-02-03 19:11:05 +08001920 //check audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08001921 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, *p_pids, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001922 //check pcr pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08001923 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, *p_pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +08001924 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001925 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1926 //if state is pause, we need process at resume api. we only record change info
1927 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1928 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1929 if (VALID_PID(segment->pids.video.pid)
1930 && VALID_PID(p_pids->video.pid)
1931 && segment->pids.video.pid != p_pids->video.pid) {
1932 //restart video
1933 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1934 }
1935 if (!VALID_PID(segment->pids.video.pid)
1936 && VALID_PID(p_pids->video.pid)
1937 && segment->pids.video.pid != p_pids->video.pid) {
1938 //start video
1939 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1940 }
1941 if (VALID_PID(segment->pids.video.pid)
1942 && !VALID_PID(p_pids->video.pid)
1943 && segment->pids.video.pid != p_pids->video.pid) {
1944 //stop video
1945 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1946 }
1947 if (VALID_PID(segment->pids.audio.pid)
1948 && VALID_PID(p_pids->audio.pid)
1949 && segment->pids.audio.pid != p_pids->audio.pid) {
1950 //restart audio
1951 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1952 }
1953 if (!VALID_PID(segment->pids.audio.pid)
1954 && VALID_PID(p_pids->audio.pid)
1955 && segment->pids.audio.pid != p_pids->audio.pid) {
1956 //start audio
1957 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1958 }
1959 if (VALID_PID(segment->pids.audio.pid)
1960 && !VALID_PID(p_pids->audio.pid)
1961 && segment->pids.audio.pid != p_pids->audio.pid) {
1962 //stop audio
1963 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1964 }
1965 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1966 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1967 //do nothing
1968 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1969 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1970 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1971 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1972 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1973 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1974 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1975 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1976 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1977 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1978 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1979 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1980 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1981 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1982 } else {
1983 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1984 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1985 }
1986
1987 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1988 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1989 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1990 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1991 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1992 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1993 //not occur this case
1994 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1995 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1996 } else {
1997 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1998 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1999 }
2000
2001 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2002 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2003 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2004 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
2005 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2006 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
2007 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2008 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
2009 } else {
2010 //not occur this case
2011 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2012 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2013 }
2014 }
2015 }
hualing chene10666f2020-04-14 13:58:37 +08002016 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002017 }
hualing chen86e7d482020-01-16 15:13:33 +08002018 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08002019 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002020 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08002021 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002022 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002023 }
hualing chen86e7d482020-01-16 15:13:33 +08002024 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002025 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002026 pthread_mutex_unlock(&player->lock);
2027 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002028}
2029/**\brief Stop play, will stop video and audio
2030 * \param[in] handle playback handle
2031 * \param[in] clear is clear last frame
2032 * \retval DVR_SUCCESS On success
2033 * \return Error code
2034 */
hualing chen040df222020-01-17 13:35:02 +08002035int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2036 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002037
2038 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002039 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002040 return DVR_FAILURE;
2041 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002042 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2043 DVR_PB_DG(1, ":playback is stoped");
2044 return DVR_SUCCESS;
2045 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002046 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2047 DVR_PB_DG(1, ":playback is stoped");
2048 return DVR_SUCCESS;
2049 }
hualing chen87072a82020-03-12 16:20:12 +08002050 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08002051 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002052 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002053 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002054 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002055 if (player->has_video) {
2056 AmTsPlayer_resumeVideoDecoding(player->handle);
2057 }
2058 if (player->has_audio) {
2059 AmTsPlayer_resumeAudioDecoding(player->handle);
2060 }
2061 if (player->has_video) {
2062 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002063 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002064 AmTsPlayer_stopVideoDecoding(player->handle);
2065 }
2066 if (player->has_audio) {
2067 player->has_audio = DVR_FALSE;
2068 AmTsPlayer_stopAudioDecoding(player->handle);
2069 }
hualing chendf118dd2020-05-21 15:49:11 +08002070 if (player->has_ad_audio) {
2071 player->has_ad_audio =DVR_FALSE;
2072 AmTsPlayer_disableADMix(player->handle);
2073 }
hualing chen266b9502020-04-04 17:39:39 +08002074
hualing chen86e7d482020-01-16 15:13:33 +08002075 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002076 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2077 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2078 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002079 player->cur_segment_id = UINT64_MAX;
2080 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002081 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08002082 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08002083 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002084 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002085}
2086/**\brief Start play audio
2087 * \param[in] handle playback handle
2088 * \param[in] params audio playback params,contains fmt and pid...
2089 * \retval DVR_SUCCESS On success
2090 * \return Error code
2091 */
hualing chen2aba4022020-03-02 13:49:55 +08002092
hualing chendf118dd2020-05-21 15:49:11 +08002093int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param, am_tsplayer_audio_params *adparam) {
hualing chen040df222020-01-17 13:35:02 +08002094 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002095
2096 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002097 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002098 return DVR_FAILURE;
2099 }
hualing chen86e7d482020-01-16 15:13:33 +08002100 _start_playback_thread(handle);
2101 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002102 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002103 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002104
hualing chendf118dd2020-05-21 15:49:11 +08002105 if (VALID_PID(adparam->pid)) {
2106 player->has_ad_audio = DVR_TRUE;
2107 DVR_PB_DG(1, "start ad audio");
2108 AmTsPlayer_setADParams(player->handle, adparam);
2109 AmTsPlayer_enableADMix(player->handle);
2110 }
hualing chen969fe7b2021-05-26 15:13:17 +08002111 if (VALID_PID(param->pid)) {
2112 DVR_PB_DG(1, "start audio");
2113 player->has_audio = DVR_TRUE;
2114 AmTsPlayer_setAudioParams(player->handle, param);
2115 AmTsPlayer_startAudioDecoding(player->handle);
2116 }
hualing chendf118dd2020-05-21 15:49:11 +08002117
hualing chen86e7d482020-01-16 15:13:33 +08002118 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002119 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
2120 player->cmd.state = DVR_PLAYBACK_STATE_START;
2121 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002122 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002123 pthread_mutex_unlock(&player->lock);
2124 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002125}
2126/**\brief Stop play audio
2127 * \param[in] handle playback handle
2128 * \retval DVR_SUCCESS On success
2129 * \return Error code
2130 */
hualing chen040df222020-01-17 13:35:02 +08002131int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2132 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002133
2134 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002135 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002136 return DVR_FAILURE;
2137 }
2138
hualing chen2aba4022020-03-02 13:49:55 +08002139 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002140 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002141 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2142 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002143 //destory thread
2144 _stop_playback_thread(handle);
2145 } else {
2146 //do nothing.video is playing
2147 }
hualing chen7a56cba2020-04-14 14:09:27 +08002148 DVR_PB_DG(1, "lock");
2149 pthread_mutex_lock(&player->lock);
2150
hualing chenf00cdc82020-06-10 14:23:35 +08002151 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002152 player->has_audio = DVR_FALSE;
2153 AmTsPlayer_stopAudioDecoding(player->handle);
2154 }
hualing chen87072a82020-03-12 16:20:12 +08002155
hualing chendf118dd2020-05-21 15:49:11 +08002156 if (player->has_ad_audio) {
2157 player->has_ad_audio =DVR_FALSE;
2158 AmTsPlayer_disableADMix(player->handle);
2159 }
2160
hualing chen87072a82020-03-12 16:20:12 +08002161 player->cmd.last_cmd = player->cmd.cur_cmd;
2162 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2163
hualing chen4b7c15d2020-04-07 16:13:48 +08002164 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002165 pthread_mutex_unlock(&player->lock);
2166 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002167}
2168/**\brief Start play video
2169 * \param[in] handle playback handle
2170 * \param[in] params video playback params,contains fmt and pid...
2171 * \retval DVR_SUCCESS On success
2172 * \return Error code
2173 */
hualing chen2aba4022020-03-02 13:49:55 +08002174int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002175 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002176
2177 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002178 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002179 return DVR_FAILURE;
2180 }
2181
hualing chen86e7d482020-01-16 15:13:33 +08002182 _start_playback_thread(handle);
2183 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002184 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002185 pthread_mutex_lock(&player->lock);
2186 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002187 AmTsPlayer_setVideoParams(player->handle, param);
2188 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002189
2190 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002191 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002192 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002193 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002194 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2195 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002196 }
2197 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002198 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2199 player->cmd.state = DVR_PLAYBACK_STATE_START;
2200 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002201 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002202 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002203 return DVR_SUCCESS;
2204}
2205/**\brief Stop play video
2206 * \param[in] handle playback handle
2207 * \retval DVR_SUCCESS On success
2208 * \return Error code
2209 */
hualing chen040df222020-01-17 13:35:02 +08002210int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2211 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002212
2213 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002214 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002215 return DVR_FAILURE;
2216 }
2217
hualing chen86e7d482020-01-16 15:13:33 +08002218 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002219 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2220 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002221 //destory thread
2222 _stop_playback_thread(handle);
2223 } else {
2224 //do nothing.audio is playing
2225 }
hualing chen7a56cba2020-04-14 14:09:27 +08002226
2227 DVR_PB_DG(1, "lock");
2228 pthread_mutex_lock(&player->lock);
2229
hualing chen87072a82020-03-12 16:20:12 +08002230 player->has_video = DVR_FALSE;
2231
2232 AmTsPlayer_stopVideoDecoding(player->handle);
2233 //playback_device_video_stop(player->handle);
2234
2235 player->cmd.last_cmd = player->cmd.cur_cmd;
2236 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2237
hualing chen4b7c15d2020-04-07 16:13:48 +08002238 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002239 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002240 return DVR_SUCCESS;
2241}
2242/**\brief Pause play
2243 * \param[in] handle playback handle
2244 * \param[in] flush whether its internal buffers should be flushed
2245 * \retval DVR_SUCCESS On success
2246 * \return Error code
2247 */
hualing chen040df222020-01-17 13:35:02 +08002248int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2249 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002250
2251 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002252 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002253 return DVR_FAILURE;
2254 }
hualing chenf00cdc82020-06-10 14:23:35 +08002255 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
2256 DVR_PB_DG(1, "player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002257 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002258 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002259 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002260 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002261 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002262 if (player->has_video)
2263 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002264 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002265 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002266
2267 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002268 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2269 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2270 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2271 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002272 } else {
2273 player->cmd.last_cmd = player->cmd.cur_cmd;
2274 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2275 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2276 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002277 }
hualing chen86e7d482020-01-16 15:13:33 +08002278 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002279 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002280
hualing chen86e7d482020-01-16 15:13:33 +08002281 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002282}
2283
hualing chen5cbe1a62020-02-10 16:36:36 +08002284//not add lock
2285static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2286{
2287 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2288
hualing chena540a7e2020-03-27 16:44:05 +08002289 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002290 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002291 return DVR_FAILURE;
2292 }
2293
hualing chen5cbe1a62020-02-10 16:36:36 +08002294 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002295 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002296 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002297 am_tsplayer_video_params vparams;
2298 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002299 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002300 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002301
hualing chendf118dd2020-05-21 15:49:11 +08002302 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002303 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002304 pthread_mutex_unlock(&player->lock);
2305
2306 switch (cmd) {
2307 case DVR_PLAYBACK_CMD_AVRESTART:
2308 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002309 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002310 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002311 break;
2312 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002313 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2314 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002315 break;
2316 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002317 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002318 break;
2319 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002320 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002321 break;
2322 case DVR_PLAYBACK_CMD_ARESTART:
2323 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002324 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002325 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002326 break;
2327 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002328 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002329 break;
2330 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002331 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002332 break;
2333 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002334 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2335 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2336 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002337 break;
2338 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002339 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2340 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002341 break;
2342 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002343 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2344 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002345 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002346 break;
2347 case DVR_PLAYBACK_CMD_STOP:
2348 break;
2349 case DVR_PLAYBACK_CMD_START:
2350 break;
2351 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002352 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2353 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002354 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002355 break;
2356 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002357 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2358 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002359 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002360 break;
2361 case DVR_PLAYBACK_CMD_FF:
2362 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002363 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002364 break;
2365 default:
2366 break;
2367 }
2368 return DVR_SUCCESS;
2369}
2370
2371/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002372 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002373 * \retval DVR_SUCCESS On success
2374 * \return Error code
2375 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002376int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2377 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2378
hualing chena540a7e2020-03-27 16:44:05 +08002379 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002380 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002381 return DVR_FAILURE;
2382 }
2383
hualing chen5cbe1a62020-02-10 16:36:36 +08002384 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002385 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002386 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002387 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002388 DVR_PB_DG(1, "dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002389 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2390 AmTsPlayer_resumeVideoDecoding(player->handle);
2391 }
2392 if (player->has_audio) {
2393 AmTsPlayer_resumeAudioDecoding(player->handle);
2394 }
2395 //check is has audio param,if has audio .we need start audio,
2396 //we will stop audio when ff fb, if reach end, we will pause.so we need
2397 //start audio when resume play
2398
2399 am_tsplayer_video_params vparams;
2400 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002401 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002402 uint64_t segmentid = player->cur_segment_id;
hualing chendf118dd2020-05-21 15:49:11 +08002403 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002404 //valid audio pid, start audio
hualing chen969fe7b2021-05-26 15:13:17 +08002405 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2406 player->has_ad_audio = DVR_TRUE;
2407 DVR_PB_DG(1, "start ad audio");
2408 AmTsPlayer_setADParams(player->handle, &adparams);
2409 AmTsPlayer_enableADMix(player->handle);
2410 }
2411
hualing chenc70a8df2020-05-12 19:23:11 +08002412 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chen266b9502020-04-04 17:39:39 +08002413 player->has_audio = DVR_TRUE;
2414 AmTsPlayer_setAudioParams(player->handle, &aparams);
2415 AmTsPlayer_startAudioDecoding(player->handle);
2416 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002417 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d speed:%d", aparams.pid, player->has_audio, player->cmd.speed.speed.speed);
hualing chen266b9502020-04-04 17:39:39 +08002418 }
hualing chendf118dd2020-05-21 15:49:11 +08002419
hualing chen87072a82020-03-12 16:20:12 +08002420 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2421 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2422 player->cmd.state = DVR_PLAYBACK_STATE_START;
2423 player->state = DVR_PLAYBACK_STATE_START;
2424 } else {
2425 player->cmd.last_cmd = player->cmd.cur_cmd;
2426 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2427 player->cmd.state = DVR_PLAYBACK_STATE_START;
2428 player->state = DVR_PLAYBACK_STATE_START;
2429 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002430 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002431 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002432 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
hualing chene41f4372020-06-06 16:29:17 +08002433 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002434 DVR_PB_DG(1, "dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002435 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002436 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002437 }
hualing chen041c4092020-04-05 15:11:50 +08002438 if (player->has_audio)
2439 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002440 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002441 player->cmd.state = DVR_PLAYBACK_STATE_START;
2442 player->state = DVR_PLAYBACK_STATE_START;
hualing chen9811b212020-10-29 11:21:44 +08002443 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2444 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002445 } else {
2446 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2447 {
2448 pthread_mutex_lock(&player->lock);
2449 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002450 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002451 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2452 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002453 if (player->has_video) {
2454 AmTsPlayer_resumeVideoDecoding(player->handle);
2455 }
2456 if (player->has_audio)
2457 AmTsPlayer_resumeAudioDecoding(player->handle);
2458
hualing chen041c4092020-04-05 15:11:50 +08002459 pthread_mutex_unlock(&player->lock);
2460 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002461 }
2462 return DVR_SUCCESS;
2463}
2464
hualing chena540a7e2020-03-27 16:44:05 +08002465static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2466
2467 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2468 DVR_PlaybackSegmentInfo_t *segment = NULL;
2469 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2470 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2471
2472 list_for_each_entry(segment, &player->segment_list, head)
2473 {
2474 if (segment->segment_id == segment_id) {
2475 cur_segment = segment;
2476 }
2477 if (segment->segment_id == set_seg_id) {
2478 set_segment = segment;
2479 }
2480 if (cur_segment != NULL && set_segment != NULL) {
2481 break;
2482 }
2483 }
2484 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002485 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002486 return DVR_TRUE;
2487 }
2488 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2489 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2490 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2491 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002492 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 +08002493 return DVR_TRUE;
2494 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002495 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002496 return DVR_FALSE;
2497}
2498
hualing chen5cbe1a62020-02-10 16:36:36 +08002499/**\brief seek
2500 * \param[in] handle playback handle
2501 * \param[in] time_offset time offset base cur segment
2502 * \retval DVR_SUCCESS On success
2503 * \return Error code
2504 */
hualing chencc91e1c2020-02-28 13:26:17 +08002505int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002506 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002507
2508 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002509 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002510 return DVR_FAILURE;
2511 }
2512
hualing chen4b7c15d2020-04-07 16:13:48 +08002513 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 +08002514 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002515
hualing chen86e7d482020-01-16 15:13:33 +08002516 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002517 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002518 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002519
hualing chen5cbe1a62020-02-10 16:36:36 +08002520 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002521 int ret = _dvr_open_segment(handle, segment_id);
2522 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002523 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002524 pthread_mutex_unlock(&player->lock);
2525 return DVR_FAILURE;
2526 }
2527 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2528 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002529 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002530 //pthread_mutex_unlock(&player->lock);
2531 //return DVR_SUCCESS;
2532 time_offset = _dvr_get_end_time(handle);
2533 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002534 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002535 time_offset = _dvr_get_end_time(handle);
hualing chen87072a82020-03-12 16:20:12 +08002536 pthread_mutex_unlock(&player->lock);
2537 return DVR_FAILURE;
2538 }
2539 }
2540
hualing chen4b7c15d2020-04-07 16:13:48 +08002541 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 +08002542 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002543 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2544 //forward playback.not seek end of file
2545 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2546 //default -2000ms
2547 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2548 }
hualing chen86e7d482020-01-16 15:13:33 +08002549 }
hualing chen2aba4022020-03-02 13:49:55 +08002550 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002551 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002552 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002553 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002554 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 +08002555 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002556 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002557
hualing chen2aba4022020-03-02 13:49:55 +08002558 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002559
2560 player->last_send_time_id = UINT64_MAX;
2561
hualing chen2aba4022020-03-02 13:49:55 +08002562 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002563 player->fffb_current = _dvr_time_getClock();
2564 player->fffb_start = player->fffb_current;
2565 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2566 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002567 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002568 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002569 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002570 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002571 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002572 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002573 }
hualing chen86e7d482020-01-16 15:13:33 +08002574 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002575 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 +08002576 if (player->has_video) {
2577 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002578 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002579 }
2580
2581 if (player->has_audio) {
2582 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002583 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002584 }
hualing chendf118dd2020-05-21 15:49:11 +08002585 if (player->has_ad_audio) {
2586 player->has_ad_audio =DVR_FALSE;
2587 AmTsPlayer_disableADMix(player->handle);
2588 }
2589
hualing chen86e7d482020-01-16 15:13:33 +08002590 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002591 am_tsplayer_video_params vparams;
2592 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002593 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002594
hualing chen040df222020-01-17 13:35:02 +08002595 player->cur_segment_id = segment_id;
2596
2597 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002598 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002599 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002600 //start audio and video
Zhiqiang Han9adc9722020-11-11 18:38:10 +08002601 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08002602 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002603 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 +08002604 pthread_mutex_unlock(&player->lock);
2605 return -1;
2606 }
2607 //add
hualing chen040df222020-01-17 13:35:02 +08002608 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002609 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002610 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002611 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08002612 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002613 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002614 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002615 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002616 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002617 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002618 }
hualing chen2aba4022020-03-02 13:49:55 +08002619 AmTsPlayer_setVideoParams(player->handle, &vparams);
2620 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002621 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
2622 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
2623 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2624 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2625 AmTsPlayer_stopFast(player->handle);
2626 }
hualing chen266b9502020-04-04 17:39:39 +08002627 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002628 }
hualing chene41f4372020-06-06 16:29:17 +08002629 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08002630 player->has_ad_audio = DVR_TRUE;
2631 DVR_PB_DG(1, "start ad audio");
2632 AmTsPlayer_setADParams(player->handle, &adparams);
2633 AmTsPlayer_enableADMix(player->handle);
2634 }
hualing chen969fe7b2021-05-26 15:13:17 +08002635 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
2636 DVR_PB_DG(1, "start audio seek");
2637 AmTsPlayer_setAudioParams(player->handle, &aparams);
2638 AmTsPlayer_startAudioDecoding(player->handle);
2639 player->has_audio = DVR_TRUE;
2640 }
hualing chen86e7d482020-01-16 15:13:33 +08002641 }
hualing chene41f4372020-06-06 16:29:17 +08002642 if (player->state == DVR_PLAYBACK_STATE_PAUSE /*&&
hualing chen2aba4022020-03-02 13:49:55 +08002643 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2644 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2645 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chene41f4372020-06-06 16:29:17 +08002646 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))*/) {
hualing chen2aba4022020-03-02 13:49:55 +08002647 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2648 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen30423862021-04-16 14:39:12 +08002649 player->seek_pause = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002650 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002651 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2652 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002653 player->speed > 1.0f||
2654 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002655 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002656 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002657 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002658 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002659 player->cmd.last_cmd = player->cmd.cur_cmd;
2660 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2661 player->cmd.state = DVR_PLAYBACK_STATE_START;
2662 player->state = DVR_PLAYBACK_STATE_START;
2663 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002664 player->last_send_time_id = UINT64_MAX;
2665 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002666 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002667
2668 return DVR_SUCCESS;
2669}
hualing chen5cbe1a62020-02-10 16:36:36 +08002670
hualing chen5cbe1a62020-02-10 16:36:36 +08002671static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2672 //get cur time of segment
2673 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002674
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002675 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002676 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002677 return DVR_FAILURE;
2678 }
2679
hualing chen31140872020-03-25 12:29:26 +08002680 int64_t cache = 0;//defalut es buf cache 500ms
2681 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002682 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002683 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2684 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen2aba4022020-03-02 13:49:55 +08002685 pthread_mutex_unlock(&player->segment_lock);
hualing chenfbf8e022020-06-15 13:43:11 +08002686 DVR_PB_DG(1, "get cur time [%lld] cache:%lld cur id [%lld]last id [%lld] pb cache len [%d] [%lld]", cur, cache, player->cur_segment_id,player->last_send_time_id, player->ts_cache_len, pos);
hualing chen87072a82020-03-12 16:20:12 +08002687 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2688 cache = 0;
2689 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002690 int cur_time = (int)(cur > cache ? cur - cache : 0);
2691 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002692}
2693
hualing chen969fe7b2021-05-26 15:13:17 +08002694static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
2695 //get cur time of segment
2696 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2697
2698 if (player == NULL || player->handle == NULL) {
2699 DVR_PB_DG(1, "player is NULL");
2700 return DVR_FAILURE;
2701 }
2702
2703 int64_t cache = 0;//defalut es buf cache 500ms
2704 int cur_time = 0;
2705 AmTsPlayer_getDelayTime(player->handle, &cache);
2706 pthread_mutex_lock(&player->segment_lock);
2707 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2708 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
2709 pthread_mutex_unlock(&player->segment_lock);
2710 DVR_PB_DG(1, "get play cur time [%lld] cache:%lld cur id [%lld]last id [%lld] pb cache len [%d] [%lld]", cur, cache, player->cur_segment_id,player->last_send_time_id, player->ts_cache_len, pos);
2711 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2712 cache = 0;
2713 }
2714 if (cur > cache) {
2715 cur_time = (int)(cur - cache);
2716 *id = player->cur_segment_id;
2717 } else if (player->last_segment_tatol > 0) {
hualing chen969fe7b2021-05-26 15:13:17 +08002718 cur_time = (int)(player->last_segment_tatol - (cache - cur));
2719 *id = player->last_segment_id;
2720 DVR_PB_DG(1, "get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_tatol);
2721 } else {
2722 cur_time = 0;
2723 *id = player->cur_segment_id;
2724 }
2725
2726 return cur_time;
2727}
2728
hualing chencc91e1c2020-02-28 13:26:17 +08002729//get current segment current pcr time of read pos
2730static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2731 //get cur time of segment
2732 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002733
2734 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002735 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002736 return DVR_FAILURE;
2737 }
2738
hualing chen2aba4022020-03-02 13:49:55 +08002739 pthread_mutex_lock(&player->segment_lock);
2740 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002741 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002742 pthread_mutex_unlock(&player->segment_lock);
2743 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002744}
2745
hualing chen4b7c15d2020-04-07 16:13:48 +08002746#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002747//start replay
2748static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2749
2750 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2751 //calculate pcr seek time
2752 int t_diff = 0;
2753 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002754
2755 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002756 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002757 return DVR_FAILURE;
2758 }
2759
hualing chen5cbe1a62020-02-10 16:36:36 +08002760 if (player->fffb_start == -1) {
2761 //set fffb start time ms
2762 player->fffb_start = _dvr_time_getClock();
2763 player->fffb_current = player->fffb_start;
2764 //get segment current time pos
2765 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002766 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 +08002767 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08002768 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08002769 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002770 } else {
2771 player->fffb_current = _dvr_time_getClock();
2772 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002773 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002774 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002775 if (seek_time <= 0) {
2776 //need seek to pre one segment
2777 seek_time = 0;
2778 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002779 //seek segment pos
2780 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002781 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002782 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08002783 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2784 //set seek time to 0;
2785 DVR_PB_DG(1, "segment seek to 0 at fb mode [%d]id[%lld]", seek_time, player->cur_segment_id);
2786 seek_time = 0;
2787 }
hualing chen041c4092020-04-05 15:11:50 +08002788 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2789 seek_time = 0;
2790 }
hualing chen2aba4022020-03-02 13:49:55 +08002791 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002792 } else {
2793 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002794 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002795 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002796 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 +08002797 }
hualing chen2aba4022020-03-02 13:49:55 +08002798 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002799}
2800
2801
2802//start replay
2803static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2804 //
2805 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002806
2807 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002808 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002809 return DVR_FAILURE;
2810 }
2811
hualing chen5cbe1a62020-02-10 16:36:36 +08002812 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002813 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002814 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002815 AmTsPlayer_stopVideoDecoding(player->handle);
2816 }
2817 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002818 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002819 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002820 AmTsPlayer_stopAudioDecoding(player->handle);
2821 }
hualing chendf118dd2020-05-21 15:49:11 +08002822 if (player->has_ad_audio) {
2823 DVR_PB_DG(1, "fffb stop audio");
2824 player->has_ad_audio =DVR_FALSE;
2825 AmTsPlayer_disableADMix(player->handle);
2826 }
hualing chen2aba4022020-03-02 13:49:55 +08002827
hualing chen5cbe1a62020-02-10 16:36:36 +08002828 //start video and audio
2829
hualing chen2aba4022020-03-02 13:49:55 +08002830 am_tsplayer_video_params vparams;
2831 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002832 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002833 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002834
2835 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002836 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002837 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002838 //start audio and video
2839 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2840 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002841 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002842 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002843 return -1;
2844 }
2845
2846 if (VALID_PID(vparams.pid)) {
2847 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002848 DVR_PB_DG(1, "fffb start video");
hualing chen0888c032020-12-18 17:54:57 +08002849 //DVR_PB_DG(1, "fffb start video and save last frame");
2850 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08002851 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002852 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2853 AmTsPlayer_setVideoParams(player->handle, &vparams);
2854 AmTsPlayer_startVideoDecoding(player->handle);
2855 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002856 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002857 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002858 }
hualing chen31140872020-03-25 12:29:26 +08002859 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08002860 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002861 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002862 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002863 return 0;
2864}
2865
2866static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2867 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002868 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002869 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002870 return DVR_FAILURE;
2871 }
2872
2873 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002874 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002875 pthread_mutex_lock(&player->lock);
2876
hualing chen2aba4022020-03-02 13:49:55 +08002877 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002878 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 +08002879
hualing chen87072a82020-03-12 16:20:12 +08002880 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2881 //seek time set 0
2882 seek_time = 0;
2883 }
hualing chen041c4092020-04-05 15:11:50 +08002884 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002885 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2886 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002887 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002888 pthread_mutex_unlock(&player->lock);
2889 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002890 //send event here and pause
2891 DVR_Play_Notify_t notify;
2892 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002893 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002894 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08002895 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08002896 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 +08002897 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002898 return DVR_SUCCESS;
2899 }
hualing chen2932d372020-04-29 13:44:00 +08002900 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002901 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002902 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002903 }
2904 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002905 _dvr_playback_fffb_replay(handle);
2906
2907 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002908 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002909
hualing chen5cbe1a62020-02-10 16:36:36 +08002910 return DVR_SUCCESS;
2911}
2912
hualing chen87072a82020-03-12 16:20:12 +08002913//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002914static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002915 //
2916 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002917
2918 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002919 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002920 return DVR_FAILURE;
2921 }
2922
hualing chen5cbe1a62020-02-10 16:36:36 +08002923 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002924 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002925 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002926 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002927 }
2928
2929 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002930 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002931 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002932 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002933 //start video and audio
2934
hualing chen2aba4022020-03-02 13:49:55 +08002935 am_tsplayer_video_params vparams;
2936 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002937 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002938 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002939
2940 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002941 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08002942 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002943 //start audio and video
2944 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002945 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002946 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002947 return -1;
2948 }
2949
2950 if (VALID_PID(vparams.pid)) {
2951 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002952 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002953 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002954 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002955 }
hualing chen266b9502020-04-04 17:39:39 +08002956 else {
hualing chen2aba4022020-03-02 13:49:55 +08002957 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002958 }
hualing chen2aba4022020-03-02 13:49:55 +08002959 AmTsPlayer_setVideoParams(player->handle, &vparams);
2960 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002961 }
hualing chena540a7e2020-03-27 16:44:05 +08002962
2963 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08002964 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08002965 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002966 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002967 } else {
hualing chendf118dd2020-05-21 15:49:11 +08002968 if (VALID_PID(adparams.pid)) {
2969 player->has_ad_audio = DVR_TRUE;
2970 DVR_PB_DG(1, "start ad audio");
2971 AmTsPlayer_setADParams(player->handle, &adparams);
2972 AmTsPlayer_enableADMix(player->handle);
2973 }
hualing chen969fe7b2021-05-26 15:13:17 +08002974 if (VALID_PID(aparams.pid)) {
2975 player->has_audio = DVR_TRUE;
2976 DVR_PB_DG(1, "start audio");
2977 AmTsPlayer_setAudioParams(player->handle, &aparams);
2978 AmTsPlayer_startAudioDecoding(player->handle);
2979 }
hualing chendf118dd2020-05-21 15:49:11 +08002980
hualing chen7a56cba2020-04-14 14:09:27 +08002981 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002982 AmTsPlayer_stopFast(player->handle);
2983 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2984 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2985 }
hualing chen2aba4022020-03-02 13:49:55 +08002986 player->cmd.last_cmd = player->cmd.cur_cmd;
2987 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002988 player->cmd.state = DVR_PLAYBACK_STATE_START;
2989 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002990 return 0;
2991}
2992
2993
hualing chenb31a6c62020-01-13 17:27:00 +08002994/**\brief Set play speed
2995 * \param[in] handle playback handle
2996 * \param[in] speed playback speed
2997 * \retval DVR_SUCCESS On success
2998 * \return Error code
2999 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003000int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3001
3002 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003003
3004 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003005 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003006 return DVR_FAILURE;
3007 }
3008
hualing chen4b7c15d2020-04-07 16:13:48 +08003009 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003010 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003011 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003012 return DVR_FAILURE;
3013 }
hualing chenf00cdc82020-06-10 14:23:35 +08003014 if (speed.speed.speed == player->cmd.speed.speed.speed) {
3015 DVR_PB_DG(1, " func: eq speed [%d]", speed.speed.speed);
3016 return DVR_SUCCESS;
3017 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003018 pthread_mutex_lock(&player->lock);
3019 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3020 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3021 player->cmd.last_cmd = player->cmd.cur_cmd;
3022 }
hualing chene41f4372020-06-06 16:29:17 +08003023
hualing chen31140872020-03-25 12:29:26 +08003024 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003025 IS_KERNEL_SPEED(speed.speed.speed) ) {
3026 //case 1. not start play.only set speed
3027 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3028 //only set speed.and return;
3029 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3030 player->cmd.speed.speed = speed.speed;
3031 player->speed = (float)speed.speed.speed/(float)100;
3032 player->fffb_play = DVR_FALSE;
3033 pthread_mutex_unlock(&player->lock);
3034 return DVR_SUCCESS;
3035 }
3036 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003037 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3038 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003039 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003040 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3041 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003042 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003043 AmTsPlayer_stopFast(player->handle);
3044 pthread_mutex_unlock(&player->lock);
3045 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
3046 pthread_mutex_lock(&player->lock);
3047 } else {
3048 //set play speed and if audio is start, stop audio.
3049 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003050 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003051 AmTsPlayer_stopAudioDecoding(player->handle);
3052 player->has_audio = DVR_FALSE;
3053 }
hualing chenb96aa2c2020-04-15 14:13:53 +08003054 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003055 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003056 }
hualing chenbcada022020-04-22 14:27:01 +08003057 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003058 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003059 player->cmd.speed.speed = speed.speed;
3060 player->speed = (float)speed.speed.speed/(float)100;
3061 pthread_mutex_unlock(&player->lock);
3062 return DVR_SUCCESS;
3063 }
hualing chen31140872020-03-25 12:29:26 +08003064 //case 3 fffb mode
3065 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3066 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3067 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003068 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003069 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003070 player->cmd.speed.speed = speed.speed;
3071 player->speed = (float)speed.speed.speed/(float)100;
3072 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003073 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003074 pthread_mutex_unlock(&player->lock);
3075 return DVR_SUCCESS;
3076 }
3077 }
3078 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003079 IS_KERNEL_SPEED(speed.speed.speed)) {
3080 //case 1. cur speed is kernel support speed,set kernel speed.
3081 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003082 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003083 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3084 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003085 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003086 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08003087 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003088 } else {
3089 //set play speed and if audio is start, stop audio.
3090 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003091 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003092 AmTsPlayer_stopAudioDecoding(player->handle);
3093 player->has_audio = DVR_FALSE;
3094 }
hualing chenf00cdc82020-06-10 14:23:35 +08003095 DVR_PB_DG(1, "start fast");
3096 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003097 }
hualing chena540a7e2020-03-27 16:44:05 +08003098 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003099 player->cmd.speed.speed = speed.speed;
3100 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003101 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003102 pthread_mutex_unlock(&player->lock);
3103 return DVR_SUCCESS;
3104 }
3105 //case 2 fffb mode
3106 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3107 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3108 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003109 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003110 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003111 player->cmd.speed.speed = speed.speed;
3112 player->speed = (float)speed.speed.speed/(float)100;
3113 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08003114 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003115 pthread_mutex_unlock(&player->lock);
3116 return DVR_SUCCESS;
3117 }
hualing chen31140872020-03-25 12:29:26 +08003118 }
hualing chena540a7e2020-03-27 16:44:05 +08003119 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3120 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003121 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003122 } else {
hualing chen31140872020-03-25 12:29:26 +08003123 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003124 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3125 else
3126 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003127 player->fffb_play = DVR_TRUE;
3128 }
3129 DVR_Bool_t init_last_time = DVR_FALSE;
3130 if (player->speed > 0.0f && speed.speed.speed < 0) {
3131 init_last_time = DVR_TRUE;
3132 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3133 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003134 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003135 player->cmd.speed.mode = speed.mode;
3136 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003137 player->speed = (float)speed.speed.speed/(float)100;
3138 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003139 _dvr_init_fffb_t(handle);
3140 if (init_last_time == DVR_TRUE)
3141 player->last_send_time_id = UINT64_MAX;
3142
hualing chen87072a82020-03-12 16:20:12 +08003143 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003144 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3145 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003146 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003147 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003148 _dvr_playback_replay(handle, DVR_FALSE);
3149 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3150 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
3151 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08003152 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003153 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003154 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08003155 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003156 return DVR_SUCCESS;
3157}
hualing chen2932d372020-04-29 13:44:00 +08003158
hualing chenb31a6c62020-01-13 17:27:00 +08003159/**\brief Get playback status
3160 * \param[in] handle playback handle
3161 * \param[out] p_status playback status
3162 * \retval DVR_SUCCESS On success
3163 * \return Error code
3164 */
hualing chen2932d372020-04-29 13:44:00 +08003165static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3166 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003167//
3168 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003169 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003170 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003171 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003172 return DVR_FAILURE;
3173 }
hualing chen2932d372020-04-29 13:44:00 +08003174 if (is_lock ==DVR_TRUE)
3175 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003176 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003177 //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 +08003178 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3179 player->state == DVR_PLAYBACK_STATE_START) {
3180 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3181 }
hualing chen041c4092020-04-05 15:11:50 +08003182
hualing chencc91e1c2020-02-28 13:26:17 +08003183 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003184 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003185
3186 if (CONTROL_SPEED_ENABLE == 1) {
3187 if (player->con_spe.ply_sta < 0) {
3188 DVR_PB_DG(1, "player dur[%d] sta[%d] cur[%d] -----reinit", player->con_spe.ply_dur, player->con_spe.ply_sta,p_status->time_cur);
3189 player->con_spe.ply_sta = p_status->time_cur;
3190 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3191 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
3192 DVR_PB_DG(1, "player dur[%d] sta[%d] cur[%d]", player->con_spe.ply_dur, player->con_spe.ply_sta,p_status->time_cur);
3193 player->con_spe.ply_sta = p_status->time_cur;
3194 }
3195
3196 if (player->con_spe.sys_sta == 0) {
3197 player->con_spe.sys_sta = _dvr_time_getClock();
3198 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3199 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3200 player->con_spe.sys_sta = _dvr_time_getClock();
3201 }
3202 }
3203
hualing chen4b7c15d2020-04-07 16:13:48 +08003204 if (player->last_send_time_id == UINT64_MAX) {
3205 player->last_send_time_id = player->cur_segment_id;
3206 player->last_cur_time = p_status->time_cur;
3207 }
3208 if (player->last_send_time_id == player->cur_segment_id) {
3209 if (player->speed > 0.0f ) {
3210 //ff
3211 if (p_status->time_cur < player->last_cur_time ) {
3212 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);
3213 p_status->time_cur = player->last_cur_time;
3214 } else {
3215 player->last_cur_time = p_status->time_cur;
3216 }
hualing chene41f4372020-06-06 16:29:17 +08003217 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003218 //fb
3219 if (p_status->time_cur > player->last_cur_time ) {
3220 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 );
3221 p_status->time_cur = player->last_cur_time;
3222 } else {
3223 player->last_cur_time = p_status->time_cur;
3224 }
3225 }
hualing chend241c7a2021-06-22 13:34:27 +08003226 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003227 player->last_cur_time = p_status->time_cur;
3228 }
hualing chen969fe7b2021-05-26 15:13:17 +08003229 player->last_send_time_id = segment_id;
3230 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003231
hualing chen5cbe1a62020-02-10 16:36:36 +08003232 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003233 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003234 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08003235 DVR_PB_DG(1, "player real state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]is_lock[%d]",
hualing chen6d24aa92020-03-23 18:43:47 +08003236 _dvr_playback_state_toString(player->state),
3237 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08003238 p_status->time_cur, p_status->time_end,
3239 p_status->segment_id,player->play_flag,
hualing chen2932d372020-04-29 13:44:00 +08003240 player->speed,
3241 is_lock);
3242 if (is_lock ==DVR_TRUE)
3243 pthread_mutex_unlock(&player->lock);
3244 return DVR_SUCCESS;
3245}
3246
3247
3248/**\brief Get playback status
3249 * \param[in] handle playback handle
3250 * \param[out] p_status playback status
3251 * \retval DVR_SUCCESS On success
3252 * \return Error code
3253 */
3254int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3255 DVR_PlaybackStatus_t *p_status) {
3256//
3257 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3258
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003259 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3260
hualing chen2932d372020-04-29 13:44:00 +08003261 if (player == NULL) {
3262 DVR_PB_DG(1, "player is NULL");
3263 return DVR_FAILURE;
3264 }
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003265 pthread_mutex_lock(&player->lock);
3266 if (!player->has_video && !player->has_audio)
3267 p_status->time_cur = 0;
3268 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08003269
hualing chenb31a6c62020-01-13 17:27:00 +08003270 return DVR_SUCCESS;
3271}
3272
hualing chen040df222020-01-17 13:35:02 +08003273void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
3274 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003275 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
3276 DVR_PB_DG(1, "segment flag: %d", segment->flags);
3277 DVR_PB_DG(1, "segment location: [%s]", segment->location);
3278 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
3279 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
3280 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3281 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 +08003282 }
hualing chenb31a6c62020-01-13 17:27:00 +08003283}
3284
hualing chen5cbe1a62020-02-10 16:36:36 +08003285int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003286 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003287
hualing chena540a7e2020-03-27 16:44:05 +08003288 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003289 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003290 return DVR_FAILURE;
3291 }
3292
hualing chen040df222020-01-17 13:35:02 +08003293 DVR_PlaybackSegmentInfo_t *segment;
3294 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003295 {
hualing chen040df222020-01-17 13:35:02 +08003296 if (segment_id >= 0) {
3297 if (segment->segment_id == segment_id) {
3298 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003299 break;
3300 }
3301 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003302 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003303 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003304 }
3305 }
3306 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003307}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003308
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003309int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003310{
3311 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3312 DVR_RETURN_IF_FALSE(player);
3313 DVR_RETURN_IF_FALSE(func);
3314
hualing chen4b7c15d2020-04-07 16:13:48 +08003315 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003316 pthread_mutex_lock(&player->lock);
3317
3318 player->dec_func = func;
3319 player->dec_userdata = userdata;
3320
3321 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003322 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003323 return DVR_SUCCESS;
3324}
3325
3326int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3327{
3328 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3329 DVR_RETURN_IF_FALSE(player);
3330 DVR_RETURN_IF_FALSE(p_secure_buf);
3331 DVR_RETURN_IF_FALSE(len);
3332
hualing chen4b7c15d2020-04-07 16:13:48 +08003333 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003334 pthread_mutex_lock(&player->lock);
3335
3336 player->is_secure_mode = 1;
3337 player->secure_buffer = p_secure_buf;
3338 player->secure_buffer_size = len;
3339
3340 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003341 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003342 return DVR_SUCCESS;
3343}