blob: d612410dd97a5f666d9a3e29704790434164a3df [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 }
200 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800201 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800202 break;
203 }
204 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800205 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800206 player->player_callback_func(player->player_callback_userdata, event);
207 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800208 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800209 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800210 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800211 }
212}
hualing chencc91e1c2020-02-28 13:26:17 +0800213
hualing chen5cbe1a62020-02-10 16:36:36 +0800214//convert video and audio fmt
215static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
216 int format = 0;
217 if (is_audio == DVR_FALSE) {
218 //for video fmt
219 switch (fmt)
220 {
221 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800222 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800223 break;
224 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800225 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800226 break;
227 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800228 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800229 break;
230 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800231 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800232 break;
hualing chena540a7e2020-03-27 16:44:05 +0800233 case DVR_VIDEO_FORMAT_VP9:
234 format = AV_VIDEO_CODEC_VP9;
235 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800236 }
237 } else {
238 //for audio fmt
239 switch (fmt)
240 {
241 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800242 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800243 break;
244 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800245 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800246 break;
247 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800248 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800249 break;
250 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800251 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800252 break;
hualing chena540a7e2020-03-27 16:44:05 +0800253 case DVR_AUDIO_FORMAT_AAC:
254 format = AV_AUDIO_CODEC_AAC;
255 break;
256 case DVR_AUDIO_FORMAT_LATM:
257 format = AV_AUDIO_CODEC_LATM;
258 break;
259 case DVR_AUDIO_FORMAT_PCM:
260 format = AV_AUDIO_CODEC_PCM;
261 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800262 }
263 }
264 return format;
265}
hualing chen040df222020-01-17 13:35:02 +0800266static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800267{
hualing chen040df222020-01-17 13:35:02 +0800268 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800269
hualing chena540a7e2020-03-27 16:44:05 +0800270 if (player == NULL || player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800271 return -1;
272
hualing chena540a7e2020-03-27 16:44:05 +0800273 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800274}
hualing chena540a7e2020-03-27 16:44:05 +0800275
hualing chen5cbe1a62020-02-10 16:36:36 +0800276//get sys time ms
277static int _dvr_time_getClock(void)
278{
279 struct timespec ts;
280 int ms;
281
282 clock_gettime(CLOCK_MONOTONIC, &ts);
283 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
284
285 return ms;
286}
hualing chen86e7d482020-01-16 15:13:33 +0800287
hualing chenb31a6c62020-01-13 17:27:00 +0800288
289//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800290static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800291{
hualing chen040df222020-01-17 13:35:02 +0800292 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800293
hualing chena540a7e2020-03-27 16:44:05 +0800294
295 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800296 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800297 return DVR_FAILURE;
298 }
299
hualing chen86e7d482020-01-16 15:13:33 +0800300 struct timespec ts;
301 clock_gettime(CLOCK_MONOTONIC, &ts);
302 //ms为毫秒,换算成秒
303 ts.tv_sec += ms/1000;
304 //在outtime的基础上,增加ms毫秒
305 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
306 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
307 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
308 //us的值有可能超过1秒,
309 ts.tv_sec += us / 1000000;
310 us = us % 1000000;
311 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800312 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
313 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800314}
hualing chen31140872020-03-25 12:29:26 +0800315//get tsplay delay time ms
316static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
317 DVR_Playback_t *player = (DVR_Playback_t *) handle;
318 int64_t cache = 0;
319 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800320 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800321 return 0;
322 }
323 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800324 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800325 return cache;
326}
hualing chenb31a6c62020-01-13 17:27:00 +0800327//send signal
hualing chen040df222020-01-17 13:35:02 +0800328static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800329{
hualing chen87072a82020-03-12 16:20:12 +0800330 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800331
332 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800333 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800334 return DVR_FAILURE;
335 }
336
hualing chen87072a82020-03-12 16:20:12 +0800337 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800338 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800339 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800340 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800341}
342
hualing chen2932d372020-04-29 13:44:00 +0800343//send playback event, need check is need lock first
344static 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 +0800345
346 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800347
348 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800349 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800350 return DVR_FAILURE;
351 }
352
hualing chencc91e1c2020-02-28 13:26:17 +0800353 switch (evt) {
354 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800355 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800356 break;
357 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
358 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800359 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800360 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800361 break;
362 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
363 break;
364 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
365 break;
366 case DVR_PLAYBACK_EVENT_NO_KEY:
367 break;
368 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800369 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800370 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800371 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800372 break;
373 case DVR_PLAYBACK_EVENT_REACHED_END:
374 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800375 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800376 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800377 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800378 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800379 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800380 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800381 default:
382 break;
383 }
384 if (player->openParams.event_fn != NULL)
385 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800386 return DVR_SUCCESS;
387}
hualing chen2932d372020-04-29 13:44:00 +0800388static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800389{
390 DVR_Play_Notify_t notify;
391 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
392 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
393 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800394 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800395 return DVR_SUCCESS;
396}
397
hualing chen2932d372020-04-29 13:44:00 +0800398static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800399{
400 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800401
hualing chen4b7c15d2020-04-07 16:13:48 +0800402 if (1) {
403 return DVR_SUCCESS;
404 }
hualing chena540a7e2020-03-27 16:44:05 +0800405 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800406 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800407 return DVR_FAILURE;
408 }
409
hualing chen6e4bfa52020-03-13 14:37:11 +0800410 if (player->send_time ==0) {
411 player->send_time = _dvr_time_getClock() + 1000;
412 } else if (player->send_time > _dvr_time_getClock()) {
413 return DVR_SUCCESS;
414 }
415 player->send_time = _dvr_time_getClock() + 1000;
416 DVR_Play_Notify_t notify;
417 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
418 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
419 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800420 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800421 return DVR_SUCCESS;
422}
423
hualing chencc91e1c2020-02-28 13:26:17 +0800424//check is ongoing segment
425static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
426
427 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800428 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800429
430 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800431 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800432 return DVR_FAILURE;
433 }
hualing chen87072a82020-03-12 16:20:12 +0800434 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800435 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800436 return DVR_FALSE;
437 }
hualing chencc91e1c2020-02-28 13:26:17 +0800438 return DVR_TRUE;
439}
hualing chen4b7c15d2020-04-07 16:13:48 +0800440
441
442static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
443 DVR_Playback_t *player = (DVR_Playback_t *) handle;
444 player->fffb_start = _dvr_time_getClock();
445 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
446 player->fffb_current = player->fffb_start;
447 //get segment current time pos
448 player->fffb_start_pcr = _dvr_get_cur_time(handle);
449 //player->fffb_current = -1;
450 //player->fffb_start = -1;
451 //player->fffb_start_pcr = -1;
452 player->next_fffb_time = _dvr_time_getClock();
453
454 return DVR_SUCCESS;
455}
456
hualing chen2aba4022020-03-02 13:49:55 +0800457static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
458 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800459 player->fffb_start = _dvr_time_getClock();
460 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
461 player->fffb_current = player->fffb_start;
462 //get segment current time pos
463 player->fffb_start_pcr = _dvr_get_cur_time(handle);
464 //player->fffb_current = -1;
465 //player->fffb_start = -1;
466 //player->fffb_start_pcr = -1;
hualing chen2aba4022020-03-02 13:49:55 +0800467 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800468 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800469 return DVR_SUCCESS;
470}
hualing chencc91e1c2020-02-28 13:26:17 +0800471//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800472static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
473
474 DVR_Playback_t *player = (DVR_Playback_t *) handle;
475 DVR_PlaybackSegmentInfo_t *segment;
476 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
477
hualing chena540a7e2020-03-27 16:44:05 +0800478 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800479 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800480 return DVR_FAILURE;
481 }
482
hualing chen87072a82020-03-12 16:20:12 +0800483 int found = 0;
484 int found_eq_id = 0;
485 list_for_each_entry(segment, &player->segment_list, head)
486 {
487 if (player->segment_is_open == DVR_FALSE) {
488 //get first segment from list, case segment is not open
489 if (!IS_FB(player->speed))
490 found = 1;
491 } else if (segment->segment_id == segmentid) {
492 //find cur segment, we need get next one
493 found_eq_id = 1;
494 if (!IS_FB(player->speed)) {
495 found = 1;
496 continue;
497 } else {
498 //if is fb mode.we need used pre segment
499 if (pre_segment != NULL) {
500 found = 1;
501 } else {
502 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800503 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800504 return DVR_FAILURE;
505 }
506 }
507 }
508 if (found == 1) {
509 found = 2;
510 break;
511 }
512 }
513 if (found != 2) {
514 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800515 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800516 return DVR_FAILURE;
517 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800518 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800519 return DVR_SUCCESS;
520}
521
522//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800523static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800524
hualing chen040df222020-01-17 13:35:02 +0800525 DVR_Playback_t *player = (DVR_Playback_t *) handle;
526 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800527 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800528
hualing chena540a7e2020-03-27 16:44:05 +0800529 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800530 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800531 return DVR_FAILURE;
532 }
533
hualing chen86e7d482020-01-16 15:13:33 +0800534 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800535 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800536
hualing chen040df222020-01-17 13:35:02 +0800537 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800538 {
hualing chencc91e1c2020-02-28 13:26:17 +0800539 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800540 //get first segment from list, case segment is not open
541 if (!IS_FB(player->speed))
542 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800543 } else if (segment->segment_id == player->cur_segment_id) {
544 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800545 found_eq_id = 1;
546 if (!IS_FB(player->speed)) {
547 found = 1;
548 continue;
549 } else {
550 //if is fb mode.we need used pre segment
551 if (pre_segment != NULL) {
552 found = 1;
553 } else {
554 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800555 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800556 return DVR_FAILURE;
557 }
558 }
hualing chen86e7d482020-01-16 15:13:33 +0800559 }
560 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800561 if (IS_FB(player->speed)) {
562 //used pre segment
563 segment = pre_segment;
564 }
hualing chencc91e1c2020-02-28 13:26:17 +0800565 //save segment info
566 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800567 player->last_segment.segment_id = player->cur_segment.segment_id;
568 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800569 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
570 //pids
571 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
572
hualing chen5cbe1a62020-02-10 16:36:36 +0800573 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800574 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800575 player->cur_segment_id = segment->segment_id;
576 player->cur_segment.segment_id = segment->segment_id;
577 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800578 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 +0800579 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800580 //pids
hualing chen040df222020-01-17 13:35:02 +0800581 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800582 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800583 break;
hualing chen86e7d482020-01-16 15:13:33 +0800584 }
hualing chen2aba4022020-03-02 13:49:55 +0800585 pre_segment = segment;
586 }
587 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
588 //used the last one segment to open
589 //get segment info
590 player->segment_is_open = DVR_TRUE;
591 player->cur_segment_id = pre_segment->segment_id;
592 player->cur_segment.segment_id = pre_segment->segment_id;
593 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800594 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 +0800595 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
596 //pids
597 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
598 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800599 }
600 if (found != 2) {
601 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800602 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800603 }
604 return DVR_SUCCESS;
605}
hualing chen040df222020-01-17 13:35:02 +0800606//open next segment to play,if reach list end return errro.
607static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800608{
hualing chen040df222020-01-17 13:35:02 +0800609 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800610 Segment_OpenParams_t params;
611 int ret = DVR_SUCCESS;
612
hualing chena540a7e2020-03-27 16:44:05 +0800613 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800614 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800615 return DVR_FAILURE;
616 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800617 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800618
619 ret = _dvr_get_next_segmentId(handle);
620 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800621 DVR_PB_DG(1, "not found segment info");
622 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800623 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800624 }
625
626 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800627 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800628 segment_close(player->r_handle);
629 player->r_handle = NULL;
630 }
631
632 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800633 //cp chur segment path to location
634 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800635 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800636 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800637 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
638
hualing chen86e7d482020-01-16 15:13:33 +0800639 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800640 if (ret == DVR_FAILURE) {
641 DVR_PB_DG(1, "open segment error");
642 }
hualing chen87072a82020-03-12 16:20:12 +0800643 pthread_mutex_unlock(&player->segment_lock);
644 int total = _dvr_get_end_time( handle);
645 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800646 if (IS_FB(player->speed)) {
647 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800648 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800649 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800650 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800651 }
hualing chen87072a82020-03-12 16:20:12 +0800652 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800653 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800654 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800655 return ret;
656}
657
hualing chen5cbe1a62020-02-10 16:36:36 +0800658//open next segment to play,if reach list end return errro.
659static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
660{
661 DVR_Playback_t *player = (DVR_Playback_t *) handle;
662 Segment_OpenParams_t params;
663 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800664 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800665 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800666 return DVR_FAILURE;
667 }
hualing chencc91e1c2020-02-28 13:26:17 +0800668 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800669 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800670 }
hualing chencc91e1c2020-02-28 13:26:17 +0800671 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800672 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800673 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800674 return DVR_FAILURE;
675 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800676 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800677 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800678
679 DVR_PlaybackSegmentInfo_t *segment;
680
681 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800682
hualing chen5cbe1a62020-02-10 16:36:36 +0800683 list_for_each_entry(segment, &player->segment_list, head)
684 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800685 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 +0800686 if (segment->segment_id == segment_id) {
687 found = 1;
688 }
689 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800690 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 +0800691 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800692 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800693 player->cur_segment_id = segment->segment_id;
694 player->cur_segment.segment_id = segment->segment_id;
695 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800696 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800697 //pids
698 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800699 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 +0800700 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800701 }
702 }
hualing chencc91e1c2020-02-28 13:26:17 +0800703 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800704 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800705 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800706 return DVR_FAILURE;
707 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800708 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800709 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800710 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800711 params.segment_id = (uint64_t)player->cur_segment.segment_id;
712 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800713 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 +0800714 if (player->r_handle != NULL) {
715 segment_close(player->r_handle);
716 player->r_handle = NULL;
717 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800718 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800719 if (ret == DVR_FAILURE) {
720 DVR_PB_DG(1, "segment opne error");
721 }
hualing chen2aba4022020-03-02 13:49:55 +0800722 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800723 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800724
hualing chen4b7c15d2020-04-07 16:13:48 +0800725 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 +0800726 return ret;
727}
728
729
730//get play info by segment id
731static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
732 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800733 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800734 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800735
736 DVR_Playback_t *player = (DVR_Playback_t *) handle;
737 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800738 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800739 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800740 return DVR_FAILURE;
741 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800742
743 int found = 0;
744
745 list_for_each_entry(segment, &player->segment_list, head)
746 {
hualing chen87072a82020-03-12 16:20:12 +0800747 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800748 //get first segment from list
749 found = 1;
750 }
751 if (segment->segment_id == segment_id) {
752 found = 1;
753 }
754 if (found == 1) {
755 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800756 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800757 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800758 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800759 player->cur_segment.segment_id = segment->segment_id;
760 player->cur_segment.flags = segment->flags;
761 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800762 player->cur_segment.pids.video.pid = segment->pids.video.pid;
763 player->cur_segment.pids.video.format = segment->pids.video.format;
764 player->cur_segment.pids.video.type = segment->pids.video.type;
765 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
766 player->cur_segment.pids.audio.format = segment->pids.audio.format;
767 player->cur_segment.pids.audio.type = segment->pids.audio.type;
768 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
769 player->cur_segment.pids.ad.format = segment->pids.ad.format;
770 player->cur_segment.pids.ad.type = segment->pids.ad.type;
771 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800772 //
hualing chen2aba4022020-03-02 13:49:55 +0800773 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800774 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800775 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800776 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800777 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
778 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800779 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 +0800780 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800781 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800782 }
783 }
hualing chencc91e1c2020-02-28 13:26:17 +0800784 if (found != 2) {
785 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800786 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800787 return DVR_FAILURE;
788 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800789
790 return DVR_SUCCESS;
791}
hualing chencc91e1c2020-02-28 13:26:17 +0800792static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
793 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800794 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800795 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800796 return DVR_FAILURE;
797 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800798
hualing chencc91e1c2020-02-28 13:26:17 +0800799 //compare cur segment
800 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
801 {
802 //check video pids, stop or restart
803 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
804 //check audio pids stop or restart
hualing chen7a56cba2020-04-14 14:09:27 +0800805 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 +0800806 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
807 //check sub audio pids stop or restart
808 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
809 //check pcr pids stop or restart
810 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
811 }
hualing chena540a7e2020-03-27 16:44:05 +0800812 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800813}
hualing chen5cbe1a62020-02-10 16:36:36 +0800814
hualing chencc91e1c2020-02-28 13:26:17 +0800815static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
816{
817 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800818 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800819 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800820 return DVR_FAILURE;
821 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800822 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 +0800823 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
824 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800825 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800826 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800827 AmTsPlayer_showVideo(player->handle);
828 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800829 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
830 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800831 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800832 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800833 AmTsPlayer_hideVideo(player->handle);
834 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800835 }
836 return DVR_SUCCESS;
837}
hualing chena540a7e2020-03-27 16:44:05 +0800838static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
839 DVR_Playback_t *player = (DVR_Playback_t *) handle;
840 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800841 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800842 return DVR_TRUE;
843 }
hualing chene41f4372020-06-06 16:29:17 +0800844 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE || 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800845 if (player->first_frame == 1) {
846 return DVR_TRUE;
847 } else {
848 return DVR_FALSE;
849 }
850 } else {
851 return DVR_TRUE;
852 }
853}
hualing chen86e7d482020-01-16 15:13:33 +0800854static void* _dvr_playback_thread(void *arg)
855{
hualing chen040df222020-01-17 13:35:02 +0800856 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800857 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800858 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800859 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800860 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800861
hualing chen39628212020-05-14 10:35:13 +0800862 #define MAX_REACHEND_TIMEOUT (3000)
863 int reach_end_timeout = 0;//ms
864 int cache_time = 0;
hualing chen6d24aa92020-03-23 18:43:47 +0800865 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800866 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800867 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800868 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800869 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
870
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800871 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800872 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800873 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chene41f4372020-06-06 16:29:17 +0800874 int retry_open_seg = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800875 if (player->is_secure_mode) {
876 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800877 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800878 return NULL;
879 }
880 }
hualing chen86e7d482020-01-16 15:13:33 +0800881 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800882 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800883 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800884 return NULL;
885 }
hualing chen2aba4022020-03-02 13:49:55 +0800886 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
887 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800888
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800889 dec_bufs.buf_data = malloc(dec_buf_size);
890 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800891 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800892 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800893 return NULL;
894 }
895 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
896 dec_bufs.buf_size = dec_buf_size;
897
hualing chencc91e1c2020-02-28 13:26:17 +0800898 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800899 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
900 }
hualing chen86e7d482020-01-16 15:13:33 +0800901
hualing chen86e7d482020-01-16 15:13:33 +0800902 if (ret != DVR_SUCCESS) {
903 if (buf != NULL) {
904 free(buf);
905 buf = NULL;
906 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800907 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800908 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800909 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800910 }
hualing chenfbf8e022020-06-15 13:43:11 +0800911 DVR_PB_DG(1, "player->vendor %d,player->has_video[%d] ", player->vendor, player->has_video);
912 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
913 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
914 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
915 player->first_trans_ok = DVR_TRUE;
916 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
917 }
hualing chencc91e1c2020-02-28 13:26:17 +0800918 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800919 //set video show
920 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800921
hualing chen86e7d482020-01-16 15:13:33 +0800922 int trick_stat = 0;
923 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800924
hualing chen86e7d482020-01-16 15:13:33 +0800925 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800926 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800927
hualing chen2aba4022020-03-02 13:49:55 +0800928 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
929 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800930 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800931 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +0800932 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +0800933 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800934 {
hualing chen2aba4022020-03-02 13:49:55 +0800935 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
936 if (trick_stat > 0) {
hualing chenbcada022020-04-22 14:27:01 +0800937 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 +0800938 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 +0800939 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +0800940 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800941 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800942 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
943 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800944 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
945 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chenbcada022020-04-22 14:27:01 +0800946 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 +0800947 //need change to pause state
948 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
949 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800950 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800951 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800952 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800953 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800954 AmTsPlayer_pauseVideoDecoding(player->handle);
955 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800956 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800957 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +0800958 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800959 }
960 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
961 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800962 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800963 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +0800964 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
965 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 +0800966 //used timeout wait need lock first,so we unlock and lock
967 //pthread_mutex_unlock(&player->lock);
968 //pthread_mutex_lock(&player->lock);
969 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
970 pthread_mutex_unlock(&player->lock);
971 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +0800972 } else if (_dvr_time_getClock() < player->next_fffb_time) {
973 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);
974 //used timeout wait need lock first,so we unlock and lock
975 //pthread_mutex_unlock(&player->lock);
976 //pthread_mutex_lock(&player->lock);
977 AmTsPlayer_pauseVideoDecoding(player->handle);
978 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
979 pthread_mutex_unlock(&player->lock);
980 continue;
981
hualing chen2aba4022020-03-02 13:49:55 +0800982 }
hualing chen2932d372020-04-29 13:44:00 +0800983 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 +0800984 pthread_mutex_unlock(&player->lock);
985 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800986 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800987 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
988 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800989 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +0800990 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +0800991 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800992 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800993 }else if (player->fffb_play == DVR_TRUE){
994 //for first into fffb when reset speed
995 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
996 _dvr_time_getClock() < player->next_fffb_time) {
997 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);
998 //used timeout wait need lock first,so we unlock and lock
999 //pthread_mutex_unlock(&player->lock);
1000 //pthread_mutex_lock(&player->lock);
1001 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1002 pthread_mutex_unlock(&player->lock);
1003 continue;
1004 }
hualing chen2932d372020-04-29 13:44:00 +08001005 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 +08001006 pthread_mutex_unlock(&player->lock);
1007 goto_rewrite = DVR_FALSE;
1008 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001009 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001010 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1011 player->first_frame = 0;
1012 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1013 pthread_mutex_lock(&player->lock);
1014 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001015 }
hualing chenb31a6c62020-01-13 17:27:00 +08001016 }
hualing chen86e7d482020-01-16 15:13:33 +08001017
hualing chen87072a82020-03-12 16:20:12 +08001018 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001019 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001020 DVR_PB_DG(1, "pause, continue");
hualing chen2932d372020-04-29 13:44:00 +08001021 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen87072a82020-03-12 16:20:12 +08001022 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1023 pthread_mutex_unlock(&player->lock);
1024 continue;
1025 }
hualing chen266b9502020-04-04 17:39:39 +08001026 //when seek action is done. we need drop write timeout data.
1027 if (player->drop_ts == DVR_TRUE) {
1028 goto_rewrite = DVR_FALSE;
1029 real_read = 0;
1030 player->drop_ts = DVR_FALSE;
1031 }
hualing chen2aba4022020-03-02 13:49:55 +08001032 if (goto_rewrite == DVR_TRUE) {
1033 goto_rewrite = DVR_FALSE;
1034 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001035 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001036 goto rewrite;
1037 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001038 //.check is need send time send end
hualing chen2932d372020-04-29 13:44:00 +08001039 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001040 pthread_mutex_lock(&player->segment_lock);
hualing chene41f4372020-06-06 16:29:17 +08001041 //DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001042 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chenfbf8e022020-06-15 13:43:11 +08001043 //DVR_PB_DG(1, "start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001044 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001045 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001046 if (read < 0 && errno == EIO) {
1047 //EIO ERROR, EXIT THRAD
1048 DVR_PB_DG(1, "read error.EIO error, exit thread");
1049 DVR_Play_Notify_t notify;
1050 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1051 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001052 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001053 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001054 goto end;
1055 } else if (read < 0) {
1056 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1057 }
hualing chen87072a82020-03-12 16:20:12 +08001058 //if on fb mode and read file end , we need calculate pos to retry read.
1059 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001060 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 +08001061 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
1062 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001063 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1064 pthread_mutex_unlock(&player->lock);
1065 continue;
1066 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001067 //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 +08001068 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001069 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001070 #define MIN_CACHE_TIME (3000)
1071 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
1072 if (_cache_time > MIN_CACHE_TIME) {
1073 DVR_PB_DG(1, "read end but cache time is %d > %d, to sleep and continue", _cache_time, MIN_CACHE_TIME);
1074 pthread_mutex_lock(&player->lock);
1075 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, (_cache_time -MIN_CACHE_TIME));
1076 pthread_mutex_unlock(&player->lock);
1077 //continue;
1078 }
hualing chen040df222020-01-17 13:35:02 +08001079 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001080 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001081 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001082
1083 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001084 //del delay time max check.
hualing chen39628212020-05-14 10:35:13 +08001085 if ((ret != DVR_SUCCESS &&
hualing chen041c4092020-04-05 15:11:50 +08001086 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001087 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001088 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1089 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001090 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001091 DVR_Play_Notify_t notify;
1092 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1093 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1094 //get play statue not here
1095 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001096 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001097 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001098 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 +08001099 pthread_mutex_lock(&player->lock);
1100 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1101 pthread_mutex_unlock(&player->lock);
1102 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001103 } else if (ret != DVR_SUCCESS) {
1104 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001105 if (delay < cache_time) {
1106 //delay time is changed and then has data to play, so not start timeout
1107 } else {
1108 reach_end_timeout = reach_end_timeout + timeout;
1109 }
1110 cache_time = delay;
hualing chen4b7c15d2020-04-07 16:13:48 +08001111 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001112 pthread_mutex_lock(&player->lock);
1113 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1114 pthread_mutex_unlock(&player->lock);
1115 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001116 }
hualing chen39628212020-05-14 10:35:13 +08001117 reach_end_timeout = 0;
1118 cache_time = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001119 pthread_mutex_lock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001120 //change next segment success case
1121 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001122 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001123 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1124 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001125 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001126 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001127 }
hualing chen39628212020-05-14 10:35:13 +08001128 reach_end_timeout = 0;
hualing chen86e7d482020-01-16 15:13:33 +08001129 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001130 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001131 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001132
hualing chena540a7e2020-03-27 16:44:05 +08001133 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001134 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001135 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001136 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001137 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001138 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001139 }
hualing chen266b9502020-04-04 17:39:39 +08001140 //if need write whole block size, we need check read buf len is eq block size.
1141 if (b_writed_whole_block == DVR_TRUE) {
1142 //buf_len is block size value.
1143 if (real_read < buf_len) {
1144 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001145 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001146 pthread_mutex_lock(&player->lock);
1147 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1148 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001149 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001150 continue;
1151 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001152 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 +08001153 }
1154 }
1155
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001156 if (player->dec_func) {
1157 DVR_CryptoParams_t crypto_params;
1158
1159 memset(&crypto_params, 0, sizeof(crypto_params));
1160 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1161 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1162 crypto_params.segment_id = player->cur_segment.segment_id;
1163 crypto_params.offset = segment_tell_position(player->r_handle);
1164
1165 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1166 crypto_params.input_buffer.addr = (size_t)buf;
1167 crypto_params.input_buffer.size = real_read;
1168
1169 if (player->is_secure_mode) {
1170 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1171 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1172 crypto_params.output_buffer.size = dec_buf_size;
1173 ret = player->dec_func(&crypto_params, player->dec_userdata);
1174 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001175 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001176 } else {
1177 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1178 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1179 crypto_params.output_buffer.size = dec_buf_size;
1180 ret = player->dec_func(&crypto_params, player->dec_userdata);
1181 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001182 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001183 }
1184 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001185 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001186 }
pengfei.liufda2a972020-04-09 14:47:15 +08001187 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001188 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001189rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001190 if (player->drop_ts == DVR_TRUE) {
1191 //need drop ts data when seek occur.we need read next loop,drop this ts data
1192 goto_rewrite = DVR_FALSE;
1193 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001194 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001195 player->drop_ts = DVR_FALSE;
1196 continue;
1197 }
hualing chen5605eed2020-05-26 18:18:06 +08001198 player->ts_cache_len = real_read;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001199 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1200 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001201 player->ts_cache_len = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001202 real_read = 0;
1203 write_success++;
hualing chen5605eed2020-05-26 18:18:06 +08001204 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001205 continue;
hualing chen87072a82020-03-12 16:20:12 +08001206 } else {
hualing chen2932d372020-04-29 13:44:00 +08001207 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 +08001208 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001209 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001210 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001211 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001212 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001213 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001214 break;
1215 }
hualing chen2aba4022020-03-02 13:49:55 +08001216 goto_rewrite = DVR_TRUE;
1217 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001218 }
1219 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001220end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001221 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001222 free(buf);
1223 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001224 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001225}
1226
1227
hualing chen040df222020-01-17 13:35:02 +08001228static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001229{
hualing chen040df222020-01-17 13:35:02 +08001230 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001231
1232 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001233 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001234 return DVR_FAILURE;
1235 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001236 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001237 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001238 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001239 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001240 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001241 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001242 if (rc < 0)
1243 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001244 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001245}
1246
1247
hualing chen040df222020-01-17 13:35:02 +08001248static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001249{
hualing chen040df222020-01-17 13:35:02 +08001250 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001251
1252 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001253 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001254 return DVR_FAILURE;
1255 }
1256
hualing chen4b7c15d2020-04-07 16:13:48 +08001257 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001258 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001259 {
1260 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001261 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001262 pthread_join(player->playback_thread, NULL);
1263 }
1264 if (player->r_handle) {
1265 segment_close(player->r_handle);
1266 player->r_handle = NULL;
1267 }
hualing chen7a56cba2020-04-14 14:09:27 +08001268 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001269 return 0;
1270}
1271
hualing chenb31a6c62020-01-13 17:27:00 +08001272/**\brief Open an dvr palyback
1273 * \param[out] p_handle dvr playback addr
1274 * \param[in] params dvr playback open parameters
1275 * \retval DVR_SUCCESS On success
1276 * \return Error code
1277 */
hualing chen040df222020-01-17 13:35:02 +08001278int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001279
hualing chen040df222020-01-17 13:35:02 +08001280 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001281 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001282
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001283 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001284
hualing chen86e7d482020-01-16 15:13:33 +08001285 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001286 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001287 pthread_condattr_init(&cattr);
1288 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1289 pthread_cond_init(&player->cond, &cattr);
1290 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001291
hualing chen5cbe1a62020-02-10 16:36:36 +08001292 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001293 INIT_LIST_HEAD(&player->segment_list);
1294 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1295 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001296 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001297 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001298 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001299 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001300 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001301 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001302
hualing chen86e7d482020-01-16 15:13:33 +08001303 //store open params
hualing chen040df222020-01-17 13:35:02 +08001304 player->openParams.dmx_dev_id = params->dmx_dev_id;
1305 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001306 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001307 player->openParams.event_fn = params->event_fn;
1308 player->openParams.event_userdata = params->event_userdata;
hualing chenfbf8e022020-06-15 13:43:11 +08001309 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001310
hualing chen5cbe1a62020-02-10 16:36:36 +08001311 player->has_pids = params->has_pids;
1312
hualing chen2aba4022020-03-02 13:49:55 +08001313 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001314
1315 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1316 //for test get callback
1317 if (0 && player->player_callback_func == NULL) {
1318 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1319 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001320 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 +08001321 }
1322 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001323
hualing chen86e7d482020-01-16 15:13:33 +08001324 //init has audio and video
1325 player->has_video = DVR_FALSE;
1326 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001327 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001328 player->last_segment_id = 0LL;
1329 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001330
hualing chen5cbe1a62020-02-10 16:36:36 +08001331 //init ff fb time
1332 player->fffb_current = -1;
1333 player->fffb_start =-1;
1334 player->fffb_start_pcr = -1;
1335 //seek time
1336 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001337 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001338
1339 //init secure stuff
1340 player->dec_func = NULL;
1341 player->dec_userdata = NULL;
1342 player->is_secure_mode = 0;
1343 player->secure_buffer = NULL;
1344 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001345 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001346
hualing chen4b7c15d2020-04-07 16:13:48 +08001347 player->fffb_play = DVR_FALSE;
1348
1349 player->last_send_time_id = UINT64_MAX;
1350 player->last_cur_time = 0;
1351
hualing chen86e7d482020-01-16 15:13:33 +08001352 *p_handle = player;
1353 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001354}
1355
1356/**\brief Close an dvr palyback
1357 * \param[in] handle playback handle
1358 * \retval DVR_SUCCESS On success
1359 * \return Error code
1360 */
hualing chen040df222020-01-17 13:35:02 +08001361int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001362
hualing chen86e7d482020-01-16 15:13:33 +08001363 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001364 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001365 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001366 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001367 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001368 return DVR_FAILURE;
1369 }
1370
hualing chencc91e1c2020-02-28 13:26:17 +08001371 if (player->state != DVR_PLAYBACK_STATE_STOP)
1372 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001373 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001374 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001375 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1376 } else {
1377 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001378 }
hualing chen7a56cba2020-04-14 14:09:27 +08001379 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001380 pthread_mutex_destroy(&player->lock);
1381 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001382
1383 if (player) {
1384 free(player);
1385 player = NULL;
1386 }
hualing chen7a56cba2020-04-14 14:09:27 +08001387 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001388 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001389}
1390
hualing chenb31a6c62020-01-13 17:27:00 +08001391/**\brief Start play audio and video, used start auido api and start video api
1392 * \param[in] handle playback handle
1393 * \param[in] params audio playback params,contains fmt and pid...
1394 * \retval DVR_SUCCESS On success
1395 * \return Error code
1396 */
hualing chen040df222020-01-17 13:35:02 +08001397int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1398 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001399 am_tsplayer_video_params vparams;
1400 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001401 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001402
1403 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001404 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001405 return DVR_FAILURE;
1406 }
hualing chencc91e1c2020-02-28 13:26:17 +08001407 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001408 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001409
hualing chena540a7e2020-03-27 16:44:05 +08001410 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001411 //can used start api to resume playback
1412 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1413 return dvr_playback_resume(handle);
1414 }
hualing chen87072a82020-03-12 16:20:12 +08001415 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001416 //if flag is puased and not decodec first frame. if user resume, we need
1417 //clear flag and set trickmode none
1418 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1419 DVR_PB_DG(1, "[%p]clear pause live flag and clear trick mode", handle);
1420 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1421 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1422 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001423 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001424 return DVR_SUCCESS;
1425 }
hualing chen86e7d482020-01-16 15:13:33 +08001426 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001427 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001428 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001429 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001430 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001431 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001432 //start audio and video
1433 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1434 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001435 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001436 pthread_mutex_unlock(&player->lock);
1437 DVR_Play_Notify_t notify;
1438 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1439 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1440 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1441 notify.info.transition_failed_data.segment_id = segment_id;
1442 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001443 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001444 return -1;
1445 }
hualing chen31140872020-03-25 12:29:26 +08001446
hualing chencc91e1c2020-02-28 13:26:17 +08001447 {
hualing chen86e7d482020-01-16 15:13:33 +08001448 if (VALID_PID(vparams.pid)) {
1449 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001450 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001451 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001452 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001453 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1454 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001455 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001456 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001457 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001458 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001459 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001460 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001461 }
1462 AmTsPlayer_setVideoParams(player->handle, &vparams);
1463 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001464 }
hualing chena540a7e2020-03-27 16:44:05 +08001465
hualing chen4b7c15d2020-04-07 16:13:48 +08001466 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1467 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001468 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1469 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1470 player->cmd.state = DVR_PLAYBACK_STATE_START;
1471 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001472 } else {
1473 player->cmd.last_cmd = player->cmd.cur_cmd;
1474 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001475 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001476 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001477 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001478 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001479 } else {
1480 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001481 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08001482 player->has_audio = DVR_TRUE;
1483 AmTsPlayer_setAudioParams(player->handle, &aparams);
1484 AmTsPlayer_startAudioDecoding(player->handle);
1485 }
hualing chendf118dd2020-05-21 15:49:11 +08001486 if (VALID_PID(adparams.pid)) {
1487 player->has_ad_audio = DVR_TRUE;
1488 DVR_PB_DG(1, "start ad audio");
1489 AmTsPlayer_setADParams(player->handle, &adparams);
1490 AmTsPlayer_enableADMix(player->handle);
1491 }
hualing chen31140872020-03-25 12:29:26 +08001492 }
hualing chencc91e1c2020-02-28 13:26:17 +08001493 player->cmd.state = DVR_PLAYBACK_STATE_START;
1494 player->state = DVR_PLAYBACK_STATE_START;
1495 }
hualing chen86e7d482020-01-16 15:13:33 +08001496 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001497 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001498 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001499 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001500 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001501}
hualing chen040df222020-01-17 13:35:02 +08001502/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001503 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001504 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001505 * \retval DVR_SUCCESS On success
1506 * \return Error code
1507 */
hualing chen040df222020-01-17 13:35:02 +08001508int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1509 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001510
hualing chena540a7e2020-03-27 16:44:05 +08001511 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001512 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001513 return DVR_FAILURE;
1514 }
1515
hualing chen4b7c15d2020-04-07 16:13:48 +08001516 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001517 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001518
hualing chen040df222020-01-17 13:35:02 +08001519 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1520 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001521
hualing chen86e7d482020-01-16 15:13:33 +08001522 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001523 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001524 //cp location
hualing chen040df222020-01-17 13:35:02 +08001525 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001526
hualing chen4b7c15d2020-04-07 16:13:48 +08001527 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 +08001528 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001529
1530 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001531 segment->pids.video.pid = info->pids.video.pid;
1532 segment->pids.video.format = info->pids.video.format;
1533 segment->pids.video.type = info->pids.video.type;
1534
hualing chen2aba4022020-03-02 13:49:55 +08001535 segment->pids.audio.pid = info->pids.audio.pid;
1536 segment->pids.audio.format = info->pids.audio.format;
1537 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001538
hualing chen2aba4022020-03-02 13:49:55 +08001539 segment->pids.ad.pid = info->pids.ad.pid;
1540 segment->pids.ad.format = info->pids.ad.format;
1541 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001542
1543 segment->pids.pcr.pid = info->pids.pcr.pid;
1544
hualing chen4b7c15d2020-04-07 16:13:48 +08001545 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 +08001546 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001547 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001548 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001549 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001550
hualing chen5cbe1a62020-02-10 16:36:36 +08001551 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001552}
hualing chen040df222020-01-17 13:35:02 +08001553/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001554 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001555 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001556 * \retval DVR_SUCCESS On success
1557 * \return Error code
1558 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001559int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001560 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001561 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001562 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001563 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001564 return DVR_FAILURE;
1565 }
1566
hualing chencc91e1c2020-02-28 13:26:17 +08001567 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001568 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001569 return DVR_FAILURE;
1570 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001571 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001572 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001573 DVR_PlaybackSegmentInfo_t *segment = NULL;
1574 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1575 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001576 {
hualing chen040df222020-01-17 13:35:02 +08001577 if (segment->segment_id == segment_id) {
1578 list_del(&segment->head);
1579 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001580 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001581 }
hualing chen86e7d482020-01-16 15:13:33 +08001582 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001583 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001584 pthread_mutex_unlock(&player->lock);
1585
1586 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001587}
hualing chen040df222020-01-17 13:35:02 +08001588/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001589 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001590 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001591 * \retval DVR_SUCCESS On success
1592 * \return Error code
1593 */
hualing chen040df222020-01-17 13:35:02 +08001594int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001595 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001596 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001597 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001598 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001599 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001600 return DVR_FAILURE;
1601 }
1602
hualing chen040df222020-01-17 13:35:02 +08001603 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001604 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001605 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001606 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001607 {
hualing chen040df222020-01-17 13:35:02 +08001608 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001609 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001610 }
hualing chen86e7d482020-01-16 15:13:33 +08001611 // if encramble to free, only set flag and return;
1612
1613 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001614 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001615 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1616 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001617 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001618 AmTsPlayer_hideVideo(player->handle);
1619 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001620 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1621 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001622 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001623 AmTsPlayer_showVideo(player->handle);
1624 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001625 } else {
1626 //do nothing
1627 }
1628 } else {
1629 //do nothing
1630 }
1631 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001632 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001633 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001634 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001635 pthread_mutex_unlock(&player->lock);
1636 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001637}
1638
1639
hualing chen5cbe1a62020-02-10 16:36:36 +08001640static 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 +08001641 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001642 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001643 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001644 return DVR_FAILURE;
1645 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001646 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001647 if (now_pid.pid == set_pid.pid) {
1648 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001649 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001650 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001651 if (VALID_PID(now_pid.pid)) {
1652 //stop now stream
1653 if (type == 0) {
1654 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001655 if (player->has_video == DVR_TRUE) {
1656 DVR_PB_DG(1, "stop video");
1657 AmTsPlayer_stopVideoDecoding(player->handle);
1658 player->has_video = DVR_FALSE;
1659 }
hualing chen86e7d482020-01-16 15:13:33 +08001660 } else if (type == 1) {
1661 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08001662 if (player->has_audio == DVR_TRUE) {
1663 DVR_PB_DG(1, "stop audio");
1664 AmTsPlayer_stopAudioDecoding(player->handle);
1665 player->has_audio = DVR_FALSE;
1666 }
hualing chen86e7d482020-01-16 15:13:33 +08001667 } else if (type == 2) {
1668 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001669 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001670 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001671 } else if (type == 3) {
1672 //pcr
1673 }
1674 }
1675 if (VALID_PID(set_pid.pid)) {
1676 //start
1677 if (type == 0) {
1678 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001679 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001680 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001681 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001682 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001683 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001684 AmTsPlayer_setVideoParams(player->handle, &vparams);
1685 AmTsPlayer_startVideoDecoding(player->handle);
1686 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001687 } else if (type == 1) {
1688 //start audio
hualing chenc70a8df2020-05-12 19:23:11 +08001689 if ((player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
1690 am_tsplayer_audio_params aparams;
1691 aparams.pid = set_pid.pid;
1692 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1693 player->has_audio = DVR_TRUE;
1694 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1695 AmTsPlayer_setAudioParams(player->handle, &aparams);
1696 AmTsPlayer_startAudioDecoding(player->handle);
1697 //playback_device_audio_start(player->handle,&aparams);
1698 }
hualing chen86e7d482020-01-16 15:13:33 +08001699 } else if (type == 2) {
hualing chen39628212020-05-14 10:35:13 +08001700 if ((player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chenc70a8df2020-05-12 19:23:11 +08001701 am_tsplayer_audio_params aparams;
1702 aparams.pid = set_pid.pid;
1703 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1704 player->has_audio = DVR_TRUE;
1705 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1706 AmTsPlayer_setADParams(player->handle, &aparams);
1707 AmTsPlayer_enableADMix(player->handle);
1708 //playback_device_audio_start(player->handle,&aparams);
1709 }
hualing chen86e7d482020-01-16 15:13:33 +08001710 } else if (type == 3) {
1711 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001712 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001713 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001714 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001715 //audio and video all close
1716 if (!player->has_audio && !player->has_video) {
1717 player->state = DVR_PLAYBACK_STATE_STOP;
1718 }
hualing chen86e7d482020-01-16 15:13:33 +08001719 }
1720 }
1721 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001722}
hualing chen5cbe1a62020-02-10 16:36:36 +08001723/**\brief dvr play back update segment pids
1724 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001725 * add pid stream and stop remove pid stream.
1726 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001727 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001728 * \retval DVR_SUCCESS On success
1729 * \return Error code
1730 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001731int 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 +08001732 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001733 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001734 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001735 return DVR_FAILURE;
1736 }
1737
hualing chen040df222020-01-17 13:35:02 +08001738 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001739 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001740 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001741 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 +08001742
hualing chen040df222020-01-17 13:35:02 +08001743 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001744 {
hualing chen040df222020-01-17 13:35:02 +08001745 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001746
1747 if (player->cur_segment_id == segment_id) {
1748 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1749 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1750 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001751 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001752 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001753 return 0;
1754 }
1755
1756 //if segment is on going segment,we need stop start stream
1757 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001758 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001759 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001760 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001761 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001762 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001763 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001764 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001765 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001766 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1767 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001768 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1769 //if state is pause, we need process at resume api. we only record change info
1770 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1771 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1772 if (VALID_PID(segment->pids.video.pid)
1773 && VALID_PID(p_pids->video.pid)
1774 && segment->pids.video.pid != p_pids->video.pid) {
1775 //restart video
1776 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1777 }
1778 if (!VALID_PID(segment->pids.video.pid)
1779 && VALID_PID(p_pids->video.pid)
1780 && segment->pids.video.pid != p_pids->video.pid) {
1781 //start video
1782 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1783 }
1784 if (VALID_PID(segment->pids.video.pid)
1785 && !VALID_PID(p_pids->video.pid)
1786 && segment->pids.video.pid != p_pids->video.pid) {
1787 //stop video
1788 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1789 }
1790 if (VALID_PID(segment->pids.audio.pid)
1791 && VALID_PID(p_pids->audio.pid)
1792 && segment->pids.audio.pid != p_pids->audio.pid) {
1793 //restart audio
1794 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1795 }
1796 if (!VALID_PID(segment->pids.audio.pid)
1797 && VALID_PID(p_pids->audio.pid)
1798 && segment->pids.audio.pid != p_pids->audio.pid) {
1799 //start audio
1800 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1801 }
1802 if (VALID_PID(segment->pids.audio.pid)
1803 && !VALID_PID(p_pids->audio.pid)
1804 && segment->pids.audio.pid != p_pids->audio.pid) {
1805 //stop audio
1806 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1807 }
1808 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1809 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1810 //do nothing
1811 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1812 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1813 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1814 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1815 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1816 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1817 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1818 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1819 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1820 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1821 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1822 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1823 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1824 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1825 } else {
1826 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1827 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1828 }
1829
1830 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1831 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1832 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1833 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1834 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1835 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1836 //not occur this case
1837 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1838 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1839 } else {
1840 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1841 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1842 }
1843
1844 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1845 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1846 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1847 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1848 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1849 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1850 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1851 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1852 } else {
1853 //not occur this case
1854 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1855 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1856 }
1857 }
1858 }
hualing chene10666f2020-04-14 13:58:37 +08001859 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08001860 }
hualing chen86e7d482020-01-16 15:13:33 +08001861 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08001862 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08001863 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08001864 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001865 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001866 }
hualing chen86e7d482020-01-16 15:13:33 +08001867 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001868 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001869 pthread_mutex_unlock(&player->lock);
1870 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001871}
1872/**\brief Stop play, will stop video and audio
1873 * \param[in] handle playback handle
1874 * \param[in] clear is clear last frame
1875 * \retval DVR_SUCCESS On success
1876 * \return Error code
1877 */
hualing chen040df222020-01-17 13:35:02 +08001878int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1879 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001880
1881 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001882 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001883 return DVR_FAILURE;
1884 }
hualing chenb96aa2c2020-04-15 14:13:53 +08001885 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1886 DVR_PB_DG(1, ":playback is stoped");
1887 return DVR_SUCCESS;
1888 }
Ke Gong3c0caba2020-04-21 22:58:18 -07001889 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1890 DVR_PB_DG(1, ":playback is stoped");
1891 return DVR_SUCCESS;
1892 }
hualing chen87072a82020-03-12 16:20:12 +08001893 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001894 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001895 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08001896 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08001897 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001898 if (player->has_video) {
1899 AmTsPlayer_resumeVideoDecoding(player->handle);
1900 }
1901 if (player->has_audio) {
1902 AmTsPlayer_resumeAudioDecoding(player->handle);
1903 }
1904 if (player->has_video) {
1905 player->has_video = DVR_FALSE;
1906 AmTsPlayer_showVideo(player->handle);
1907 AmTsPlayer_stopVideoDecoding(player->handle);
1908 }
1909 if (player->has_audio) {
1910 player->has_audio = DVR_FALSE;
1911 AmTsPlayer_stopAudioDecoding(player->handle);
1912 }
hualing chendf118dd2020-05-21 15:49:11 +08001913 if (player->has_ad_audio) {
1914 player->has_ad_audio =DVR_FALSE;
1915 AmTsPlayer_disableADMix(player->handle);
1916 }
hualing chen266b9502020-04-04 17:39:39 +08001917
hualing chen86e7d482020-01-16 15:13:33 +08001918 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001919 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1920 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1921 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001922 player->cur_segment_id = UINT64_MAX;
1923 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001924 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08001925 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08001926 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001927 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001928}
1929/**\brief Start play audio
1930 * \param[in] handle playback handle
1931 * \param[in] params audio playback params,contains fmt and pid...
1932 * \retval DVR_SUCCESS On success
1933 * \return Error code
1934 */
hualing chen2aba4022020-03-02 13:49:55 +08001935
hualing chendf118dd2020-05-21 15:49:11 +08001936int 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 +08001937 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001938
1939 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001940 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001941 return DVR_FAILURE;
1942 }
hualing chen86e7d482020-01-16 15:13:33 +08001943 _start_playback_thread(handle);
1944 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001945 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001946 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001947
1948 if (VALID_PID(param->pid)) {
1949 DVR_PB_DG(1, "start audio");
1950 player->has_audio = DVR_TRUE;
1951 AmTsPlayer_setAudioParams(player->handle, param);
1952 AmTsPlayer_startAudioDecoding(player->handle);
1953 }
1954 if (VALID_PID(adparam->pid)) {
1955 player->has_ad_audio = DVR_TRUE;
1956 DVR_PB_DG(1, "start ad audio");
1957 AmTsPlayer_setADParams(player->handle, adparam);
1958 AmTsPlayer_enableADMix(player->handle);
1959 }
1960
hualing chen86e7d482020-01-16 15:13:33 +08001961 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001962 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1963 player->cmd.state = DVR_PLAYBACK_STATE_START;
1964 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001965 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001966 pthread_mutex_unlock(&player->lock);
1967 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001968}
1969/**\brief Stop play audio
1970 * \param[in] handle playback handle
1971 * \retval DVR_SUCCESS On success
1972 * \return Error code
1973 */
hualing chen040df222020-01-17 13:35:02 +08001974int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1975 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001976
1977 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001978 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001979 return DVR_FAILURE;
1980 }
1981
hualing chen2aba4022020-03-02 13:49:55 +08001982 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001983 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001984 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1985 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001986 //destory thread
1987 _stop_playback_thread(handle);
1988 } else {
1989 //do nothing.video is playing
1990 }
hualing chen7a56cba2020-04-14 14:09:27 +08001991 DVR_PB_DG(1, "lock");
1992 pthread_mutex_lock(&player->lock);
1993
hualing chenf00cdc82020-06-10 14:23:35 +08001994 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08001995 player->has_audio = DVR_FALSE;
1996 AmTsPlayer_stopAudioDecoding(player->handle);
1997 }
hualing chen87072a82020-03-12 16:20:12 +08001998
hualing chendf118dd2020-05-21 15:49:11 +08001999 if (player->has_ad_audio) {
2000 player->has_ad_audio =DVR_FALSE;
2001 AmTsPlayer_disableADMix(player->handle);
2002 }
2003
hualing chen87072a82020-03-12 16:20:12 +08002004 player->cmd.last_cmd = player->cmd.cur_cmd;
2005 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2006
hualing chen4b7c15d2020-04-07 16:13:48 +08002007 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002008 pthread_mutex_unlock(&player->lock);
2009 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002010}
2011/**\brief Start play video
2012 * \param[in] handle playback handle
2013 * \param[in] params video playback params,contains fmt and pid...
2014 * \retval DVR_SUCCESS On success
2015 * \return Error code
2016 */
hualing chen2aba4022020-03-02 13:49:55 +08002017int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002018 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002019
2020 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002021 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002022 return DVR_FAILURE;
2023 }
2024
hualing chen86e7d482020-01-16 15:13:33 +08002025 _start_playback_thread(handle);
2026 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002027 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002028 pthread_mutex_lock(&player->lock);
2029 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002030 AmTsPlayer_setVideoParams(player->handle, param);
2031 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002032
2033 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002034 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002035 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002036 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002037 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2038 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002039 }
2040 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002041 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2042 player->cmd.state = DVR_PLAYBACK_STATE_START;
2043 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002044 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002045 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002046 return DVR_SUCCESS;
2047}
2048/**\brief Stop play video
2049 * \param[in] handle playback handle
2050 * \retval DVR_SUCCESS On success
2051 * \return Error code
2052 */
hualing chen040df222020-01-17 13:35:02 +08002053int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2054 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002055
2056 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002057 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002058 return DVR_FAILURE;
2059 }
2060
hualing chen86e7d482020-01-16 15:13:33 +08002061 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002062 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2063 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002064 //destory thread
2065 _stop_playback_thread(handle);
2066 } else {
2067 //do nothing.audio is playing
2068 }
hualing chen7a56cba2020-04-14 14:09:27 +08002069
2070 DVR_PB_DG(1, "lock");
2071 pthread_mutex_lock(&player->lock);
2072
hualing chen87072a82020-03-12 16:20:12 +08002073 player->has_video = DVR_FALSE;
2074
2075 AmTsPlayer_stopVideoDecoding(player->handle);
2076 //playback_device_video_stop(player->handle);
2077
2078 player->cmd.last_cmd = player->cmd.cur_cmd;
2079 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2080
hualing chen4b7c15d2020-04-07 16:13:48 +08002081 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002082 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002083 return DVR_SUCCESS;
2084}
2085/**\brief Pause play
2086 * \param[in] handle playback handle
2087 * \param[in] flush whether its internal buffers should be flushed
2088 * \retval DVR_SUCCESS On success
2089 * \return Error code
2090 */
hualing chen040df222020-01-17 13:35:02 +08002091int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2092 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002093
2094 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002095 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002096 return DVR_FAILURE;
2097 }
hualing chenf00cdc82020-06-10 14:23:35 +08002098 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
2099 DVR_PB_DG(1, "player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002100 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002101 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002102 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002103 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002104 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002105 if (player->has_video)
2106 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002107 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002108 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002109
2110 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002111 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2112 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2113 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2114 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002115 } else {
2116 player->cmd.last_cmd = player->cmd.cur_cmd;
2117 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2118 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2119 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002120 }
hualing chen86e7d482020-01-16 15:13:33 +08002121 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002122 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002123
hualing chen86e7d482020-01-16 15:13:33 +08002124 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002125}
2126
hualing chen5cbe1a62020-02-10 16:36:36 +08002127//not add lock
2128static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2129{
2130 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2131
hualing chena540a7e2020-03-27 16:44:05 +08002132 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002133 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002134 return DVR_FAILURE;
2135 }
2136
hualing chen5cbe1a62020-02-10 16:36:36 +08002137 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002138 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002139 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002140 am_tsplayer_video_params vparams;
2141 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002142 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002143 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002144
hualing chendf118dd2020-05-21 15:49:11 +08002145 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002146 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002147 pthread_mutex_unlock(&player->lock);
2148
2149 switch (cmd) {
2150 case DVR_PLAYBACK_CMD_AVRESTART:
2151 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002152 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002153 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002154 break;
2155 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002156 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2157 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002158 break;
2159 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002160 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002161 break;
2162 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002163 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002164 break;
2165 case DVR_PLAYBACK_CMD_ARESTART:
2166 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002167 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002168 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002169 break;
2170 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002171 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002172 break;
2173 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002174 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002175 break;
2176 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002177 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2178 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2179 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002180 break;
2181 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002182 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2183 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002184 break;
2185 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002186 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2187 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002188 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002189 break;
2190 case DVR_PLAYBACK_CMD_STOP:
2191 break;
2192 case DVR_PLAYBACK_CMD_START:
2193 break;
2194 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002195 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2196 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002197 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002198 break;
2199 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002200 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2201 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002202 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002203 break;
2204 case DVR_PLAYBACK_CMD_FF:
2205 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002206 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002207 break;
2208 default:
2209 break;
2210 }
2211 return DVR_SUCCESS;
2212}
2213
2214/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002215 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002216 * \retval DVR_SUCCESS On success
2217 * \return Error code
2218 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002219int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2220 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2221
hualing chena540a7e2020-03-27 16:44:05 +08002222 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002223 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002224 return DVR_FAILURE;
2225 }
2226
hualing chen5cbe1a62020-02-10 16:36:36 +08002227 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002228 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002229 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002230 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002231 DVR_PB_DG(1, "dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002232 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2233 AmTsPlayer_resumeVideoDecoding(player->handle);
2234 }
2235 if (player->has_audio) {
2236 AmTsPlayer_resumeAudioDecoding(player->handle);
2237 }
2238 //check is has audio param,if has audio .we need start audio,
2239 //we will stop audio when ff fb, if reach end, we will pause.so we need
2240 //start audio when resume play
2241
2242 am_tsplayer_video_params vparams;
2243 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002244 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002245 uint64_t segmentid = player->cur_segment_id;
hualing chendf118dd2020-05-21 15:49:11 +08002246 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002247 //valid audio pid, start audio
hualing chenc70a8df2020-05-12 19:23:11 +08002248 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 +08002249 player->has_audio = DVR_TRUE;
2250 AmTsPlayer_setAudioParams(player->handle, &aparams);
2251 AmTsPlayer_startAudioDecoding(player->handle);
2252 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002253 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 +08002254 }
hualing chendf118dd2020-05-21 15:49:11 +08002255
2256 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2257 player->has_ad_audio = DVR_TRUE;
2258 DVR_PB_DG(1, "start ad audio");
2259 AmTsPlayer_setADParams(player->handle, &adparams);
2260 AmTsPlayer_enableADMix(player->handle);
2261 }
2262
hualing chen87072a82020-03-12 16:20:12 +08002263 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2264 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2265 player->cmd.state = DVR_PLAYBACK_STATE_START;
2266 player->state = DVR_PLAYBACK_STATE_START;
2267 } else {
2268 player->cmd.last_cmd = player->cmd.cur_cmd;
2269 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2270 player->cmd.state = DVR_PLAYBACK_STATE_START;
2271 player->state = DVR_PLAYBACK_STATE_START;
2272 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002273 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002274 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002275 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
hualing chene41f4372020-06-06 16:29:17 +08002276 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002277 DVR_PB_DG(1, "dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002278 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002279 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002280 }
hualing chen041c4092020-04-05 15:11:50 +08002281 if (player->has_audio)
2282 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002283 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002284 player->cmd.state = DVR_PLAYBACK_STATE_START;
2285 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002286 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002287 } else {
2288 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2289 {
2290 pthread_mutex_lock(&player->lock);
2291 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002292 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002293 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2294 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2295 pthread_mutex_unlock(&player->lock);
2296 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002297 }
2298 return DVR_SUCCESS;
2299}
2300
hualing chena540a7e2020-03-27 16:44:05 +08002301static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2302
2303 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2304 DVR_PlaybackSegmentInfo_t *segment = NULL;
2305 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2306 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2307
2308 list_for_each_entry(segment, &player->segment_list, head)
2309 {
2310 if (segment->segment_id == segment_id) {
2311 cur_segment = segment;
2312 }
2313 if (segment->segment_id == set_seg_id) {
2314 set_segment = segment;
2315 }
2316 if (cur_segment != NULL && set_segment != NULL) {
2317 break;
2318 }
2319 }
2320 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002321 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002322 return DVR_TRUE;
2323 }
2324 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2325 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2326 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2327 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002328 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 +08002329 return DVR_TRUE;
2330 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002331 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002332 return DVR_FALSE;
2333}
2334
hualing chen5cbe1a62020-02-10 16:36:36 +08002335/**\brief seek
2336 * \param[in] handle playback handle
2337 * \param[in] time_offset time offset base cur segment
2338 * \retval DVR_SUCCESS On success
2339 * \return Error code
2340 */
hualing chencc91e1c2020-02-28 13:26:17 +08002341int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002342 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002343
2344 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002345 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002346 return DVR_FAILURE;
2347 }
2348
hualing chen4b7c15d2020-04-07 16:13:48 +08002349 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 +08002350 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002351
hualing chen86e7d482020-01-16 15:13:33 +08002352 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002353 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002354 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002355
hualing chen5cbe1a62020-02-10 16:36:36 +08002356 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002357 int ret = _dvr_open_segment(handle, segment_id);
2358 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002359 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002360 pthread_mutex_unlock(&player->lock);
2361 return DVR_FAILURE;
2362 }
2363 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2364 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002365 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002366 //pthread_mutex_unlock(&player->lock);
2367 //return DVR_SUCCESS;
2368 time_offset = _dvr_get_end_time(handle);
2369 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002370 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002371 time_offset = _dvr_get_end_time(handle);
hualing chen87072a82020-03-12 16:20:12 +08002372 pthread_mutex_unlock(&player->lock);
2373 return DVR_FAILURE;
2374 }
2375 }
2376
hualing chen4b7c15d2020-04-07 16:13:48 +08002377 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 +08002378 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002379 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2380 //forward playback.not seek end of file
2381 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2382 //default -2000ms
2383 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2384 }
hualing chen86e7d482020-01-16 15:13:33 +08002385 }
hualing chen2aba4022020-03-02 13:49:55 +08002386 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002387 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002388 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002389 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002390 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 +08002391 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002392 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002393
hualing chen2aba4022020-03-02 13:49:55 +08002394 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002395
2396 player->last_send_time_id = UINT64_MAX;
2397
hualing chen2aba4022020-03-02 13:49:55 +08002398 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002399 player->fffb_current = _dvr_time_getClock();
2400 player->fffb_start = player->fffb_current;
2401 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2402 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002403 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002404 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002405 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002406 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002407 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002408 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002409 }
hualing chen86e7d482020-01-16 15:13:33 +08002410 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002411 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 +08002412 if (player->has_video) {
2413 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002414 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002415 }
2416
2417 if (player->has_audio) {
2418 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002419 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002420 }
hualing chendf118dd2020-05-21 15:49:11 +08002421 if (player->has_ad_audio) {
2422 player->has_ad_audio =DVR_FALSE;
2423 AmTsPlayer_disableADMix(player->handle);
2424 }
2425
hualing chen86e7d482020-01-16 15:13:33 +08002426 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002427 am_tsplayer_video_params vparams;
2428 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002429 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002430
hualing chen040df222020-01-17 13:35:02 +08002431 player->cur_segment_id = segment_id;
2432
2433 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002434 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002435 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002436 //start audio and video
2437 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2438 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002439 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 +08002440 pthread_mutex_unlock(&player->lock);
2441 return -1;
2442 }
2443 //add
hualing chen040df222020-01-17 13:35:02 +08002444 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002445 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002446 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002447 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08002448 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002449 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002450 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002451 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002452 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002453 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002454 }
hualing chen2aba4022020-03-02 13:49:55 +08002455 AmTsPlayer_setVideoParams(player->handle, &vparams);
2456 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002457 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
2458 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
2459 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2460 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2461 AmTsPlayer_stopFast(player->handle);
2462 }
hualing chen266b9502020-04-04 17:39:39 +08002463 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002464 }
hualing chene41f4372020-06-06 16:29:17 +08002465 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002466 DVR_PB_DG(1, "start audio seek");
hualing chen2aba4022020-03-02 13:49:55 +08002467 AmTsPlayer_setAudioParams(player->handle, &aparams);
2468 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002469 player->has_audio = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002470 }
hualing chene41f4372020-06-06 16:29:17 +08002471 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08002472 player->has_ad_audio = DVR_TRUE;
2473 DVR_PB_DG(1, "start ad audio");
2474 AmTsPlayer_setADParams(player->handle, &adparams);
2475 AmTsPlayer_enableADMix(player->handle);
2476 }
hualing chen86e7d482020-01-16 15:13:33 +08002477 }
hualing chene41f4372020-06-06 16:29:17 +08002478 if (player->state == DVR_PLAYBACK_STATE_PAUSE /*&&
hualing chen2aba4022020-03-02 13:49:55 +08002479 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2480 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2481 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chene41f4372020-06-06 16:29:17 +08002482 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))*/) {
hualing chen2aba4022020-03-02 13:49:55 +08002483 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2484 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002485 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002486 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2487 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002488 player->speed > 1.0f||
2489 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002490 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002491 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002492 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002493 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002494 player->cmd.last_cmd = player->cmd.cur_cmd;
2495 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2496 player->cmd.state = DVR_PLAYBACK_STATE_START;
2497 player->state = DVR_PLAYBACK_STATE_START;
2498 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002499 player->last_send_time_id = UINT64_MAX;
2500 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002501 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002502
2503 return DVR_SUCCESS;
2504}
hualing chen5cbe1a62020-02-10 16:36:36 +08002505
hualing chen5cbe1a62020-02-10 16:36:36 +08002506static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2507 //get cur time of segment
2508 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002509
2510 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002511 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002512 return DVR_FAILURE;
2513 }
2514
hualing chen31140872020-03-25 12:29:26 +08002515 int64_t cache = 0;//defalut es buf cache 500ms
2516 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002517 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002518 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2519 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen2aba4022020-03-02 13:49:55 +08002520 pthread_mutex_unlock(&player->segment_lock);
hualing chenfbf8e022020-06-15 13:43:11 +08002521 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 +08002522 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2523 cache = 0;
2524 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002525 int cur_time = (int)(cur > cache ? cur - cache : 0);
2526 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002527}
2528
2529//get current segment current pcr time of read pos
2530static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2531 //get cur time of segment
2532 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002533
2534 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002535 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002536 return DVR_FAILURE;
2537 }
2538
hualing chen2aba4022020-03-02 13:49:55 +08002539 pthread_mutex_lock(&player->segment_lock);
2540 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002541 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002542 pthread_mutex_unlock(&player->segment_lock);
2543 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002544}
2545
hualing chen4b7c15d2020-04-07 16:13:48 +08002546#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002547//start replay
2548static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2549
2550 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2551 //calculate pcr seek time
2552 int t_diff = 0;
2553 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002554
2555 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002556 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002557 return DVR_FAILURE;
2558 }
2559
hualing chen5cbe1a62020-02-10 16:36:36 +08002560 if (player->fffb_start == -1) {
2561 //set fffb start time ms
2562 player->fffb_start = _dvr_time_getClock();
2563 player->fffb_current = player->fffb_start;
2564 //get segment current time pos
2565 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002566 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 +08002567 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08002568 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08002569 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002570 } else {
2571 player->fffb_current = _dvr_time_getClock();
2572 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002573 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002574 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002575 if (seek_time <= 0) {
2576 //need seek to pre one segment
2577 seek_time = 0;
2578 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002579 //seek segment pos
2580 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002581 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002582 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08002583 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2584 //set seek time to 0;
2585 DVR_PB_DG(1, "segment seek to 0 at fb mode [%d]id[%lld]", seek_time, player->cur_segment_id);
2586 seek_time = 0;
2587 }
hualing chen041c4092020-04-05 15:11:50 +08002588 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2589 seek_time = 0;
2590 }
hualing chen2aba4022020-03-02 13:49:55 +08002591 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002592 } else {
2593 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002594 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002595 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002596 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 +08002597 }
hualing chen2aba4022020-03-02 13:49:55 +08002598 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002599}
2600
2601
2602//start replay
2603static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2604 //
2605 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002606
2607 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002608 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002609 return DVR_FAILURE;
2610 }
2611
hualing chen5cbe1a62020-02-10 16:36:36 +08002612 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002613 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002614 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002615 AmTsPlayer_stopVideoDecoding(player->handle);
2616 }
2617 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002618 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002619 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002620 AmTsPlayer_stopAudioDecoding(player->handle);
2621 }
hualing chendf118dd2020-05-21 15:49:11 +08002622 if (player->has_ad_audio) {
2623 DVR_PB_DG(1, "fffb stop audio");
2624 player->has_ad_audio =DVR_FALSE;
2625 AmTsPlayer_disableADMix(player->handle);
2626 }
hualing chen2aba4022020-03-02 13:49:55 +08002627
hualing chen5cbe1a62020-02-10 16:36:36 +08002628 //start video and audio
2629
hualing chen2aba4022020-03-02 13:49:55 +08002630 am_tsplayer_video_params vparams;
2631 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002632 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002633 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002634
2635 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002636 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002637 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002638 //start audio and video
2639 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2640 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002641 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002642 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002643 return -1;
2644 }
2645
2646 if (VALID_PID(vparams.pid)) {
2647 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002648 DVR_PB_DG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08002649 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002650 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2651 AmTsPlayer_setVideoParams(player->handle, &vparams);
2652 AmTsPlayer_startVideoDecoding(player->handle);
2653 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002654 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002655 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002656 }
hualing chen31140872020-03-25 12:29:26 +08002657 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08002658 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002659 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002660 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002661 return 0;
2662}
2663
2664static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2665 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002666 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002667 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002668 return DVR_FAILURE;
2669 }
2670
2671 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002672 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002673 pthread_mutex_lock(&player->lock);
2674
hualing chen2aba4022020-03-02 13:49:55 +08002675 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002676 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 +08002677
hualing chen87072a82020-03-12 16:20:12 +08002678 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2679 //seek time set 0
2680 seek_time = 0;
2681 }
hualing chen041c4092020-04-05 15:11:50 +08002682 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002683 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2684 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002685 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002686 pthread_mutex_unlock(&player->lock);
2687 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002688 //send event here and pause
2689 DVR_Play_Notify_t notify;
2690 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002691 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002692 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08002693 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08002694 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 +08002695 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002696 return DVR_SUCCESS;
2697 }
hualing chen2932d372020-04-29 13:44:00 +08002698 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002699 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002700 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002701 }
2702 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002703 _dvr_playback_fffb_replay(handle);
2704
2705 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002706 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002707
hualing chen5cbe1a62020-02-10 16:36:36 +08002708 return DVR_SUCCESS;
2709}
2710
hualing chen87072a82020-03-12 16:20:12 +08002711//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002712static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002713 //
2714 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002715
2716 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002717 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002718 return DVR_FAILURE;
2719 }
2720
hualing chen5cbe1a62020-02-10 16:36:36 +08002721 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002722 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002723 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002724 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002725 }
2726
2727 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002728 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002729 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002730 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002731 //start video and audio
2732
hualing chen2aba4022020-03-02 13:49:55 +08002733 am_tsplayer_video_params vparams;
2734 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002735 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002736 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002737
2738 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002739 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08002740 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002741 //start audio and video
2742 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002743 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002744 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002745 return -1;
2746 }
2747
2748 if (VALID_PID(vparams.pid)) {
2749 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002750 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002751 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002752 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002753 }
hualing chen266b9502020-04-04 17:39:39 +08002754 else {
hualing chen2aba4022020-03-02 13:49:55 +08002755 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002756 }
hualing chen2aba4022020-03-02 13:49:55 +08002757 AmTsPlayer_setVideoParams(player->handle, &vparams);
2758 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002759 }
hualing chena540a7e2020-03-27 16:44:05 +08002760
2761 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08002762 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08002763 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002764 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002765 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002766 if (VALID_PID(aparams.pid)) {
2767 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002768 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08002769 AmTsPlayer_startAudioDecoding(player->handle);
2770 AmTsPlayer_setAudioParams(player->handle, &aparams);
hualing chena540a7e2020-03-27 16:44:05 +08002771 }
hualing chendf118dd2020-05-21 15:49:11 +08002772 if (VALID_PID(adparams.pid)) {
2773 player->has_ad_audio = DVR_TRUE;
2774 DVR_PB_DG(1, "start ad audio");
2775 AmTsPlayer_setADParams(player->handle, &adparams);
2776 AmTsPlayer_enableADMix(player->handle);
2777 }
2778
hualing chen7a56cba2020-04-14 14:09:27 +08002779 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002780 AmTsPlayer_stopFast(player->handle);
2781 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2782 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2783 }
hualing chen2aba4022020-03-02 13:49:55 +08002784 player->cmd.last_cmd = player->cmd.cur_cmd;
2785 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002786 player->cmd.state = DVR_PLAYBACK_STATE_START;
2787 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002788 return 0;
2789}
2790
2791
hualing chenb31a6c62020-01-13 17:27:00 +08002792/**\brief Set play speed
2793 * \param[in] handle playback handle
2794 * \param[in] speed playback speed
2795 * \retval DVR_SUCCESS On success
2796 * \return Error code
2797 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002798int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2799
2800 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002801
2802 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002803 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002804 return DVR_FAILURE;
2805 }
2806
hualing chen4b7c15d2020-04-07 16:13:48 +08002807 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002808 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002809 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002810 return DVR_FAILURE;
2811 }
hualing chenf00cdc82020-06-10 14:23:35 +08002812 if (speed.speed.speed == player->cmd.speed.speed.speed) {
2813 DVR_PB_DG(1, " func: eq speed [%d]", speed.speed.speed);
2814 return DVR_SUCCESS;
2815 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002816 pthread_mutex_lock(&player->lock);
2817 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2818 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2819 player->cmd.last_cmd = player->cmd.cur_cmd;
2820 }
hualing chene41f4372020-06-06 16:29:17 +08002821
hualing chen31140872020-03-25 12:29:26 +08002822 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08002823 IS_KERNEL_SPEED(speed.speed.speed) ) {
2824 //case 1. not start play.only set speed
2825 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2826 //only set speed.and return;
2827 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
2828 player->cmd.speed.speed = speed.speed;
2829 player->speed = (float)speed.speed.speed/(float)100;
2830 player->fffb_play = DVR_FALSE;
2831 pthread_mutex_unlock(&player->lock);
2832 return DVR_SUCCESS;
2833 }
2834 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08002835 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2836 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002837 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002838 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2839 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002840 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002841 AmTsPlayer_stopFast(player->handle);
2842 pthread_mutex_unlock(&player->lock);
2843 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2844 pthread_mutex_lock(&player->lock);
2845 } else {
2846 //set play speed and if audio is start, stop audio.
2847 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002848 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002849 AmTsPlayer_stopAudioDecoding(player->handle);
2850 player->has_audio = DVR_FALSE;
2851 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002852 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002853 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002854 }
hualing chenbcada022020-04-22 14:27:01 +08002855 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08002856 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002857 player->cmd.speed.speed = speed.speed;
2858 player->speed = (float)speed.speed.speed/(float)100;
2859 pthread_mutex_unlock(&player->lock);
2860 return DVR_SUCCESS;
2861 }
hualing chen31140872020-03-25 12:29:26 +08002862 //case 3 fffb mode
2863 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2864 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2865 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002866 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002867 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002868 player->cmd.speed.speed = speed.speed;
2869 player->speed = (float)speed.speed.speed/(float)100;
2870 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08002871 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002872 pthread_mutex_unlock(&player->lock);
2873 return DVR_SUCCESS;
2874 }
2875 }
2876 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002877 IS_KERNEL_SPEED(speed.speed.speed)) {
2878 //case 1. cur speed is kernel support speed,set kernel speed.
2879 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002880 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002881 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2882 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002883 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002884 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08002885 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08002886 } else {
2887 //set play speed and if audio is start, stop audio.
2888 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002889 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002890 AmTsPlayer_stopAudioDecoding(player->handle);
2891 player->has_audio = DVR_FALSE;
2892 }
hualing chenf00cdc82020-06-10 14:23:35 +08002893 DVR_PB_DG(1, "start fast");
2894 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08002895 }
hualing chena540a7e2020-03-27 16:44:05 +08002896 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002897 player->cmd.speed.speed = speed.speed;
2898 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08002899 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002900 pthread_mutex_unlock(&player->lock);
2901 return DVR_SUCCESS;
2902 }
2903 //case 2 fffb mode
2904 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2905 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2906 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002907 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002908 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002909 player->cmd.speed.speed = speed.speed;
2910 player->speed = (float)speed.speed.speed/(float)100;
2911 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08002912 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002913 pthread_mutex_unlock(&player->lock);
2914 return DVR_SUCCESS;
2915 }
hualing chen31140872020-03-25 12:29:26 +08002916 }
hualing chena540a7e2020-03-27 16:44:05 +08002917 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2918 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08002919 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08002920 } else {
hualing chen31140872020-03-25 12:29:26 +08002921 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002922 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2923 else
2924 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08002925 player->fffb_play = DVR_TRUE;
2926 }
2927 DVR_Bool_t init_last_time = DVR_FALSE;
2928 if (player->speed > 0.0f && speed.speed.speed < 0) {
2929 init_last_time = DVR_TRUE;
2930 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
2931 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002932 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002933 player->cmd.speed.mode = speed.mode;
2934 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002935 player->speed = (float)speed.speed.speed/(float)100;
2936 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08002937 _dvr_init_fffb_t(handle);
2938 if (init_last_time == DVR_TRUE)
2939 player->last_send_time_id = UINT64_MAX;
2940
hualing chen87072a82020-03-12 16:20:12 +08002941 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002942 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2943 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002944 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002945 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08002946 _dvr_playback_replay(handle, DVR_FALSE);
2947 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2948 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2949 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08002950 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08002951 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002952 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002953 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002954 return DVR_SUCCESS;
2955}
hualing chen2932d372020-04-29 13:44:00 +08002956
hualing chenb31a6c62020-01-13 17:27:00 +08002957/**\brief Get playback status
2958 * \param[in] handle playback handle
2959 * \param[out] p_status playback status
2960 * \retval DVR_SUCCESS On success
2961 * \return Error code
2962 */
hualing chen2932d372020-04-29 13:44:00 +08002963static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
2964 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002965//
2966 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002967
2968 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002969 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002970 return DVR_FAILURE;
2971 }
hualing chen2932d372020-04-29 13:44:00 +08002972 if (is_lock ==DVR_TRUE)
2973 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002974 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002975 //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 +08002976 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2977 player->state == DVR_PLAYBACK_STATE_START) {
2978 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2979 }
hualing chen041c4092020-04-05 15:11:50 +08002980
hualing chencc91e1c2020-02-28 13:26:17 +08002981 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002982 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002983 if (player->last_send_time_id == UINT64_MAX) {
2984 player->last_send_time_id = player->cur_segment_id;
2985 player->last_cur_time = p_status->time_cur;
2986 }
2987 if (player->last_send_time_id == player->cur_segment_id) {
2988 if (player->speed > 0.0f ) {
2989 //ff
2990 if (p_status->time_cur < player->last_cur_time ) {
2991 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);
2992 p_status->time_cur = player->last_cur_time;
2993 } else {
2994 player->last_cur_time = p_status->time_cur;
2995 }
hualing chene41f4372020-06-06 16:29:17 +08002996 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08002997 //fb
2998 if (p_status->time_cur > player->last_cur_time ) {
2999 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 );
3000 p_status->time_cur = player->last_cur_time;
3001 } else {
3002 player->last_cur_time = p_status->time_cur;
3003 }
3004 }
3005 } else {
3006 player->last_cur_time = p_status->time_cur;
3007 }
3008 player->last_send_time_id = player->cur_segment_id;
hualing chen041c4092020-04-05 15:11:50 +08003009 p_status->segment_id = player->cur_segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003010
hualing chen5cbe1a62020-02-10 16:36:36 +08003011 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003012 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003013 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08003014 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 +08003015 _dvr_playback_state_toString(player->state),
3016 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08003017 p_status->time_cur, p_status->time_end,
3018 p_status->segment_id,player->play_flag,
hualing chen2932d372020-04-29 13:44:00 +08003019 player->speed,
3020 is_lock);
3021 if (is_lock ==DVR_TRUE)
3022 pthread_mutex_unlock(&player->lock);
3023 return DVR_SUCCESS;
3024}
3025
3026
3027/**\brief Get playback status
3028 * \param[in] handle playback handle
3029 * \param[out] p_status playback status
3030 * \retval DVR_SUCCESS On success
3031 * \return Error code
3032 */
3033int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3034 DVR_PlaybackStatus_t *p_status) {
3035//
3036 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3037
3038 if (player == NULL) {
3039 DVR_PB_DG(1, "player is NULL");
3040 return DVR_FAILURE;
3041 }
3042 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3043
hualing chenb31a6c62020-01-13 17:27:00 +08003044 return DVR_SUCCESS;
3045}
3046
hualing chen040df222020-01-17 13:35:02 +08003047void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
3048 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003049 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
3050 DVR_PB_DG(1, "segment flag: %d", segment->flags);
3051 DVR_PB_DG(1, "segment location: [%s]", segment->location);
3052 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
3053 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
3054 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3055 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 +08003056 }
hualing chenb31a6c62020-01-13 17:27:00 +08003057}
3058
hualing chen5cbe1a62020-02-10 16:36:36 +08003059int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003060 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003061
hualing chena540a7e2020-03-27 16:44:05 +08003062 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003063 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003064 return DVR_FAILURE;
3065 }
3066
hualing chen040df222020-01-17 13:35:02 +08003067 DVR_PlaybackSegmentInfo_t *segment;
3068 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003069 {
hualing chen040df222020-01-17 13:35:02 +08003070 if (segment_id >= 0) {
3071 if (segment->segment_id == segment_id) {
3072 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003073 break;
3074 }
3075 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003076 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003077 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003078 }
3079 }
3080 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003081}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003082
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003083int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003084{
3085 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3086 DVR_RETURN_IF_FALSE(player);
3087 DVR_RETURN_IF_FALSE(func);
3088
hualing chen4b7c15d2020-04-07 16:13:48 +08003089 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003090 pthread_mutex_lock(&player->lock);
3091
3092 player->dec_func = func;
3093 player->dec_userdata = userdata;
3094
3095 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003096 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003097 return DVR_SUCCESS;
3098}
3099
3100int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3101{
3102 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3103 DVR_RETURN_IF_FALSE(player);
3104 DVR_RETURN_IF_FALSE(p_secure_buf);
3105 DVR_RETURN_IF_FALSE(len);
3106
hualing chen4b7c15d2020-04-07 16:13:48 +08003107 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003108 pthread_mutex_lock(&player->lock);
3109
3110 player->is_secure_mode = 1;
3111 player->secure_buffer = p_secure_buf;
3112 player->secure_buffer_size = len;
3113
3114 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003115 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003116 return DVR_SUCCESS;
3117}