blob: 216e7d7b47e7bb81f562093091c22b56a1ced065 [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) ;
hualing chen2932d372020-04-29 13:44:00 +080049static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
50 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chen87072a82020-03-12 16:20:12 +080051
hualing chenbcada022020-04-22 14:27:01 +080052
53static char* _cmd_toString(int cmd)
54{
55
56 char *string[DVR_PLAYBACK_CMD_NONE+1]={
57 "start",
58 "stop",
59 "vstart",
60 "astart",
61 "vstop",
62 "astop",
63 "vrestart",
64 "arestart",
65 "avrestart",
66 "vstopastart",
67 "astopvstart",
68 "vstoparestart",
69 "astopvrestart",
70 "vstartarestart",
71 "astartvrestart",
72 "pause",
73 "resume",
74 "seek",
75 "ff",
76 "fb",
77 "NONE"
78 };
79
80 if (cmd > DVR_PLAYBACK_CMD_NONE) {
81 return "unkown";
82 } else {
83 return string[cmd];
84 }
85}
86
87
hualing chen6d24aa92020-03-23 18:43:47 +080088static char* _dvr_playback_state_toString(int stat)
89{
90 char *string[DVR_PLAYBACK_STATE_FB+1]={
91 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080092 "stop",
hualing chen31140872020-03-25 12:29:26 +080093 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080094 "ff",
95 "fb"
96 };
97
98 if (stat > DVR_PLAYBACK_STATE_FB) {
99 return "unkown";
100 } else {
101 return string[stat];
102 }
103}
hualing chena540a7e2020-03-27 16:44:05 +0800104
105static DVR_Bool_t _dvr_support_speed(int speed) {
106
107 DVR_Bool_t ret = DVR_FALSE;
108
109 switch (speed) {
110 case PLAYBACK_SPEED_FBX2:
111 case PLAYBACK_SPEED_FBX4:
112 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800113 case PLAYBACK_SPEED_FBX16:
114 case PLAYBACK_SPEED_FBX12:
115 case PLAYBACK_SPEED_FBX32:
116 case PLAYBACK_SPEED_FBX48:
117 case PLAYBACK_SPEED_FBX64:
118 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800119 case PLAYBACK_SPEED_S2:
120 case PLAYBACK_SPEED_S4:
121 case PLAYBACK_SPEED_S8:
122 case PLAYBACK_SPEED_X1:
123 case PLAYBACK_SPEED_X2:
124 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800125 case PLAYBACK_SPEED_X3:
126 case PLAYBACK_SPEED_X5:
127 case PLAYBACK_SPEED_X6:
128 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800129 case PLAYBACK_SPEED_X8:
130 case PLAYBACK_SPEED_X12:
131 case PLAYBACK_SPEED_X16:
132 case PLAYBACK_SPEED_X32:
133 case PLAYBACK_SPEED_X48:
134 case PLAYBACK_SPEED_X64:
135 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800136 ret = DVR_TRUE;
137 break;
138 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800139 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800140 break;
141 }
142 return ret;
143}
hualing chen6e4bfa52020-03-13 14:37:11 +0800144void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
145{
hualing chen4b7c15d2020-04-07 16:13:48 +0800146 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800147 DVR_Playback_t *player = NULL;
148 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800149 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800150 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800151 }
152 switch (event->type) {
153 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
154 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800155 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800156 event->event.video_format.frame_width,
157 event->event.video_format.frame_height,
158 event->event.video_format.frame_rate);
159 break;
160 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800161 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
162 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800163 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800164 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800165 break;
166 }
167 default:
168 break;
169 }
170}
hualing chen2aba4022020-03-02 13:49:55 +0800171void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
172{
hualing chen6e4bfa52020-03-13 14:37:11 +0800173 DVR_Playback_t *player = NULL;
174 if (user_data != NULL) {
175 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800176 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800177 }
hualing chen2aba4022020-03-02 13:49:55 +0800178 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800179 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
180 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800181 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800182 event->event.video_format.frame_width,
183 event->event.video_format.frame_height,
184 event->event.video_format.frame_rate);
185 break;
186 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800187 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
188 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800189 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800190 if (player != NULL)
191 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800192 break;
193 }
194 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800195 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800196 break;
197 }
198 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800199 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800200 player->player_callback_func(player->player_callback_userdata, event);
201 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800202 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800203 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800204 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800205 }
206}
hualing chencc91e1c2020-02-28 13:26:17 +0800207
hualing chen5cbe1a62020-02-10 16:36:36 +0800208//convert video and audio fmt
209static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
210 int format = 0;
211 if (is_audio == DVR_FALSE) {
212 //for video fmt
213 switch (fmt)
214 {
215 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800216 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800217 break;
218 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800219 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800220 break;
221 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800222 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800223 break;
224 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800225 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800226 break;
hualing chena540a7e2020-03-27 16:44:05 +0800227 case DVR_VIDEO_FORMAT_VP9:
228 format = AV_VIDEO_CODEC_VP9;
229 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800230 }
231 } else {
232 //for audio fmt
233 switch (fmt)
234 {
235 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800236 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800237 break;
238 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800239 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800240 break;
241 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800242 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800243 break;
244 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800245 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800246 break;
hualing chena540a7e2020-03-27 16:44:05 +0800247 case DVR_AUDIO_FORMAT_AAC:
248 format = AV_AUDIO_CODEC_AAC;
249 break;
250 case DVR_AUDIO_FORMAT_LATM:
251 format = AV_AUDIO_CODEC_LATM;
252 break;
253 case DVR_AUDIO_FORMAT_PCM:
254 format = AV_AUDIO_CODEC_PCM;
255 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800256 }
257 }
258 return format;
259}
hualing chen040df222020-01-17 13:35:02 +0800260static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800261{
hualing chen040df222020-01-17 13:35:02 +0800262 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800263
hualing chena540a7e2020-03-27 16:44:05 +0800264 if (player == NULL || player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800265 return -1;
266
hualing chena540a7e2020-03-27 16:44:05 +0800267 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800268}
hualing chena540a7e2020-03-27 16:44:05 +0800269
hualing chen5cbe1a62020-02-10 16:36:36 +0800270//get sys time ms
271static int _dvr_time_getClock(void)
272{
273 struct timespec ts;
274 int ms;
275
276 clock_gettime(CLOCK_MONOTONIC, &ts);
277 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
278
279 return ms;
280}
hualing chen86e7d482020-01-16 15:13:33 +0800281
hualing chenb31a6c62020-01-13 17:27:00 +0800282
283//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800284static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800285{
hualing chen040df222020-01-17 13:35:02 +0800286 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800287
hualing chena540a7e2020-03-27 16:44:05 +0800288
289 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800290 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800291 return DVR_FAILURE;
292 }
293
hualing chen86e7d482020-01-16 15:13:33 +0800294 struct timespec ts;
295 clock_gettime(CLOCK_MONOTONIC, &ts);
296 //ms为毫秒,换算成秒
297 ts.tv_sec += ms/1000;
298 //在outtime的基础上,增加ms毫秒
299 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
300 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
301 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
302 //us的值有可能超过1秒,
303 ts.tv_sec += us / 1000000;
304 us = us % 1000000;
305 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800306 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
307 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800308}
hualing chen31140872020-03-25 12:29:26 +0800309//get tsplay delay time ms
310static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
311 DVR_Playback_t *player = (DVR_Playback_t *) handle;
312 int64_t cache = 0;
313 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800314 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800315 return 0;
316 }
317 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800318 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800319 return cache;
320}
hualing chenb31a6c62020-01-13 17:27:00 +0800321//send signal
hualing chen040df222020-01-17 13:35:02 +0800322static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800323{
hualing chen87072a82020-03-12 16:20:12 +0800324 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800325
326 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800327 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800328 return DVR_FAILURE;
329 }
330
hualing chen87072a82020-03-12 16:20:12 +0800331 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800332 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800333 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800334 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800335}
336
hualing chen2932d372020-04-29 13:44:00 +0800337//send playback event, need check is need lock first
338static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify, DVR_Bool_t is_lock) {
hualing chencc91e1c2020-02-28 13:26:17 +0800339
340 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800341
342 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800343 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800344 return DVR_FAILURE;
345 }
346
hualing chencc91e1c2020-02-28 13:26:17 +0800347 switch (evt) {
348 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800349 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800350 break;
351 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
352 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800353 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800354 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800355 break;
356 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
357 break;
358 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
359 break;
360 case DVR_PLAYBACK_EVENT_NO_KEY:
361 break;
362 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800363 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800364 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800365 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800366 break;
367 case DVR_PLAYBACK_EVENT_REACHED_END:
368 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800369 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800370 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800371 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800372 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800373 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800374 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800375 default:
376 break;
377 }
378 if (player->openParams.event_fn != NULL)
379 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800380 return DVR_SUCCESS;
381}
hualing chen2932d372020-04-29 13:44:00 +0800382static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800383{
384 DVR_Play_Notify_t notify;
385 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
386 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
387 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800388 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800389 return DVR_SUCCESS;
390}
391
hualing chen2932d372020-04-29 13:44:00 +0800392static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800393{
394 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800395
hualing chen4b7c15d2020-04-07 16:13:48 +0800396 if (1) {
397 return DVR_SUCCESS;
398 }
hualing chena540a7e2020-03-27 16:44:05 +0800399 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800400 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800401 return DVR_FAILURE;
402 }
403
hualing chen6e4bfa52020-03-13 14:37:11 +0800404 if (player->send_time ==0) {
405 player->send_time = _dvr_time_getClock() + 1000;
406 } else if (player->send_time > _dvr_time_getClock()) {
407 return DVR_SUCCESS;
408 }
409 player->send_time = _dvr_time_getClock() + 1000;
410 DVR_Play_Notify_t notify;
411 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
412 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
413 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800414 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800415 return DVR_SUCCESS;
416}
417
hualing chencc91e1c2020-02-28 13:26:17 +0800418//check is ongoing segment
419static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
420
421 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800422 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800423
424 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800425 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800426 return DVR_FAILURE;
427 }
hualing chen87072a82020-03-12 16:20:12 +0800428 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800429 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800430 return DVR_FALSE;
431 }
hualing chencc91e1c2020-02-28 13:26:17 +0800432 return DVR_TRUE;
433}
hualing chen4b7c15d2020-04-07 16:13:48 +0800434
435
436static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
437 DVR_Playback_t *player = (DVR_Playback_t *) handle;
438 player->fffb_start = _dvr_time_getClock();
439 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
440 player->fffb_current = player->fffb_start;
441 //get segment current time pos
442 player->fffb_start_pcr = _dvr_get_cur_time(handle);
443 //player->fffb_current = -1;
444 //player->fffb_start = -1;
445 //player->fffb_start_pcr = -1;
446 player->next_fffb_time = _dvr_time_getClock();
447
448 return DVR_SUCCESS;
449}
450
hualing chen2aba4022020-03-02 13:49:55 +0800451static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
452 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800453 player->fffb_start = _dvr_time_getClock();
454 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
455 player->fffb_current = player->fffb_start;
456 //get segment current time pos
457 player->fffb_start_pcr = _dvr_get_cur_time(handle);
458 //player->fffb_current = -1;
459 //player->fffb_start = -1;
460 //player->fffb_start_pcr = -1;
hualing chen2aba4022020-03-02 13:49:55 +0800461 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800462 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800463 return DVR_SUCCESS;
464}
hualing chencc91e1c2020-02-28 13:26:17 +0800465//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800466static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
467
468 DVR_Playback_t *player = (DVR_Playback_t *) handle;
469 DVR_PlaybackSegmentInfo_t *segment;
470 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
471
hualing chena540a7e2020-03-27 16:44:05 +0800472 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800473 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800474 return DVR_FAILURE;
475 }
476
hualing chen87072a82020-03-12 16:20:12 +0800477 int found = 0;
478 int found_eq_id = 0;
479 list_for_each_entry(segment, &player->segment_list, head)
480 {
481 if (player->segment_is_open == DVR_FALSE) {
482 //get first segment from list, case segment is not open
483 if (!IS_FB(player->speed))
484 found = 1;
485 } else if (segment->segment_id == segmentid) {
486 //find cur segment, we need get next one
487 found_eq_id = 1;
488 if (!IS_FB(player->speed)) {
489 found = 1;
490 continue;
491 } else {
492 //if is fb mode.we need used pre segment
493 if (pre_segment != NULL) {
494 found = 1;
495 } else {
496 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800497 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800498 return DVR_FAILURE;
499 }
500 }
501 }
502 if (found == 1) {
503 found = 2;
504 break;
505 }
506 }
507 if (found != 2) {
508 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800509 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800510 return DVR_FAILURE;
511 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800512 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800513 return DVR_SUCCESS;
514}
515
516//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800517static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800518
hualing chen040df222020-01-17 13:35:02 +0800519 DVR_Playback_t *player = (DVR_Playback_t *) handle;
520 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800521 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800522
hualing chena540a7e2020-03-27 16:44:05 +0800523 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800524 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800525 return DVR_FAILURE;
526 }
527
hualing chen86e7d482020-01-16 15:13:33 +0800528 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800529 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800530
hualing chen040df222020-01-17 13:35:02 +0800531 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800532 {
hualing chencc91e1c2020-02-28 13:26:17 +0800533 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800534 //get first segment from list, case segment is not open
535 if (!IS_FB(player->speed))
536 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800537 } else if (segment->segment_id == player->cur_segment_id) {
538 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800539 found_eq_id = 1;
540 if (!IS_FB(player->speed)) {
541 found = 1;
542 continue;
543 } else {
544 //if is fb mode.we need used pre segment
545 if (pre_segment != NULL) {
546 found = 1;
547 } else {
548 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800549 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800550 return DVR_FAILURE;
551 }
552 }
hualing chen86e7d482020-01-16 15:13:33 +0800553 }
554 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800555 if (IS_FB(player->speed)) {
556 //used pre segment
557 segment = pre_segment;
558 }
hualing chencc91e1c2020-02-28 13:26:17 +0800559 //save segment info
560 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800561 player->last_segment.segment_id = player->cur_segment.segment_id;
562 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800563 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
564 //pids
565 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
566
hualing chen5cbe1a62020-02-10 16:36:36 +0800567 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800568 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800569 player->cur_segment_id = segment->segment_id;
570 player->cur_segment.segment_id = segment->segment_id;
571 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800572 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 +0800573 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800574 //pids
hualing chen040df222020-01-17 13:35:02 +0800575 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800576 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800577 break;
hualing chen86e7d482020-01-16 15:13:33 +0800578 }
hualing chen2aba4022020-03-02 13:49:55 +0800579 pre_segment = segment;
580 }
581 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
582 //used the last one segment to open
583 //get segment info
584 player->segment_is_open = DVR_TRUE;
585 player->cur_segment_id = pre_segment->segment_id;
586 player->cur_segment.segment_id = pre_segment->segment_id;
587 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800588 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 +0800589 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
590 //pids
591 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
592 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800593 }
594 if (found != 2) {
595 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800596 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800597 }
598 return DVR_SUCCESS;
599}
hualing chen040df222020-01-17 13:35:02 +0800600//open next segment to play,if reach list end return errro.
601static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800602{
hualing chen040df222020-01-17 13:35:02 +0800603 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800604 Segment_OpenParams_t params;
605 int ret = DVR_SUCCESS;
606
hualing chena540a7e2020-03-27 16:44:05 +0800607 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800608 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800609 return DVR_FAILURE;
610 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800611 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800612
613 ret = _dvr_get_next_segmentId(handle);
614 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800615 DVR_PB_DG(1, "not found segment info");
616 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800617 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800618 }
619
620 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800621 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800622 segment_close(player->r_handle);
623 player->r_handle = NULL;
624 }
625
626 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800627 //cp chur segment path to location
628 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800629 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800630 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800631 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
632
hualing chen86e7d482020-01-16 15:13:33 +0800633 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800634 if (ret == DVR_FAILURE) {
635 DVR_PB_DG(1, "open segment error");
636 }
hualing chen87072a82020-03-12 16:20:12 +0800637 pthread_mutex_unlock(&player->segment_lock);
638 int total = _dvr_get_end_time( handle);
639 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800640 if (IS_FB(player->speed)) {
641 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800642 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800643 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800644 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800645 }
hualing chen87072a82020-03-12 16:20:12 +0800646 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800647 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800648 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800649 return ret;
650}
651
hualing chen5cbe1a62020-02-10 16:36:36 +0800652//open next segment to play,if reach list end return errro.
653static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
654{
655 DVR_Playback_t *player = (DVR_Playback_t *) handle;
656 Segment_OpenParams_t params;
657 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800658 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800659 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800660 return DVR_FAILURE;
661 }
hualing chencc91e1c2020-02-28 13:26:17 +0800662 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800663 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800664 }
hualing chencc91e1c2020-02-28 13:26:17 +0800665 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800666 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800667 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800668 return DVR_FAILURE;
669 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800670 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800671 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800672
673 DVR_PlaybackSegmentInfo_t *segment;
674
675 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800676
hualing chen5cbe1a62020-02-10 16:36:36 +0800677 list_for_each_entry(segment, &player->segment_list, head)
678 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800679 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 +0800680 if (segment->segment_id == segment_id) {
681 found = 1;
682 }
683 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800684 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 +0800685 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800686 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800687 player->cur_segment_id = segment->segment_id;
688 player->cur_segment.segment_id = segment->segment_id;
689 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800690 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800691 //pids
692 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800693 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 +0800694 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800695 }
696 }
hualing chencc91e1c2020-02-28 13:26:17 +0800697 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800698 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800699 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800700 return DVR_FAILURE;
701 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800702 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800703 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800704 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800705 params.segment_id = (uint64_t)player->cur_segment.segment_id;
706 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800707 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 +0800708 if (player->r_handle != NULL) {
709 segment_close(player->r_handle);
710 player->r_handle = NULL;
711 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800712 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800713 if (ret == DVR_FAILURE) {
714 DVR_PB_DG(1, "segment opne error");
715 }
hualing chen2aba4022020-03-02 13:49:55 +0800716 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800717 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800718
hualing chen4b7c15d2020-04-07 16:13:48 +0800719 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 +0800720 return ret;
721}
722
723
724//get play info by segment id
725static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
726 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800727 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800728 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800729
730 DVR_Playback_t *player = (DVR_Playback_t *) handle;
731 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800732 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800733 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800734 return DVR_FAILURE;
735 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800736
737 int found = 0;
738
739 list_for_each_entry(segment, &player->segment_list, head)
740 {
hualing chen87072a82020-03-12 16:20:12 +0800741 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800742 //get first segment from list
743 found = 1;
744 }
745 if (segment->segment_id == segment_id) {
746 found = 1;
747 }
748 if (found == 1) {
749 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800750 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800751 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800752 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800753 player->cur_segment.segment_id = segment->segment_id;
754 player->cur_segment.flags = segment->flags;
755 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800756 player->cur_segment.pids.video.pid = segment->pids.video.pid;
757 player->cur_segment.pids.video.format = segment->pids.video.format;
758 player->cur_segment.pids.video.type = segment->pids.video.type;
759 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
760 player->cur_segment.pids.audio.format = segment->pids.audio.format;
761 player->cur_segment.pids.audio.type = segment->pids.audio.type;
762 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
763 player->cur_segment.pids.ad.format = segment->pids.ad.format;
764 player->cur_segment.pids.ad.type = segment->pids.ad.type;
765 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800766 //
hualing chen2aba4022020-03-02 13:49:55 +0800767 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800768 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800769 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800770 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800771 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
772 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800773 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 +0800774 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800775 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800776 }
777 }
hualing chencc91e1c2020-02-28 13:26:17 +0800778 if (found != 2) {
779 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800780 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800781 return DVR_FAILURE;
782 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800783
784 return DVR_SUCCESS;
785}
hualing chencc91e1c2020-02-28 13:26:17 +0800786static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
787 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800788 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800789 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800790 return DVR_FAILURE;
791 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800792
hualing chencc91e1c2020-02-28 13:26:17 +0800793 //compare cur segment
794 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
795 {
796 //check video pids, stop or restart
797 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
798 //check audio pids stop or restart
hualing chen7a56cba2020-04-14 14:09:27 +0800799 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 +0800800 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
801 //check sub audio pids stop or restart
802 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
803 //check pcr pids stop or restart
804 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
805 }
hualing chena540a7e2020-03-27 16:44:05 +0800806 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800807}
hualing chen5cbe1a62020-02-10 16:36:36 +0800808
hualing chencc91e1c2020-02-28 13:26:17 +0800809static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
810{
811 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800812 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800813 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800814 return DVR_FAILURE;
815 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800816 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 +0800817 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
818 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800819 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800820 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800821 AmTsPlayer_showVideo(player->handle);
822 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800823 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
824 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800825 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800826 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800827 AmTsPlayer_hideVideo(player->handle);
828 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800829 }
830 return DVR_SUCCESS;
831}
hualing chena540a7e2020-03-27 16:44:05 +0800832static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
833 DVR_Playback_t *player = (DVR_Playback_t *) handle;
834 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800835 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800836 return DVR_TRUE;
837 }
hualing chen266b9502020-04-04 17:39:39 +0800838 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chena540a7e2020-03-27 16:44:05 +0800839 if (player->first_frame == 1) {
840 return DVR_TRUE;
841 } else {
842 return DVR_FALSE;
843 }
844 } else {
845 return DVR_TRUE;
846 }
847}
hualing chen86e7d482020-01-16 15:13:33 +0800848static void* _dvr_playback_thread(void *arg)
849{
hualing chen040df222020-01-17 13:35:02 +0800850 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800851 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800852 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800853 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800854 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800855
hualing chen39628212020-05-14 10:35:13 +0800856 #define MAX_REACHEND_TIMEOUT (3000)
857 int reach_end_timeout = 0;//ms
858 int cache_time = 0;
hualing chen6d24aa92020-03-23 18:43:47 +0800859 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800860 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800861 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800862 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800863 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
864
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800865 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800866 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800867 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800868
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800869 if (player->is_secure_mode) {
870 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800871 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800872 return NULL;
873 }
874 }
hualing chen86e7d482020-01-16 15:13:33 +0800875 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800876 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800877 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800878 return NULL;
879 }
hualing chen2aba4022020-03-02 13:49:55 +0800880 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
881 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800882
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800883 dec_bufs.buf_data = malloc(dec_buf_size);
884 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800885 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800886 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800887 return NULL;
888 }
889 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
890 dec_bufs.buf_size = dec_buf_size;
891
hualing chencc91e1c2020-02-28 13:26:17 +0800892 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800893 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
894 }
hualing chen86e7d482020-01-16 15:13:33 +0800895
hualing chen86e7d482020-01-16 15:13:33 +0800896 if (ret != DVR_SUCCESS) {
897 if (buf != NULL) {
898 free(buf);
899 buf = NULL;
900 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800901 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800902 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800903 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800904 }
hualing chencc91e1c2020-02-28 13:26:17 +0800905 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800906 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
hualing chencc91e1c2020-02-28 13:26:17 +0800907 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800908 //set video show
909 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800910
hualing chen86e7d482020-01-16 15:13:33 +0800911 int trick_stat = 0;
912 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800913
hualing chen86e7d482020-01-16 15:13:33 +0800914 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800915 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800916
hualing chen2aba4022020-03-02 13:49:55 +0800917 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
918 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800919 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800920 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +0800921 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +0800922 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800923 {
hualing chen2aba4022020-03-02 13:49:55 +0800924 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
925 if (trick_stat > 0) {
hualing chenbcada022020-04-22 14:27:01 +0800926 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]", player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +0800927 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 +0800928 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +0800929 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800930 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800931 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
932 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800933 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
934 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chenbcada022020-04-22 14:27:01 +0800935 DVR_PB_DG(1, "pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]", player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +0800936 //need change to pause state
937 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
938 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800939 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800940 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800941 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800942 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800943 AmTsPlayer_pauseVideoDecoding(player->handle);
944 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800945 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800946 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +0800947 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800948 }
949 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
950 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800951 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800952 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +0800953 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
954 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 +0800955 //used timeout wait need lock first,so we unlock and lock
956 //pthread_mutex_unlock(&player->lock);
957 //pthread_mutex_lock(&player->lock);
958 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
959 pthread_mutex_unlock(&player->lock);
960 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +0800961 } else if (_dvr_time_getClock() < player->next_fffb_time) {
962 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);
963 //used timeout wait need lock first,so we unlock and lock
964 //pthread_mutex_unlock(&player->lock);
965 //pthread_mutex_lock(&player->lock);
966 AmTsPlayer_pauseVideoDecoding(player->handle);
967 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
968 pthread_mutex_unlock(&player->lock);
969 continue;
970
hualing chen2aba4022020-03-02 13:49:55 +0800971 }
hualing chen2932d372020-04-29 13:44:00 +0800972 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d][%s][%d]", player->speed, goto_rewrite, real_read, _dvr_playback_state_toString(player->state), player->cmd);
hualing chen2aba4022020-03-02 13:49:55 +0800973 pthread_mutex_unlock(&player->lock);
974 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800975 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800976 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
977 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800978 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +0800979 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +0800980 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800981 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800982 }else if (player->fffb_play == DVR_TRUE){
983 //for first into fffb when reset speed
984 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
985 _dvr_time_getClock() < player->next_fffb_time) {
986 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);
987 //used timeout wait need lock first,so we unlock and lock
988 //pthread_mutex_unlock(&player->lock);
989 //pthread_mutex_lock(&player->lock);
990 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
991 pthread_mutex_unlock(&player->lock);
992 continue;
993 }
hualing chen2932d372020-04-29 13:44:00 +0800994 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]", player->speed, goto_rewrite, real_read, _dvr_playback_state_toString(player->state), player->cmd, player->fffb_play);
hualing chen4b7c15d2020-04-07 16:13:48 +0800995 pthread_mutex_unlock(&player->lock);
996 goto_rewrite = DVR_FALSE;
997 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +0800998 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +0800999 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1000 player->first_frame = 0;
1001 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1002 pthread_mutex_lock(&player->lock);
1003 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001004 }
hualing chenb31a6c62020-01-13 17:27:00 +08001005 }
hualing chen86e7d482020-01-16 15:13:33 +08001006
hualing chen87072a82020-03-12 16:20:12 +08001007 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001008 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001009 DVR_PB_DG(1, "pause, continue");
hualing chen2932d372020-04-29 13:44:00 +08001010 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen87072a82020-03-12 16:20:12 +08001011 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1012 pthread_mutex_unlock(&player->lock);
1013 continue;
1014 }
hualing chen266b9502020-04-04 17:39:39 +08001015 //when seek action is done. we need drop write timeout data.
1016 if (player->drop_ts == DVR_TRUE) {
1017 goto_rewrite = DVR_FALSE;
1018 real_read = 0;
1019 player->drop_ts = DVR_FALSE;
1020 }
hualing chen2aba4022020-03-02 13:49:55 +08001021 if (goto_rewrite == DVR_TRUE) {
1022 goto_rewrite = DVR_FALSE;
1023 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001024 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001025 goto rewrite;
1026 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001027 //.check is need send time send end
hualing chen2932d372020-04-29 13:44:00 +08001028 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001029 pthread_mutex_lock(&player->segment_lock);
hualing chen39628212020-05-14 10:35:13 +08001030 DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001031 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen39628212020-05-14 10:35:13 +08001032 DVR_PB_DG(1, "start read end");
hualing chen4b7c15d2020-04-07 16:13:48 +08001033 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001034 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001035 if (read < 0 && errno == EIO) {
1036 //EIO ERROR, EXIT THRAD
1037 DVR_PB_DG(1, "read error.EIO error, exit thread");
1038 DVR_Play_Notify_t notify;
1039 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1040 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen2932d372020-04-29 13:44:00 +08001041 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001042 goto end;
1043 } else if (read < 0) {
1044 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1045 }
hualing chen87072a82020-03-12 16:20:12 +08001046 //if on fb mode and read file end , we need calculate pos to retry read.
1047 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001048 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 +08001049 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
1050 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001051 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1052 pthread_mutex_unlock(&player->lock);
1053 continue;
1054 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001055 //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 +08001056 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001057 //file end.need to play next segment
hualing chen040df222020-01-17 13:35:02 +08001058 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001059 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001060 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001061
1062 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001063 //del delay time max check.
hualing chen39628212020-05-14 10:35:13 +08001064 if ((ret != DVR_SUCCESS &&
hualing chen041c4092020-04-05 15:11:50 +08001065 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001066 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001067 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1068 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001069 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001070 DVR_Play_Notify_t notify;
1071 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1072 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1073 //get play statue not here
1074 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001075 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001076 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001077 DVR_PB_DG(1, "playback is send end delay:[%d]reach_end_timeout[%d]ms", delay, reach_end_timeout);
hualing chen31140872020-03-25 12:29:26 +08001078 pthread_mutex_lock(&player->lock);
1079 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1080 pthread_mutex_unlock(&player->lock);
1081 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001082 } else if (ret != DVR_SUCCESS) {
1083 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001084 if (delay < cache_time) {
1085 //delay time is changed and then has data to play, so not start timeout
1086 } else {
1087 reach_end_timeout = reach_end_timeout + timeout;
1088 }
1089 cache_time = delay;
hualing chen4b7c15d2020-04-07 16:13:48 +08001090 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001091 pthread_mutex_lock(&player->lock);
1092 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1093 pthread_mutex_unlock(&player->lock);
1094 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001095 }
hualing chen39628212020-05-14 10:35:13 +08001096 reach_end_timeout = 0;
1097 cache_time = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001098 pthread_mutex_lock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001099 //change next segment success case
1100 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001101 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001102 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1103 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001104 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001105 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001106 }
hualing chen39628212020-05-14 10:35:13 +08001107 reach_end_timeout = 0;
hualing chen86e7d482020-01-16 15:13:33 +08001108 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001109 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001110 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001111
hualing chena540a7e2020-03-27 16:44:05 +08001112 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001113 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001114 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001115 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001116 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001117 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001118 }
hualing chen266b9502020-04-04 17:39:39 +08001119 //if need write whole block size, we need check read buf len is eq block size.
1120 if (b_writed_whole_block == DVR_TRUE) {
1121 //buf_len is block size value.
1122 if (real_read < buf_len) {
1123 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001124 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001125 pthread_mutex_lock(&player->lock);
1126 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1127 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001128 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001129 continue;
1130 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001131 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 +08001132 }
1133 }
1134
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001135 if (player->dec_func) {
1136 DVR_CryptoParams_t crypto_params;
1137
1138 memset(&crypto_params, 0, sizeof(crypto_params));
1139 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1140 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1141 crypto_params.segment_id = player->cur_segment.segment_id;
1142 crypto_params.offset = segment_tell_position(player->r_handle);
1143
1144 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1145 crypto_params.input_buffer.addr = (size_t)buf;
1146 crypto_params.input_buffer.size = real_read;
1147
1148 if (player->is_secure_mode) {
1149 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1150 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1151 crypto_params.output_buffer.size = dec_buf_size;
1152 ret = player->dec_func(&crypto_params, player->dec_userdata);
1153 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001154 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001155 } else {
1156 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1157 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1158 crypto_params.output_buffer.size = dec_buf_size;
1159 ret = player->dec_func(&crypto_params, player->dec_userdata);
1160 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001161 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001162 }
1163 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001164 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001165 }
pengfei.liufda2a972020-04-09 14:47:15 +08001166 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001167 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001168rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001169 if (player->drop_ts == DVR_TRUE) {
1170 //need drop ts data when seek occur.we need read next loop,drop this ts data
1171 goto_rewrite = DVR_FALSE;
1172 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001173 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001174 player->drop_ts = DVR_FALSE;
1175 continue;
1176 }
hualing chen5605eed2020-05-26 18:18:06 +08001177 player->ts_cache_len = real_read;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001178 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1179 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001180 player->ts_cache_len = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001181 real_read = 0;
1182 write_success++;
hualing chen5605eed2020-05-26 18:18:06 +08001183 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001184 continue;
hualing chen87072a82020-03-12 16:20:12 +08001185 } else {
hualing chen2932d372020-04-29 13:44:00 +08001186 DVR_PB_DG(1, "write time out write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001187 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001188 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001189 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001190 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001191 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001192 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001193 break;
1194 }
hualing chen2aba4022020-03-02 13:49:55 +08001195 goto_rewrite = DVR_TRUE;
1196 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001197 }
1198 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001199end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001200 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001201 free(buf);
1202 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001203 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001204}
1205
1206
hualing chen040df222020-01-17 13:35:02 +08001207static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001208{
hualing chen040df222020-01-17 13:35:02 +08001209 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001210
1211 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001212 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001213 return DVR_FAILURE;
1214 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001215 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001216 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001217 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001218 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001219 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001220 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001221 if (rc < 0)
1222 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001223 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001224}
1225
1226
hualing chen040df222020-01-17 13:35:02 +08001227static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001228{
hualing chen040df222020-01-17 13:35:02 +08001229 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001230
1231 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001232 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001233 return DVR_FAILURE;
1234 }
1235
hualing chen4b7c15d2020-04-07 16:13:48 +08001236 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001237 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001238 {
1239 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001240 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001241 pthread_join(player->playback_thread, NULL);
1242 }
1243 if (player->r_handle) {
1244 segment_close(player->r_handle);
1245 player->r_handle = NULL;
1246 }
hualing chen7a56cba2020-04-14 14:09:27 +08001247 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001248 return 0;
1249}
1250
hualing chenb31a6c62020-01-13 17:27:00 +08001251/**\brief Open an dvr palyback
1252 * \param[out] p_handle dvr playback addr
1253 * \param[in] params dvr playback open parameters
1254 * \retval DVR_SUCCESS On success
1255 * \return Error code
1256 */
hualing chen040df222020-01-17 13:35:02 +08001257int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001258
hualing chen040df222020-01-17 13:35:02 +08001259 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001260 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001261
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001262 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001263
hualing chen86e7d482020-01-16 15:13:33 +08001264 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001265 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001266 pthread_condattr_init(&cattr);
1267 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1268 pthread_cond_init(&player->cond, &cattr);
1269 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001270
hualing chen5cbe1a62020-02-10 16:36:36 +08001271 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001272 INIT_LIST_HEAD(&player->segment_list);
1273 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1274 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001275 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001276 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001277 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001278 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001279 player->speed = 1.0f;
hualing chen2aba4022020-03-02 13:49:55 +08001280
hualing chen86e7d482020-01-16 15:13:33 +08001281 //store open params
hualing chen040df222020-01-17 13:35:02 +08001282 player->openParams.dmx_dev_id = params->dmx_dev_id;
1283 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001284 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001285 player->openParams.event_fn = params->event_fn;
1286 player->openParams.event_userdata = params->event_userdata;
1287
hualing chen5cbe1a62020-02-10 16:36:36 +08001288 player->has_pids = params->has_pids;
1289
hualing chen2aba4022020-03-02 13:49:55 +08001290 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001291
1292 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1293 //for test get callback
1294 if (0 && player->player_callback_func == NULL) {
1295 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1296 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001297 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 +08001298 }
1299 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001300
hualing chen86e7d482020-01-16 15:13:33 +08001301 //init has audio and video
1302 player->has_video = DVR_FALSE;
1303 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001304 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001305 player->last_segment_id = 0LL;
1306 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001307
hualing chen5cbe1a62020-02-10 16:36:36 +08001308 //init ff fb time
1309 player->fffb_current = -1;
1310 player->fffb_start =-1;
1311 player->fffb_start_pcr = -1;
1312 //seek time
1313 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001314 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001315
1316 //init secure stuff
1317 player->dec_func = NULL;
1318 player->dec_userdata = NULL;
1319 player->is_secure_mode = 0;
1320 player->secure_buffer = NULL;
1321 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001322 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001323
hualing chen4b7c15d2020-04-07 16:13:48 +08001324 player->fffb_play = DVR_FALSE;
1325
1326 player->last_send_time_id = UINT64_MAX;
1327 player->last_cur_time = 0;
1328
hualing chen86e7d482020-01-16 15:13:33 +08001329 *p_handle = player;
1330 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001331}
1332
1333/**\brief Close an dvr palyback
1334 * \param[in] handle playback handle
1335 * \retval DVR_SUCCESS On success
1336 * \return Error code
1337 */
hualing chen040df222020-01-17 13:35:02 +08001338int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001339
hualing chen86e7d482020-01-16 15:13:33 +08001340 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001341 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001342 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001343 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001344 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001345 return DVR_FAILURE;
1346 }
1347
hualing chencc91e1c2020-02-28 13:26:17 +08001348 if (player->state != DVR_PLAYBACK_STATE_STOP)
1349 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001350 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001351 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001352 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1353 } else {
1354 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001355 }
hualing chen7a56cba2020-04-14 14:09:27 +08001356 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001357 pthread_mutex_destroy(&player->lock);
1358 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001359
1360 if (player) {
1361 free(player);
1362 player = NULL;
1363 }
hualing chen7a56cba2020-04-14 14:09:27 +08001364 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001365 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001366}
1367
hualing chenb31a6c62020-01-13 17:27:00 +08001368/**\brief Start play audio and video, used start auido api and start video api
1369 * \param[in] handle playback handle
1370 * \param[in] params audio playback params,contains fmt and pid...
1371 * \retval DVR_SUCCESS On success
1372 * \return Error code
1373 */
hualing chen040df222020-01-17 13:35:02 +08001374int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1375 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001376 am_tsplayer_video_params vparams;
1377 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001378 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001379
1380 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001381 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001382 return DVR_FAILURE;
1383 }
hualing chencc91e1c2020-02-28 13:26:17 +08001384 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001385 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001386
hualing chena540a7e2020-03-27 16:44:05 +08001387 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001388 //can used start api to resume playback
1389 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1390 return dvr_playback_resume(handle);
1391 }
hualing chen87072a82020-03-12 16:20:12 +08001392 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001393 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001394 return DVR_SUCCESS;
1395 }
hualing chen86e7d482020-01-16 15:13:33 +08001396 player->play_flag = flag;
hualing chen5cbe1a62020-02-10 16:36:36 +08001397 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001398 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001399 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001400 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001401 //start audio and video
1402 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1403 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001404 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001405 pthread_mutex_unlock(&player->lock);
1406 DVR_Play_Notify_t notify;
1407 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1408 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1409 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1410 notify.info.transition_failed_data.segment_id = segment_id;
1411 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001412 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001413 return -1;
1414 }
hualing chen31140872020-03-25 12:29:26 +08001415
hualing chencc91e1c2020-02-28 13:26:17 +08001416 {
hualing chen86e7d482020-01-16 15:13:33 +08001417 if (VALID_PID(vparams.pid)) {
1418 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001419 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001420 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001421 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001422 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1423 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001424 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001425 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001426 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001427 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001428 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001429 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001430 }
1431 AmTsPlayer_setVideoParams(player->handle, &vparams);
1432 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001433 }
hualing chena540a7e2020-03-27 16:44:05 +08001434
hualing chen4b7c15d2020-04-07 16:13:48 +08001435 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1436 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001437 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1438 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1439 player->cmd.state = DVR_PLAYBACK_STATE_START;
1440 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001441 } else {
1442 player->cmd.last_cmd = player->cmd.cur_cmd;
1443 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001444 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001445 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001446 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001447 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001448 } else {
1449 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001450 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08001451 player->has_audio = DVR_TRUE;
1452 AmTsPlayer_setAudioParams(player->handle, &aparams);
1453 AmTsPlayer_startAudioDecoding(player->handle);
1454 }
hualing chendf118dd2020-05-21 15:49:11 +08001455 if (VALID_PID(adparams.pid)) {
1456 player->has_ad_audio = DVR_TRUE;
1457 DVR_PB_DG(1, "start ad audio");
1458 AmTsPlayer_setADParams(player->handle, &adparams);
1459 AmTsPlayer_enableADMix(player->handle);
1460 }
hualing chen31140872020-03-25 12:29:26 +08001461 }
hualing chencc91e1c2020-02-28 13:26:17 +08001462 player->cmd.state = DVR_PLAYBACK_STATE_START;
1463 player->state = DVR_PLAYBACK_STATE_START;
1464 }
hualing chen86e7d482020-01-16 15:13:33 +08001465 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001466 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001467 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001468 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001469 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001470}
hualing chen040df222020-01-17 13:35:02 +08001471/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001472 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001473 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001474 * \retval DVR_SUCCESS On success
1475 * \return Error code
1476 */
hualing chen040df222020-01-17 13:35:02 +08001477int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1478 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001479
hualing chena540a7e2020-03-27 16:44:05 +08001480 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001481 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001482 return DVR_FAILURE;
1483 }
1484
hualing chen4b7c15d2020-04-07 16:13:48 +08001485 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001486 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001487
hualing chen040df222020-01-17 13:35:02 +08001488 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1489 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001490
hualing chen86e7d482020-01-16 15:13:33 +08001491 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001492 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001493 //cp location
hualing chen040df222020-01-17 13:35:02 +08001494 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001495
hualing chen4b7c15d2020-04-07 16:13:48 +08001496 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 +08001497 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001498
1499 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001500 segment->pids.video.pid = info->pids.video.pid;
1501 segment->pids.video.format = info->pids.video.format;
1502 segment->pids.video.type = info->pids.video.type;
1503
hualing chen2aba4022020-03-02 13:49:55 +08001504 segment->pids.audio.pid = info->pids.audio.pid;
1505 segment->pids.audio.format = info->pids.audio.format;
1506 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001507
hualing chen2aba4022020-03-02 13:49:55 +08001508 segment->pids.ad.pid = info->pids.ad.pid;
1509 segment->pids.ad.format = info->pids.ad.format;
1510 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001511
1512 segment->pids.pcr.pid = info->pids.pcr.pid;
1513
hualing chen4b7c15d2020-04-07 16:13:48 +08001514 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 +08001515 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001516 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001517 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001518 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001519
hualing chen5cbe1a62020-02-10 16:36:36 +08001520 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001521}
hualing chen040df222020-01-17 13:35:02 +08001522/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001523 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001524 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001525 * \retval DVR_SUCCESS On success
1526 * \return Error code
1527 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001528int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001529 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001530 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001531 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001532 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001533 return DVR_FAILURE;
1534 }
1535
hualing chencc91e1c2020-02-28 13:26:17 +08001536 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001537 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001538 return DVR_FAILURE;
1539 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001540 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001541 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001542 DVR_PlaybackSegmentInfo_t *segment = NULL;
1543 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1544 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001545 {
hualing chen040df222020-01-17 13:35:02 +08001546 if (segment->segment_id == segment_id) {
1547 list_del(&segment->head);
1548 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001549 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001550 }
hualing chen86e7d482020-01-16 15:13:33 +08001551 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001552 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001553 pthread_mutex_unlock(&player->lock);
1554
1555 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001556}
hualing chen040df222020-01-17 13:35:02 +08001557/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001558 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001559 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001560 * \retval DVR_SUCCESS On success
1561 * \return Error code
1562 */
hualing chen040df222020-01-17 13:35:02 +08001563int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001564 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001565 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001566 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001567 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001568 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001569 return DVR_FAILURE;
1570 }
1571
hualing chen040df222020-01-17 13:35:02 +08001572 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001573 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001574 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001575 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001576 {
hualing chen040df222020-01-17 13:35:02 +08001577 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001578 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001579 }
hualing chen86e7d482020-01-16 15:13:33 +08001580 // if encramble to free, only set flag and return;
1581
1582 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001583 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001584 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1585 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001586 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001587 AmTsPlayer_hideVideo(player->handle);
1588 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001589 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1590 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001591 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001592 AmTsPlayer_showVideo(player->handle);
1593 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001594 } else {
1595 //do nothing
1596 }
1597 } else {
1598 //do nothing
1599 }
1600 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001601 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001602 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001603 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001604 pthread_mutex_unlock(&player->lock);
1605 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001606}
1607
1608
hualing chen5cbe1a62020-02-10 16:36:36 +08001609static 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 +08001610 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001611 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001612 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001613 return DVR_FAILURE;
1614 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001615 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001616 if (now_pid.pid == set_pid.pid) {
1617 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001618 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001619 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001620 if (VALID_PID(now_pid.pid)) {
1621 //stop now stream
1622 if (type == 0) {
1623 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001624 if (player->has_video == DVR_TRUE) {
1625 DVR_PB_DG(1, "stop video");
1626 AmTsPlayer_stopVideoDecoding(player->handle);
1627 player->has_video = DVR_FALSE;
1628 }
hualing chen86e7d482020-01-16 15:13:33 +08001629 } else if (type == 1) {
1630 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08001631 if (player->has_audio == DVR_TRUE) {
1632 DVR_PB_DG(1, "stop audio");
1633 AmTsPlayer_stopAudioDecoding(player->handle);
1634 player->has_audio = DVR_FALSE;
1635 }
hualing chen86e7d482020-01-16 15:13:33 +08001636 } else if (type == 2) {
1637 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001638 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001639 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001640 } else if (type == 3) {
1641 //pcr
1642 }
1643 }
1644 if (VALID_PID(set_pid.pid)) {
1645 //start
1646 if (type == 0) {
1647 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001648 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001649 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001650 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001651 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001652 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001653 AmTsPlayer_setVideoParams(player->handle, &vparams);
1654 AmTsPlayer_startVideoDecoding(player->handle);
1655 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001656 } else if (type == 1) {
1657 //start audio
hualing chenc70a8df2020-05-12 19:23:11 +08001658 if ((player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
1659 am_tsplayer_audio_params aparams;
1660 aparams.pid = set_pid.pid;
1661 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1662 player->has_audio = DVR_TRUE;
1663 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1664 AmTsPlayer_setAudioParams(player->handle, &aparams);
1665 AmTsPlayer_startAudioDecoding(player->handle);
1666 //playback_device_audio_start(player->handle,&aparams);
1667 }
hualing chen86e7d482020-01-16 15:13:33 +08001668 } else if (type == 2) {
hualing chen39628212020-05-14 10:35:13 +08001669 if ((player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chenc70a8df2020-05-12 19:23:11 +08001670 am_tsplayer_audio_params aparams;
1671 aparams.pid = set_pid.pid;
1672 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1673 player->has_audio = DVR_TRUE;
1674 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1675 AmTsPlayer_setADParams(player->handle, &aparams);
1676 AmTsPlayer_enableADMix(player->handle);
1677 //playback_device_audio_start(player->handle,&aparams);
1678 }
hualing chen86e7d482020-01-16 15:13:33 +08001679 } else if (type == 3) {
1680 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001681 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001682 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001683 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001684 //audio and video all close
1685 if (!player->has_audio && !player->has_video) {
1686 player->state = DVR_PLAYBACK_STATE_STOP;
1687 }
hualing chen86e7d482020-01-16 15:13:33 +08001688 }
1689 }
1690 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001691}
hualing chen5cbe1a62020-02-10 16:36:36 +08001692/**\brief dvr play back update segment pids
1693 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001694 * add pid stream and stop remove pid stream.
1695 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001696 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001697 * \retval DVR_SUCCESS On success
1698 * \return Error code
1699 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001700int 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 +08001701 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001702 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001703 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001704 return DVR_FAILURE;
1705 }
1706
hualing chen040df222020-01-17 13:35:02 +08001707 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001708 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001709 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001710 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 +08001711
hualing chen040df222020-01-17 13:35:02 +08001712 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001713 {
hualing chen040df222020-01-17 13:35:02 +08001714 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001715
1716 if (player->cur_segment_id == segment_id) {
1717 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1718 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1719 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001720 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001721 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001722 return 0;
1723 }
1724
1725 //if segment is on going segment,we need stop start stream
1726 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001727 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001728 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001729 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001730 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001731 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001732 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001733 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001734 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001735 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1736 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001737 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1738 //if state is pause, we need process at resume api. we only record change info
1739 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1740 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1741 if (VALID_PID(segment->pids.video.pid)
1742 && VALID_PID(p_pids->video.pid)
1743 && segment->pids.video.pid != p_pids->video.pid) {
1744 //restart video
1745 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1746 }
1747 if (!VALID_PID(segment->pids.video.pid)
1748 && VALID_PID(p_pids->video.pid)
1749 && segment->pids.video.pid != p_pids->video.pid) {
1750 //start video
1751 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1752 }
1753 if (VALID_PID(segment->pids.video.pid)
1754 && !VALID_PID(p_pids->video.pid)
1755 && segment->pids.video.pid != p_pids->video.pid) {
1756 //stop video
1757 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1758 }
1759 if (VALID_PID(segment->pids.audio.pid)
1760 && VALID_PID(p_pids->audio.pid)
1761 && segment->pids.audio.pid != p_pids->audio.pid) {
1762 //restart audio
1763 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1764 }
1765 if (!VALID_PID(segment->pids.audio.pid)
1766 && VALID_PID(p_pids->audio.pid)
1767 && segment->pids.audio.pid != p_pids->audio.pid) {
1768 //start audio
1769 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1770 }
1771 if (VALID_PID(segment->pids.audio.pid)
1772 && !VALID_PID(p_pids->audio.pid)
1773 && segment->pids.audio.pid != p_pids->audio.pid) {
1774 //stop audio
1775 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1776 }
1777 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1778 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1779 //do nothing
1780 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1781 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1782 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1783 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1784 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1785 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1786 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1787 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1788 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1789 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1790 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1791 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1792 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1793 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1794 } else {
1795 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1796 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1797 }
1798
1799 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1800 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1801 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1802 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1803 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1804 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1805 //not occur this case
1806 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1807 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1808 } else {
1809 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1810 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1811 }
1812
1813 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1814 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1815 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1816 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1817 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1818 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1819 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1820 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1821 } else {
1822 //not occur this case
1823 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1824 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1825 }
1826 }
1827 }
hualing chene10666f2020-04-14 13:58:37 +08001828 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08001829 }
hualing chen86e7d482020-01-16 15:13:33 +08001830 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08001831 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08001832 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08001833 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001834 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001835 }
hualing chen86e7d482020-01-16 15:13:33 +08001836 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001837 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001838 pthread_mutex_unlock(&player->lock);
1839 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001840}
1841/**\brief Stop play, will stop video and audio
1842 * \param[in] handle playback handle
1843 * \param[in] clear is clear last frame
1844 * \retval DVR_SUCCESS On success
1845 * \return Error code
1846 */
hualing chen040df222020-01-17 13:35:02 +08001847int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1848 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001849
1850 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001851 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001852 return DVR_FAILURE;
1853 }
hualing chenb96aa2c2020-04-15 14:13:53 +08001854 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1855 DVR_PB_DG(1, ":playback is stoped");
1856 return DVR_SUCCESS;
1857 }
Ke Gong3c0caba2020-04-21 22:58:18 -07001858 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1859 DVR_PB_DG(1, ":playback is stoped");
1860 return DVR_SUCCESS;
1861 }
hualing chen87072a82020-03-12 16:20:12 +08001862 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001863 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001864 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08001865 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08001866 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001867 if (player->has_video) {
1868 AmTsPlayer_resumeVideoDecoding(player->handle);
1869 }
1870 if (player->has_audio) {
1871 AmTsPlayer_resumeAudioDecoding(player->handle);
1872 }
1873 if (player->has_video) {
1874 player->has_video = DVR_FALSE;
1875 AmTsPlayer_showVideo(player->handle);
1876 AmTsPlayer_stopVideoDecoding(player->handle);
1877 }
1878 if (player->has_audio) {
1879 player->has_audio = DVR_FALSE;
1880 AmTsPlayer_stopAudioDecoding(player->handle);
1881 }
hualing chendf118dd2020-05-21 15:49:11 +08001882 if (player->has_ad_audio) {
1883 player->has_ad_audio =DVR_FALSE;
1884 AmTsPlayer_disableADMix(player->handle);
1885 }
hualing chen266b9502020-04-04 17:39:39 +08001886
hualing chen86e7d482020-01-16 15:13:33 +08001887 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001888 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1889 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1890 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001891 player->cur_segment_id = UINT64_MAX;
1892 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001893 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08001894 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08001895 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001896 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001897}
1898/**\brief Start play audio
1899 * \param[in] handle playback handle
1900 * \param[in] params audio playback params,contains fmt and pid...
1901 * \retval DVR_SUCCESS On success
1902 * \return Error code
1903 */
hualing chen2aba4022020-03-02 13:49:55 +08001904
hualing chendf118dd2020-05-21 15:49:11 +08001905int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param, am_tsplayer_audio_params *adparam) {
hualing chen040df222020-01-17 13:35:02 +08001906 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001907
1908 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001909 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001910 return DVR_FAILURE;
1911 }
hualing chen86e7d482020-01-16 15:13:33 +08001912 _start_playback_thread(handle);
1913 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001914 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001915 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001916
1917 if (VALID_PID(param->pid)) {
1918 DVR_PB_DG(1, "start audio");
1919 player->has_audio = DVR_TRUE;
1920 AmTsPlayer_setAudioParams(player->handle, param);
1921 AmTsPlayer_startAudioDecoding(player->handle);
1922 }
1923 if (VALID_PID(adparam->pid)) {
1924 player->has_ad_audio = DVR_TRUE;
1925 DVR_PB_DG(1, "start ad audio");
1926 AmTsPlayer_setADParams(player->handle, adparam);
1927 AmTsPlayer_enableADMix(player->handle);
1928 }
1929
hualing chen86e7d482020-01-16 15:13:33 +08001930 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001931 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1932 player->cmd.state = DVR_PLAYBACK_STATE_START;
1933 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001934 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001935 pthread_mutex_unlock(&player->lock);
1936 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001937}
1938/**\brief Stop play audio
1939 * \param[in] handle playback handle
1940 * \retval DVR_SUCCESS On success
1941 * \return Error code
1942 */
hualing chen040df222020-01-17 13:35:02 +08001943int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1944 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001945
1946 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001947 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001948 return DVR_FAILURE;
1949 }
1950
hualing chen2aba4022020-03-02 13:49:55 +08001951 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001952 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001953 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1954 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001955 //destory thread
1956 _stop_playback_thread(handle);
1957 } else {
1958 //do nothing.video is playing
1959 }
hualing chen7a56cba2020-04-14 14:09:27 +08001960 DVR_PB_DG(1, "lock");
1961 pthread_mutex_lock(&player->lock);
1962
hualing chendf118dd2020-05-21 15:49:11 +08001963 if (player->has_ad_audio) {
1964 player->has_audio = DVR_FALSE;
1965 AmTsPlayer_stopAudioDecoding(player->handle);
1966 }
hualing chen87072a82020-03-12 16:20:12 +08001967
hualing chendf118dd2020-05-21 15:49:11 +08001968 if (player->has_ad_audio) {
1969 player->has_ad_audio =DVR_FALSE;
1970 AmTsPlayer_disableADMix(player->handle);
1971 }
1972
hualing chen87072a82020-03-12 16:20:12 +08001973 player->cmd.last_cmd = player->cmd.cur_cmd;
1974 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
1975
hualing chen4b7c15d2020-04-07 16:13:48 +08001976 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001977 pthread_mutex_unlock(&player->lock);
1978 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001979}
1980/**\brief Start play video
1981 * \param[in] handle playback handle
1982 * \param[in] params video playback params,contains fmt and pid...
1983 * \retval DVR_SUCCESS On success
1984 * \return Error code
1985 */
hualing chen2aba4022020-03-02 13:49:55 +08001986int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001987 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001988
1989 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001990 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001991 return DVR_FAILURE;
1992 }
1993
hualing chen86e7d482020-01-16 15:13:33 +08001994 _start_playback_thread(handle);
1995 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001996 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001997 pthread_mutex_lock(&player->lock);
1998 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001999 AmTsPlayer_setVideoParams(player->handle, param);
2000 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002001
2002 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002003 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002004 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002005 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002006 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2007 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002008 }
2009 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002010 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2011 player->cmd.state = DVR_PLAYBACK_STATE_START;
2012 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002013 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002014 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002015 return DVR_SUCCESS;
2016}
2017/**\brief Stop play video
2018 * \param[in] handle playback handle
2019 * \retval DVR_SUCCESS On success
2020 * \return Error code
2021 */
hualing chen040df222020-01-17 13:35:02 +08002022int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2023 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002024
2025 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002026 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002027 return DVR_FAILURE;
2028 }
2029
hualing chen86e7d482020-01-16 15:13:33 +08002030 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002031 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2032 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002033 //destory thread
2034 _stop_playback_thread(handle);
2035 } else {
2036 //do nothing.audio is playing
2037 }
hualing chen7a56cba2020-04-14 14:09:27 +08002038
2039 DVR_PB_DG(1, "lock");
2040 pthread_mutex_lock(&player->lock);
2041
hualing chen87072a82020-03-12 16:20:12 +08002042 player->has_video = DVR_FALSE;
2043
2044 AmTsPlayer_stopVideoDecoding(player->handle);
2045 //playback_device_video_stop(player->handle);
2046
2047 player->cmd.last_cmd = player->cmd.cur_cmd;
2048 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2049
hualing chen4b7c15d2020-04-07 16:13:48 +08002050 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002051 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002052 return DVR_SUCCESS;
2053}
2054/**\brief Pause play
2055 * \param[in] handle playback handle
2056 * \param[in] flush whether its internal buffers should be flushed
2057 * \retval DVR_SUCCESS On success
2058 * \return Error code
2059 */
hualing chen040df222020-01-17 13:35:02 +08002060int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2061 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002062
2063 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002064 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002065 return DVR_FAILURE;
2066 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002067 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002068 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002069 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002070 if (player->has_video)
2071 AmTsPlayer_pauseVideoDecoding(player->handle);
2072 if (player->has_video)
2073 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002074
2075 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002076 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2077 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2078 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2079 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002080 } else {
2081 player->cmd.last_cmd = player->cmd.cur_cmd;
2082 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2083 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2084 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002085 }
hualing chen86e7d482020-01-16 15:13:33 +08002086 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002087 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002088
hualing chen86e7d482020-01-16 15:13:33 +08002089 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002090}
2091
hualing chen5cbe1a62020-02-10 16:36:36 +08002092//not add lock
2093static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2094{
2095 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2096
hualing chena540a7e2020-03-27 16:44:05 +08002097 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002098 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002099 return DVR_FAILURE;
2100 }
2101
hualing chen5cbe1a62020-02-10 16:36:36 +08002102 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002103 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002104 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002105 am_tsplayer_video_params vparams;
2106 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002107 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002108 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002109
hualing chendf118dd2020-05-21 15:49:11 +08002110 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002111 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002112 pthread_mutex_unlock(&player->lock);
2113
2114 switch (cmd) {
2115 case DVR_PLAYBACK_CMD_AVRESTART:
2116 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002117 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002118 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002119 break;
2120 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002121 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2122 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002123 break;
2124 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002125 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002126 break;
2127 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002128 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002129 break;
2130 case DVR_PLAYBACK_CMD_ARESTART:
2131 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002132 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002133 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002134 break;
2135 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002136 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002137 break;
2138 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002139 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002140 break;
2141 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002142 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2143 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2144 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002145 break;
2146 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002147 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2148 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002149 break;
2150 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002151 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2152 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002153 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002154 break;
2155 case DVR_PLAYBACK_CMD_STOP:
2156 break;
2157 case DVR_PLAYBACK_CMD_START:
2158 break;
2159 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002160 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2161 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002162 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002163 break;
2164 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002165 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2166 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002167 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002168 break;
2169 case DVR_PLAYBACK_CMD_FF:
2170 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002171 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002172 break;
2173 default:
2174 break;
2175 }
2176 return DVR_SUCCESS;
2177}
2178
2179/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002180 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002181 * \retval DVR_SUCCESS On success
2182 * \return Error code
2183 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002184int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2185 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2186
hualing chena540a7e2020-03-27 16:44:05 +08002187 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002188 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002189 return DVR_FAILURE;
2190 }
2191
hualing chen5cbe1a62020-02-10 16:36:36 +08002192 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002193 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002194 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002195 if (player->has_video) {
2196 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2197 AmTsPlayer_resumeVideoDecoding(player->handle);
2198 }
2199 if (player->has_audio) {
2200 AmTsPlayer_resumeAudioDecoding(player->handle);
2201 }
2202 //check is has audio param,if has audio .we need start audio,
2203 //we will stop audio when ff fb, if reach end, we will pause.so we need
2204 //start audio when resume play
2205
2206 am_tsplayer_video_params vparams;
2207 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002208 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002209 uint64_t segmentid = player->cur_segment_id;
hualing chendf118dd2020-05-21 15:49:11 +08002210 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002211 //valid audio pid, start audio
hualing chenc70a8df2020-05-12 19:23:11 +08002212 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chen266b9502020-04-04 17:39:39 +08002213 player->has_audio = DVR_TRUE;
2214 AmTsPlayer_setAudioParams(player->handle, &aparams);
2215 AmTsPlayer_startAudioDecoding(player->handle);
2216 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002217 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d speed:%d", aparams.pid, player->has_audio, player->cmd.speed.speed.speed);
hualing chen266b9502020-04-04 17:39:39 +08002218 }
hualing chendf118dd2020-05-21 15:49:11 +08002219
2220 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2221 player->has_ad_audio = DVR_TRUE;
2222 DVR_PB_DG(1, "start ad audio");
2223 AmTsPlayer_setADParams(player->handle, &adparams);
2224 AmTsPlayer_enableADMix(player->handle);
2225 }
2226
hualing chen87072a82020-03-12 16:20:12 +08002227 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2228 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2229 player->cmd.state = DVR_PLAYBACK_STATE_START;
2230 player->state = DVR_PLAYBACK_STATE_START;
2231 } else {
2232 player->cmd.last_cmd = player->cmd.cur_cmd;
2233 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2234 player->cmd.state = DVR_PLAYBACK_STATE_START;
2235 player->state = DVR_PLAYBACK_STATE_START;
2236 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002237 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002238 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002239 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
2240 if (player->has_video)
2241 AmTsPlayer_resumeVideoDecoding(player->handle);
2242 if (player->has_audio)
2243 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002244 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002245 player->cmd.state = DVR_PLAYBACK_STATE_START;
2246 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002247 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002248 } else {
2249 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2250 {
2251 pthread_mutex_lock(&player->lock);
2252 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002253 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002254 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2255 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2256 pthread_mutex_unlock(&player->lock);
2257 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002258 }
2259 return DVR_SUCCESS;
2260}
2261
hualing chena540a7e2020-03-27 16:44:05 +08002262static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2263
2264 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2265 DVR_PlaybackSegmentInfo_t *segment = NULL;
2266 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2267 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2268
2269 list_for_each_entry(segment, &player->segment_list, head)
2270 {
2271 if (segment->segment_id == segment_id) {
2272 cur_segment = segment;
2273 }
2274 if (segment->segment_id == set_seg_id) {
2275 set_segment = segment;
2276 }
2277 if (cur_segment != NULL && set_segment != NULL) {
2278 break;
2279 }
2280 }
2281 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002282 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002283 return DVR_TRUE;
2284 }
2285 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2286 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2287 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2288 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002289 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 +08002290 return DVR_TRUE;
2291 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002292 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002293 return DVR_FALSE;
2294}
2295
hualing chen5cbe1a62020-02-10 16:36:36 +08002296/**\brief seek
2297 * \param[in] handle playback handle
2298 * \param[in] time_offset time offset base cur segment
2299 * \retval DVR_SUCCESS On success
2300 * \return Error code
2301 */
hualing chencc91e1c2020-02-28 13:26:17 +08002302int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002303 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002304
2305 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002306 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002307 return DVR_FAILURE;
2308 }
2309
hualing chen4b7c15d2020-04-07 16:13:48 +08002310 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 +08002311 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002312
hualing chen86e7d482020-01-16 15:13:33 +08002313 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002314 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002315 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002316
hualing chen5cbe1a62020-02-10 16:36:36 +08002317 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002318 int ret = _dvr_open_segment(handle, segment_id);
2319 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002320 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002321 pthread_mutex_unlock(&player->lock);
2322 return DVR_FAILURE;
2323 }
2324 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2325 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002326 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002327 //pthread_mutex_unlock(&player->lock);
2328 //return DVR_SUCCESS;
2329 time_offset = _dvr_get_end_time(handle);
2330 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002331 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chen87072a82020-03-12 16:20:12 +08002332 pthread_mutex_unlock(&player->lock);
2333 return DVR_FAILURE;
2334 }
2335 }
2336
hualing chen4b7c15d2020-04-07 16:13:48 +08002337 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 +08002338 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002339 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2340 //forward playback.not seek end of file
2341 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2342 //default -2000ms
2343 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2344 }
hualing chen86e7d482020-01-16 15:13:33 +08002345 }
hualing chen2aba4022020-03-02 13:49:55 +08002346 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002347 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002348 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002349 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002350 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 +08002351 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002352 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002353
hualing chen2aba4022020-03-02 13:49:55 +08002354 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002355
2356 player->last_send_time_id = UINT64_MAX;
2357
hualing chen2aba4022020-03-02 13:49:55 +08002358 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002359 player->fffb_current = _dvr_time_getClock();
2360 player->fffb_start = player->fffb_current;
2361 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2362 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002363 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002364 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002365 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002366 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002367 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002368 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002369 }
hualing chen86e7d482020-01-16 15:13:33 +08002370 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002371 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 +08002372 if (player->has_video) {
2373 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002374 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002375 }
2376
2377 if (player->has_audio) {
2378 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002379 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002380 }
hualing chendf118dd2020-05-21 15:49:11 +08002381 if (player->has_ad_audio) {
2382 player->has_ad_audio =DVR_FALSE;
2383 AmTsPlayer_disableADMix(player->handle);
2384 }
2385
hualing chen86e7d482020-01-16 15:13:33 +08002386 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002387 am_tsplayer_video_params vparams;
2388 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002389 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002390
hualing chen040df222020-01-17 13:35:02 +08002391 player->cur_segment_id = segment_id;
2392
2393 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002394 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002395 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002396 //start audio and video
2397 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2398 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002399 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 +08002400 pthread_mutex_unlock(&player->lock);
2401 return -1;
2402 }
2403 //add
hualing chen040df222020-01-17 13:35:02 +08002404 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002405 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002406 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002407 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002408 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002409 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002410 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002411 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002412 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002413 }
hualing chen2aba4022020-03-02 13:49:55 +08002414 AmTsPlayer_setVideoParams(player->handle, &vparams);
2415 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002416 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002417 }
hualing chen86e7d482020-01-16 15:13:33 +08002418 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002419 DVR_PB_DG(1, "start audio seek");
hualing chen2aba4022020-03-02 13:49:55 +08002420 AmTsPlayer_setAudioParams(player->handle, &aparams);
2421 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002422 player->has_audio = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002423 }
hualing chendf118dd2020-05-21 15:49:11 +08002424 if (VALID_PID(adparams.pid)) {
2425 player->has_ad_audio = DVR_TRUE;
2426 DVR_PB_DG(1, "start ad audio");
2427 AmTsPlayer_setADParams(player->handle, &adparams);
2428 AmTsPlayer_enableADMix(player->handle);
2429 }
hualing chen86e7d482020-01-16 15:13:33 +08002430 }
hualing chen2aba4022020-03-02 13:49:55 +08002431 if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
2432 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2433 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2434 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
2435 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))) {
2436 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2437 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002438 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002439 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2440 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002441 player->speed > 1.0f||
2442 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002443 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002444 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002445 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002446 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002447 player->cmd.last_cmd = player->cmd.cur_cmd;
2448 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2449 player->cmd.state = DVR_PLAYBACK_STATE_START;
2450 player->state = DVR_PLAYBACK_STATE_START;
2451 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002452 player->last_send_time_id = UINT64_MAX;
2453 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002454 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002455
2456 return DVR_SUCCESS;
2457}
hualing chen5cbe1a62020-02-10 16:36:36 +08002458
hualing chen5cbe1a62020-02-10 16:36:36 +08002459static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2460 //get cur time of segment
2461 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002462
2463 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002464 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002465 return DVR_FAILURE;
2466 }
2467
hualing chen31140872020-03-25 12:29:26 +08002468 int64_t cache = 0;//defalut es buf cache 500ms
2469 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002470 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002471 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2472 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen2aba4022020-03-02 13:49:55 +08002473 pthread_mutex_unlock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002474 DVR_PB_DG(1, "get cur time [%lld] cache:%lld cur id [%lld] pb cache len [%d]", cur, cache, player->cur_segment_id, player->ts_cache_len);
hualing chen87072a82020-03-12 16:20:12 +08002475 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2476 cache = 0;
2477 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002478 int cur_time = (int)(cur > cache ? cur - cache : 0);
2479 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002480}
2481
2482//get current segment current pcr time of read pos
2483static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2484 //get cur time of segment
2485 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002486
2487 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002488 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002489 return DVR_FAILURE;
2490 }
2491
hualing chen2aba4022020-03-02 13:49:55 +08002492 pthread_mutex_lock(&player->segment_lock);
2493 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002494 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002495 pthread_mutex_unlock(&player->segment_lock);
2496 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002497}
2498
hualing chen4b7c15d2020-04-07 16:13:48 +08002499#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002500//start replay
2501static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2502
2503 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2504 //calculate pcr seek time
2505 int t_diff = 0;
2506 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002507
2508 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002509 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002510 return DVR_FAILURE;
2511 }
2512
hualing chen5cbe1a62020-02-10 16:36:36 +08002513 if (player->fffb_start == -1) {
2514 //set fffb start time ms
2515 player->fffb_start = _dvr_time_getClock();
2516 player->fffb_current = player->fffb_start;
2517 //get segment current time pos
2518 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002519 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 +08002520 t_diff = 0;
hualing chen2aba4022020-03-02 13:49:55 +08002521 //default first time 1ms seek
hualing chen87072a82020-03-12 16:20:12 +08002522 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002523 } else {
2524 player->fffb_current = _dvr_time_getClock();
2525 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002526 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002527 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002528 if (seek_time <= 0) {
2529 //need seek to pre one segment
2530 seek_time = 0;
2531 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002532 //seek segment pos
2533 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002534 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002535 player->ts_cache_len = 0;
hualing chen041c4092020-04-05 15:11:50 +08002536 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2537 seek_time = 0;
2538 }
hualing chen2aba4022020-03-02 13:49:55 +08002539 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002540 } else {
2541 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002542 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002543 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002544 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 +08002545 }
hualing chen2aba4022020-03-02 13:49:55 +08002546 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002547}
2548
2549
2550//start replay
2551static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2552 //
2553 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002554
2555 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002556 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002557 return DVR_FAILURE;
2558 }
2559
hualing chen5cbe1a62020-02-10 16:36:36 +08002560 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002561 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002562 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002563 AmTsPlayer_stopVideoDecoding(player->handle);
2564 }
2565 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002566 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002567 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002568 AmTsPlayer_stopAudioDecoding(player->handle);
2569 }
hualing chendf118dd2020-05-21 15:49:11 +08002570 if (player->has_ad_audio) {
2571 DVR_PB_DG(1, "fffb stop audio");
2572 player->has_ad_audio =DVR_FALSE;
2573 AmTsPlayer_disableADMix(player->handle);
2574 }
hualing chen2aba4022020-03-02 13:49:55 +08002575
hualing chen5cbe1a62020-02-10 16:36:36 +08002576 //start video and audio
2577
hualing chen2aba4022020-03-02 13:49:55 +08002578 am_tsplayer_video_params vparams;
2579 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002580 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002581 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002582
2583 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002584 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002585 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002586 //start audio and video
2587 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2588 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002589 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002590 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002591 return -1;
2592 }
2593
2594 if (VALID_PID(vparams.pid)) {
2595 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002596 DVR_PB_DG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08002597 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002598 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2599 AmTsPlayer_setVideoParams(player->handle, &vparams);
2600 AmTsPlayer_startVideoDecoding(player->handle);
2601 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002602 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002603 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002604 }
hualing chen31140872020-03-25 12:29:26 +08002605 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08002606 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002607 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002608 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002609 return 0;
2610}
2611
2612static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2613 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002614 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002615 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002616 return DVR_FAILURE;
2617 }
2618
2619 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002620 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002621 pthread_mutex_lock(&player->lock);
2622
hualing chen2aba4022020-03-02 13:49:55 +08002623 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002624 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 +08002625
hualing chen87072a82020-03-12 16:20:12 +08002626 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2627 //seek time set 0
2628 seek_time = 0;
2629 }
hualing chen041c4092020-04-05 15:11:50 +08002630 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002631 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2632 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002633 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002634 pthread_mutex_unlock(&player->lock);
2635 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002636 //send event here and pause
2637 DVR_Play_Notify_t notify;
2638 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002639 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002640 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08002641 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08002642 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 +08002643 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002644 return DVR_SUCCESS;
2645 }
hualing chen2932d372020-04-29 13:44:00 +08002646 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002647 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002648 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002649 }
2650 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002651 _dvr_playback_fffb_replay(handle);
2652
2653 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002654 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002655
hualing chen5cbe1a62020-02-10 16:36:36 +08002656 return DVR_SUCCESS;
2657}
2658
hualing chen87072a82020-03-12 16:20:12 +08002659//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002660static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002661 //
2662 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002663
2664 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002665 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002666 return DVR_FAILURE;
2667 }
2668
hualing chen5cbe1a62020-02-10 16:36:36 +08002669 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002670 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002671 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002672 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002673 }
2674
2675 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002676 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002677 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002678 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002679 //start video and audio
2680
hualing chen2aba4022020-03-02 13:49:55 +08002681 am_tsplayer_video_params vparams;
2682 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002683 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002684 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002685
2686 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002687 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08002688 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002689 //start audio and video
2690 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002691 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002692 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002693 return -1;
2694 }
2695
2696 if (VALID_PID(vparams.pid)) {
2697 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002698 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002699 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002700 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002701 }
hualing chen266b9502020-04-04 17:39:39 +08002702 else {
hualing chen2aba4022020-03-02 13:49:55 +08002703 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002704 }
hualing chen2aba4022020-03-02 13:49:55 +08002705 AmTsPlayer_setVideoParams(player->handle, &vparams);
2706 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002707 }
hualing chena540a7e2020-03-27 16:44:05 +08002708
2709 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08002710 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08002711 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002712 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002713 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002714 if (VALID_PID(aparams.pid)) {
2715 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002716 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08002717 AmTsPlayer_startAudioDecoding(player->handle);
2718 AmTsPlayer_setAudioParams(player->handle, &aparams);
hualing chena540a7e2020-03-27 16:44:05 +08002719 }
hualing chendf118dd2020-05-21 15:49:11 +08002720 if (VALID_PID(adparams.pid)) {
2721 player->has_ad_audio = DVR_TRUE;
2722 DVR_PB_DG(1, "start ad audio");
2723 AmTsPlayer_setADParams(player->handle, &adparams);
2724 AmTsPlayer_enableADMix(player->handle);
2725 }
2726
hualing chen7a56cba2020-04-14 14:09:27 +08002727 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002728 AmTsPlayer_stopFast(player->handle);
2729 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2730 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2731 }
hualing chen2aba4022020-03-02 13:49:55 +08002732 player->cmd.last_cmd = player->cmd.cur_cmd;
2733 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002734 player->cmd.state = DVR_PLAYBACK_STATE_START;
2735 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002736 return 0;
2737}
2738
2739
hualing chenb31a6c62020-01-13 17:27:00 +08002740/**\brief Set play speed
2741 * \param[in] handle playback handle
2742 * \param[in] speed playback speed
2743 * \retval DVR_SUCCESS On success
2744 * \return Error code
2745 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002746int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2747
2748 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002749
2750 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002751 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002752 return DVR_FAILURE;
2753 }
2754
hualing chen4b7c15d2020-04-07 16:13:48 +08002755 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002756 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002757 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002758 return DVR_FAILURE;
2759 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002760 pthread_mutex_lock(&player->lock);
2761 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2762 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2763 player->cmd.last_cmd = player->cmd.cur_cmd;
2764 }
hualing chen31140872020-03-25 12:29:26 +08002765 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002766 IS_KERNEL_SPEED(speed.speed.speed)) {
2767 //case 1. cur speed is 100,set 200 50 25 12 .
2768 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2769 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002770 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002771 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2772 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002773 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002774 AmTsPlayer_stopFast(player->handle);
2775 pthread_mutex_unlock(&player->lock);
2776 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2777 pthread_mutex_lock(&player->lock);
2778 } else {
2779 //set play speed and if audio is start, stop audio.
2780 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002781 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002782 AmTsPlayer_stopAudioDecoding(player->handle);
2783 player->has_audio = DVR_FALSE;
2784 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002785 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002786 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002787 }
hualing chenbcada022020-04-22 14:27:01 +08002788 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08002789 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002790 player->cmd.speed.speed = speed.speed;
2791 player->speed = (float)speed.speed.speed/(float)100;
2792 pthread_mutex_unlock(&player->lock);
2793 return DVR_SUCCESS;
2794 }
2795 //case 2. not start play
2796 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2797 //only set speed.and return;
hualing chena540a7e2020-03-27 16:44:05 +08002798 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002799 player->cmd.speed.speed = speed.speed;
2800 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08002801 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002802 pthread_mutex_unlock(&player->lock);
2803 return DVR_SUCCESS;
hualing chen87072a82020-03-12 16:20:12 +08002804 }
hualing chen31140872020-03-25 12:29:26 +08002805 //case 3 fffb mode
2806 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2807 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2808 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002809 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002810 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002811 player->cmd.speed.speed = speed.speed;
2812 player->speed = (float)speed.speed.speed/(float)100;
2813 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08002814 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002815 pthread_mutex_unlock(&player->lock);
2816 return DVR_SUCCESS;
2817 }
2818 }
2819 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002820 IS_KERNEL_SPEED(speed.speed.speed)) {
2821 //case 1. cur speed is kernel support speed,set kernel speed.
2822 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002823 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002824 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2825 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002826 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002827 AmTsPlayer_stopFast(player->handle);
2828 pthread_mutex_unlock(&player->lock);
2829 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2830 pthread_mutex_lock(&player->lock);
2831 } else {
2832 //set play speed and if audio is start, stop audio.
2833 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002834 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002835 AmTsPlayer_stopAudioDecoding(player->handle);
2836 player->has_audio = DVR_FALSE;
2837 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002838 DVR_PB_DG(1, "start fast");
2839 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08002840 }
hualing chena540a7e2020-03-27 16:44:05 +08002841 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002842 player->cmd.speed.speed = speed.speed;
2843 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08002844 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002845 pthread_mutex_unlock(&player->lock);
2846 return DVR_SUCCESS;
2847 }
2848 //case 2 fffb mode
2849 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2850 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2851 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002852 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002853 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002854 player->cmd.speed.speed = speed.speed;
2855 player->speed = (float)speed.speed.speed/(float)100;
2856 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08002857 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002858 pthread_mutex_unlock(&player->lock);
2859 return DVR_SUCCESS;
2860 }
hualing chen31140872020-03-25 12:29:26 +08002861 }
hualing chena540a7e2020-03-27 16:44:05 +08002862 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2863 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08002864 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08002865 } else {
hualing chen31140872020-03-25 12:29:26 +08002866 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002867 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2868 else
2869 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08002870 player->fffb_play = DVR_TRUE;
2871 }
2872 DVR_Bool_t init_last_time = DVR_FALSE;
2873 if (player->speed > 0.0f && speed.speed.speed < 0) {
2874 init_last_time = DVR_TRUE;
2875 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
2876 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002877 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002878 player->cmd.speed.mode = speed.mode;
2879 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002880 player->speed = (float)speed.speed.speed/(float)100;
2881 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08002882 _dvr_init_fffb_t(handle);
2883 if (init_last_time == DVR_TRUE)
2884 player->last_send_time_id = UINT64_MAX;
2885
hualing chen87072a82020-03-12 16:20:12 +08002886 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002887 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2888 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002889 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002890 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08002891 _dvr_playback_replay(handle, DVR_FALSE);
2892 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2893 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2894 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08002895 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08002896 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002897 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002898 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002899 return DVR_SUCCESS;
2900}
hualing chen2932d372020-04-29 13:44:00 +08002901
hualing chenb31a6c62020-01-13 17:27:00 +08002902/**\brief Get playback status
2903 * \param[in] handle playback handle
2904 * \param[out] p_status playback status
2905 * \retval DVR_SUCCESS On success
2906 * \return Error code
2907 */
hualing chen2932d372020-04-29 13:44:00 +08002908static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
2909 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002910//
2911 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002912
2913 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002914 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002915 return DVR_FAILURE;
2916 }
hualing chen2932d372020-04-29 13:44:00 +08002917 if (is_lock ==DVR_TRUE)
2918 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002919 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002920 //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 +08002921 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2922 player->state == DVR_PLAYBACK_STATE_START) {
2923 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2924 }
hualing chen041c4092020-04-05 15:11:50 +08002925
hualing chencc91e1c2020-02-28 13:26:17 +08002926 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002927 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002928 if (player->last_send_time_id == UINT64_MAX) {
2929 player->last_send_time_id = player->cur_segment_id;
2930 player->last_cur_time = p_status->time_cur;
2931 }
2932 if (player->last_send_time_id == player->cur_segment_id) {
2933 if (player->speed > 0.0f ) {
2934 //ff
2935 if (p_status->time_cur < player->last_cur_time ) {
2936 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);
2937 p_status->time_cur = player->last_cur_time;
2938 } else {
2939 player->last_cur_time = p_status->time_cur;
2940 }
2941 } else if (player->speed < -1.0f){
2942 //fb
2943 if (p_status->time_cur > player->last_cur_time ) {
2944 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 );
2945 p_status->time_cur = player->last_cur_time;
2946 } else {
2947 player->last_cur_time = p_status->time_cur;
2948 }
2949 }
2950 } else {
2951 player->last_cur_time = p_status->time_cur;
2952 }
2953 player->last_send_time_id = player->cur_segment_id;
hualing chen041c4092020-04-05 15:11:50 +08002954 p_status->segment_id = player->cur_segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08002955
hualing chen5cbe1a62020-02-10 16:36:36 +08002956 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08002957 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08002958 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08002959 DVR_PB_DG(1, "player real state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]is_lock[%d]",
hualing chen6d24aa92020-03-23 18:43:47 +08002960 _dvr_playback_state_toString(player->state),
2961 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08002962 p_status->time_cur, p_status->time_end,
2963 p_status->segment_id,player->play_flag,
hualing chen2932d372020-04-29 13:44:00 +08002964 player->speed,
2965 is_lock);
2966 if (is_lock ==DVR_TRUE)
2967 pthread_mutex_unlock(&player->lock);
2968 return DVR_SUCCESS;
2969}
2970
2971
2972/**\brief Get playback status
2973 * \param[in] handle playback handle
2974 * \param[out] p_status playback status
2975 * \retval DVR_SUCCESS On success
2976 * \return Error code
2977 */
2978int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
2979 DVR_PlaybackStatus_t *p_status) {
2980//
2981 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2982
2983 if (player == NULL) {
2984 DVR_PB_DG(1, "player is NULL");
2985 return DVR_FAILURE;
2986 }
2987 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
2988
hualing chenb31a6c62020-01-13 17:27:00 +08002989 return DVR_SUCCESS;
2990}
2991
hualing chen040df222020-01-17 13:35:02 +08002992void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
2993 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002994 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
2995 DVR_PB_DG(1, "segment flag: %d", segment->flags);
2996 DVR_PB_DG(1, "segment location: [%s]", segment->location);
2997 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
2998 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
2999 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3000 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 +08003001 }
hualing chenb31a6c62020-01-13 17:27:00 +08003002}
3003
hualing chen5cbe1a62020-02-10 16:36:36 +08003004int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003005 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003006
hualing chena540a7e2020-03-27 16:44:05 +08003007 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003008 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003009 return DVR_FAILURE;
3010 }
3011
hualing chen040df222020-01-17 13:35:02 +08003012 DVR_PlaybackSegmentInfo_t *segment;
3013 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003014 {
hualing chen040df222020-01-17 13:35:02 +08003015 if (segment_id >= 0) {
3016 if (segment->segment_id == segment_id) {
3017 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003018 break;
3019 }
3020 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003021 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003022 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003023 }
3024 }
3025 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003026}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003027
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003028int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003029{
3030 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3031 DVR_RETURN_IF_FALSE(player);
3032 DVR_RETURN_IF_FALSE(func);
3033
hualing chen4b7c15d2020-04-07 16:13:48 +08003034 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003035 pthread_mutex_lock(&player->lock);
3036
3037 player->dec_func = func;
3038 player->dec_userdata = userdata;
3039
3040 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003041 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003042 return DVR_SUCCESS;
3043}
3044
3045int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3046{
3047 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3048 DVR_RETURN_IF_FALSE(player);
3049 DVR_RETURN_IF_FALSE(p_secure_buf);
3050 DVR_RETURN_IF_FALSE(len);
3051
hualing chen4b7c15d2020-04-07 16:13:48 +08003052 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003053 pthread_mutex_lock(&player->lock);
3054
3055 player->is_secure_mode = 1;
3056 player->secure_buffer = p_secure_buf;
3057 player->secure_buffer_size = len;
3058
3059 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003060 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003061 return DVR_SUCCESS;
3062}