blob: f6c6743f7c7bcee5e535a16870a432d012082828 [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <poll.h>
11#include <errno.h>
12#include <signal.h>
13#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080014#include <errno.h>
hualing chenb31a6c62020-01-13 17:27:00 +080015
hualing chenb31a6c62020-01-13 17:27:00 +080016#include "dvr_playback.h"
17
hualing chen4b7c15d2020-04-07 16:13:48 +080018#define DVR_PB_DG(_level, _fmt, ...) \
19 DVR_DEBUG(_level, "playback %-30.30s:%d " _fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
20
hualing chena540a7e2020-03-27 16:44:05 +080021
hualing chenb31a6c62020-01-13 17:27:00 +080022#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080023
24
25#define FF_SPEED (2.0f)
26#define FB_SPEED (-1.0f)
27#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
28#define IS_FB(_SPEED_) ((_SPEED_) < FB_SPEED)
29
30#define IS_KERNEL_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_X1) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
31#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
32
hualing chenb31a6c62020-01-13 17:27:00 +080033
hualing chenb5cd42e2020-04-15 17:03:34 +080034#define FFFB_SLEEP_TIME (1000)//500ms
hualing chen4b7c15d2020-04-07 16:13:48 +080035#define FB_DEFAULT_LEFT_TIME (10000)
hualing chen31140872020-03-25 12:29:26 +080036//if tsplayer delay time < 200 and no data can read, we will pause
37#define MIN_TSPLAYER_DELAY_TIME (200)
38
hualing chen041c4092020-04-05 15:11:50 +080039#define MAX_CACHE_TIME (30000)
40
hualing chena540a7e2020-03-27 16:44:05 +080041static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080042//
43static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chencc91e1c2020-02-28 13:26:17 +080044static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type);
45static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
46static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080047static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080048static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
49
hualing chen6d24aa92020-03-23 18:43:47 +080050static char* _dvr_playback_state_toString(int stat)
51{
52 char *string[DVR_PLAYBACK_STATE_FB+1]={
53 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080054 "stop",
hualing chen31140872020-03-25 12:29:26 +080055 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080056 "ff",
57 "fb"
58 };
59
60 if (stat > DVR_PLAYBACK_STATE_FB) {
61 return "unkown";
62 } else {
63 return string[stat];
64 }
65}
hualing chena540a7e2020-03-27 16:44:05 +080066
67static DVR_Bool_t _dvr_support_speed(int speed) {
68
69 DVR_Bool_t ret = DVR_FALSE;
70
71 switch (speed) {
72 case PLAYBACK_SPEED_FBX2:
73 case PLAYBACK_SPEED_FBX4:
74 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +080075 case PLAYBACK_SPEED_FBX16:
76 case PLAYBACK_SPEED_FBX12:
77 case PLAYBACK_SPEED_FBX32:
78 case PLAYBACK_SPEED_FBX48:
79 case PLAYBACK_SPEED_FBX64:
80 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +080081 case PLAYBACK_SPEED_S2:
82 case PLAYBACK_SPEED_S4:
83 case PLAYBACK_SPEED_S8:
84 case PLAYBACK_SPEED_X1:
85 case PLAYBACK_SPEED_X2:
86 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +080087 case PLAYBACK_SPEED_X3:
88 case PLAYBACK_SPEED_X5:
89 case PLAYBACK_SPEED_X6:
90 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +080091 case PLAYBACK_SPEED_X8:
92 case PLAYBACK_SPEED_X12:
93 case PLAYBACK_SPEED_X16:
94 case PLAYBACK_SPEED_X32:
95 case PLAYBACK_SPEED_X48:
96 case PLAYBACK_SPEED_X64:
97 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +080098 ret = DVR_TRUE;
99 break;
100 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800101 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800102 break;
103 }
104 return ret;
105}
hualing chen6e4bfa52020-03-13 14:37:11 +0800106void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
107{
hualing chen4b7c15d2020-04-07 16:13:48 +0800108 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800109 DVR_Playback_t *player = NULL;
110 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800111 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800112 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800113 }
114 switch (event->type) {
115 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
116 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800117 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800118 event->event.video_format.frame_width,
119 event->event.video_format.frame_height,
120 event->event.video_format.frame_rate);
121 break;
122 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800123 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
124 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800125 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800126 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800127 break;
128 }
129 default:
130 break;
131 }
132}
hualing chen2aba4022020-03-02 13:49:55 +0800133void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
134{
hualing chen6e4bfa52020-03-13 14:37:11 +0800135 DVR_Playback_t *player = NULL;
136 if (user_data != NULL) {
137 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800138 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800139 }
hualing chen2aba4022020-03-02 13:49:55 +0800140 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800141 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
142 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800143 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800144 event->event.video_format.frame_width,
145 event->event.video_format.frame_height,
146 event->event.video_format.frame_rate);
147 break;
148 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800149 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
150 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800151 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800152 if (player != NULL)
153 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800154 break;
155 }
156 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800157 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800158 break;
159 }
160 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800161 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800162 player->player_callback_func(player->player_callback_userdata, event);
163 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800164 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800165 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800166 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800167 }
168}
hualing chencc91e1c2020-02-28 13:26:17 +0800169
hualing chen5cbe1a62020-02-10 16:36:36 +0800170//convert video and audio fmt
171static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
172 int format = 0;
173 if (is_audio == DVR_FALSE) {
174 //for video fmt
175 switch (fmt)
176 {
177 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800178 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800179 break;
180 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800181 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800182 break;
183 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800184 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800185 break;
186 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800187 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800188 break;
hualing chena540a7e2020-03-27 16:44:05 +0800189 case DVR_VIDEO_FORMAT_VP9:
190 format = AV_VIDEO_CODEC_VP9;
191 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800192 }
193 } else {
194 //for audio fmt
195 switch (fmt)
196 {
197 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800198 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800199 break;
200 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800201 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800202 break;
203 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800204 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800205 break;
206 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800207 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800208 break;
hualing chena540a7e2020-03-27 16:44:05 +0800209 case DVR_AUDIO_FORMAT_AAC:
210 format = AV_AUDIO_CODEC_AAC;
211 break;
212 case DVR_AUDIO_FORMAT_LATM:
213 format = AV_AUDIO_CODEC_LATM;
214 break;
215 case DVR_AUDIO_FORMAT_PCM:
216 format = AV_AUDIO_CODEC_PCM;
217 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800218 }
219 }
220 return format;
221}
hualing chen040df222020-01-17 13:35:02 +0800222static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800223{
hualing chen040df222020-01-17 13:35:02 +0800224 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800225
hualing chena540a7e2020-03-27 16:44:05 +0800226 if (player == NULL || player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800227 return -1;
228
hualing chena540a7e2020-03-27 16:44:05 +0800229 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800230}
hualing chena540a7e2020-03-27 16:44:05 +0800231
hualing chen5cbe1a62020-02-10 16:36:36 +0800232//get sys time ms
233static int _dvr_time_getClock(void)
234{
235 struct timespec ts;
236 int ms;
237
238 clock_gettime(CLOCK_MONOTONIC, &ts);
239 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
240
241 return ms;
242}
hualing chen86e7d482020-01-16 15:13:33 +0800243
hualing chenb31a6c62020-01-13 17:27:00 +0800244
245//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800246static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800247{
hualing chen040df222020-01-17 13:35:02 +0800248 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800249
hualing chena540a7e2020-03-27 16:44:05 +0800250
251 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800252 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800253 return DVR_FAILURE;
254 }
255
hualing chen86e7d482020-01-16 15:13:33 +0800256 struct timespec ts;
257 clock_gettime(CLOCK_MONOTONIC, &ts);
258 //ms为毫秒,换算成秒
259 ts.tv_sec += ms/1000;
260 //在outtime的基础上,增加ms毫秒
261 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
262 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
263 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
264 //us的值有可能超过1秒,
265 ts.tv_sec += us / 1000000;
266 us = us % 1000000;
267 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800268 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
269 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800270}
hualing chen31140872020-03-25 12:29:26 +0800271//get tsplay delay time ms
272static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
273 DVR_Playback_t *player = (DVR_Playback_t *) handle;
274 int64_t cache = 0;
275 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800276 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800277 return 0;
278 }
279 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800280 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800281 return cache;
282}
hualing chenb31a6c62020-01-13 17:27:00 +0800283//send signal
hualing chen040df222020-01-17 13:35:02 +0800284static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800285{
hualing chen87072a82020-03-12 16:20:12 +0800286 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800287
288 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800289 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800290 return DVR_FAILURE;
291 }
292
hualing chen87072a82020-03-12 16:20:12 +0800293 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800294 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800295 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800296 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800297}
298
hualing chencc91e1c2020-02-28 13:26:17 +0800299//send playback event
300static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify) {
301
302 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800303
304 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800305 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800306 return DVR_FAILURE;
307 }
308
hualing chencc91e1c2020-02-28 13:26:17 +0800309 switch (evt) {
310 case DVR_PLAYBACK_EVENT_ERROR:
hualing chenb5cd42e2020-04-15 17:03:34 +0800311 dvr_playback_get_status(handle, &(notify->play_status));
hualing chencc91e1c2020-02-28 13:26:17 +0800312 break;
313 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
314 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800315 DVR_PB_DG(1, "trans ok EVENT");
hualing chencc91e1c2020-02-28 13:26:17 +0800316 dvr_playback_get_status(handle, &(notify->play_status));
317 break;
318 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
319 break;
320 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
321 break;
322 case DVR_PLAYBACK_EVENT_NO_KEY:
323 break;
324 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800325 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800326 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2aba4022020-03-02 13:49:55 +0800327 dvr_playback_get_status(handle, &(notify->play_status));
hualing chencc91e1c2020-02-28 13:26:17 +0800328 break;
329 case DVR_PLAYBACK_EVENT_REACHED_END:
330 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800331 DVR_PB_DG(1, "reached end EVENT");
hualing chencc91e1c2020-02-28 13:26:17 +0800332 dvr_playback_get_status(handle, &(notify->play_status));
333 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800334 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen6e4bfa52020-03-13 14:37:11 +0800335 dvr_playback_get_status(handle, &(notify->play_status));
336 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800337 default:
338 break;
339 }
340 if (player->openParams.event_fn != NULL)
341 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800342 return DVR_SUCCESS;
343}
344static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle)
345{
346 DVR_Play_Notify_t notify;
347 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
348 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
349 //get play statue not here
350 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify);
351 return DVR_SUCCESS;
352}
353
hualing chen6e4bfa52020-03-13 14:37:11 +0800354static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle)
355{
356 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800357
hualing chen4b7c15d2020-04-07 16:13:48 +0800358 if (1) {
359 return DVR_SUCCESS;
360 }
hualing chena540a7e2020-03-27 16:44:05 +0800361 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800362 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800363 return DVR_FAILURE;
364 }
365
hualing chen6e4bfa52020-03-13 14:37:11 +0800366 if (player->send_time ==0) {
367 player->send_time = _dvr_time_getClock() + 1000;
368 } else if (player->send_time > _dvr_time_getClock()) {
369 return DVR_SUCCESS;
370 }
371 player->send_time = _dvr_time_getClock() + 1000;
372 DVR_Play_Notify_t notify;
373 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
374 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
375 //get play statue not here
376 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify);
377 return DVR_SUCCESS;
378}
379
hualing chencc91e1c2020-02-28 13:26:17 +0800380//check is ongoing segment
381static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
382
383 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800384 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800385
386 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800387 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800388 return DVR_FAILURE;
389 }
hualing chen87072a82020-03-12 16:20:12 +0800390 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800391 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800392 return DVR_FALSE;
393 }
hualing chencc91e1c2020-02-28 13:26:17 +0800394 return DVR_TRUE;
395}
hualing chen4b7c15d2020-04-07 16:13:48 +0800396
397
398static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
399 DVR_Playback_t *player = (DVR_Playback_t *) handle;
400 player->fffb_start = _dvr_time_getClock();
401 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
402 player->fffb_current = player->fffb_start;
403 //get segment current time pos
404 player->fffb_start_pcr = _dvr_get_cur_time(handle);
405 //player->fffb_current = -1;
406 //player->fffb_start = -1;
407 //player->fffb_start_pcr = -1;
408 player->next_fffb_time = _dvr_time_getClock();
409
410 return DVR_SUCCESS;
411}
412
hualing chen2aba4022020-03-02 13:49:55 +0800413static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
414 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800415 player->fffb_start = _dvr_time_getClock();
416 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
417 player->fffb_current = player->fffb_start;
418 //get segment current time pos
419 player->fffb_start_pcr = _dvr_get_cur_time(handle);
420 //player->fffb_current = -1;
421 //player->fffb_start = -1;
422 //player->fffb_start_pcr = -1;
hualing chen2aba4022020-03-02 13:49:55 +0800423 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800424 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800425 return DVR_SUCCESS;
426}
hualing chencc91e1c2020-02-28 13:26:17 +0800427//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800428static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
429
430 DVR_Playback_t *player = (DVR_Playback_t *) handle;
431 DVR_PlaybackSegmentInfo_t *segment;
432 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
433
hualing chena540a7e2020-03-27 16:44:05 +0800434 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800435 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800436 return DVR_FAILURE;
437 }
438
hualing chen87072a82020-03-12 16:20:12 +0800439 int found = 0;
440 int found_eq_id = 0;
441 list_for_each_entry(segment, &player->segment_list, head)
442 {
443 if (player->segment_is_open == DVR_FALSE) {
444 //get first segment from list, case segment is not open
445 if (!IS_FB(player->speed))
446 found = 1;
447 } else if (segment->segment_id == segmentid) {
448 //find cur segment, we need get next one
449 found_eq_id = 1;
450 if (!IS_FB(player->speed)) {
451 found = 1;
452 continue;
453 } else {
454 //if is fb mode.we need used pre segment
455 if (pre_segment != NULL) {
456 found = 1;
457 } else {
458 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800459 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800460 return DVR_FAILURE;
461 }
462 }
463 }
464 if (found == 1) {
465 found = 2;
466 break;
467 }
468 }
469 if (found != 2) {
470 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800471 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800472 return DVR_FAILURE;
473 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800474 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800475 return DVR_SUCCESS;
476}
477
478//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800479static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800480
hualing chen040df222020-01-17 13:35:02 +0800481 DVR_Playback_t *player = (DVR_Playback_t *) handle;
482 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800483 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800484
hualing chena540a7e2020-03-27 16:44:05 +0800485 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800486 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800487 return DVR_FAILURE;
488 }
489
hualing chen86e7d482020-01-16 15:13:33 +0800490 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800491 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800492
hualing chen040df222020-01-17 13:35:02 +0800493 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800494 {
hualing chencc91e1c2020-02-28 13:26:17 +0800495 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800496 //get first segment from list, case segment is not open
497 if (!IS_FB(player->speed))
498 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800499 } else if (segment->segment_id == player->cur_segment_id) {
500 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800501 found_eq_id = 1;
502 if (!IS_FB(player->speed)) {
503 found = 1;
504 continue;
505 } else {
506 //if is fb mode.we need used pre segment
507 if (pre_segment != NULL) {
508 found = 1;
509 } else {
510 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800511 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800512 return DVR_FAILURE;
513 }
514 }
hualing chen86e7d482020-01-16 15:13:33 +0800515 }
516 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800517 if (IS_FB(player->speed)) {
518 //used pre segment
519 segment = pre_segment;
520 }
hualing chencc91e1c2020-02-28 13:26:17 +0800521 //save segment info
522 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800523 player->last_segment.segment_id = player->cur_segment.segment_id;
524 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800525 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
526 //pids
527 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
528
hualing chen5cbe1a62020-02-10 16:36:36 +0800529 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800530 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800531 player->cur_segment_id = segment->segment_id;
532 player->cur_segment.segment_id = segment->segment_id;
533 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800534 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 +0800535 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800536 //pids
hualing chen040df222020-01-17 13:35:02 +0800537 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800538 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800539 break;
hualing chen86e7d482020-01-16 15:13:33 +0800540 }
hualing chen2aba4022020-03-02 13:49:55 +0800541 pre_segment = segment;
542 }
543 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
544 //used the last one segment to open
545 //get segment info
546 player->segment_is_open = DVR_TRUE;
547 player->cur_segment_id = pre_segment->segment_id;
548 player->cur_segment.segment_id = pre_segment->segment_id;
549 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800550 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 +0800551 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
552 //pids
553 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
554 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800555 }
556 if (found != 2) {
557 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800558 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800559 }
560 return DVR_SUCCESS;
561}
hualing chen040df222020-01-17 13:35:02 +0800562//open next segment to play,if reach list end return errro.
563static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800564{
hualing chen040df222020-01-17 13:35:02 +0800565 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800566 Segment_OpenParams_t params;
567 int ret = DVR_SUCCESS;
568
hualing chena540a7e2020-03-27 16:44:05 +0800569 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800570 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800571 return DVR_FAILURE;
572 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800573 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800574
575 ret = _dvr_get_next_segmentId(handle);
576 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800577 DVR_PB_DG(1, "not found segment info");
578 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800579 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800580 }
581
582 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800583 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800584 segment_close(player->r_handle);
585 player->r_handle = NULL;
586 }
587
588 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800589 //cp chur segment path to location
590 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800591 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800592 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800593 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
594
hualing chen86e7d482020-01-16 15:13:33 +0800595 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800596 if (ret == DVR_FAILURE) {
597 DVR_PB_DG(1, "open segment error");
598 }
hualing chen87072a82020-03-12 16:20:12 +0800599 pthread_mutex_unlock(&player->segment_lock);
600 int total = _dvr_get_end_time( handle);
601 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800602 if (IS_FB(player->speed)) {
603 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen266b9502020-04-04 17:39:39 +0800604 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800605 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800606 }
hualing chen87072a82020-03-12 16:20:12 +0800607 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800608 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800609 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800610 return ret;
611}
612
hualing chen5cbe1a62020-02-10 16:36:36 +0800613//open next segment to play,if reach list end return errro.
614static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
615{
616 DVR_Playback_t *player = (DVR_Playback_t *) handle;
617 Segment_OpenParams_t params;
618 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800619 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800620 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800621 return DVR_FAILURE;
622 }
hualing chencc91e1c2020-02-28 13:26:17 +0800623 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800624 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800625 }
hualing chencc91e1c2020-02-28 13:26:17 +0800626 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800627 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800628 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800629 return DVR_FAILURE;
630 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800631 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800632 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800633
634 DVR_PlaybackSegmentInfo_t *segment;
635
636 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800637
hualing chen5cbe1a62020-02-10 16:36:36 +0800638 list_for_each_entry(segment, &player->segment_list, head)
639 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800640 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 +0800641 if (segment->segment_id == segment_id) {
642 found = 1;
643 }
644 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800645 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 +0800646 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800647 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800648 player->cur_segment_id = segment->segment_id;
649 player->cur_segment.segment_id = segment->segment_id;
650 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800651 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800652 //pids
653 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800654 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 +0800655 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800656 }
657 }
hualing chencc91e1c2020-02-28 13:26:17 +0800658 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800659 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800660 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800661 return DVR_FAILURE;
662 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800663 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800664 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800665 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800666 params.segment_id = (uint64_t)player->cur_segment.segment_id;
667 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800668 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 +0800669 if (player->r_handle != NULL) {
670 segment_close(player->r_handle);
671 player->r_handle = NULL;
672 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800673 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800674 if (ret == DVR_FAILURE) {
675 DVR_PB_DG(1, "segment opne error");
676 }
hualing chen2aba4022020-03-02 13:49:55 +0800677 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800678 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800679
hualing chen4b7c15d2020-04-07 16:13:48 +0800680 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 +0800681 return ret;
682}
683
684
685//get play info by segment id
686static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
687 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800688 am_tsplayer_video_params *vparam,
689 am_tsplayer_audio_params *aparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800690
691 DVR_Playback_t *player = (DVR_Playback_t *) handle;
692 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800693 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800694 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800695 return DVR_FAILURE;
696 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800697
698 int found = 0;
699
700 list_for_each_entry(segment, &player->segment_list, head)
701 {
hualing chen87072a82020-03-12 16:20:12 +0800702 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800703 //get first segment from list
704 found = 1;
705 }
706 if (segment->segment_id == segment_id) {
707 found = 1;
708 }
709 if (found == 1) {
710 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800711 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800712 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800713 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800714 player->cur_segment.segment_id = segment->segment_id;
715 player->cur_segment.flags = segment->flags;
716 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800717 player->cur_segment.pids.video.pid = segment->pids.video.pid;
718 player->cur_segment.pids.video.format = segment->pids.video.format;
719 player->cur_segment.pids.video.type = segment->pids.video.type;
720 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
721 player->cur_segment.pids.audio.format = segment->pids.audio.format;
722 player->cur_segment.pids.audio.type = segment->pids.audio.type;
723 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
724 player->cur_segment.pids.ad.format = segment->pids.ad.format;
725 player->cur_segment.pids.ad.type = segment->pids.ad.type;
726 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800727 //
hualing chen2aba4022020-03-02 13:49:55 +0800728 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800729 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800730 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800731 aparam->pid = segment->pids.audio.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800732 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 +0800733 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800734 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800735 }
736 }
hualing chencc91e1c2020-02-28 13:26:17 +0800737 if (found != 2) {
738 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800739 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800740 return DVR_FAILURE;
741 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800742
743 return DVR_SUCCESS;
744}
hualing chencc91e1c2020-02-28 13:26:17 +0800745static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
746 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800747 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800748 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800749 return DVR_FAILURE;
750 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800751
hualing chencc91e1c2020-02-28 13:26:17 +0800752 //compare cur segment
753 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
754 {
755 //check video pids, stop or restart
756 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
757 //check audio pids stop or restart
hualing chen7a56cba2020-04-14 14:09:27 +0800758 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 +0800759 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
760 //check sub audio pids stop or restart
761 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
762 //check pcr pids stop or restart
763 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
764 }
hualing chena540a7e2020-03-27 16:44:05 +0800765 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800766}
hualing chen5cbe1a62020-02-10 16:36:36 +0800767
hualing chencc91e1c2020-02-28 13:26:17 +0800768static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
769{
770 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800771 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800772 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800773 return DVR_FAILURE;
774 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800775 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 +0800776 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
777 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800778 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800779 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800780 AmTsPlayer_showVideo(player->handle);
781 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800782 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
783 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800784 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800785 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800786 AmTsPlayer_hideVideo(player->handle);
787 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800788 }
789 return DVR_SUCCESS;
790}
hualing chena540a7e2020-03-27 16:44:05 +0800791static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
792 DVR_Playback_t *player = (DVR_Playback_t *) handle;
793 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800794 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800795 return DVR_TRUE;
796 }
hualing chen266b9502020-04-04 17:39:39 +0800797 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chena540a7e2020-03-27 16:44:05 +0800798 if (player->first_frame == 1) {
799 return DVR_TRUE;
800 } else {
801 return DVR_FALSE;
802 }
803 } else {
804 return DVR_TRUE;
805 }
806}
hualing chen86e7d482020-01-16 15:13:33 +0800807static void* _dvr_playback_thread(void *arg)
808{
hualing chen040df222020-01-17 13:35:02 +0800809 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800810 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800811 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800812 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800813 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800814
hualing chen6d24aa92020-03-23 18:43:47 +0800815 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800816 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800817 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800818 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800819 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
820
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800821 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800822 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800823 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800824
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800825 if (player->is_secure_mode) {
826 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800827 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800828 return NULL;
829 }
830 }
hualing chen86e7d482020-01-16 15:13:33 +0800831 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800832 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800833 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800834 return NULL;
835 }
hualing chen2aba4022020-03-02 13:49:55 +0800836 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
837 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800838
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800839 dec_bufs.buf_data = malloc(dec_buf_size);
840 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800841 DVR_PB_DG(1, "Malloc dec buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800842 return NULL;
843 }
844 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
845 dec_bufs.buf_size = dec_buf_size;
846
hualing chencc91e1c2020-02-28 13:26:17 +0800847 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800848 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
849 }
hualing chen86e7d482020-01-16 15:13:33 +0800850
hualing chen86e7d482020-01-16 15:13:33 +0800851 if (ret != DVR_SUCCESS) {
852 if (buf != NULL) {
853 free(buf);
854 buf = NULL;
855 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800856 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800857 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800858 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800859 }
hualing chencc91e1c2020-02-28 13:26:17 +0800860 //get play statue not here
861 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
862 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800863 //set video show
864 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800865
hualing chen86e7d482020-01-16 15:13:33 +0800866 int trick_stat = 0;
867 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800868
hualing chen86e7d482020-01-16 15:13:33 +0800869 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800870 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800871
hualing chen2aba4022020-03-02 13:49:55 +0800872 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
873 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800874 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800875 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen31140872020-03-25 12:29:26 +0800876 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800877 {
hualing chen2aba4022020-03-02 13:49:55 +0800878 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
879 if (trick_stat > 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800880 DVR_PB_DG(1, "trick stat[%d] is > 0", trick_stat);
hualing chen87072a82020-03-12 16:20:12 +0800881 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 +0800882 //check last cmd
883 if(player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800884 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800885 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
886 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800887 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
888 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800889 DVR_PB_DG(1, "pause play-------");
hualing chen2aba4022020-03-02 13:49:55 +0800890 //need change to pause state
891 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
892 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800893 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800894 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800895 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800896 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800897 AmTsPlayer_pauseVideoDecoding(player->handle);
898 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800899 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800900 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +0800901 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800902 }
903 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
904 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800905 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800906 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +0800907 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
908 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 +0800909 //used timeout wait need lock first,so we unlock and lock
910 //pthread_mutex_unlock(&player->lock);
911 //pthread_mutex_lock(&player->lock);
912 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
913 pthread_mutex_unlock(&player->lock);
914 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +0800915 } else if (_dvr_time_getClock() < player->next_fffb_time) {
916 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);
917 //used timeout wait need lock first,so we unlock and lock
918 //pthread_mutex_unlock(&player->lock);
919 //pthread_mutex_lock(&player->lock);
920 AmTsPlayer_pauseVideoDecoding(player->handle);
921 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
922 pthread_mutex_unlock(&player->lock);
923 continue;
924
hualing chen2aba4022020-03-02 13:49:55 +0800925 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800926 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
hualing chen2aba4022020-03-02 13:49:55 +0800927 pthread_mutex_unlock(&player->lock);
928 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800929 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800930 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
931 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800932 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
933 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800934 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800935 }else if (player->fffb_play == DVR_TRUE){
936 //for first into fffb when reset speed
937 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
938 _dvr_time_getClock() < player->next_fffb_time) {
939 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);
940 //used timeout wait need lock first,so we unlock and lock
941 //pthread_mutex_unlock(&player->lock);
942 //pthread_mutex_lock(&player->lock);
943 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
944 pthread_mutex_unlock(&player->lock);
945 continue;
946 }
947 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
948 pthread_mutex_unlock(&player->lock);
949 goto_rewrite = DVR_FALSE;
950 real_read = 0;
951 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
952 player->first_frame = 0;
953 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
954 pthread_mutex_lock(&player->lock);
955 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +0800956 }
hualing chenb31a6c62020-01-13 17:27:00 +0800957 }
hualing chen86e7d482020-01-16 15:13:33 +0800958
hualing chen87072a82020-03-12 16:20:12 +0800959 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800960 //check is need send time send end
961 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800962 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
963 pthread_mutex_unlock(&player->lock);
964 continue;
965 }
hualing chen266b9502020-04-04 17:39:39 +0800966 //when seek action is done. we need drop write timeout data.
967 if (player->drop_ts == DVR_TRUE) {
968 goto_rewrite = DVR_FALSE;
969 real_read = 0;
970 player->drop_ts = DVR_FALSE;
971 }
hualing chen2aba4022020-03-02 13:49:55 +0800972 if (goto_rewrite == DVR_TRUE) {
973 goto_rewrite = DVR_FALSE;
974 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800975 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +0800976 goto rewrite;
977 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800978 //.check is need send time send end
979 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen4b7c15d2020-04-07 16:13:48 +0800980 pthread_mutex_lock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800981 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen4b7c15d2020-04-07 16:13:48 +0800982 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800983 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +0800984 if (read < 0 && errno == EIO) {
985 //EIO ERROR, EXIT THRAD
986 DVR_PB_DG(1, "read error.EIO error, exit thread");
987 DVR_Play_Notify_t notify;
988 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
989 notify.event = DVR_PLAYBACK_EVENT_ERROR;
990 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify);
991 goto end;
992 } else if (read < 0) {
993 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
994 }
hualing chen87072a82020-03-12 16:20:12 +0800995 //if on fb mode and read file end , we need calculate pos to retry read.
996 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800997 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 +0800998 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
999 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001000 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1001 pthread_mutex_unlock(&player->lock);
1002 continue;
1003 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001004 //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 +08001005 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001006 //file end.need to play next segment
hualing chen040df222020-01-17 13:35:02 +08001007 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001008 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001009 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001010
1011 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08001012 if (ret != DVR_SUCCESS &&
1013 (delay <= MIN_TSPLAYER_DELAY_TIME ||
1014 delay > MAX_CACHE_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001015 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen041c4092020-04-05 15:11:50 +08001016 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) {
hualing chena540a7e2020-03-27 16:44:05 +08001017 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001018 DVR_Play_Notify_t notify;
1019 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1020 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1021 //get play statue not here
1022 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen31140872020-03-25 12:29:26 +08001023 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify);
1024 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen4b7c15d2020-04-07 16:13:48 +08001025 DVR_PB_DG(1, "playback is send end delay:[%d]", delay);
hualing chen31140872020-03-25 12:29:26 +08001026 pthread_mutex_lock(&player->lock);
1027 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1028 pthread_mutex_unlock(&player->lock);
1029 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001030 } else if (ret != DVR_SUCCESS) {
1031 //not send event and pause,sleep and go to next time to recheck
hualing chen4b7c15d2020-04-07 16:13:48 +08001032 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001033 pthread_mutex_lock(&player->lock);
1034 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1035 pthread_mutex_unlock(&player->lock);
1036 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001037 }
hualing chen31140872020-03-25 12:29:26 +08001038 //change next segment success case
hualing chencc91e1c2020-02-28 13:26:17 +08001039 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
1040 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001041 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001042 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1043 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001044 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001045 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001046 }
1047 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001048 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001049 wbufs.buf_data = buf;
hualing chena540a7e2020-03-27 16:44:05 +08001050 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001051 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001052 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001053 real_read = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001054 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001055 }
hualing chen266b9502020-04-04 17:39:39 +08001056 //if need write whole block size, we need check read buf len is eq block size.
1057 if (b_writed_whole_block == DVR_TRUE) {
1058 //buf_len is block size value.
1059 if (real_read < buf_len) {
1060 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001061 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001062 pthread_mutex_lock(&player->lock);
1063 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1064 pthread_mutex_unlock(&player->lock);
1065 continue;
1066 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001067 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 +08001068 }
1069 }
1070
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001071 if (player->dec_func) {
1072 DVR_CryptoParams_t crypto_params;
1073
1074 memset(&crypto_params, 0, sizeof(crypto_params));
1075 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1076 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1077 crypto_params.segment_id = player->cur_segment.segment_id;
1078 crypto_params.offset = segment_tell_position(player->r_handle);
1079
1080 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1081 crypto_params.input_buffer.addr = (size_t)buf;
1082 crypto_params.input_buffer.size = real_read;
1083
1084 if (player->is_secure_mode) {
1085 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1086 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1087 crypto_params.output_buffer.size = dec_buf_size;
1088 ret = player->dec_func(&crypto_params, player->dec_userdata);
1089 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001090 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001091 } else {
1092 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1093 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1094 crypto_params.output_buffer.size = dec_buf_size;
1095 ret = player->dec_func(&crypto_params, player->dec_userdata);
1096 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001097 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001098 }
1099 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001100 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001101 }
pengfei.liufda2a972020-04-09 14:47:15 +08001102 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001103 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001104rewrite:
hualing chen041c4092020-04-05 15:11:50 +08001105
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001106 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1107 if (ret == AM_TSPLAYER_OK) {
hualing chena540a7e2020-03-27 16:44:05 +08001108 real_read = 0;
1109 write_success++;
1110 continue;
hualing chen87072a82020-03-12 16:20:12 +08001111 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001112 DVR_PB_DG(1, "write time out write_success:%d", write_success);
hualing chena540a7e2020-03-27 16:44:05 +08001113 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001114 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001115 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001116 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001117 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001118 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001119 break;
1120 }
hualing chen2aba4022020-03-02 13:49:55 +08001121 goto_rewrite = DVR_TRUE;
1122 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001123 }
1124 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001125end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001126 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001127 free(buf);
1128 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001129 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001130}
1131
1132
hualing chen040df222020-01-17 13:35:02 +08001133static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001134{
hualing chen040df222020-01-17 13:35:02 +08001135 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001136
1137 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001138 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001139 return DVR_FAILURE;
1140 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001141 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001142 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001143 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001144 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001145 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001146 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001147 if (rc < 0)
1148 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001149 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001150}
1151
1152
hualing chen040df222020-01-17 13:35:02 +08001153static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001154{
hualing chen040df222020-01-17 13:35:02 +08001155 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001156
1157 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001158 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001159 return DVR_FAILURE;
1160 }
1161
hualing chen4b7c15d2020-04-07 16:13:48 +08001162 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001163 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001164 {
1165 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001166 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001167 pthread_join(player->playback_thread, NULL);
1168 }
1169 if (player->r_handle) {
1170 segment_close(player->r_handle);
1171 player->r_handle = NULL;
1172 }
hualing chen7a56cba2020-04-14 14:09:27 +08001173 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001174 return 0;
1175}
1176
hualing chenb31a6c62020-01-13 17:27:00 +08001177/**\brief Open an dvr palyback
1178 * \param[out] p_handle dvr playback addr
1179 * \param[in] params dvr playback open parameters
1180 * \retval DVR_SUCCESS On success
1181 * \return Error code
1182 */
hualing chen040df222020-01-17 13:35:02 +08001183int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001184
hualing chen040df222020-01-17 13:35:02 +08001185 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001186 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001187
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001188 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001189
hualing chen86e7d482020-01-16 15:13:33 +08001190 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001191 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001192 pthread_condattr_init(&cattr);
1193 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1194 pthread_cond_init(&player->cond, &cattr);
1195 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001196
hualing chen5cbe1a62020-02-10 16:36:36 +08001197 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001198 INIT_LIST_HEAD(&player->segment_list);
1199 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1200 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001201 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001202 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001203 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001204 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001205 player->speed = 1.0f;
hualing chen2aba4022020-03-02 13:49:55 +08001206
hualing chen86e7d482020-01-16 15:13:33 +08001207 //store open params
hualing chen040df222020-01-17 13:35:02 +08001208 player->openParams.dmx_dev_id = params->dmx_dev_id;
1209 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001210 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001211 player->openParams.event_fn = params->event_fn;
1212 player->openParams.event_userdata = params->event_userdata;
1213
hualing chen5cbe1a62020-02-10 16:36:36 +08001214 player->has_pids = params->has_pids;
1215
hualing chen2aba4022020-03-02 13:49:55 +08001216 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001217
1218 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1219 //for test get callback
1220 if (0 && player->player_callback_func == NULL) {
1221 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1222 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001223 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 +08001224 }
1225 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001226
hualing chen86e7d482020-01-16 15:13:33 +08001227 //init has audio and video
1228 player->has_video = DVR_FALSE;
1229 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001230 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001231 player->last_segment_id = 0LL;
1232 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001233
hualing chen5cbe1a62020-02-10 16:36:36 +08001234 //init ff fb time
1235 player->fffb_current = -1;
1236 player->fffb_start =-1;
1237 player->fffb_start_pcr = -1;
1238 //seek time
1239 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001240 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001241
1242 //init secure stuff
1243 player->dec_func = NULL;
1244 player->dec_userdata = NULL;
1245 player->is_secure_mode = 0;
1246 player->secure_buffer = NULL;
1247 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001248 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001249
hualing chen4b7c15d2020-04-07 16:13:48 +08001250 player->fffb_play = DVR_FALSE;
1251
1252 player->last_send_time_id = UINT64_MAX;
1253 player->last_cur_time = 0;
1254
hualing chen86e7d482020-01-16 15:13:33 +08001255 *p_handle = player;
1256 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001257}
1258
1259/**\brief Close an dvr palyback
1260 * \param[in] handle playback handle
1261 * \retval DVR_SUCCESS On success
1262 * \return Error code
1263 */
hualing chen040df222020-01-17 13:35:02 +08001264int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001265
hualing chen86e7d482020-01-16 15:13:33 +08001266 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001267 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001268 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001269 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001270 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001271 return DVR_FAILURE;
1272 }
1273
hualing chencc91e1c2020-02-28 13:26:17 +08001274 if (player->state != DVR_PLAYBACK_STATE_STOP)
1275 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001276 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001277 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001278 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1279 } else {
1280 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001281 }
hualing chen7a56cba2020-04-14 14:09:27 +08001282 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001283 pthread_mutex_destroy(&player->lock);
1284 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001285
1286 if (player) {
1287 free(player);
1288 player = NULL;
1289 }
hualing chen7a56cba2020-04-14 14:09:27 +08001290 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001291 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001292}
1293
hualing chenb31a6c62020-01-13 17:27:00 +08001294/**\brief Start play audio and video, used start auido api and start video api
1295 * \param[in] handle playback handle
1296 * \param[in] params audio playback params,contains fmt and pid...
1297 * \retval DVR_SUCCESS On success
1298 * \return Error code
1299 */
hualing chen040df222020-01-17 13:35:02 +08001300int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1301 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001302 am_tsplayer_video_params vparams;
1303 am_tsplayer_audio_params aparams;
hualing chena540a7e2020-03-27 16:44:05 +08001304
1305 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001306 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001307 return DVR_FAILURE;
1308 }
hualing chencc91e1c2020-02-28 13:26:17 +08001309 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001310 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001311
hualing chena540a7e2020-03-27 16:44:05 +08001312 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001313 //can used start api to resume playback
1314 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1315 return dvr_playback_resume(handle);
1316 }
hualing chen87072a82020-03-12 16:20:12 +08001317 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001318 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001319 return DVR_SUCCESS;
1320 }
hualing chen86e7d482020-01-16 15:13:33 +08001321 player->play_flag = flag;
hualing chen5cbe1a62020-02-10 16:36:36 +08001322 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001323 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001324 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001325 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001326 //start audio and video
1327 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1328 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001329 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001330 pthread_mutex_unlock(&player->lock);
1331 DVR_Play_Notify_t notify;
1332 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1333 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1334 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1335 notify.info.transition_failed_data.segment_id = segment_id;
1336 //get play statue not here
1337 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify);
hualing chen86e7d482020-01-16 15:13:33 +08001338 return -1;
1339 }
hualing chen31140872020-03-25 12:29:26 +08001340
hualing chencc91e1c2020-02-28 13:26:17 +08001341 {
hualing chen86e7d482020-01-16 15:13:33 +08001342 if (VALID_PID(vparams.pid)) {
1343 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001344 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001345 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001346 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001347 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1348 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001349 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001350 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001351 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001352 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001353 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001354 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001355 }
1356 AmTsPlayer_setVideoParams(player->handle, &vparams);
1357 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001358 }
hualing chena540a7e2020-03-27 16:44:05 +08001359
hualing chen4b7c15d2020-04-07 16:13:48 +08001360 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1361 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001362 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1363 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1364 player->cmd.state = DVR_PLAYBACK_STATE_START;
1365 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001366 } else {
1367 player->cmd.last_cmd = player->cmd.cur_cmd;
1368 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001369 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001370 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001371 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001372 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001373 } else {
1374 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001375 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08001376 player->has_audio = DVR_TRUE;
1377 AmTsPlayer_setAudioParams(player->handle, &aparams);
1378 AmTsPlayer_startAudioDecoding(player->handle);
1379 }
hualing chen31140872020-03-25 12:29:26 +08001380 }
hualing chencc91e1c2020-02-28 13:26:17 +08001381 player->cmd.state = DVR_PLAYBACK_STATE_START;
1382 player->state = DVR_PLAYBACK_STATE_START;
1383 }
hualing chen86e7d482020-01-16 15:13:33 +08001384 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001385 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001386 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001387 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001388 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001389}
hualing chen040df222020-01-17 13:35:02 +08001390/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001391 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001392 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001393 * \retval DVR_SUCCESS On success
1394 * \return Error code
1395 */
hualing chen040df222020-01-17 13:35:02 +08001396int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1397 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001398
hualing chena540a7e2020-03-27 16:44:05 +08001399 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001400 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001401 return DVR_FAILURE;
1402 }
1403
hualing chen4b7c15d2020-04-07 16:13:48 +08001404 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001405 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001406
hualing chen040df222020-01-17 13:35:02 +08001407 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1408 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001409
hualing chen86e7d482020-01-16 15:13:33 +08001410 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001411 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001412 //cp location
hualing chen040df222020-01-17 13:35:02 +08001413 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001414
hualing chen4b7c15d2020-04-07 16:13:48 +08001415 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 +08001416 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001417
1418 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001419 segment->pids.video.pid = info->pids.video.pid;
1420 segment->pids.video.format = info->pids.video.format;
1421 segment->pids.video.type = info->pids.video.type;
1422
hualing chen2aba4022020-03-02 13:49:55 +08001423 segment->pids.audio.pid = info->pids.audio.pid;
1424 segment->pids.audio.format = info->pids.audio.format;
1425 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001426
hualing chen2aba4022020-03-02 13:49:55 +08001427 segment->pids.ad.pid = info->pids.ad.pid;
1428 segment->pids.ad.format = info->pids.ad.format;
1429 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001430
1431 segment->pids.pcr.pid = info->pids.pcr.pid;
1432
hualing chen4b7c15d2020-04-07 16:13:48 +08001433 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 +08001434 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001435 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001436 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001437 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001438
hualing chen5cbe1a62020-02-10 16:36:36 +08001439 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001440}
hualing chen040df222020-01-17 13:35:02 +08001441/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001442 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001443 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001444 * \retval DVR_SUCCESS On success
1445 * \return Error code
1446 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001447int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001448 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001449 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001450 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001451 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001452 return DVR_FAILURE;
1453 }
1454
hualing chencc91e1c2020-02-28 13:26:17 +08001455 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001456 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001457 return DVR_FAILURE;
1458 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001459 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001460 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001461 DVR_PlaybackSegmentInfo_t *segment = NULL;
1462 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1463 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001464 {
hualing chen040df222020-01-17 13:35:02 +08001465 if (segment->segment_id == segment_id) {
1466 list_del(&segment->head);
1467 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001468 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001469 }
hualing chen86e7d482020-01-16 15:13:33 +08001470 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001471 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001472 pthread_mutex_unlock(&player->lock);
1473
1474 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001475}
hualing chen040df222020-01-17 13:35:02 +08001476/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001477 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001478 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001479 * \retval DVR_SUCCESS On success
1480 * \return Error code
1481 */
hualing chen040df222020-01-17 13:35:02 +08001482int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001483 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001484 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001485 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001486 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001487 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001488 return DVR_FAILURE;
1489 }
1490
hualing chen040df222020-01-17 13:35:02 +08001491 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001492 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001493 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001494 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001495 {
hualing chen040df222020-01-17 13:35:02 +08001496 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001497 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001498 }
hualing chen86e7d482020-01-16 15:13:33 +08001499 // if encramble to free, only set flag and return;
1500
1501 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001502 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001503 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1504 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001505 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001506 AmTsPlayer_hideVideo(player->handle);
1507 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001508 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1509 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001510 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001511 AmTsPlayer_showVideo(player->handle);
1512 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001513 } else {
1514 //do nothing
1515 }
1516 } else {
1517 //do nothing
1518 }
1519 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001520 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001521 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001522 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001523 pthread_mutex_unlock(&player->lock);
1524 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001525}
1526
1527
hualing chen5cbe1a62020-02-10 16:36:36 +08001528static 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 +08001529 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001530 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001531 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001532 return DVR_FAILURE;
1533 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001534 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001535 if (now_pid.pid == set_pid.pid) {
1536 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001537 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001538 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001539 if (VALID_PID(now_pid.pid)) {
1540 //stop now stream
1541 if (type == 0) {
1542 //stop vieo
hualing chen4b7c15d2020-04-07 16:13:48 +08001543 DVR_PB_DG(1, "stop video");
hualing chen2aba4022020-03-02 13:49:55 +08001544 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001545 player->has_video = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001546 } else if (type == 1) {
1547 //stop audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001548 DVR_PB_DG(1, "stop audio");
hualing chen2aba4022020-03-02 13:49:55 +08001549 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001550 player->has_audio = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001551 } else if (type == 2) {
1552 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001553 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001554 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001555 } else if (type == 3) {
1556 //pcr
1557 }
1558 }
1559 if (VALID_PID(set_pid.pid)) {
1560 //start
1561 if (type == 0) {
1562 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001563 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001564 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001565 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001566 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001567 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001568 AmTsPlayer_setVideoParams(player->handle, &vparams);
1569 AmTsPlayer_startVideoDecoding(player->handle);
1570 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001571 } else if (type == 1) {
1572 //start audio
hualing chen2aba4022020-03-02 13:49:55 +08001573 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001574 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001575 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001576 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001577 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001578 AmTsPlayer_setAudioParams(player->handle, &aparams);
1579 AmTsPlayer_startAudioDecoding(player->handle);
1580 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001581 } else if (type == 2) {
hualing chen2aba4022020-03-02 13:49:55 +08001582 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001583 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001584 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001585 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001586 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chena540a7e2020-03-27 16:44:05 +08001587 AmTsPlayer_setADParams(player->handle, &aparams);
1588 AmTsPlayer_enableADMix(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001589 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001590 } else if (type == 3) {
1591 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001592 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001593 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001594 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001595 //audio and video all close
1596 if (!player->has_audio && !player->has_video) {
1597 player->state = DVR_PLAYBACK_STATE_STOP;
1598 }
hualing chen86e7d482020-01-16 15:13:33 +08001599 }
1600 }
1601 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001602}
hualing chen5cbe1a62020-02-10 16:36:36 +08001603/**\brief dvr play back update segment pids
1604 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001605 * add pid stream and stop remove pid stream.
1606 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001607 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001608 * \retval DVR_SUCCESS On success
1609 * \return Error code
1610 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001611int 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 +08001612 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001613 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001614 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001615 return DVR_FAILURE;
1616 }
1617
hualing chen040df222020-01-17 13:35:02 +08001618 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001619 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001620 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001621 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 +08001622
hualing chen040df222020-01-17 13:35:02 +08001623 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001624 {
hualing chen040df222020-01-17 13:35:02 +08001625 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001626
1627 if (player->cur_segment_id == segment_id) {
1628 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1629 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1630 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001631 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001632 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001633 return 0;
1634 }
1635
1636 //if segment is on going segment,we need stop start stream
1637 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001638 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001639 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001640 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001641 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001642 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001643 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001644 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001645 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001646 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1647 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001648 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1649 //if state is pause, we need process at resume api. we only record change info
1650 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1651 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1652 if (VALID_PID(segment->pids.video.pid)
1653 && VALID_PID(p_pids->video.pid)
1654 && segment->pids.video.pid != p_pids->video.pid) {
1655 //restart video
1656 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1657 }
1658 if (!VALID_PID(segment->pids.video.pid)
1659 && VALID_PID(p_pids->video.pid)
1660 && segment->pids.video.pid != p_pids->video.pid) {
1661 //start video
1662 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1663 }
1664 if (VALID_PID(segment->pids.video.pid)
1665 && !VALID_PID(p_pids->video.pid)
1666 && segment->pids.video.pid != p_pids->video.pid) {
1667 //stop video
1668 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1669 }
1670 if (VALID_PID(segment->pids.audio.pid)
1671 && VALID_PID(p_pids->audio.pid)
1672 && segment->pids.audio.pid != p_pids->audio.pid) {
1673 //restart audio
1674 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1675 }
1676 if (!VALID_PID(segment->pids.audio.pid)
1677 && VALID_PID(p_pids->audio.pid)
1678 && segment->pids.audio.pid != p_pids->audio.pid) {
1679 //start audio
1680 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1681 }
1682 if (VALID_PID(segment->pids.audio.pid)
1683 && !VALID_PID(p_pids->audio.pid)
1684 && segment->pids.audio.pid != p_pids->audio.pid) {
1685 //stop audio
1686 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1687 }
1688 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1689 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1690 //do nothing
1691 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1692 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1693 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1694 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1695 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1696 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1697 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1698 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1699 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1700 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1701 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1702 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1703 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1704 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1705 } else {
1706 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1707 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1708 }
1709
1710 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1711 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1712 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1713 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1714 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1715 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1716 //not occur this case
1717 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1718 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1719 } else {
1720 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1721 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1722 }
1723
1724 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1725 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1726 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1727 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1728 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1729 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1730 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1731 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1732 } else {
1733 //not occur this case
1734 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1735 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1736 }
1737 }
1738 }
hualing chene10666f2020-04-14 13:58:37 +08001739 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08001740 }
hualing chen86e7d482020-01-16 15:13:33 +08001741 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08001742 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08001743 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08001744 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001745 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001746 }
hualing chen86e7d482020-01-16 15:13:33 +08001747 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001748 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001749 pthread_mutex_unlock(&player->lock);
1750 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001751}
1752/**\brief Stop play, will stop video and audio
1753 * \param[in] handle playback handle
1754 * \param[in] clear is clear last frame
1755 * \retval DVR_SUCCESS On success
1756 * \return Error code
1757 */
hualing chen040df222020-01-17 13:35:02 +08001758int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1759 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001760
1761 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001762 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001763 return DVR_FAILURE;
1764 }
hualing chenb96aa2c2020-04-15 14:13:53 +08001765 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1766 DVR_PB_DG(1, ":playback is stoped");
1767 return DVR_SUCCESS;
1768 }
Ke Gong3c0caba2020-04-21 22:58:18 -07001769 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1770 DVR_PB_DG(1, ":playback is stoped");
1771 return DVR_SUCCESS;
1772 }
hualing chen7a56cba2020-04-14 14:09:27 +08001773 DVR_PB_DG(1, ":into");
hualing chen87072a82020-03-12 16:20:12 +08001774 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001775 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001776 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08001777 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08001778 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001779 if (player->has_video) {
1780 AmTsPlayer_resumeVideoDecoding(player->handle);
1781 }
1782 if (player->has_audio) {
1783 AmTsPlayer_resumeAudioDecoding(player->handle);
1784 }
hualing chen7a56cba2020-04-14 14:09:27 +08001785 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001786 if (player->has_video) {
1787 player->has_video = DVR_FALSE;
1788 AmTsPlayer_showVideo(player->handle);
1789 AmTsPlayer_stopVideoDecoding(player->handle);
1790 }
hualing chen7a56cba2020-04-14 14:09:27 +08001791 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001792 if (player->has_audio) {
1793 player->has_audio = DVR_FALSE;
1794 AmTsPlayer_stopAudioDecoding(player->handle);
1795 }
hualing chen7a56cba2020-04-14 14:09:27 +08001796 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001797
hualing chen86e7d482020-01-16 15:13:33 +08001798 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001799 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1800 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1801 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001802 player->cur_segment_id = UINT64_MAX;
1803 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001804 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08001805 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08001806 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001807 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001808}
1809/**\brief Start play audio
1810 * \param[in] handle playback handle
1811 * \param[in] params audio playback params,contains fmt and pid...
1812 * \retval DVR_SUCCESS On success
1813 * \return Error code
1814 */
hualing chen2aba4022020-03-02 13:49:55 +08001815
1816int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001817 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001818
1819 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001820 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001821 return DVR_FAILURE;
1822 }
hualing chen86e7d482020-01-16 15:13:33 +08001823 _start_playback_thread(handle);
1824 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001825 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001826 pthread_mutex_lock(&player->lock);
1827 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001828 AmTsPlayer_setAudioParams(player->handle, param);
1829 AmTsPlayer_startAudioDecoding(player->handle);
1830 //playback_device_audio_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001831 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001832 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1833 player->cmd.state = DVR_PLAYBACK_STATE_START;
1834 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001835 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001836 pthread_mutex_unlock(&player->lock);
1837 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001838}
1839/**\brief Stop play audio
1840 * \param[in] handle playback handle
1841 * \retval DVR_SUCCESS On success
1842 * \return Error code
1843 */
hualing chen040df222020-01-17 13:35:02 +08001844int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1845 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001846
1847 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001848 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001849 return DVR_FAILURE;
1850 }
1851
hualing chen2aba4022020-03-02 13:49:55 +08001852 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001853 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001854 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1855 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001856 //destory thread
1857 _stop_playback_thread(handle);
1858 } else {
1859 //do nothing.video is playing
1860 }
hualing chen7a56cba2020-04-14 14:09:27 +08001861 DVR_PB_DG(1, "lock");
1862 pthread_mutex_lock(&player->lock);
1863
hualing chen87072a82020-03-12 16:20:12 +08001864 player->has_audio = DVR_FALSE;
1865
1866 AmTsPlayer_stopAudioDecoding(player->handle);
1867 player->cmd.last_cmd = player->cmd.cur_cmd;
1868 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
1869
hualing chen4b7c15d2020-04-07 16:13:48 +08001870 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001871 pthread_mutex_unlock(&player->lock);
1872 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001873}
1874/**\brief Start play video
1875 * \param[in] handle playback handle
1876 * \param[in] params video playback params,contains fmt and pid...
1877 * \retval DVR_SUCCESS On success
1878 * \return Error code
1879 */
hualing chen2aba4022020-03-02 13:49:55 +08001880int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001881 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001882
1883 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001884 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001885 return DVR_FAILURE;
1886 }
1887
hualing chen86e7d482020-01-16 15:13:33 +08001888 _start_playback_thread(handle);
1889 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001890 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001891 pthread_mutex_lock(&player->lock);
1892 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001893 AmTsPlayer_setVideoParams(player->handle, param);
1894 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001895
1896 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001897 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08001898 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001899 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08001900 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1901 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08001902 }
1903 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001904 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
1905 player->cmd.state = DVR_PLAYBACK_STATE_START;
1906 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001907 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001908 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001909 return DVR_SUCCESS;
1910}
1911/**\brief Stop play video
1912 * \param[in] handle playback handle
1913 * \retval DVR_SUCCESS On success
1914 * \return Error code
1915 */
hualing chen040df222020-01-17 13:35:02 +08001916int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
1917 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001918
1919 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001920 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001921 return DVR_FAILURE;
1922 }
1923
hualing chen86e7d482020-01-16 15:13:33 +08001924 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001925 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1926 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001927 //destory thread
1928 _stop_playback_thread(handle);
1929 } else {
1930 //do nothing.audio is playing
1931 }
hualing chen7a56cba2020-04-14 14:09:27 +08001932
1933 DVR_PB_DG(1, "lock");
1934 pthread_mutex_lock(&player->lock);
1935
hualing chen87072a82020-03-12 16:20:12 +08001936 player->has_video = DVR_FALSE;
1937
1938 AmTsPlayer_stopVideoDecoding(player->handle);
1939 //playback_device_video_stop(player->handle);
1940
1941 player->cmd.last_cmd = player->cmd.cur_cmd;
1942 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
1943
hualing chen4b7c15d2020-04-07 16:13:48 +08001944 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001945 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001946 return DVR_SUCCESS;
1947}
1948/**\brief Pause play
1949 * \param[in] handle playback handle
1950 * \param[in] flush whether its internal buffers should be flushed
1951 * \retval DVR_SUCCESS On success
1952 * \return Error code
1953 */
hualing chen040df222020-01-17 13:35:02 +08001954int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
1955 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001956
1957 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001958 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001959 return DVR_FAILURE;
1960 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001961 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001962 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001963 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08001964 if (player->has_video)
1965 AmTsPlayer_pauseVideoDecoding(player->handle);
1966 if (player->has_video)
1967 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001968
1969 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001970 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1971 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1972 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1973 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001974 } else {
1975 player->cmd.last_cmd = player->cmd.cur_cmd;
1976 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1977 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1978 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001979 }
hualing chen86e7d482020-01-16 15:13:33 +08001980 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001981 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08001982
hualing chen86e7d482020-01-16 15:13:33 +08001983 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001984}
1985
hualing chen5cbe1a62020-02-10 16:36:36 +08001986//not add lock
1987static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
1988{
1989 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1990
hualing chena540a7e2020-03-27 16:44:05 +08001991 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001992 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001993 return DVR_FAILURE;
1994 }
1995
hualing chen5cbe1a62020-02-10 16:36:36 +08001996 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08001997 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08001998 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001999 am_tsplayer_video_params vparams;
2000 am_tsplayer_audio_params aparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002001 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002002
2003 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002004 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002005 pthread_mutex_unlock(&player->lock);
2006
2007 switch (cmd) {
2008 case DVR_PLAYBACK_CMD_AVRESTART:
2009 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002010 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002011 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002012 break;
2013 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002014 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2015 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002016 break;
2017 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002018 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002019 break;
2020 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002021 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002022 break;
2023 case DVR_PLAYBACK_CMD_ARESTART:
2024 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002025 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2026 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002027 break;
2028 case DVR_PLAYBACK_CMD_ASTART:
hualing chen2aba4022020-03-02 13:49:55 +08002029 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002030 break;
2031 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002032 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002033 break;
2034 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002035 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2036 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2037 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002038 break;
2039 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002040 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2041 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002042 break;
2043 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002044 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2045 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2046 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002047 break;
2048 case DVR_PLAYBACK_CMD_STOP:
2049 break;
2050 case DVR_PLAYBACK_CMD_START:
2051 break;
2052 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002053 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2054 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
2055 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002056 break;
2057 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002058 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2059 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
2060 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002061 break;
2062 case DVR_PLAYBACK_CMD_FF:
2063 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002064 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002065 break;
2066 default:
2067 break;
2068 }
2069 return DVR_SUCCESS;
2070}
2071
2072/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002073 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002074 * \retval DVR_SUCCESS On success
2075 * \return Error code
2076 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002077int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2078 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2079
hualing chena540a7e2020-03-27 16:44:05 +08002080 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002081 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002082 return DVR_FAILURE;
2083 }
2084
hualing chen5cbe1a62020-02-10 16:36:36 +08002085 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002086 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002087 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002088 if (player->has_video) {
2089 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2090 AmTsPlayer_resumeVideoDecoding(player->handle);
2091 }
2092 if (player->has_audio) {
2093 AmTsPlayer_resumeAudioDecoding(player->handle);
2094 }
2095 //check is has audio param,if has audio .we need start audio,
2096 //we will stop audio when ff fb, if reach end, we will pause.so we need
2097 //start audio when resume play
2098
2099 am_tsplayer_video_params vparams;
2100 am_tsplayer_audio_params aparams;
2101 uint64_t segmentid = player->cur_segment_id;
2102 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
2103 //valid audio pid, start audio
2104 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid)) {
2105 player->has_audio = DVR_TRUE;
2106 AmTsPlayer_setAudioParams(player->handle, &aparams);
2107 AmTsPlayer_startAudioDecoding(player->handle);
2108 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002109 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d", aparams.pid, player->has_audio);
hualing chen266b9502020-04-04 17:39:39 +08002110 }
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_START;
2114 player->state = DVR_PLAYBACK_STATE_START;
2115 } else {
2116 player->cmd.last_cmd = player->cmd.cur_cmd;
2117 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2118 player->cmd.state = DVR_PLAYBACK_STATE_START;
2119 player->state = DVR_PLAYBACK_STATE_START;
2120 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002121 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002122 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002123 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
2124 if (player->has_video)
2125 AmTsPlayer_resumeVideoDecoding(player->handle);
2126 if (player->has_audio)
2127 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002128 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002129 player->cmd.state = DVR_PLAYBACK_STATE_START;
2130 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002131 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002132 } else {
2133 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2134 {
2135 pthread_mutex_lock(&player->lock);
2136 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002137 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002138 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2139 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2140 pthread_mutex_unlock(&player->lock);
2141 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002142 }
2143 return DVR_SUCCESS;
2144}
2145
hualing chena540a7e2020-03-27 16:44:05 +08002146static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2147
2148 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2149 DVR_PlaybackSegmentInfo_t *segment = NULL;
2150 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2151 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2152
2153 list_for_each_entry(segment, &player->segment_list, head)
2154 {
2155 if (segment->segment_id == segment_id) {
2156 cur_segment = segment;
2157 }
2158 if (segment->segment_id == set_seg_id) {
2159 set_segment = segment;
2160 }
2161 if (cur_segment != NULL && set_segment != NULL) {
2162 break;
2163 }
2164 }
2165 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002166 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002167 return DVR_TRUE;
2168 }
2169 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2170 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2171 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2172 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002173 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 +08002174 return DVR_TRUE;
2175 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002176 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002177 return DVR_FALSE;
2178}
2179
hualing chen5cbe1a62020-02-10 16:36:36 +08002180/**\brief seek
2181 * \param[in] handle playback handle
2182 * \param[in] time_offset time offset base cur segment
2183 * \retval DVR_SUCCESS On success
2184 * \return Error code
2185 */
hualing chencc91e1c2020-02-28 13:26:17 +08002186int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002187 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002188
2189 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002190 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002191 return DVR_FAILURE;
2192 }
2193
hualing chen4b7c15d2020-04-07 16:13:48 +08002194 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 +08002195 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002196
hualing chen86e7d482020-01-16 15:13:33 +08002197 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002198 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002199 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002200
hualing chen5cbe1a62020-02-10 16:36:36 +08002201 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002202 int ret = _dvr_open_segment(handle, segment_id);
2203 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002204 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002205 pthread_mutex_unlock(&player->lock);
2206 return DVR_FAILURE;
2207 }
2208 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2209 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002210 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002211 //pthread_mutex_unlock(&player->lock);
2212 //return DVR_SUCCESS;
2213 time_offset = _dvr_get_end_time(handle);
2214 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002215 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chen87072a82020-03-12 16:20:12 +08002216 pthread_mutex_unlock(&player->lock);
2217 return DVR_FAILURE;
2218 }
2219 }
2220
hualing chen4b7c15d2020-04-07 16:13:48 +08002221 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 +08002222 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002223 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2224 //forward playback.not seek end of file
2225 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2226 //default -2000ms
2227 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2228 }
hualing chen86e7d482020-01-16 15:13:33 +08002229 }
hualing chen2aba4022020-03-02 13:49:55 +08002230 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002231 player->drop_ts = DVR_TRUE;
2232 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002233 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 +08002234 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002235 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002236
hualing chen2aba4022020-03-02 13:49:55 +08002237 _dvr_get_end_time(handle);
2238 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002239 player->fffb_current = _dvr_time_getClock();
2240 player->fffb_start = player->fffb_current;
2241 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2242 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002243 //pause state if need to replayer false
2244 if (player->state == DVR_PLAYBACK_STATE_STOP ||
2245 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002246 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002247 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002248 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002249 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002250 }
hualing chen86e7d482020-01-16 15:13:33 +08002251 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002252 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 +08002253 if (player->has_video) {
2254 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002255 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002256 }
2257
2258 if (player->has_audio) {
2259 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002260 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002261 }
hualing chen86e7d482020-01-16 15:13:33 +08002262 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002263 am_tsplayer_video_params vparams;
2264 am_tsplayer_audio_params aparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002265
hualing chen040df222020-01-17 13:35:02 +08002266 player->cur_segment_id = segment_id;
2267
2268 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002269 //get segment info and audio video pid fmt ;
2270 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08002271 //start audio and video
2272 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2273 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002274 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 +08002275 pthread_mutex_unlock(&player->lock);
2276 return -1;
2277 }
2278 //add
hualing chen040df222020-01-17 13:35:02 +08002279 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002280 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002281 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002282 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chen31140872020-03-25 12:29:26 +08002283 player->speed > 1.0f||
2284 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002285 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002286 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002287 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002288 }
hualing chen2aba4022020-03-02 13:49:55 +08002289 AmTsPlayer_setVideoParams(player->handle, &vparams);
2290 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002291 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002292 }
hualing chen86e7d482020-01-16 15:13:33 +08002293 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002294 DVR_PB_DG(1, "start audio seek");
hualing chen2aba4022020-03-02 13:49:55 +08002295 AmTsPlayer_setAudioParams(player->handle, &aparams);
2296 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002297 player->has_audio = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002298 }
hualing chen86e7d482020-01-16 15:13:33 +08002299 }
hualing chen2aba4022020-03-02 13:49:55 +08002300 if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
2301 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2302 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2303 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
2304 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))) {
2305 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2306 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002307 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002308 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2309 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002310 player->speed > 1.0f||
2311 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002312 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002313 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002314 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002315 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002316 player->cmd.last_cmd = player->cmd.cur_cmd;
2317 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2318 player->cmd.state = DVR_PLAYBACK_STATE_START;
2319 player->state = DVR_PLAYBACK_STATE_START;
2320 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002321 player->last_send_time_id = UINT64_MAX;
2322 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002323 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002324
2325 return DVR_SUCCESS;
2326}
hualing chen5cbe1a62020-02-10 16:36:36 +08002327
hualing chen5cbe1a62020-02-10 16:36:36 +08002328static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2329 //get cur time of segment
2330 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002331
2332 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002333 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002334 return DVR_FAILURE;
2335 }
2336
hualing chen31140872020-03-25 12:29:26 +08002337 int64_t cache = 0;//defalut es buf cache 500ms
2338 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002339 pthread_mutex_lock(&player->segment_lock);
2340 uint64_t cur = segment_tell_current_time(player->r_handle);
2341 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002342 DVR_PB_DG(1, "get cur time [%lld] cache:%lld cur id [%lld]", cur, cache, player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002343 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2344 cache = 0;
2345 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002346 int cur_time = (int)(cur > cache ? cur - cache : 0);
2347 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002348}
2349
2350//get current segment current pcr time of read pos
2351static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2352 //get cur time of segment
2353 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002354
2355 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002356 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002357 return DVR_FAILURE;
2358 }
2359
hualing chen2aba4022020-03-02 13:49:55 +08002360 pthread_mutex_lock(&player->segment_lock);
2361 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002362 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002363 pthread_mutex_unlock(&player->segment_lock);
2364 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002365}
2366
hualing chen4b7c15d2020-04-07 16:13:48 +08002367#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002368//start replay
2369static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2370
2371 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2372 //calculate pcr seek time
2373 int t_diff = 0;
2374 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002375
2376 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002377 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002378 return DVR_FAILURE;
2379 }
2380
hualing chen5cbe1a62020-02-10 16:36:36 +08002381 if (player->fffb_start == -1) {
2382 //set fffb start time ms
2383 player->fffb_start = _dvr_time_getClock();
2384 player->fffb_current = player->fffb_start;
2385 //get segment current time pos
2386 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002387 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 +08002388 t_diff = 0;
hualing chen2aba4022020-03-02 13:49:55 +08002389 //default first time 1ms seek
hualing chen87072a82020-03-12 16:20:12 +08002390 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002391 } else {
2392 player->fffb_current = _dvr_time_getClock();
2393 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002394 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002395 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002396 if (seek_time <= 0) {
2397 //need seek to pre one segment
2398 seek_time = 0;
2399 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002400 //seek segment pos
2401 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002402 pthread_mutex_lock(&player->segment_lock);
hualing chen041c4092020-04-05 15:11:50 +08002403 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2404 seek_time = 0;
2405 }
hualing chen2aba4022020-03-02 13:49:55 +08002406 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002407 } else {
2408 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002409 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002410 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002411 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 +08002412 }
hualing chen2aba4022020-03-02 13:49:55 +08002413 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002414}
2415
2416
2417//start replay
2418static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2419 //
2420 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002421
2422 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002423 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002424 return DVR_FAILURE;
2425 }
2426
hualing chen5cbe1a62020-02-10 16:36:36 +08002427 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002428 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002429 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002430 AmTsPlayer_stopVideoDecoding(player->handle);
2431 }
2432 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002433 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002434 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002435 AmTsPlayer_stopAudioDecoding(player->handle);
2436 }
2437
hualing chen5cbe1a62020-02-10 16:36:36 +08002438 //start video and audio
2439
hualing chen2aba4022020-03-02 13:49:55 +08002440 am_tsplayer_video_params vparams;
2441 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002442 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002443
2444 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002445 //pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002446 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2447 //start audio and video
2448 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2449 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002450 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002451 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002452 return -1;
2453 }
2454
2455 if (VALID_PID(vparams.pid)) {
2456 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002457 DVR_PB_DG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08002458 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002459 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2460 AmTsPlayer_setVideoParams(player->handle, &vparams);
2461 AmTsPlayer_startVideoDecoding(player->handle);
2462 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002463 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002464 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002465 }
hualing chena540a7e2020-03-27 16:44:05 +08002466 if (0 && VALID_PID(aparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002467 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002468 DVR_PB_DG(1, "fffb start audio");
hualing chen2aba4022020-03-02 13:49:55 +08002469 AmTsPlayer_setAudioParams(player->handle, &aparams);
2470 AmTsPlayer_startAudioDecoding(player->handle);
2471 //playback_device_audio_start(player->handle , &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002472 }
hualing chen31140872020-03-25 12:29:26 +08002473 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08002474 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002475 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002476 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002477 return 0;
2478}
2479
2480static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2481 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002482
2483 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002484 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002485 return DVR_FAILURE;
2486 }
2487
2488 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002489 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002490 pthread_mutex_lock(&player->lock);
2491
hualing chen2aba4022020-03-02 13:49:55 +08002492 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002493 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 +08002494
hualing chen87072a82020-03-12 16:20:12 +08002495 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2496 //seek time set 0
2497 seek_time = 0;
2498 }
hualing chen041c4092020-04-05 15:11:50 +08002499 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002500 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2501 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002502 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002503 pthread_mutex_unlock(&player->lock);
2504 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002505 //send event here and pause
2506 DVR_Play_Notify_t notify;
2507 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002508 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002509 //get play statue not here
2510 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify);
hualing chen4b7c15d2020-04-07 16:13:48 +08002511 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 +08002512 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002513 return DVR_SUCCESS;
2514 }
hualing chen87072a82020-03-12 16:20:12 +08002515 _dvr_playback_sent_transition_ok(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002516 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002517 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002518 }
2519 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002520 _dvr_playback_fffb_replay(handle);
2521
2522 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002523 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002524
hualing chen5cbe1a62020-02-10 16:36:36 +08002525 return DVR_SUCCESS;
2526}
2527
hualing chen87072a82020-03-12 16:20:12 +08002528//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002529static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002530 //
2531 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002532
2533 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002534 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002535 return DVR_FAILURE;
2536 }
2537
hualing chen5cbe1a62020-02-10 16:36:36 +08002538 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002539 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002540 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002541 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002542 }
2543
2544 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002545 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002546 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002547 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002548 //start video and audio
2549
hualing chen2aba4022020-03-02 13:49:55 +08002550 am_tsplayer_video_params vparams;
2551 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002552 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002553
2554 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002555 DVR_PB_DG(1, "into");
hualing chen5cbe1a62020-02-10 16:36:36 +08002556 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2557 //start audio and video
2558 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002559 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002560 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002561 return -1;
2562 }
2563
2564 if (VALID_PID(vparams.pid)) {
2565 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002566 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002567 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002568 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002569 }
hualing chen266b9502020-04-04 17:39:39 +08002570 else {
hualing chen2aba4022020-03-02 13:49:55 +08002571 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002572 }
hualing chen2aba4022020-03-02 13:49:55 +08002573 AmTsPlayer_setVideoParams(player->handle, &vparams);
2574 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002575 }
hualing chena540a7e2020-03-27 16:44:05 +08002576
2577 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08002578 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08002579 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002580 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002581 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002582 if (VALID_PID(aparams.pid)) {
2583 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002584 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08002585 AmTsPlayer_startAudioDecoding(player->handle);
2586 AmTsPlayer_setAudioParams(player->handle, &aparams);
hualing chena540a7e2020-03-27 16:44:05 +08002587 }
hualing chen7a56cba2020-04-14 14:09:27 +08002588 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002589 AmTsPlayer_stopFast(player->handle);
2590 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2591 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2592 }
hualing chen2aba4022020-03-02 13:49:55 +08002593 player->cmd.last_cmd = player->cmd.cur_cmd;
2594 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002595 player->cmd.state = DVR_PLAYBACK_STATE_START;
2596 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002597 return 0;
2598}
2599
2600
hualing chenb31a6c62020-01-13 17:27:00 +08002601/**\brief Set play speed
2602 * \param[in] handle playback handle
2603 * \param[in] speed playback speed
2604 * \retval DVR_SUCCESS On success
2605 * \return Error code
2606 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002607int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2608
2609 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002610
2611 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002612 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002613 return DVR_FAILURE;
2614 }
2615
hualing chen4b7c15d2020-04-07 16:13:48 +08002616 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002617 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002618 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002619 return DVR_FAILURE;
2620 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002621 pthread_mutex_lock(&player->lock);
2622 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2623 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2624 player->cmd.last_cmd = player->cmd.cur_cmd;
2625 }
hualing chen31140872020-03-25 12:29:26 +08002626 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002627 IS_KERNEL_SPEED(speed.speed.speed)) {
2628 //case 1. cur speed is 100,set 200 50 25 12 .
2629 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2630 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002631 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002632 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2633 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002634 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002635 AmTsPlayer_stopFast(player->handle);
2636 pthread_mutex_unlock(&player->lock);
2637 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2638 pthread_mutex_lock(&player->lock);
2639 } else {
2640 //set play speed and if audio is start, stop audio.
2641 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002642 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002643 AmTsPlayer_stopAudioDecoding(player->handle);
2644 player->has_audio = DVR_FALSE;
2645 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002646 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002647 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002648 }
hualing chena540a7e2020-03-27 16:44:05 +08002649 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002650 player->cmd.speed.speed = speed.speed;
2651 player->speed = (float)speed.speed.speed/(float)100;
2652 pthread_mutex_unlock(&player->lock);
2653 return DVR_SUCCESS;
2654 }
2655 //case 2. not start play
2656 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2657 //only set speed.and return;
hualing chena540a7e2020-03-27 16:44:05 +08002658 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002659 player->cmd.speed.speed = speed.speed;
2660 player->speed = (float)speed.speed.speed/(float)100;
2661 pthread_mutex_unlock(&player->lock);
2662 return DVR_SUCCESS;
hualing chen87072a82020-03-12 16:20:12 +08002663 }
hualing chen31140872020-03-25 12:29:26 +08002664 //case 3 fffb mode
2665 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2666 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2667 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002668 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002669 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002670 player->cmd.speed.speed = speed.speed;
2671 player->speed = (float)speed.speed.speed/(float)100;
2672 _dvr_playback_replay(handle, DVR_FALSE);
2673 pthread_mutex_unlock(&player->lock);
2674 return DVR_SUCCESS;
2675 }
2676 }
2677 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002678 IS_KERNEL_SPEED(speed.speed.speed)) {
2679 //case 1. cur speed is kernel support speed,set kernel speed.
2680 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002681 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002682 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2683 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002684 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002685 AmTsPlayer_stopFast(player->handle);
2686 pthread_mutex_unlock(&player->lock);
2687 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2688 pthread_mutex_lock(&player->lock);
2689 } else {
2690 //set play speed and if audio is start, stop audio.
2691 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002692 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002693 AmTsPlayer_stopAudioDecoding(player->handle);
2694 player->has_audio = DVR_FALSE;
2695 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002696 DVR_PB_DG(1, "start fast");
2697 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08002698 }
hualing chena540a7e2020-03-27 16:44:05 +08002699 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002700 player->cmd.speed.speed = speed.speed;
2701 player->speed = (float)speed.speed.speed/(float)100;
2702 pthread_mutex_unlock(&player->lock);
2703 return DVR_SUCCESS;
2704 }
2705 //case 2 fffb mode
2706 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2707 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2708 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002709 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002710 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002711 player->cmd.speed.speed = speed.speed;
2712 player->speed = (float)speed.speed.speed/(float)100;
2713 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2714 pthread_mutex_unlock(&player->lock);
2715 return DVR_SUCCESS;
2716 }
hualing chen31140872020-03-25 12:29:26 +08002717 }
hualing chena540a7e2020-03-27 16:44:05 +08002718 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2719 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chen87072a82020-03-12 16:20:12 +08002720 } else {
hualing chen31140872020-03-25 12:29:26 +08002721 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002722 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2723 else
2724 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08002725 player->fffb_play = DVR_TRUE;
2726 }
2727 DVR_Bool_t init_last_time = DVR_FALSE;
2728 if (player->speed > 0.0f && speed.speed.speed < 0) {
2729 init_last_time = DVR_TRUE;
2730 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
2731 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002732 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002733 player->cmd.speed.mode = speed.mode;
2734 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002735 player->speed = (float)speed.speed.speed/(float)100;
hualing chen4b7c15d2020-04-07 16:13:48 +08002736#if 0
2737 if (abs((int)(player->speed)) > 1) {
2738 //seek speed*1000 ms at fb mode
2739 pthread_mutex_lock(&player->segment_lock);
2740 uint64_t cur = segment_tell_current_time(player->r_handle);
2741 int diff = abs((int)(player->speed * 1000));
2742 DVR_PB_DG(1, " cur:%ull diff:%d", cur, diff);
2743 if (cur > diff)
2744 cur = cur - diff;
2745 else
2746 cur = 0;
2747 segment_seek(player->r_handle, cur, player->openParams.block_size);
2748 pthread_mutex_unlock(&player->segment_lock);
2749 }
2750#endif
hualing chen31140872020-03-25 12:29:26 +08002751 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08002752 _dvr_init_fffb_t(handle);
2753 if (init_last_time == DVR_TRUE)
2754 player->last_send_time_id = UINT64_MAX;
2755
hualing chen87072a82020-03-12 16:20:12 +08002756 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002757 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2758 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002759 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002760 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08002761 _dvr_playback_replay(handle, DVR_FALSE);
2762 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2763 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2764 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08002765 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08002766 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002767 //need exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002768 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002769 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002770 return DVR_SUCCESS;
2771}
2772/**\brief Get playback status
2773 * \param[in] handle playback handle
2774 * \param[out] p_status playback status
2775 * \retval DVR_SUCCESS On success
2776 * \return Error code
2777 */
hualing chen040df222020-01-17 13:35:02 +08002778int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002779 DVR_PlaybackStatus_t *p_status) {
2780//
2781 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002782
2783 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002784 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002785 return DVR_FAILURE;
2786 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002787
2788 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002789 //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 +08002790 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2791 player->state == DVR_PLAYBACK_STATE_START) {
2792 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2793 }
hualing chen041c4092020-04-05 15:11:50 +08002794
hualing chencc91e1c2020-02-28 13:26:17 +08002795 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002796 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002797 if (player->last_send_time_id == UINT64_MAX) {
2798 player->last_send_time_id = player->cur_segment_id;
2799 player->last_cur_time = p_status->time_cur;
2800 }
2801 if (player->last_send_time_id == player->cur_segment_id) {
2802 if (player->speed > 0.0f ) {
2803 //ff
2804 if (p_status->time_cur < player->last_cur_time ) {
2805 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);
2806 p_status->time_cur = player->last_cur_time;
2807 } else {
2808 player->last_cur_time = p_status->time_cur;
2809 }
2810 } else if (player->speed < -1.0f){
2811 //fb
2812 if (p_status->time_cur > player->last_cur_time ) {
2813 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 );
2814 p_status->time_cur = player->last_cur_time;
2815 } else {
2816 player->last_cur_time = p_status->time_cur;
2817 }
2818 }
2819 } else {
2820 player->last_cur_time = p_status->time_cur;
2821 }
2822 player->last_send_time_id = player->cur_segment_id;
hualing chen041c4092020-04-05 15:11:50 +08002823 p_status->segment_id = player->cur_segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08002824
hualing chen5cbe1a62020-02-10 16:36:36 +08002825 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08002826 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08002827 p_status->flags = player->cur_segment.flags;
hualing chen4b7c15d2020-04-07 16:13:48 +08002828 DVR_PB_DG(1, "player state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]",
hualing chen6d24aa92020-03-23 18:43:47 +08002829 _dvr_playback_state_toString(player->state),
2830 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08002831 p_status->time_cur, p_status->time_end,
2832 p_status->segment_id,player->play_flag,
2833 player->speed);
hualing chenb31a6c62020-01-13 17:27:00 +08002834 return DVR_SUCCESS;
2835}
2836
hualing chen040df222020-01-17 13:35:02 +08002837void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
2838 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002839 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
2840 DVR_PB_DG(1, "segment flag: %d", segment->flags);
2841 DVR_PB_DG(1, "segment location: [%s]", segment->location);
2842 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
2843 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
2844 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
2845 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 +08002846 }
hualing chenb31a6c62020-01-13 17:27:00 +08002847}
2848
hualing chen5cbe1a62020-02-10 16:36:36 +08002849int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002850 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08002851
hualing chena540a7e2020-03-27 16:44:05 +08002852 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002853 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002854 return DVR_FAILURE;
2855 }
2856
hualing chen040df222020-01-17 13:35:02 +08002857 DVR_PlaybackSegmentInfo_t *segment;
2858 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002859 {
hualing chen040df222020-01-17 13:35:02 +08002860 if (segment_id >= 0) {
2861 if (segment->segment_id == segment_id) {
2862 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002863 break;
2864 }
2865 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08002866 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08002867 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002868 }
2869 }
2870 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002871}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002872
pengfei.liu27cc4ec2020-04-03 16:28:16 +08002873int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002874{
2875 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2876 DVR_RETURN_IF_FALSE(player);
2877 DVR_RETURN_IF_FALSE(func);
2878
hualing chen4b7c15d2020-04-07 16:13:48 +08002879 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002880 pthread_mutex_lock(&player->lock);
2881
2882 player->dec_func = func;
2883 player->dec_userdata = userdata;
2884
2885 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002886 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002887 return DVR_SUCCESS;
2888}
2889
2890int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
2891{
2892 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2893 DVR_RETURN_IF_FALSE(player);
2894 DVR_RETURN_IF_FALSE(p_secure_buf);
2895 DVR_RETURN_IF_FALSE(len);
2896
hualing chen4b7c15d2020-04-07 16:13:48 +08002897 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002898 pthread_mutex_lock(&player->lock);
2899
2900 player->is_secure_mode = 1;
2901 player->secure_buffer = p_secure_buf;
2902 player->secure_buffer_size = len;
2903
2904 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002905 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002906 return DVR_SUCCESS;
2907}