blob: 499fbf4b6e982ec4c414f2d33eda9dac73886809 [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <poll.h>
11#include <errno.h>
12#include <signal.h>
13#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080014#include <errno.h>
hualing chenb31a6c62020-01-13 17:27:00 +080015
hualing chenb31a6c62020-01-13 17:27:00 +080016#include "dvr_playback.h"
17
hualing chen4b7c15d2020-04-07 16:13:48 +080018#define DVR_PB_DG(_level, _fmt, ...) \
19 DVR_DEBUG(_level, "playback %-30.30s:%d " _fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
20
hualing chena540a7e2020-03-27 16:44:05 +080021
hualing chenb31a6c62020-01-13 17:27:00 +080022#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080023
24
25#define FF_SPEED (2.0f)
26#define FB_SPEED (-1.0f)
27#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
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 chencc91e1c2020-02-28 13:26:17 +080044static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type);
45static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
46static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080047static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080048static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
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 chena540a7e2020-03-27 16:44:05 +0800196 if (player != NULL)
197 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800198 break;
199 }
hualing chen487ae6d2020-07-22 10:34:11 +0800200 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
201 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
202 player->first_trans_ok = DVR_TRUE;
203 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
204 }
205 if (player != NULL && player->has_video == DVR_FALSE) {
206 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
207 player->first_frame = 1;
208 }
209 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800210 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800211 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800212 break;
213 }
214 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800215 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800216 player->player_callback_func(player->player_callback_userdata, event);
217 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800218 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800219 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800220 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800221 }
222}
hualing chencc91e1c2020-02-28 13:26:17 +0800223
hualing chen5cbe1a62020-02-10 16:36:36 +0800224//convert video and audio fmt
225static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
226 int format = 0;
227 if (is_audio == DVR_FALSE) {
228 //for video fmt
229 switch (fmt)
230 {
231 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800232 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800233 break;
234 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800235 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800236 break;
237 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800238 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800239 break;
240 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800241 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800242 break;
hualing chena540a7e2020-03-27 16:44:05 +0800243 case DVR_VIDEO_FORMAT_VP9:
244 format = AV_VIDEO_CODEC_VP9;
245 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800246 }
247 } else {
248 //for audio fmt
249 switch (fmt)
250 {
251 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800252 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800253 break;
254 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800255 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800256 break;
257 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800258 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800259 break;
260 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800261 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800262 break;
hualing chena540a7e2020-03-27 16:44:05 +0800263 case DVR_AUDIO_FORMAT_AAC:
264 format = AV_AUDIO_CODEC_AAC;
265 break;
266 case DVR_AUDIO_FORMAT_LATM:
267 format = AV_AUDIO_CODEC_LATM;
268 break;
269 case DVR_AUDIO_FORMAT_PCM:
270 format = AV_AUDIO_CODEC_PCM;
271 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800272 }
273 }
274 return format;
275}
hualing chen040df222020-01-17 13:35:02 +0800276static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800277{
hualing chen040df222020-01-17 13:35:02 +0800278 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800279
hualing chena540a7e2020-03-27 16:44:05 +0800280 if (player == NULL || player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800281 return -1;
282
hualing chena540a7e2020-03-27 16:44:05 +0800283 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800284}
hualing chena540a7e2020-03-27 16:44:05 +0800285
hualing chen5cbe1a62020-02-10 16:36:36 +0800286//get sys time ms
287static int _dvr_time_getClock(void)
288{
289 struct timespec ts;
290 int ms;
291
292 clock_gettime(CLOCK_MONOTONIC, &ts);
293 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
294
295 return ms;
296}
hualing chen86e7d482020-01-16 15:13:33 +0800297
hualing chenb31a6c62020-01-13 17:27:00 +0800298
299//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800300static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800301{
hualing chen040df222020-01-17 13:35:02 +0800302 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800303
hualing chena540a7e2020-03-27 16:44:05 +0800304
305 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800306 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800307 return DVR_FAILURE;
308 }
309
hualing chen86e7d482020-01-16 15:13:33 +0800310 struct timespec ts;
311 clock_gettime(CLOCK_MONOTONIC, &ts);
312 //ms为毫秒,换算成秒
313 ts.tv_sec += ms/1000;
314 //在outtime的基础上,增加ms毫秒
315 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
316 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
317 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
318 //us的值有可能超过1秒,
319 ts.tv_sec += us / 1000000;
320 us = us % 1000000;
321 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800322 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
323 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800324}
hualing chen31140872020-03-25 12:29:26 +0800325//get tsplay delay time ms
326static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
327 DVR_Playback_t *player = (DVR_Playback_t *) handle;
328 int64_t cache = 0;
329 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800330 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800331 return 0;
332 }
333 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800334 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800335 return cache;
336}
hualing chenb31a6c62020-01-13 17:27:00 +0800337//send signal
hualing chen040df222020-01-17 13:35:02 +0800338static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800339{
hualing chen87072a82020-03-12 16:20:12 +0800340 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800341
342 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800343 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800344 return DVR_FAILURE;
345 }
346
hualing chen87072a82020-03-12 16:20:12 +0800347 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800348 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800349 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800350 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800351}
352
hualing chen2932d372020-04-29 13:44:00 +0800353//send playback event, need check is need lock first
354static 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 +0800355
356 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800357
358 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800359 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800360 return DVR_FAILURE;
361 }
362
hualing chencc91e1c2020-02-28 13:26:17 +0800363 switch (evt) {
364 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800365 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800366 break;
367 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
368 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800369 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800370 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800371 break;
372 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
373 break;
374 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
375 break;
376 case DVR_PLAYBACK_EVENT_NO_KEY:
377 break;
378 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800379 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800380 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800381 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800382 break;
383 case DVR_PLAYBACK_EVENT_REACHED_END:
384 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800385 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800386 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800387 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800388 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800389 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800390 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800391 default:
392 break;
393 }
394 if (player->openParams.event_fn != NULL)
395 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800396 return DVR_SUCCESS;
397}
hualing chen2932d372020-04-29 13:44:00 +0800398static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800399{
400 DVR_Play_Notify_t notify;
401 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
402 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
403 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800404 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800405 return DVR_SUCCESS;
406}
407
hualing chen2932d372020-04-29 13:44:00 +0800408static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800409{
410 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800411
hualing chene3797f02021-01-13 14:53:28 +0800412 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800413 return DVR_SUCCESS;
414 }
hualing chena540a7e2020-03-27 16:44:05 +0800415 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800416 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800417 return DVR_FAILURE;
418 }
419
hualing chen6e4bfa52020-03-13 14:37:11 +0800420 if (player->send_time ==0) {
hualing chen0888c032020-12-18 17:54:57 +0800421 player->send_time = _dvr_time_getClock() + 500;
422 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800423 return DVR_SUCCESS;
424 }
hualing chen0888c032020-12-18 17:54:57 +0800425 player->send_time = _dvr_time_getClock() + 500;
hualing chen6e4bfa52020-03-13 14:37:11 +0800426 DVR_Play_Notify_t notify;
427 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
428 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
429 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800430 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800431 return DVR_SUCCESS;
432}
433
hualing chencc91e1c2020-02-28 13:26:17 +0800434//check is ongoing segment
435static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
436
437 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800438 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800439
440 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800441 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800442 return DVR_FAILURE;
443 }
hualing chen87072a82020-03-12 16:20:12 +0800444 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800445 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800446 return DVR_FALSE;
447 }
hualing chencc91e1c2020-02-28 13:26:17 +0800448 return DVR_TRUE;
449}
hualing chen4b7c15d2020-04-07 16:13:48 +0800450
451
452static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
453 DVR_Playback_t *player = (DVR_Playback_t *) handle;
454 player->fffb_start = _dvr_time_getClock();
455 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
456 player->fffb_current = player->fffb_start;
457 //get segment current time pos
458 player->fffb_start_pcr = _dvr_get_cur_time(handle);
459 //player->fffb_current = -1;
460 //player->fffb_start = -1;
461 //player->fffb_start_pcr = -1;
462 player->next_fffb_time = _dvr_time_getClock();
463
464 return DVR_SUCCESS;
465}
466
hualing chen2aba4022020-03-02 13:49:55 +0800467static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
468 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800469 player->fffb_start = _dvr_time_getClock();
470 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
471 player->fffb_current = player->fffb_start;
472 //get segment current time pos
473 player->fffb_start_pcr = _dvr_get_cur_time(handle);
474 //player->fffb_current = -1;
475 //player->fffb_start = -1;
476 //player->fffb_start_pcr = -1;
hualing chen2aba4022020-03-02 13:49:55 +0800477 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800478 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800479 return DVR_SUCCESS;
480}
hualing chencc91e1c2020-02-28 13:26:17 +0800481//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800482static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
483
484 DVR_Playback_t *player = (DVR_Playback_t *) handle;
485 DVR_PlaybackSegmentInfo_t *segment;
486 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
487
hualing chena540a7e2020-03-27 16:44:05 +0800488 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800489 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800490 return DVR_FAILURE;
491 }
492
hualing chen87072a82020-03-12 16:20:12 +0800493 int found = 0;
494 int found_eq_id = 0;
495 list_for_each_entry(segment, &player->segment_list, head)
496 {
497 if (player->segment_is_open == DVR_FALSE) {
498 //get first segment from list, case segment is not open
499 if (!IS_FB(player->speed))
500 found = 1;
501 } else if (segment->segment_id == segmentid) {
502 //find cur segment, we need get next one
503 found_eq_id = 1;
504 if (!IS_FB(player->speed)) {
505 found = 1;
506 continue;
507 } else {
508 //if is fb mode.we need used pre segment
509 if (pre_segment != NULL) {
510 found = 1;
511 } else {
512 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800513 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800514 return DVR_FAILURE;
515 }
516 }
517 }
518 if (found == 1) {
519 found = 2;
520 break;
521 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800522 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800523 }
524 if (found != 2) {
525 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800526 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800527 return DVR_FAILURE;
528 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800529 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800530 return DVR_SUCCESS;
531}
532
533//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800534static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800535
hualing chen040df222020-01-17 13:35:02 +0800536 DVR_Playback_t *player = (DVR_Playback_t *) handle;
537 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800538 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800539
hualing chena540a7e2020-03-27 16:44:05 +0800540 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800541 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800542 return DVR_FAILURE;
543 }
544
hualing chen86e7d482020-01-16 15:13:33 +0800545 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800546 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800547
hualing chen040df222020-01-17 13:35:02 +0800548 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800549 {
hualing chencc91e1c2020-02-28 13:26:17 +0800550 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800551 //get first segment from list, case segment is not open
552 if (!IS_FB(player->speed))
553 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800554 } else if (segment->segment_id == player->cur_segment_id) {
555 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800556 found_eq_id = 1;
557 if (!IS_FB(player->speed)) {
558 found = 1;
559 continue;
560 } else {
561 //if is fb mode.we need used pre segment
562 if (pre_segment != NULL) {
563 found = 1;
564 } else {
565 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800566 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800567 return DVR_FAILURE;
568 }
569 }
hualing chen86e7d482020-01-16 15:13:33 +0800570 }
571 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800572 if (IS_FB(player->speed)) {
573 //used pre segment
574 segment = pre_segment;
575 }
hualing chencc91e1c2020-02-28 13:26:17 +0800576 //save segment info
577 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800578 player->last_segment.segment_id = player->cur_segment.segment_id;
579 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800580 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
581 //pids
582 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
583
hualing chen5cbe1a62020-02-10 16:36:36 +0800584 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800585 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800586 player->cur_segment_id = segment->segment_id;
587 player->cur_segment.segment_id = segment->segment_id;
588 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800589 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 +0800590 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800591 //pids
hualing chen040df222020-01-17 13:35:02 +0800592 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800593 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800594 break;
hualing chen86e7d482020-01-16 15:13:33 +0800595 }
hualing chen2aba4022020-03-02 13:49:55 +0800596 pre_segment = segment;
597 }
598 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
599 //used the last one segment to open
600 //get segment info
601 player->segment_is_open = DVR_TRUE;
602 player->cur_segment_id = pre_segment->segment_id;
603 player->cur_segment.segment_id = pre_segment->segment_id;
604 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800605 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 +0800606 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
607 //pids
608 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
609 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800610 }
611 if (found != 2) {
612 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800613 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800614 }
615 return DVR_SUCCESS;
616}
hualing chen040df222020-01-17 13:35:02 +0800617//open next segment to play,if reach list end return errro.
618static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800619{
hualing chen040df222020-01-17 13:35:02 +0800620 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800621 Segment_OpenParams_t params;
622 int ret = DVR_SUCCESS;
623
hualing chena540a7e2020-03-27 16:44:05 +0800624 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800625 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800626 return DVR_FAILURE;
627 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800628 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800629
630 ret = _dvr_get_next_segmentId(handle);
631 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800632 DVR_PB_DG(1, "not found segment info");
633 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800634 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800635 }
636
637 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800638 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800639 segment_close(player->r_handle);
640 player->r_handle = NULL;
641 }
642
643 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800644 //cp chur segment path to location
645 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800646 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800647 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800648 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
649
hualing chen86e7d482020-01-16 15:13:33 +0800650 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800651 if (ret == DVR_FAILURE) {
652 DVR_PB_DG(1, "open segment error");
653 }
hualing chen87072a82020-03-12 16:20:12 +0800654 pthread_mutex_unlock(&player->segment_lock);
655 int total = _dvr_get_end_time( handle);
656 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800657 if (IS_FB(player->speed)) {
658 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800659 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800660 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800661 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800662 }
hualing chen87072a82020-03-12 16:20:12 +0800663 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800664 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800665 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800666 return ret;
667}
668
hualing chen5cbe1a62020-02-10 16:36:36 +0800669//open next segment to play,if reach list end return errro.
670static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
671{
672 DVR_Playback_t *player = (DVR_Playback_t *) handle;
673 Segment_OpenParams_t params;
674 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800675 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800676 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800677 return DVR_FAILURE;
678 }
hualing chencc91e1c2020-02-28 13:26:17 +0800679 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800680 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800681 }
hualing chencc91e1c2020-02-28 13:26:17 +0800682 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800683 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800684 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800685 return DVR_FAILURE;
686 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800687 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800688 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800689
690 DVR_PlaybackSegmentInfo_t *segment;
691
692 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800693
hualing chen5cbe1a62020-02-10 16:36:36 +0800694 list_for_each_entry(segment, &player->segment_list, head)
695 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800696 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 +0800697 if (segment->segment_id == segment_id) {
698 found = 1;
699 }
700 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800701 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 +0800702 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800703 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800704 player->cur_segment_id = segment->segment_id;
705 player->cur_segment.segment_id = segment->segment_id;
706 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800707 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800708 //pids
709 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800710 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 +0800711 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800712 }
713 }
hualing chencc91e1c2020-02-28 13:26:17 +0800714 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800715 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800716 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800717 return DVR_FAILURE;
718 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800719 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800720 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800721 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800722 params.segment_id = (uint64_t)player->cur_segment.segment_id;
723 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800724 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 +0800725 if (player->r_handle != NULL) {
726 segment_close(player->r_handle);
727 player->r_handle = NULL;
728 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800729 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800730 if (ret == DVR_FAILURE) {
731 DVR_PB_DG(1, "segment opne error");
732 }
hualing chen2aba4022020-03-02 13:49:55 +0800733 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800734 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800735
hualing chen4b7c15d2020-04-07 16:13:48 +0800736 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 +0800737 return ret;
738}
739
740
741//get play info by segment id
742static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
743 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800744 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800745 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800746
747 DVR_Playback_t *player = (DVR_Playback_t *) handle;
748 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800749 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800750 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800751 return DVR_FAILURE;
752 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800753
754 int found = 0;
755
756 list_for_each_entry(segment, &player->segment_list, head)
757 {
hualing chen87072a82020-03-12 16:20:12 +0800758 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800759 //get first segment from list
760 found = 1;
761 }
762 if (segment->segment_id == segment_id) {
763 found = 1;
764 }
765 if (found == 1) {
766 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800767 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800768 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800769 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800770 player->cur_segment.segment_id = segment->segment_id;
771 player->cur_segment.flags = segment->flags;
772 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800773 player->cur_segment.pids.video.pid = segment->pids.video.pid;
774 player->cur_segment.pids.video.format = segment->pids.video.format;
775 player->cur_segment.pids.video.type = segment->pids.video.type;
776 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
777 player->cur_segment.pids.audio.format = segment->pids.audio.format;
778 player->cur_segment.pids.audio.type = segment->pids.audio.type;
779 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
780 player->cur_segment.pids.ad.format = segment->pids.ad.format;
781 player->cur_segment.pids.ad.type = segment->pids.ad.type;
782 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800783 //
hualing chen2aba4022020-03-02 13:49:55 +0800784 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800785 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800786 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800787 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800788 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
789 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800790 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 +0800791 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800792 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800793 }
794 }
hualing chencc91e1c2020-02-28 13:26:17 +0800795 if (found != 2) {
796 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800797 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800798 return DVR_FAILURE;
799 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800800
801 return DVR_SUCCESS;
802}
hualing chencc91e1c2020-02-28 13:26:17 +0800803static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
804 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800805 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800806 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800807 return DVR_FAILURE;
808 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800809
hualing chencc91e1c2020-02-28 13:26:17 +0800810 //compare cur segment
811 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
812 {
813 //check video pids, stop or restart
814 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
815 //check audio pids stop or restart
816 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
817 //check sub audio pids stop or restart
818 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
hualing chene3797f02021-01-13 14:53:28 +0800819 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 +0800820 //check pcr pids stop or restart
821 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
822 }
hualing chena540a7e2020-03-27 16:44:05 +0800823 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800824}
hualing chen5cbe1a62020-02-10 16:36:36 +0800825
hualing chencc91e1c2020-02-28 13:26:17 +0800826static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
827{
828 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800829 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800830 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800831 return DVR_FAILURE;
832 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800833 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
834 DVR_PB_DG(1, "vendor is amlogic. no used segment flag to hide or show av");
835 return DVR_SUCCESS;
836 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800837 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 +0800838 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
839 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800840 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800841 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800842 AmTsPlayer_showVideo(player->handle);
843 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800844 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
845 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800846 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800847 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800848 AmTsPlayer_hideVideo(player->handle);
849 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800850 }
851 return DVR_SUCCESS;
852}
hualing chene3797f02021-01-13 14:53:28 +0800853/*
854if decodec sucess first time.
855sucess: return true
856fail: return false
857*/
hualing chena540a7e2020-03-27 16:44:05 +0800858static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
859 DVR_Playback_t *player = (DVR_Playback_t *) handle;
860 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800861 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800862 return DVR_TRUE;
863 }
hualing chene3797f02021-01-13 14:53:28 +0800864 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800865 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800866 } else {
867 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800868 }
869}
hualing chen86e7d482020-01-16 15:13:33 +0800870static void* _dvr_playback_thread(void *arg)
871{
hualing chen040df222020-01-17 13:35:02 +0800872 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800873 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800874 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800875 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800876 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800877
hualing chen39628212020-05-14 10:35:13 +0800878 #define MAX_REACHEND_TIMEOUT (3000)
879 int reach_end_timeout = 0;//ms
880 int cache_time = 0;
hualing chen6d24aa92020-03-23 18:43:47 +0800881 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800882 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800883 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800884 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800885 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
886
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800887 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800888 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800889 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chene41f4372020-06-06 16:29:17 +0800890 int retry_open_seg = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800891 if (player->is_secure_mode) {
892 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800893 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800894 return NULL;
895 }
896 }
hualing chen86e7d482020-01-16 15:13:33 +0800897 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800898 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800899 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800900 return NULL;
901 }
hualing chen2aba4022020-03-02 13:49:55 +0800902 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
903 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800904
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800905 dec_bufs.buf_data = malloc(dec_buf_size);
906 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800907 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800908 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800909 return NULL;
910 }
911 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
912 dec_bufs.buf_size = dec_buf_size;
913
hualing chencc91e1c2020-02-28 13:26:17 +0800914 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800915 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
916 }
hualing chen86e7d482020-01-16 15:13:33 +0800917
hualing chen86e7d482020-01-16 15:13:33 +0800918 if (ret != DVR_SUCCESS) {
919 if (buf != NULL) {
920 free(buf);
921 buf = NULL;
922 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800923 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800924 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800925 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800926 }
hualing chen4fe3bee2020-10-23 13:58:52 +0800927 DVR_PB_DG(1, "player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
928 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +0800929 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
930 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
931 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
932 player->first_trans_ok = DVR_TRUE;
933 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
934 }
hualing chencc91e1c2020-02-28 13:26:17 +0800935 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800936 //set video show
937 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800938
hualing chen86e7d482020-01-16 15:13:33 +0800939 int trick_stat = 0;
940 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800941
hualing chen86e7d482020-01-16 15:13:33 +0800942 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800943 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800944
hualing chen2aba4022020-03-02 13:49:55 +0800945 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
946 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800947 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800948 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +0800949 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +0800950 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800951 {
hualing chen2aba4022020-03-02 13:49:55 +0800952 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
953 if (trick_stat > 0) {
hualing chenbcada022020-04-22 14:27:01 +0800954 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]", player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +0800955 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 +0800956 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +0800957 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800958 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800959 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
960 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800961 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
962 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chenbcada022020-04-22 14:27:01 +0800963 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 +0800964 //need change to pause state
965 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
966 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800967 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800968 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800969 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800970 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +0800971 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +0800972 AmTsPlayer_pauseVideoDecoding(player->handle);
973 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800974 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800975 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +0800976 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800977 }
978 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
979 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800980 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800981 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +0800982 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
983 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 +0800984 //used timeout wait need lock first,so we unlock and lock
985 //pthread_mutex_unlock(&player->lock);
986 //pthread_mutex_lock(&player->lock);
987 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
988 pthread_mutex_unlock(&player->lock);
989 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +0800990 } else if (_dvr_time_getClock() < player->next_fffb_time) {
991 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);
992 //used timeout wait need lock first,so we unlock and lock
993 //pthread_mutex_unlock(&player->lock);
994 //pthread_mutex_lock(&player->lock);
995 AmTsPlayer_pauseVideoDecoding(player->handle);
996 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
997 pthread_mutex_unlock(&player->lock);
998 continue;
999
hualing chen2aba4022020-03-02 13:49:55 +08001000 }
hualing chen2932d372020-04-29 13:44:00 +08001001 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);
hualing chen2aba4022020-03-02 13:49:55 +08001002 pthread_mutex_unlock(&player->lock);
1003 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001004 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001005 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1006 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001007 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001008 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001009 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001010 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001011 }else if (player->fffb_play == DVR_TRUE){
1012 //for first into fffb when reset speed
1013 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1014 _dvr_time_getClock() < player->next_fffb_time) {
1015 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);
1016 //used timeout wait need lock first,so we unlock and lock
1017 //pthread_mutex_unlock(&player->lock);
1018 //pthread_mutex_lock(&player->lock);
1019 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1020 pthread_mutex_unlock(&player->lock);
1021 continue;
1022 }
hualing chen2932d372020-04-29 13:44:00 +08001023 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, player->fffb_play);
hualing chen4b7c15d2020-04-07 16:13:48 +08001024 pthread_mutex_unlock(&player->lock);
1025 goto_rewrite = DVR_FALSE;
1026 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001027 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001028 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1029 player->first_frame = 0;
1030 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1031 pthread_mutex_lock(&player->lock);
1032 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001033 }
hualing chenb31a6c62020-01-13 17:27:00 +08001034 }
hualing chen86e7d482020-01-16 15:13:33 +08001035
hualing chen87072a82020-03-12 16:20:12 +08001036 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001037 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001038 DVR_PB_DG(1, "pause, continue");
hualing chen2932d372020-04-29 13:44:00 +08001039 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen87072a82020-03-12 16:20:12 +08001040 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1041 pthread_mutex_unlock(&player->lock);
1042 continue;
1043 }
hualing chen266b9502020-04-04 17:39:39 +08001044 //when seek action is done. we need drop write timeout data.
1045 if (player->drop_ts == DVR_TRUE) {
1046 goto_rewrite = DVR_FALSE;
1047 real_read = 0;
1048 player->drop_ts = DVR_FALSE;
1049 }
hualing chen2aba4022020-03-02 13:49:55 +08001050 if (goto_rewrite == DVR_TRUE) {
1051 goto_rewrite = DVR_FALSE;
1052 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001053 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001054 goto rewrite;
1055 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001056 //.check is need send time send end
hualing chen2932d372020-04-29 13:44:00 +08001057 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001058 pthread_mutex_lock(&player->segment_lock);
hualing chene41f4372020-06-06 16:29:17 +08001059 //DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001060 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chenfbf8e022020-06-15 13:43:11 +08001061 //DVR_PB_DG(1, "start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001062 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001063 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001064 if (read < 0 && errno == EIO) {
1065 //EIO ERROR, EXIT THRAD
1066 DVR_PB_DG(1, "read error.EIO error, exit thread");
1067 DVR_Play_Notify_t notify;
1068 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1069 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001070 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001071 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001072 goto end;
1073 } else if (read < 0) {
1074 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1075 }
hualing chen87072a82020-03-12 16:20:12 +08001076 //if on fb mode and read file end , we need calculate pos to retry read.
1077 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001078 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 +08001079 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
1080 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001081 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1082 pthread_mutex_unlock(&player->lock);
1083 continue;
1084 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001085 //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 +08001086 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001087 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001088 #define MIN_CACHE_TIME (3000)
1089 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001090 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001091 if (_cache_time > MIN_CACHE_TIME) {
hualing chene41f4372020-06-06 16:29:17 +08001092 pthread_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001093 /*if cache time > 20s , we think get time is error,*/
1094 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
1095 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1096 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1097 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1098 }
1099 _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 +08001100 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001101 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 +08001102 //continue;
1103 }
hualing chen040df222020-01-17 13:35:02 +08001104 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001105 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001106 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001107
1108 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chene3797f02021-01-13 14:53:28 +08001109 if (ret != DVR_SUCCESS) {
1110 player->noData++;
1111 DVR_PB_DG(1, "playback is sleep:[%d]ms nodata[%d]", timeout, player->noData);
1112 if (player->noData == 4) {
1113 DVR_PB_DG(1, "playback send nodata event nodata[%d]", player->noData);
1114 //send event here and pause
1115 DVR_Play_Notify_t notify;
1116 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1117 notify.event = DVR_PLAYBACK_EVENT_NODATA;
1118 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_NODATA");
1119 //get play statue not here
1120 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1121 }
1122 }
1123 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001124 if ((ret != DVR_SUCCESS &&
hualing chen041c4092020-04-05 15:11:50 +08001125 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001126 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001127 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1128 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001129 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001130 DVR_Play_Notify_t notify;
1131 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1132 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1133 //get play statue not here
1134 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001135 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001136 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001137 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 +08001138 pthread_mutex_lock(&player->lock);
1139 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1140 pthread_mutex_unlock(&player->lock);
1141 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001142 } else if (ret != DVR_SUCCESS) {
1143 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001144 if (delay < cache_time) {
1145 //delay time is changed and then has data to play, so not start timeout
1146 } else {
1147 reach_end_timeout = reach_end_timeout + timeout;
1148 }
1149 cache_time = delay;
hualing chen4b7c15d2020-04-07 16:13:48 +08001150 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001151 pthread_mutex_lock(&player->lock);
1152 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1153 pthread_mutex_unlock(&player->lock);
1154 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001155 }
hualing chen39628212020-05-14 10:35:13 +08001156 reach_end_timeout = 0;
1157 cache_time = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001158 pthread_mutex_lock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001159 //change next segment success case
1160 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001161 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001162 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1163 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001164 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001165 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001166 }//read len 0 check end
1167 if (player->noData > 0) {
1168 player->noData = 0;
1169 DVR_PB_DG(1, "playback send data event resume[%d]", player->noData);
1170 //send event here and pause
1171 DVR_Play_Notify_t notify;
1172 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1173 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
1174 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_DATARESUME");
1175 //get play statue not here
1176 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001177 }
hualing chen39628212020-05-14 10:35:13 +08001178 reach_end_timeout = 0;
hualing chen86e7d482020-01-16 15:13:33 +08001179 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001180 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001181 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001182
hualing chena540a7e2020-03-27 16:44:05 +08001183 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001184 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001185 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001186 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001187 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001188 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001189 }
hualing chen266b9502020-04-04 17:39:39 +08001190 //if need write whole block size, we need check read buf len is eq block size.
1191 if (b_writed_whole_block == DVR_TRUE) {
1192 //buf_len is block size value.
1193 if (real_read < buf_len) {
1194 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001195 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001196 pthread_mutex_lock(&player->lock);
1197 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1198 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001199 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001200 continue;
1201 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001202 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 +08001203 }
1204 }
1205
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001206 if (player->dec_func) {
1207 DVR_CryptoParams_t crypto_params;
1208
1209 memset(&crypto_params, 0, sizeof(crypto_params));
1210 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1211 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1212 crypto_params.segment_id = player->cur_segment.segment_id;
hualing chen1f26ffa2020-11-03 10:39:20 +08001213 crypto_params.offset = segment_tell_position(player->r_handle) - wbufs.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001214 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
1215 DVR_PB_DG(1, "offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001216 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1217 crypto_params.input_buffer.addr = (size_t)buf;
1218 crypto_params.input_buffer.size = real_read;
1219
1220 if (player->is_secure_mode) {
1221 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1222 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1223 crypto_params.output_buffer.size = dec_buf_size;
1224 ret = player->dec_func(&crypto_params, player->dec_userdata);
1225 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001226 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001227 } else {
1228 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1229 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1230 crypto_params.output_buffer.size = dec_buf_size;
1231 ret = player->dec_func(&crypto_params, player->dec_userdata);
1232 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001233 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001234 }
1235 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001236 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001237 }
pengfei.liufda2a972020-04-09 14:47:15 +08001238 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001239 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001240rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001241 if (player->drop_ts == DVR_TRUE) {
1242 //need drop ts data when seek occur.we need read next loop,drop this ts data
1243 goto_rewrite = DVR_FALSE;
1244 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001245 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001246 player->drop_ts = DVR_FALSE;
1247 continue;
1248 }
hualing chen5605eed2020-05-26 18:18:06 +08001249 player->ts_cache_len = real_read;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001250 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1251 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001252 player->ts_cache_len = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001253 real_read = 0;
1254 write_success++;
hualing chen5605eed2020-05-26 18:18:06 +08001255 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001256 continue;
hualing chen87072a82020-03-12 16:20:12 +08001257 } else {
hualing chen2932d372020-04-29 13:44:00 +08001258 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 +08001259 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001260 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001261 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001262 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001263 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001264 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001265 break;
1266 }
hualing chen2aba4022020-03-02 13:49:55 +08001267 goto_rewrite = DVR_TRUE;
1268 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001269 }
1270 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001271end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001272 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001273 free(buf);
1274 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001275 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001276}
1277
1278
hualing chen040df222020-01-17 13:35:02 +08001279static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001280{
hualing chen040df222020-01-17 13:35:02 +08001281 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001282
1283 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001284 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001285 return DVR_FAILURE;
1286 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001287 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001288 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001289 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001290 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001291 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001292 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001293 if (rc < 0)
1294 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001295 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001296}
1297
1298
hualing chen040df222020-01-17 13:35:02 +08001299static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001300{
hualing chen040df222020-01-17 13:35:02 +08001301 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001302
1303 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001304 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001305 return DVR_FAILURE;
1306 }
1307
hualing chen4b7c15d2020-04-07 16:13:48 +08001308 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001309 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001310 {
1311 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001312 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001313 pthread_join(player->playback_thread, NULL);
1314 }
1315 if (player->r_handle) {
1316 segment_close(player->r_handle);
1317 player->r_handle = NULL;
1318 }
hualing chen7a56cba2020-04-14 14:09:27 +08001319 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001320 return 0;
1321}
1322
hualing chenb31a6c62020-01-13 17:27:00 +08001323/**\brief Open an dvr palyback
1324 * \param[out] p_handle dvr playback addr
1325 * \param[in] params dvr playback open parameters
1326 * \retval DVR_SUCCESS On success
1327 * \return Error code
1328 */
hualing chen040df222020-01-17 13:35:02 +08001329int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001330
hualing chen040df222020-01-17 13:35:02 +08001331 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001332 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001333
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001334 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001335
hualing chen86e7d482020-01-16 15:13:33 +08001336 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001337 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001338 pthread_condattr_init(&cattr);
1339 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1340 pthread_cond_init(&player->cond, &cattr);
1341 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001342
hualing chen5cbe1a62020-02-10 16:36:36 +08001343 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001344 INIT_LIST_HEAD(&player->segment_list);
1345 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1346 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001347 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001348 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001349 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001350 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001351 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001352 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001353
hualing chen86e7d482020-01-16 15:13:33 +08001354 //store open params
hualing chen040df222020-01-17 13:35:02 +08001355 player->openParams.dmx_dev_id = params->dmx_dev_id;
1356 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001357 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001358 player->openParams.event_fn = params->event_fn;
1359 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001360 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001361 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001362
hualing chen5cbe1a62020-02-10 16:36:36 +08001363 player->has_pids = params->has_pids;
1364
hualing chen2aba4022020-03-02 13:49:55 +08001365 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001366
1367 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1368 //for test get callback
1369 if (0 && player->player_callback_func == NULL) {
1370 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1371 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001372 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 +08001373 }
1374 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001375
hualing chen86e7d482020-01-16 15:13:33 +08001376 //init has audio and video
1377 player->has_video = DVR_FALSE;
1378 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001379 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001380 player->last_segment_id = 0LL;
1381 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001382
hualing chen5cbe1a62020-02-10 16:36:36 +08001383 //init ff fb time
1384 player->fffb_current = -1;
1385 player->fffb_start =-1;
1386 player->fffb_start_pcr = -1;
1387 //seek time
1388 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001389 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001390
1391 //init secure stuff
1392 player->dec_func = NULL;
1393 player->dec_userdata = NULL;
1394 player->is_secure_mode = 0;
1395 player->secure_buffer = NULL;
1396 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001397 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001398
hualing chen4b7c15d2020-04-07 16:13:48 +08001399 player->fffb_play = DVR_FALSE;
1400
1401 player->last_send_time_id = UINT64_MAX;
1402 player->last_cur_time = 0;
1403
hualing chen86e7d482020-01-16 15:13:33 +08001404 *p_handle = player;
1405 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001406}
1407
1408/**\brief Close an dvr palyback
1409 * \param[in] handle playback handle
1410 * \retval DVR_SUCCESS On success
1411 * \return Error code
1412 */
hualing chen040df222020-01-17 13:35:02 +08001413int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001414
hualing chen86e7d482020-01-16 15:13:33 +08001415 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001416 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001417 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001418 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001419 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001420 return DVR_FAILURE;
1421 }
1422
hualing chencc91e1c2020-02-28 13:26:17 +08001423 if (player->state != DVR_PLAYBACK_STATE_STOP)
1424 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001425 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001426 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001427 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1428 } else {
1429 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001430 }
hualing chen7a56cba2020-04-14 14:09:27 +08001431 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001432 pthread_mutex_destroy(&player->lock);
1433 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001434
1435 if (player) {
1436 free(player);
1437 player = NULL;
1438 }
hualing chen7a56cba2020-04-14 14:09:27 +08001439 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001440 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001441}
1442
hualing chenb31a6c62020-01-13 17:27:00 +08001443/**\brief Start play audio and video, used start auido api and start video api
1444 * \param[in] handle playback handle
1445 * \param[in] params audio playback params,contains fmt and pid...
1446 * \retval DVR_SUCCESS On success
1447 * \return Error code
1448 */
hualing chen040df222020-01-17 13:35:02 +08001449int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1450 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001451 am_tsplayer_video_params vparams;
1452 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001453 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001454
1455 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001456 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001457 return DVR_FAILURE;
1458 }
hualing chencc91e1c2020-02-28 13:26:17 +08001459 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001460 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001461
hualing chena540a7e2020-03-27 16:44:05 +08001462 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001463 //can used start api to resume playback
1464 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1465 return dvr_playback_resume(handle);
1466 }
hualing chen87072a82020-03-12 16:20:12 +08001467 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001468 //if flag is puased and not decodec first frame. if user resume, we need
1469 //clear flag and set trickmode none
1470 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1471 DVR_PB_DG(1, "[%p]clear pause live flag and clear trick mode", handle);
1472 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1473 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1474 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001475 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001476 return DVR_SUCCESS;
1477 }
hualing chen86e7d482020-01-16 15:13:33 +08001478 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001479 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001480 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001481 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001482 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001483 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001484 //start audio and video
Zhiqiang Hana9d261b2020-11-11 18:38:10 +08001485 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001486 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001487 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001488 pthread_mutex_unlock(&player->lock);
1489 DVR_Play_Notify_t notify;
1490 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1491 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1492 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1493 notify.info.transition_failed_data.segment_id = segment_id;
1494 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001495 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001496 return -1;
1497 }
hualing chen31140872020-03-25 12:29:26 +08001498
hualing chencc91e1c2020-02-28 13:26:17 +08001499 {
hualing chen86e7d482020-01-16 15:13:33 +08001500 if (VALID_PID(vparams.pid)) {
1501 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001502 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001503 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001504 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001505 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1506 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001507 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001508 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001509 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001510 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001511 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001512 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001513 }
hualing chena93bbbc2020-12-22 17:23:42 +08001514 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001515 AmTsPlayer_setVideoParams(player->handle, &vparams);
1516 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001517 }
hualing chena540a7e2020-03-27 16:44:05 +08001518
hualing chen4b7c15d2020-04-07 16:13:48 +08001519 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1520 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001521 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1522 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1523 player->cmd.state = DVR_PLAYBACK_STATE_START;
1524 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001525 } else {
1526 player->cmd.last_cmd = player->cmd.cur_cmd;
1527 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001528 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001529 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001530 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001531 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001532 } else {
1533 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001534 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08001535 player->has_audio = DVR_TRUE;
1536 AmTsPlayer_setAudioParams(player->handle, &aparams);
1537 AmTsPlayer_startAudioDecoding(player->handle);
1538 }
hualing chendf118dd2020-05-21 15:49:11 +08001539 if (VALID_PID(adparams.pid)) {
1540 player->has_ad_audio = DVR_TRUE;
1541 DVR_PB_DG(1, "start ad audio");
1542 AmTsPlayer_setADParams(player->handle, &adparams);
1543 AmTsPlayer_enableADMix(player->handle);
1544 }
hualing chen31140872020-03-25 12:29:26 +08001545 }
hualing chencc91e1c2020-02-28 13:26:17 +08001546 player->cmd.state = DVR_PLAYBACK_STATE_START;
1547 player->state = DVR_PLAYBACK_STATE_START;
1548 }
hualing chen86e7d482020-01-16 15:13:33 +08001549 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001550 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001551 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001552 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001553 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001554}
hualing chen040df222020-01-17 13:35:02 +08001555/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001556 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001557 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001558 * \retval DVR_SUCCESS On success
1559 * \return Error code
1560 */
hualing chen040df222020-01-17 13:35:02 +08001561int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1562 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001563
hualing chena540a7e2020-03-27 16:44:05 +08001564 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001565 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001566 return DVR_FAILURE;
1567 }
1568
hualing chen4b7c15d2020-04-07 16:13:48 +08001569 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001570 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001571
hualing chen040df222020-01-17 13:35:02 +08001572 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1573 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001574
hualing chen86e7d482020-01-16 15:13:33 +08001575 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001576 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001577 //cp location
hualing chen040df222020-01-17 13:35:02 +08001578 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001579
hualing chen4b7c15d2020-04-07 16:13:48 +08001580 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 +08001581 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001582
1583 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001584 segment->pids.video.pid = info->pids.video.pid;
1585 segment->pids.video.format = info->pids.video.format;
1586 segment->pids.video.type = info->pids.video.type;
1587
hualing chen2aba4022020-03-02 13:49:55 +08001588 segment->pids.audio.pid = info->pids.audio.pid;
1589 segment->pids.audio.format = info->pids.audio.format;
1590 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001591
hualing chen2aba4022020-03-02 13:49:55 +08001592 segment->pids.ad.pid = info->pids.ad.pid;
1593 segment->pids.ad.format = info->pids.ad.format;
1594 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001595
1596 segment->pids.pcr.pid = info->pids.pcr.pid;
1597
hualing chen4b7c15d2020-04-07 16:13:48 +08001598 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 +08001599 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001600 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001601 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001602 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001603
hualing chen5cbe1a62020-02-10 16:36:36 +08001604 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001605}
hualing chen040df222020-01-17 13:35:02 +08001606/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001607 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001608 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001609 * \retval DVR_SUCCESS On success
1610 * \return Error code
1611 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001612int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001613 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001614 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001615 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001616 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001617 return DVR_FAILURE;
1618 }
1619
hualing chencc91e1c2020-02-28 13:26:17 +08001620 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001621 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001622 return DVR_FAILURE;
1623 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001624 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001625 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001626 DVR_PlaybackSegmentInfo_t *segment = NULL;
1627 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1628 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001629 {
hualing chen040df222020-01-17 13:35:02 +08001630 if (segment->segment_id == segment_id) {
1631 list_del(&segment->head);
1632 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001633 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001634 }
hualing chen86e7d482020-01-16 15:13:33 +08001635 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001636 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001637 pthread_mutex_unlock(&player->lock);
1638
1639 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001640}
hualing chen040df222020-01-17 13:35:02 +08001641/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001642 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001643 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001644 * \retval DVR_SUCCESS On success
1645 * \return Error code
1646 */
hualing chen040df222020-01-17 13:35:02 +08001647int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001648 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001649 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001650 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001651 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001652 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001653 return DVR_FAILURE;
1654 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001655 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
1656 DVR_PB_DG(1, "vendor is amlogic. not hide or show av and update segment");
1657 return DVR_SUCCESS;
1658 }
hualing chena540a7e2020-03-27 16:44:05 +08001659
hualing chen040df222020-01-17 13:35:02 +08001660 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001661 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001662 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001663 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001664 {
hualing chen040df222020-01-17 13:35:02 +08001665 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001666 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001667 }
hualing chen86e7d482020-01-16 15:13:33 +08001668 // if encramble to free, only set flag and return;
1669
1670 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001671 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001672 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1673 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001674 //disable display, mute
hualing chen703f3572021-01-06 12:51:34 +08001675 DVR_PB_DG(1, "mute av");
hualing chen2aba4022020-03-02 13:49:55 +08001676 AmTsPlayer_hideVideo(player->handle);
1677 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001678 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1679 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001680 //enable display, unmute
hualing chen703f3572021-01-06 12:51:34 +08001681 DVR_PB_DG(1, "unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08001682 AmTsPlayer_showVideo(player->handle);
1683 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001684 } else {
1685 //do nothing
1686 }
1687 } else {
1688 //do nothing
1689 }
1690 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001691 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001692 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001693 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001694 pthread_mutex_unlock(&player->lock);
1695 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001696}
1697
1698
hualing chen5cbe1a62020-02-10 16:36:36 +08001699static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type) {
hualing chen040df222020-01-17 13:35:02 +08001700 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001701 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001702 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001703 return DVR_FAILURE;
1704 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001705 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001706 if (now_pid.pid == set_pid.pid) {
1707 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001708 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001709 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001710 if (VALID_PID(now_pid.pid)) {
1711 //stop now stream
1712 if (type == 0) {
1713 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001714 if (player->has_video == DVR_TRUE) {
1715 DVR_PB_DG(1, "stop video");
1716 AmTsPlayer_stopVideoDecoding(player->handle);
1717 player->has_video = DVR_FALSE;
1718 }
hualing chen86e7d482020-01-16 15:13:33 +08001719 } else if (type == 1) {
1720 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08001721 if (player->has_audio == DVR_TRUE) {
1722 DVR_PB_DG(1, "stop audio");
1723 AmTsPlayer_stopAudioDecoding(player->handle);
1724 player->has_audio = DVR_FALSE;
1725 }
hualing chen86e7d482020-01-16 15:13:33 +08001726 } else if (type == 2) {
1727 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001728 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001729 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001730 } else if (type == 3) {
1731 //pcr
1732 }
1733 }
1734 if (VALID_PID(set_pid.pid)) {
1735 //start
1736 if (type == 0) {
1737 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001738 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001739 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001740 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001741 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001742 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001743 AmTsPlayer_setVideoParams(player->handle, &vparams);
1744 AmTsPlayer_startVideoDecoding(player->handle);
1745 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001746 } else if (type == 1) {
1747 //start audio
hualing chenc70a8df2020-05-12 19:23:11 +08001748 if ((player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
1749 am_tsplayer_audio_params aparams;
1750 aparams.pid = set_pid.pid;
1751 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1752 player->has_audio = DVR_TRUE;
1753 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1754 AmTsPlayer_setAudioParams(player->handle, &aparams);
1755 AmTsPlayer_startAudioDecoding(player->handle);
1756 //playback_device_audio_start(player->handle,&aparams);
1757 }
hualing chen86e7d482020-01-16 15:13:33 +08001758 } else if (type == 2) {
hualing chen39628212020-05-14 10:35:13 +08001759 if ((player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chenc70a8df2020-05-12 19:23:11 +08001760 am_tsplayer_audio_params aparams;
1761 aparams.pid = set_pid.pid;
1762 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1763 player->has_audio = DVR_TRUE;
1764 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1765 AmTsPlayer_setADParams(player->handle, &aparams);
1766 AmTsPlayer_enableADMix(player->handle);
1767 //playback_device_audio_start(player->handle,&aparams);
1768 }
hualing chen86e7d482020-01-16 15:13:33 +08001769 } else if (type == 3) {
1770 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001771 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001772 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001773 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001774 //audio and video all close
1775 if (!player->has_audio && !player->has_video) {
1776 player->state = DVR_PLAYBACK_STATE_STOP;
1777 }
hualing chen86e7d482020-01-16 15:13:33 +08001778 }
1779 }
1780 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001781}
hualing chen5cbe1a62020-02-10 16:36:36 +08001782/**\brief dvr play back update segment pids
1783 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001784 * add pid stream and stop remove pid stream.
1785 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001786 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001787 * \retval DVR_SUCCESS On success
1788 * \return Error code
1789 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001790int 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 +08001791 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001792 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001793 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001794 return DVR_FAILURE;
1795 }
1796
hualing chen040df222020-01-17 13:35:02 +08001797 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001798 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001799 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001800 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 +08001801
hualing chen040df222020-01-17 13:35:02 +08001802 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001803 {
hualing chen040df222020-01-17 13:35:02 +08001804 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001805
1806 if (player->cur_segment_id == segment_id) {
1807 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1808 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1809 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001810 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001811 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001812 return 0;
1813 }
1814
1815 //if segment is on going segment,we need stop start stream
1816 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001817 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001818 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001819 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001820 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001821 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001822 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001823 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001824 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001825 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1826 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001827 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1828 //if state is pause, we need process at resume api. we only record change info
1829 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1830 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1831 if (VALID_PID(segment->pids.video.pid)
1832 && VALID_PID(p_pids->video.pid)
1833 && segment->pids.video.pid != p_pids->video.pid) {
1834 //restart video
1835 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1836 }
1837 if (!VALID_PID(segment->pids.video.pid)
1838 && VALID_PID(p_pids->video.pid)
1839 && segment->pids.video.pid != p_pids->video.pid) {
1840 //start video
1841 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1842 }
1843 if (VALID_PID(segment->pids.video.pid)
1844 && !VALID_PID(p_pids->video.pid)
1845 && segment->pids.video.pid != p_pids->video.pid) {
1846 //stop video
1847 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1848 }
1849 if (VALID_PID(segment->pids.audio.pid)
1850 && VALID_PID(p_pids->audio.pid)
1851 && segment->pids.audio.pid != p_pids->audio.pid) {
1852 //restart audio
1853 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1854 }
1855 if (!VALID_PID(segment->pids.audio.pid)
1856 && VALID_PID(p_pids->audio.pid)
1857 && segment->pids.audio.pid != p_pids->audio.pid) {
1858 //start audio
1859 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1860 }
1861 if (VALID_PID(segment->pids.audio.pid)
1862 && !VALID_PID(p_pids->audio.pid)
1863 && segment->pids.audio.pid != p_pids->audio.pid) {
1864 //stop audio
1865 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1866 }
1867 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1868 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1869 //do nothing
1870 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1871 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1872 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1873 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1874 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1875 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1876 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1877 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1878 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1879 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1880 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1881 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1882 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1883 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1884 } else {
1885 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1886 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1887 }
1888
1889 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1890 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1891 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1892 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1893 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1894 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1895 //not occur this case
1896 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1897 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1898 } else {
1899 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1900 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1901 }
1902
1903 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1904 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1905 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1906 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1907 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1908 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1909 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1910 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1911 } else {
1912 //not occur this case
1913 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1914 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1915 }
1916 }
1917 }
hualing chene10666f2020-04-14 13:58:37 +08001918 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08001919 }
hualing chen86e7d482020-01-16 15:13:33 +08001920 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08001921 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08001922 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08001923 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001924 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001925 }
hualing chen86e7d482020-01-16 15:13:33 +08001926 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001927 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001928 pthread_mutex_unlock(&player->lock);
1929 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001930}
1931/**\brief Stop play, will stop video and audio
1932 * \param[in] handle playback handle
1933 * \param[in] clear is clear last frame
1934 * \retval DVR_SUCCESS On success
1935 * \return Error code
1936 */
hualing chen040df222020-01-17 13:35:02 +08001937int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1938 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001939
1940 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001941 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001942 return DVR_FAILURE;
1943 }
hualing chenb96aa2c2020-04-15 14:13:53 +08001944 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1945 DVR_PB_DG(1, ":playback is stoped");
1946 return DVR_SUCCESS;
1947 }
Ke Gong3c0caba2020-04-21 22:58:18 -07001948 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1949 DVR_PB_DG(1, ":playback is stoped");
1950 return DVR_SUCCESS;
1951 }
hualing chen87072a82020-03-12 16:20:12 +08001952 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001953 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001954 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08001955 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08001956 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001957 if (player->has_video) {
1958 AmTsPlayer_resumeVideoDecoding(player->handle);
1959 }
1960 if (player->has_audio) {
1961 AmTsPlayer_resumeAudioDecoding(player->handle);
1962 }
1963 if (player->has_video) {
1964 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08001965 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001966 AmTsPlayer_stopVideoDecoding(player->handle);
1967 }
1968 if (player->has_audio) {
1969 player->has_audio = DVR_FALSE;
1970 AmTsPlayer_stopAudioDecoding(player->handle);
1971 }
hualing chendf118dd2020-05-21 15:49:11 +08001972 if (player->has_ad_audio) {
1973 player->has_ad_audio =DVR_FALSE;
1974 AmTsPlayer_disableADMix(player->handle);
1975 }
hualing chen266b9502020-04-04 17:39:39 +08001976
hualing chen86e7d482020-01-16 15:13:33 +08001977 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001978 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1979 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1980 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001981 player->cur_segment_id = UINT64_MAX;
1982 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001983 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08001984 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08001985 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001986 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001987}
1988/**\brief Start play audio
1989 * \param[in] handle playback handle
1990 * \param[in] params audio playback params,contains fmt and pid...
1991 * \retval DVR_SUCCESS On success
1992 * \return Error code
1993 */
hualing chen2aba4022020-03-02 13:49:55 +08001994
hualing chendf118dd2020-05-21 15:49:11 +08001995int 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 +08001996 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001997
1998 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001999 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002000 return DVR_FAILURE;
2001 }
hualing chen86e7d482020-01-16 15:13:33 +08002002 _start_playback_thread(handle);
2003 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002004 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002005 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002006
2007 if (VALID_PID(param->pid)) {
2008 DVR_PB_DG(1, "start audio");
2009 player->has_audio = DVR_TRUE;
2010 AmTsPlayer_setAudioParams(player->handle, param);
2011 AmTsPlayer_startAudioDecoding(player->handle);
2012 }
2013 if (VALID_PID(adparam->pid)) {
2014 player->has_ad_audio = DVR_TRUE;
2015 DVR_PB_DG(1, "start ad audio");
2016 AmTsPlayer_setADParams(player->handle, adparam);
2017 AmTsPlayer_enableADMix(player->handle);
2018 }
2019
hualing chen86e7d482020-01-16 15:13:33 +08002020 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002021 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
2022 player->cmd.state = DVR_PLAYBACK_STATE_START;
2023 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002024 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002025 pthread_mutex_unlock(&player->lock);
2026 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002027}
2028/**\brief Stop play audio
2029 * \param[in] handle playback handle
2030 * \retval DVR_SUCCESS On success
2031 * \return Error code
2032 */
hualing chen040df222020-01-17 13:35:02 +08002033int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2034 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002035
2036 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002037 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002038 return DVR_FAILURE;
2039 }
2040
hualing chen2aba4022020-03-02 13:49:55 +08002041 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002042 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002043 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2044 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002045 //destory thread
2046 _stop_playback_thread(handle);
2047 } else {
2048 //do nothing.video is playing
2049 }
hualing chen7a56cba2020-04-14 14:09:27 +08002050 DVR_PB_DG(1, "lock");
2051 pthread_mutex_lock(&player->lock);
2052
hualing chenf00cdc82020-06-10 14:23:35 +08002053 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002054 player->has_audio = DVR_FALSE;
2055 AmTsPlayer_stopAudioDecoding(player->handle);
2056 }
hualing chen87072a82020-03-12 16:20:12 +08002057
hualing chendf118dd2020-05-21 15:49:11 +08002058 if (player->has_ad_audio) {
2059 player->has_ad_audio =DVR_FALSE;
2060 AmTsPlayer_disableADMix(player->handle);
2061 }
2062
hualing chen87072a82020-03-12 16:20:12 +08002063 player->cmd.last_cmd = player->cmd.cur_cmd;
2064 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2065
hualing chen4b7c15d2020-04-07 16:13:48 +08002066 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002067 pthread_mutex_unlock(&player->lock);
2068 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002069}
2070/**\brief Start play video
2071 * \param[in] handle playback handle
2072 * \param[in] params video playback params,contains fmt and pid...
2073 * \retval DVR_SUCCESS On success
2074 * \return Error code
2075 */
hualing chen2aba4022020-03-02 13:49:55 +08002076int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002077 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002078
2079 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002080 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002081 return DVR_FAILURE;
2082 }
2083
hualing chen86e7d482020-01-16 15:13:33 +08002084 _start_playback_thread(handle);
2085 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002086 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002087 pthread_mutex_lock(&player->lock);
2088 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002089 AmTsPlayer_setVideoParams(player->handle, param);
2090 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002091
2092 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002093 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002094 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002095 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002096 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2097 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002098 }
2099 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002100 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2101 player->cmd.state = DVR_PLAYBACK_STATE_START;
2102 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002103 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002104 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002105 return DVR_SUCCESS;
2106}
2107/**\brief Stop play video
2108 * \param[in] handle playback handle
2109 * \retval DVR_SUCCESS On success
2110 * \return Error code
2111 */
hualing chen040df222020-01-17 13:35:02 +08002112int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2113 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002114
2115 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002116 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002117 return DVR_FAILURE;
2118 }
2119
hualing chen86e7d482020-01-16 15:13:33 +08002120 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002121 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2122 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002123 //destory thread
2124 _stop_playback_thread(handle);
2125 } else {
2126 //do nothing.audio is playing
2127 }
hualing chen7a56cba2020-04-14 14:09:27 +08002128
2129 DVR_PB_DG(1, "lock");
2130 pthread_mutex_lock(&player->lock);
2131
hualing chen87072a82020-03-12 16:20:12 +08002132 player->has_video = DVR_FALSE;
2133
2134 AmTsPlayer_stopVideoDecoding(player->handle);
2135 //playback_device_video_stop(player->handle);
2136
2137 player->cmd.last_cmd = player->cmd.cur_cmd;
2138 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2139
hualing chen4b7c15d2020-04-07 16:13:48 +08002140 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002141 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002142 return DVR_SUCCESS;
2143}
2144/**\brief Pause play
2145 * \param[in] handle playback handle
2146 * \param[in] flush whether its internal buffers should be flushed
2147 * \retval DVR_SUCCESS On success
2148 * \return Error code
2149 */
hualing chen040df222020-01-17 13:35:02 +08002150int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2151 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002152
2153 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002154 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002155 return DVR_FAILURE;
2156 }
hualing chenf00cdc82020-06-10 14:23:35 +08002157 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
2158 DVR_PB_DG(1, "player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002159 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002160 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002161 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002162 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002163 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002164 if (player->has_video)
2165 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002166 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002167 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002168
2169 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002170 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2171 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2172 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2173 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002174 } else {
2175 player->cmd.last_cmd = player->cmd.cur_cmd;
2176 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2177 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2178 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002179 }
hualing chen86e7d482020-01-16 15:13:33 +08002180 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002181 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002182
hualing chen86e7d482020-01-16 15:13:33 +08002183 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002184}
2185
hualing chen5cbe1a62020-02-10 16:36:36 +08002186//not add lock
2187static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2188{
2189 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2190
hualing chena540a7e2020-03-27 16:44:05 +08002191 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002192 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002193 return DVR_FAILURE;
2194 }
2195
hualing chen5cbe1a62020-02-10 16:36:36 +08002196 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002197 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002198 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002199 am_tsplayer_video_params vparams;
2200 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002201 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002202 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002203
hualing chendf118dd2020-05-21 15:49:11 +08002204 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002205 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002206 pthread_mutex_unlock(&player->lock);
2207
2208 switch (cmd) {
2209 case DVR_PLAYBACK_CMD_AVRESTART:
2210 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002211 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002212 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002213 break;
2214 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002215 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2216 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002217 break;
2218 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002219 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002220 break;
2221 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002222 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002223 break;
2224 case DVR_PLAYBACK_CMD_ARESTART:
2225 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002226 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002227 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002228 break;
2229 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002230 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002231 break;
2232 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002233 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002234 break;
2235 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002236 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2237 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2238 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002239 break;
2240 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002241 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2242 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002243 break;
2244 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002245 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2246 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002247 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002248 break;
2249 case DVR_PLAYBACK_CMD_STOP:
2250 break;
2251 case DVR_PLAYBACK_CMD_START:
2252 break;
2253 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002254 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2255 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002256 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002257 break;
2258 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002259 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2260 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002261 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002262 break;
2263 case DVR_PLAYBACK_CMD_FF:
2264 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002265 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002266 break;
2267 default:
2268 break;
2269 }
2270 return DVR_SUCCESS;
2271}
2272
2273/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002274 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002275 * \retval DVR_SUCCESS On success
2276 * \return Error code
2277 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002278int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2279 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2280
hualing chena540a7e2020-03-27 16:44:05 +08002281 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002282 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002283 return DVR_FAILURE;
2284 }
2285
hualing chen5cbe1a62020-02-10 16:36:36 +08002286 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002287 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002288 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002289 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002290 DVR_PB_DG(1, "dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002291 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2292 AmTsPlayer_resumeVideoDecoding(player->handle);
2293 }
2294 if (player->has_audio) {
2295 AmTsPlayer_resumeAudioDecoding(player->handle);
2296 }
2297 //check is has audio param,if has audio .we need start audio,
2298 //we will stop audio when ff fb, if reach end, we will pause.so we need
2299 //start audio when resume play
2300
2301 am_tsplayer_video_params vparams;
2302 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002303 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002304 uint64_t segmentid = player->cur_segment_id;
hualing chendf118dd2020-05-21 15:49:11 +08002305 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002306 //valid audio pid, start audio
hualing chenc70a8df2020-05-12 19:23:11 +08002307 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 +08002308 player->has_audio = DVR_TRUE;
2309 AmTsPlayer_setAudioParams(player->handle, &aparams);
2310 AmTsPlayer_startAudioDecoding(player->handle);
2311 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002312 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 +08002313 }
hualing chendf118dd2020-05-21 15:49:11 +08002314
2315 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2316 player->has_ad_audio = DVR_TRUE;
2317 DVR_PB_DG(1, "start ad audio");
2318 AmTsPlayer_setADParams(player->handle, &adparams);
2319 AmTsPlayer_enableADMix(player->handle);
2320 }
2321
hualing chen87072a82020-03-12 16:20:12 +08002322 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2323 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2324 player->cmd.state = DVR_PLAYBACK_STATE_START;
2325 player->state = DVR_PLAYBACK_STATE_START;
2326 } else {
2327 player->cmd.last_cmd = player->cmd.cur_cmd;
2328 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2329 player->cmd.state = DVR_PLAYBACK_STATE_START;
2330 player->state = DVR_PLAYBACK_STATE_START;
2331 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002332 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002333 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002334 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
hualing chene41f4372020-06-06 16:29:17 +08002335 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002336 DVR_PB_DG(1, "dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002337 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002338 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002339 }
hualing chen041c4092020-04-05 15:11:50 +08002340 if (player->has_audio)
2341 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002342 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002343 player->cmd.state = DVR_PLAYBACK_STATE_START;
2344 player->state = DVR_PLAYBACK_STATE_START;
hualing chen9811b212020-10-29 11:21:44 +08002345 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2346 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002347 } else {
2348 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2349 {
2350 pthread_mutex_lock(&player->lock);
2351 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002352 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002353 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2354 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002355 if (player->has_video) {
2356 AmTsPlayer_resumeVideoDecoding(player->handle);
2357 }
2358 if (player->has_audio)
2359 AmTsPlayer_resumeAudioDecoding(player->handle);
2360
hualing chen041c4092020-04-05 15:11:50 +08002361 pthread_mutex_unlock(&player->lock);
2362 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002363 }
2364 return DVR_SUCCESS;
2365}
2366
hualing chena540a7e2020-03-27 16:44:05 +08002367static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2368
2369 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2370 DVR_PlaybackSegmentInfo_t *segment = NULL;
2371 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2372 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2373
2374 list_for_each_entry(segment, &player->segment_list, head)
2375 {
2376 if (segment->segment_id == segment_id) {
2377 cur_segment = segment;
2378 }
2379 if (segment->segment_id == set_seg_id) {
2380 set_segment = segment;
2381 }
2382 if (cur_segment != NULL && set_segment != NULL) {
2383 break;
2384 }
2385 }
2386 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002387 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002388 return DVR_TRUE;
2389 }
2390 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2391 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2392 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2393 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002394 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 +08002395 return DVR_TRUE;
2396 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002397 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002398 return DVR_FALSE;
2399}
2400
hualing chen5cbe1a62020-02-10 16:36:36 +08002401/**\brief seek
2402 * \param[in] handle playback handle
2403 * \param[in] time_offset time offset base cur segment
2404 * \retval DVR_SUCCESS On success
2405 * \return Error code
2406 */
hualing chencc91e1c2020-02-28 13:26:17 +08002407int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002408 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002409
2410 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002411 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002412 return DVR_FAILURE;
2413 }
2414
hualing chen4b7c15d2020-04-07 16:13:48 +08002415 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 +08002416 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002417
hualing chen86e7d482020-01-16 15:13:33 +08002418 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002419 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002420 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002421
hualing chen5cbe1a62020-02-10 16:36:36 +08002422 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002423 int ret = _dvr_open_segment(handle, segment_id);
2424 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002425 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002426 pthread_mutex_unlock(&player->lock);
2427 return DVR_FAILURE;
2428 }
2429 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2430 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002431 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002432 //pthread_mutex_unlock(&player->lock);
2433 //return DVR_SUCCESS;
2434 time_offset = _dvr_get_end_time(handle);
2435 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002436 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002437 time_offset = _dvr_get_end_time(handle);
hualing chen87072a82020-03-12 16:20:12 +08002438 pthread_mutex_unlock(&player->lock);
2439 return DVR_FAILURE;
2440 }
2441 }
2442
hualing chen4b7c15d2020-04-07 16:13:48 +08002443 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 +08002444 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002445 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2446 //forward playback.not seek end of file
2447 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2448 //default -2000ms
2449 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2450 }
hualing chen86e7d482020-01-16 15:13:33 +08002451 }
hualing chen2aba4022020-03-02 13:49:55 +08002452 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002453 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002454 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002455 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002456 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 +08002457 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002458 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002459
hualing chen2aba4022020-03-02 13:49:55 +08002460 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002461
2462 player->last_send_time_id = UINT64_MAX;
2463
hualing chen2aba4022020-03-02 13:49:55 +08002464 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002465 player->fffb_current = _dvr_time_getClock();
2466 player->fffb_start = player->fffb_current;
2467 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2468 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002469 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002470 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002471 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002472 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002473 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002474 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002475 }
hualing chen86e7d482020-01-16 15:13:33 +08002476 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002477 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 +08002478 if (player->has_video) {
2479 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002480 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002481 }
2482
2483 if (player->has_audio) {
2484 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002485 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002486 }
hualing chendf118dd2020-05-21 15:49:11 +08002487 if (player->has_ad_audio) {
2488 player->has_ad_audio =DVR_FALSE;
2489 AmTsPlayer_disableADMix(player->handle);
2490 }
2491
hualing chen86e7d482020-01-16 15:13:33 +08002492 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002493 am_tsplayer_video_params vparams;
2494 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002495 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002496
hualing chen040df222020-01-17 13:35:02 +08002497 player->cur_segment_id = segment_id;
2498
2499 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002500 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002501 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002502 //start audio and video
Zhiqiang Han9adc9722020-11-11 18:38:10 +08002503 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08002504 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002505 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 +08002506 pthread_mutex_unlock(&player->lock);
2507 return -1;
2508 }
2509 //add
hualing chen040df222020-01-17 13:35:02 +08002510 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002511 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002512 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002513 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08002514 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002515 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002516 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002517 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002518 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002519 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002520 }
hualing chen2aba4022020-03-02 13:49:55 +08002521 AmTsPlayer_setVideoParams(player->handle, &vparams);
2522 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002523 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
2524 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
2525 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2526 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2527 AmTsPlayer_stopFast(player->handle);
2528 }
hualing chen266b9502020-04-04 17:39:39 +08002529 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002530 }
hualing chene41f4372020-06-06 16:29:17 +08002531 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002532 DVR_PB_DG(1, "start audio seek");
hualing chen2aba4022020-03-02 13:49:55 +08002533 AmTsPlayer_setAudioParams(player->handle, &aparams);
2534 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002535 player->has_audio = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002536 }
hualing chene41f4372020-06-06 16:29:17 +08002537 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08002538 player->has_ad_audio = DVR_TRUE;
2539 DVR_PB_DG(1, "start ad audio");
2540 AmTsPlayer_setADParams(player->handle, &adparams);
2541 AmTsPlayer_enableADMix(player->handle);
2542 }
hualing chen86e7d482020-01-16 15:13:33 +08002543 }
hualing chene41f4372020-06-06 16:29:17 +08002544 if (player->state == DVR_PLAYBACK_STATE_PAUSE /*&&
hualing chen2aba4022020-03-02 13:49:55 +08002545 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2546 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2547 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chene41f4372020-06-06 16:29:17 +08002548 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))*/) {
hualing chen2aba4022020-03-02 13:49:55 +08002549 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2550 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002551 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002552 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2553 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002554 player->speed > 1.0f||
2555 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002556 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002557 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002558 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002559 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002560 player->cmd.last_cmd = player->cmd.cur_cmd;
2561 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2562 player->cmd.state = DVR_PLAYBACK_STATE_START;
2563 player->state = DVR_PLAYBACK_STATE_START;
2564 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002565 player->last_send_time_id = UINT64_MAX;
2566 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002567 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002568
2569 return DVR_SUCCESS;
2570}
hualing chen5cbe1a62020-02-10 16:36:36 +08002571
hualing chen5cbe1a62020-02-10 16:36:36 +08002572static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2573 //get cur time of segment
2574 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002575
2576 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002577 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002578 return DVR_FAILURE;
2579 }
2580
hualing chen31140872020-03-25 12:29:26 +08002581 int64_t cache = 0;//defalut es buf cache 500ms
2582 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002583 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002584 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2585 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen2aba4022020-03-02 13:49:55 +08002586 pthread_mutex_unlock(&player->segment_lock);
hualing chenfbf8e022020-06-15 13:43:11 +08002587 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 +08002588 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2589 cache = 0;
2590 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002591 int cur_time = (int)(cur > cache ? cur - cache : 0);
2592 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002593}
2594
2595//get current segment current pcr time of read pos
2596static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2597 //get cur time of segment
2598 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002599
2600 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002601 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002602 return DVR_FAILURE;
2603 }
2604
hualing chen2aba4022020-03-02 13:49:55 +08002605 pthread_mutex_lock(&player->segment_lock);
2606 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002607 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002608 pthread_mutex_unlock(&player->segment_lock);
2609 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002610}
2611
hualing chen4b7c15d2020-04-07 16:13:48 +08002612#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002613//start replay
2614static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2615
2616 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2617 //calculate pcr seek time
2618 int t_diff = 0;
2619 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002620
2621 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002622 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002623 return DVR_FAILURE;
2624 }
2625
hualing chen5cbe1a62020-02-10 16:36:36 +08002626 if (player->fffb_start == -1) {
2627 //set fffb start time ms
2628 player->fffb_start = _dvr_time_getClock();
2629 player->fffb_current = player->fffb_start;
2630 //get segment current time pos
2631 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002632 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 +08002633 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08002634 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08002635 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002636 } else {
2637 player->fffb_current = _dvr_time_getClock();
2638 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002639 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002640 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002641 if (seek_time <= 0) {
2642 //need seek to pre one segment
2643 seek_time = 0;
2644 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002645 //seek segment pos
2646 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002647 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002648 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08002649 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2650 //set seek time to 0;
2651 DVR_PB_DG(1, "segment seek to 0 at fb mode [%d]id[%lld]", seek_time, player->cur_segment_id);
2652 seek_time = 0;
2653 }
hualing chen041c4092020-04-05 15:11:50 +08002654 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2655 seek_time = 0;
2656 }
hualing chen2aba4022020-03-02 13:49:55 +08002657 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002658 } else {
2659 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002660 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002661 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002662 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 +08002663 }
hualing chen2aba4022020-03-02 13:49:55 +08002664 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002665}
2666
2667
2668//start replay
2669static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2670 //
2671 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002672
2673 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002674 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002675 return DVR_FAILURE;
2676 }
2677
hualing chen5cbe1a62020-02-10 16:36:36 +08002678 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002679 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002680 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002681 AmTsPlayer_stopVideoDecoding(player->handle);
2682 }
2683 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002684 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002685 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002686 AmTsPlayer_stopAudioDecoding(player->handle);
2687 }
hualing chendf118dd2020-05-21 15:49:11 +08002688 if (player->has_ad_audio) {
2689 DVR_PB_DG(1, "fffb stop audio");
2690 player->has_ad_audio =DVR_FALSE;
2691 AmTsPlayer_disableADMix(player->handle);
2692 }
hualing chen2aba4022020-03-02 13:49:55 +08002693
hualing chen5cbe1a62020-02-10 16:36:36 +08002694 //start video and audio
2695
hualing chen2aba4022020-03-02 13:49:55 +08002696 am_tsplayer_video_params vparams;
2697 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002698 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002699 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002700
2701 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002702 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002703 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002704 //start audio and video
2705 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2706 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002707 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002708 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002709 return -1;
2710 }
2711
2712 if (VALID_PID(vparams.pid)) {
2713 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002714 DVR_PB_DG(1, "fffb start video");
hualing chen0888c032020-12-18 17:54:57 +08002715 //DVR_PB_DG(1, "fffb start video and save last frame");
2716 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08002717 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002718 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2719 AmTsPlayer_setVideoParams(player->handle, &vparams);
2720 AmTsPlayer_startVideoDecoding(player->handle);
2721 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002722 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002723 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002724 }
hualing chen31140872020-03-25 12:29:26 +08002725 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08002726 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002727 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002728 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002729 return 0;
2730}
2731
2732static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2733 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002734 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
2739 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002740 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002741 pthread_mutex_lock(&player->lock);
2742
hualing chen2aba4022020-03-02 13:49:55 +08002743 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002744 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 +08002745
hualing chen87072a82020-03-12 16:20:12 +08002746 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2747 //seek time set 0
2748 seek_time = 0;
2749 }
hualing chen041c4092020-04-05 15:11:50 +08002750 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002751 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2752 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002753 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002754 pthread_mutex_unlock(&player->lock);
2755 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002756 //send event here and pause
2757 DVR_Play_Notify_t notify;
2758 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002759 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002760 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08002761 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08002762 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 +08002763 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002764 return DVR_SUCCESS;
2765 }
hualing chen2932d372020-04-29 13:44:00 +08002766 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002767 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002768 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002769 }
2770 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002771 _dvr_playback_fffb_replay(handle);
2772
2773 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002774 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002775
hualing chen5cbe1a62020-02-10 16:36:36 +08002776 return DVR_SUCCESS;
2777}
2778
hualing chen87072a82020-03-12 16:20:12 +08002779//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002780static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002781 //
2782 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002783
2784 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002785 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002786 return DVR_FAILURE;
2787 }
2788
hualing chen5cbe1a62020-02-10 16:36:36 +08002789 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002790 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002791 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002792 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002793 }
2794
2795 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002796 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002797 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002798 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002799 //start video and audio
2800
hualing chen2aba4022020-03-02 13:49:55 +08002801 am_tsplayer_video_params vparams;
2802 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002803 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002804 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002805
2806 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002807 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08002808 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002809 //start audio and video
2810 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002811 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002812 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002813 return -1;
2814 }
2815
2816 if (VALID_PID(vparams.pid)) {
2817 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002818 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002819 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002820 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002821 }
hualing chen266b9502020-04-04 17:39:39 +08002822 else {
hualing chen2aba4022020-03-02 13:49:55 +08002823 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002824 }
hualing chen2aba4022020-03-02 13:49:55 +08002825 AmTsPlayer_setVideoParams(player->handle, &vparams);
2826 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002827 }
hualing chena540a7e2020-03-27 16:44:05 +08002828
2829 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08002830 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08002831 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002832 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002833 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002834 if (VALID_PID(aparams.pid)) {
2835 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002836 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08002837 AmTsPlayer_setAudioParams(player->handle, &aparams);
Zhiqiang Hane013e3e2020-12-03 13:34:56 +08002838 AmTsPlayer_startAudioDecoding(player->handle);
hualing chena540a7e2020-03-27 16:44:05 +08002839 }
hualing chendf118dd2020-05-21 15:49:11 +08002840 if (VALID_PID(adparams.pid)) {
2841 player->has_ad_audio = DVR_TRUE;
2842 DVR_PB_DG(1, "start ad audio");
2843 AmTsPlayer_setADParams(player->handle, &adparams);
2844 AmTsPlayer_enableADMix(player->handle);
2845 }
2846
hualing chen7a56cba2020-04-14 14:09:27 +08002847 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002848 AmTsPlayer_stopFast(player->handle);
2849 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2850 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2851 }
hualing chen2aba4022020-03-02 13:49:55 +08002852 player->cmd.last_cmd = player->cmd.cur_cmd;
2853 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002854 player->cmd.state = DVR_PLAYBACK_STATE_START;
2855 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002856 return 0;
2857}
2858
2859
hualing chenb31a6c62020-01-13 17:27:00 +08002860/**\brief Set play speed
2861 * \param[in] handle playback handle
2862 * \param[in] speed playback speed
2863 * \retval DVR_SUCCESS On success
2864 * \return Error code
2865 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002866int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2867
2868 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002869
2870 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002871 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002872 return DVR_FAILURE;
2873 }
2874
hualing chen4b7c15d2020-04-07 16:13:48 +08002875 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002876 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002877 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002878 return DVR_FAILURE;
2879 }
hualing chenf00cdc82020-06-10 14:23:35 +08002880 if (speed.speed.speed == player->cmd.speed.speed.speed) {
2881 DVR_PB_DG(1, " func: eq speed [%d]", speed.speed.speed);
2882 return DVR_SUCCESS;
2883 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002884 pthread_mutex_lock(&player->lock);
2885 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2886 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2887 player->cmd.last_cmd = player->cmd.cur_cmd;
2888 }
hualing chene41f4372020-06-06 16:29:17 +08002889
hualing chen31140872020-03-25 12:29:26 +08002890 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08002891 IS_KERNEL_SPEED(speed.speed.speed) ) {
2892 //case 1. not start play.only set speed
2893 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2894 //only set speed.and return;
2895 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
2896 player->cmd.speed.speed = speed.speed;
2897 player->speed = (float)speed.speed.speed/(float)100;
2898 player->fffb_play = DVR_FALSE;
2899 pthread_mutex_unlock(&player->lock);
2900 return DVR_SUCCESS;
2901 }
2902 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08002903 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2904 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002905 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002906 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2907 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002908 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002909 AmTsPlayer_stopFast(player->handle);
2910 pthread_mutex_unlock(&player->lock);
2911 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2912 pthread_mutex_lock(&player->lock);
2913 } else {
2914 //set play speed and if audio is start, stop audio.
2915 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002916 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002917 AmTsPlayer_stopAudioDecoding(player->handle);
2918 player->has_audio = DVR_FALSE;
2919 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002920 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002921 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002922 }
hualing chenbcada022020-04-22 14:27:01 +08002923 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08002924 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002925 player->cmd.speed.speed = speed.speed;
2926 player->speed = (float)speed.speed.speed/(float)100;
2927 pthread_mutex_unlock(&player->lock);
2928 return DVR_SUCCESS;
2929 }
hualing chen31140872020-03-25 12:29:26 +08002930 //case 3 fffb mode
2931 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2932 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2933 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002934 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002935 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002936 player->cmd.speed.speed = speed.speed;
2937 player->speed = (float)speed.speed.speed/(float)100;
2938 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08002939 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002940 pthread_mutex_unlock(&player->lock);
2941 return DVR_SUCCESS;
2942 }
2943 }
2944 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002945 IS_KERNEL_SPEED(speed.speed.speed)) {
2946 //case 1. cur speed is kernel support speed,set kernel speed.
2947 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002948 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002949 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2950 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002951 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002952 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08002953 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08002954 } else {
2955 //set play speed and if audio is start, stop audio.
2956 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002957 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002958 AmTsPlayer_stopAudioDecoding(player->handle);
2959 player->has_audio = DVR_FALSE;
2960 }
hualing chenf00cdc82020-06-10 14:23:35 +08002961 DVR_PB_DG(1, "start fast");
2962 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08002963 }
hualing chena540a7e2020-03-27 16:44:05 +08002964 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002965 player->cmd.speed.speed = speed.speed;
2966 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08002967 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002968 pthread_mutex_unlock(&player->lock);
2969 return DVR_SUCCESS;
2970 }
2971 //case 2 fffb mode
2972 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2973 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2974 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002975 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002976 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002977 player->cmd.speed.speed = speed.speed;
2978 player->speed = (float)speed.speed.speed/(float)100;
2979 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08002980 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002981 pthread_mutex_unlock(&player->lock);
2982 return DVR_SUCCESS;
2983 }
hualing chen31140872020-03-25 12:29:26 +08002984 }
hualing chena540a7e2020-03-27 16:44:05 +08002985 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2986 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08002987 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08002988 } else {
hualing chen31140872020-03-25 12:29:26 +08002989 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002990 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2991 else
2992 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08002993 player->fffb_play = DVR_TRUE;
2994 }
2995 DVR_Bool_t init_last_time = DVR_FALSE;
2996 if (player->speed > 0.0f && speed.speed.speed < 0) {
2997 init_last_time = DVR_TRUE;
2998 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
2999 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003000 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003001 player->cmd.speed.mode = speed.mode;
3002 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003003 player->speed = (float)speed.speed.speed/(float)100;
3004 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003005 _dvr_init_fffb_t(handle);
3006 if (init_last_time == DVR_TRUE)
3007 player->last_send_time_id = UINT64_MAX;
3008
hualing chen87072a82020-03-12 16:20:12 +08003009 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003010 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3011 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003012 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003013 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003014 _dvr_playback_replay(handle, DVR_FALSE);
3015 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3016 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
3017 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08003018 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003019 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003020 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08003021 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003022 return DVR_SUCCESS;
3023}
hualing chen2932d372020-04-29 13:44:00 +08003024
hualing chenb31a6c62020-01-13 17:27:00 +08003025/**\brief Get playback status
3026 * \param[in] handle playback handle
3027 * \param[out] p_status playback status
3028 * \retval DVR_SUCCESS On success
3029 * \return Error code
3030 */
hualing chen2932d372020-04-29 13:44:00 +08003031static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3032 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003033//
3034 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003035
3036 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003037 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003038 return DVR_FAILURE;
3039 }
hualing chen2932d372020-04-29 13:44:00 +08003040 if (is_lock ==DVR_TRUE)
3041 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003042 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003043 //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 +08003044 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3045 player->state == DVR_PLAYBACK_STATE_START) {
3046 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3047 }
hualing chen041c4092020-04-05 15:11:50 +08003048
hualing chencc91e1c2020-02-28 13:26:17 +08003049 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08003050 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003051 if (player->last_send_time_id == UINT64_MAX) {
3052 player->last_send_time_id = player->cur_segment_id;
3053 player->last_cur_time = p_status->time_cur;
3054 }
3055 if (player->last_send_time_id == player->cur_segment_id) {
3056 if (player->speed > 0.0f ) {
3057 //ff
3058 if (p_status->time_cur < player->last_cur_time ) {
3059 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);
3060 p_status->time_cur = player->last_cur_time;
3061 } else {
3062 player->last_cur_time = p_status->time_cur;
3063 }
hualing chene41f4372020-06-06 16:29:17 +08003064 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003065 //fb
3066 if (p_status->time_cur > player->last_cur_time ) {
3067 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 );
3068 p_status->time_cur = player->last_cur_time;
3069 } else {
3070 player->last_cur_time = p_status->time_cur;
3071 }
3072 }
3073 } else {
3074 player->last_cur_time = p_status->time_cur;
3075 }
3076 player->last_send_time_id = player->cur_segment_id;
hualing chen041c4092020-04-05 15:11:50 +08003077 p_status->segment_id = player->cur_segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003078
hualing chen5cbe1a62020-02-10 16:36:36 +08003079 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003080 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003081 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08003082 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 +08003083 _dvr_playback_state_toString(player->state),
3084 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08003085 p_status->time_cur, p_status->time_end,
3086 p_status->segment_id,player->play_flag,
hualing chen2932d372020-04-29 13:44:00 +08003087 player->speed,
3088 is_lock);
3089 if (is_lock ==DVR_TRUE)
3090 pthread_mutex_unlock(&player->lock);
3091 return DVR_SUCCESS;
3092}
3093
3094
3095/**\brief Get playback status
3096 * \param[in] handle playback handle
3097 * \param[out] p_status playback status
3098 * \retval DVR_SUCCESS On success
3099 * \return Error code
3100 */
3101int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3102 DVR_PlaybackStatus_t *p_status) {
3103//
3104 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3105
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003106 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3107
hualing chen2932d372020-04-29 13:44:00 +08003108 if (player == NULL) {
3109 DVR_PB_DG(1, "player is NULL");
3110 return DVR_FAILURE;
3111 }
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003112 pthread_mutex_lock(&player->lock);
3113 if (!player->has_video && !player->has_audio)
3114 p_status->time_cur = 0;
3115 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08003116
hualing chenb31a6c62020-01-13 17:27:00 +08003117 return DVR_SUCCESS;
3118}
3119
hualing chen040df222020-01-17 13:35:02 +08003120void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
3121 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003122 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
3123 DVR_PB_DG(1, "segment flag: %d", segment->flags);
3124 DVR_PB_DG(1, "segment location: [%s]", segment->location);
3125 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
3126 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
3127 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3128 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 +08003129 }
hualing chenb31a6c62020-01-13 17:27:00 +08003130}
3131
hualing chen5cbe1a62020-02-10 16:36:36 +08003132int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003133 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003134
hualing chena540a7e2020-03-27 16:44:05 +08003135 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003136 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003137 return DVR_FAILURE;
3138 }
3139
hualing chen040df222020-01-17 13:35:02 +08003140 DVR_PlaybackSegmentInfo_t *segment;
3141 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003142 {
hualing chen040df222020-01-17 13:35:02 +08003143 if (segment_id >= 0) {
3144 if (segment->segment_id == segment_id) {
3145 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003146 break;
3147 }
3148 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003149 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003150 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003151 }
3152 }
3153 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003154}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003155
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003156int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003157{
3158 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3159 DVR_RETURN_IF_FALSE(player);
3160 DVR_RETURN_IF_FALSE(func);
3161
hualing chen4b7c15d2020-04-07 16:13:48 +08003162 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003163 pthread_mutex_lock(&player->lock);
3164
3165 player->dec_func = func;
3166 player->dec_userdata = userdata;
3167
3168 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003169 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003170 return DVR_SUCCESS;
3171}
3172
3173int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3174{
3175 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3176 DVR_RETURN_IF_FALSE(player);
3177 DVR_RETURN_IF_FALSE(p_secure_buf);
3178 DVR_RETURN_IF_FALSE(len);
3179
hualing chen4b7c15d2020-04-07 16:13:48 +08003180 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003181 pthread_mutex_lock(&player->lock);
3182
3183 player->is_secure_mode = 1;
3184 player->secure_buffer = p_secure_buf;
3185 player->secure_buffer_size = len;
3186
3187 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003188 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003189 return DVR_SUCCESS;
3190}