blob: 3b3b248fe43ee38429a5449e546b94591c6e9c90 [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>
14
hualing chenb31a6c62020-01-13 17:27:00 +080015#include "dvr_playback.h"
16
hualing chen4b7c15d2020-04-07 16:13:48 +080017#define DVR_PB_DG(_level, _fmt, ...) \
18 DVR_DEBUG(_level, "playback %-30.30s:%d " _fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
19
hualing chena540a7e2020-03-27 16:44:05 +080020
hualing chenb31a6c62020-01-13 17:27:00 +080021#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080022
23
24#define FF_SPEED (2.0f)
25#define FB_SPEED (-1.0f)
26#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
27#define IS_FB(_SPEED_) ((_SPEED_) < FB_SPEED)
28
29#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))
30#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
31
hualing chenb31a6c62020-01-13 17:27:00 +080032
hualing chen041c4092020-04-05 15:11:50 +080033#define FFFB_SLEEP_TIME (500)//500ms
hualing chen4b7c15d2020-04-07 16:13:48 +080034#define FB_DEFAULT_LEFT_TIME (10000)
hualing chen31140872020-03-25 12:29:26 +080035//if tsplayer delay time < 200 and no data can read, we will pause
36#define MIN_TSPLAYER_DELAY_TIME (200)
37
hualing chen041c4092020-04-05 15:11:50 +080038#define MAX_CACHE_TIME (30000)
39
hualing chena540a7e2020-03-27 16:44:05 +080040static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080041//
42static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chencc91e1c2020-02-28 13:26:17 +080043static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type);
44static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
45static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080046static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080047static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
48
hualing chen6d24aa92020-03-23 18:43:47 +080049static char* _dvr_playback_state_toString(int stat)
50{
51 char *string[DVR_PLAYBACK_STATE_FB+1]={
52 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080053 "stop",
hualing chen31140872020-03-25 12:29:26 +080054 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080055 "ff",
56 "fb"
57 };
58
59 if (stat > DVR_PLAYBACK_STATE_FB) {
60 return "unkown";
61 } else {
62 return string[stat];
63 }
64}
hualing chena540a7e2020-03-27 16:44:05 +080065
66static DVR_Bool_t _dvr_support_speed(int speed) {
67
68 DVR_Bool_t ret = DVR_FALSE;
69
70 switch (speed) {
71 case PLAYBACK_SPEED_FBX2:
72 case PLAYBACK_SPEED_FBX4:
73 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +080074 case PLAYBACK_SPEED_FBX16:
75 case PLAYBACK_SPEED_FBX12:
76 case PLAYBACK_SPEED_FBX32:
77 case PLAYBACK_SPEED_FBX48:
78 case PLAYBACK_SPEED_FBX64:
79 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +080080 case PLAYBACK_SPEED_S2:
81 case PLAYBACK_SPEED_S4:
82 case PLAYBACK_SPEED_S8:
83 case PLAYBACK_SPEED_X1:
84 case PLAYBACK_SPEED_X2:
85 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +080086 case PLAYBACK_SPEED_X3:
87 case PLAYBACK_SPEED_X5:
88 case PLAYBACK_SPEED_X6:
89 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +080090 case PLAYBACK_SPEED_X8:
91 case PLAYBACK_SPEED_X12:
92 case PLAYBACK_SPEED_X16:
93 case PLAYBACK_SPEED_X32:
94 case PLAYBACK_SPEED_X48:
95 case PLAYBACK_SPEED_X64:
96 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +080097 ret = DVR_TRUE;
98 break;
99 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800100 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800101 break;
102 }
103 return ret;
104}
hualing chen6e4bfa52020-03-13 14:37:11 +0800105void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
106{
hualing chen4b7c15d2020-04-07 16:13:48 +0800107 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800108 DVR_Playback_t *player = NULL;
109 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800110 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800111 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800112 }
113 switch (event->type) {
114 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
115 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800116 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800117 event->event.video_format.frame_width,
118 event->event.video_format.frame_height,
119 event->event.video_format.frame_rate);
120 break;
121 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800122 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
123 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800124 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800125 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800126 break;
127 }
128 default:
129 break;
130 }
131}
hualing chen2aba4022020-03-02 13:49:55 +0800132void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
133{
hualing chen6e4bfa52020-03-13 14:37:11 +0800134 DVR_Playback_t *player = NULL;
135 if (user_data != NULL) {
136 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800137 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800138 }
hualing chen2aba4022020-03-02 13:49:55 +0800139 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800140 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
141 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800142 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800143 event->event.video_format.frame_width,
144 event->event.video_format.frame_height,
145 event->event.video_format.frame_rate);
146 break;
147 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800148 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
149 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800150 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800151 if (player != NULL)
152 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800153 break;
154 }
155 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800156 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800157 break;
158 }
159 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800160 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800161 player->player_callback_func(player->player_callback_userdata, event);
162 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800163 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800164 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800165 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800166 }
167}
hualing chencc91e1c2020-02-28 13:26:17 +0800168
hualing chen5cbe1a62020-02-10 16:36:36 +0800169//convert video and audio fmt
170static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
171 int format = 0;
172 if (is_audio == DVR_FALSE) {
173 //for video fmt
174 switch (fmt)
175 {
176 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800177 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800178 break;
179 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800180 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800181 break;
182 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800183 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800184 break;
185 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800186 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800187 break;
hualing chena540a7e2020-03-27 16:44:05 +0800188 case DVR_VIDEO_FORMAT_VP9:
189 format = AV_VIDEO_CODEC_VP9;
190 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800191 }
192 } else {
193 //for audio fmt
194 switch (fmt)
195 {
196 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800197 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800198 break;
199 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800200 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800201 break;
202 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800203 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800204 break;
205 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800206 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800207 break;
hualing chena540a7e2020-03-27 16:44:05 +0800208 case DVR_AUDIO_FORMAT_AAC:
209 format = AV_AUDIO_CODEC_AAC;
210 break;
211 case DVR_AUDIO_FORMAT_LATM:
212 format = AV_AUDIO_CODEC_LATM;
213 break;
214 case DVR_AUDIO_FORMAT_PCM:
215 format = AV_AUDIO_CODEC_PCM;
216 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800217 }
218 }
219 return format;
220}
hualing chen040df222020-01-17 13:35:02 +0800221static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800222{
hualing chen040df222020-01-17 13:35:02 +0800223 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800224
hualing chena540a7e2020-03-27 16:44:05 +0800225 if (player == NULL || player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800226 return -1;
227
hualing chena540a7e2020-03-27 16:44:05 +0800228 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800229}
hualing chena540a7e2020-03-27 16:44:05 +0800230
hualing chen5cbe1a62020-02-10 16:36:36 +0800231//get sys time ms
232static int _dvr_time_getClock(void)
233{
234 struct timespec ts;
235 int ms;
236
237 clock_gettime(CLOCK_MONOTONIC, &ts);
238 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
239
240 return ms;
241}
hualing chen86e7d482020-01-16 15:13:33 +0800242
hualing chenb31a6c62020-01-13 17:27:00 +0800243
244//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800245static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800246{
hualing chen040df222020-01-17 13:35:02 +0800247 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800248
hualing chena540a7e2020-03-27 16:44:05 +0800249
250 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800251 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800252 return DVR_FAILURE;
253 }
254
hualing chen86e7d482020-01-16 15:13:33 +0800255 struct timespec ts;
256 clock_gettime(CLOCK_MONOTONIC, &ts);
257 //ms为毫秒,换算成秒
258 ts.tv_sec += ms/1000;
259 //在outtime的基础上,增加ms毫秒
260 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
261 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
262 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
263 //us的值有可能超过1秒,
264 ts.tv_sec += us / 1000000;
265 us = us % 1000000;
266 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800267 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
268 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800269}
hualing chen31140872020-03-25 12:29:26 +0800270//get tsplay delay time ms
271static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
272 DVR_Playback_t *player = (DVR_Playback_t *) handle;
273 int64_t cache = 0;
274 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800275 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800276 return 0;
277 }
278 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800279 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800280 return cache;
281}
hualing chenb31a6c62020-01-13 17:27:00 +0800282//send signal
hualing chen040df222020-01-17 13:35:02 +0800283static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800284{
hualing chen87072a82020-03-12 16:20:12 +0800285 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800286
287 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800288 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800289 return DVR_FAILURE;
290 }
291
hualing chen87072a82020-03-12 16:20:12 +0800292 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800293 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800294 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800295 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800296}
297
hualing chencc91e1c2020-02-28 13:26:17 +0800298//send playback event
299static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify) {
300
301 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800302
303 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800304 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800305 return DVR_FAILURE;
306 }
307
hualing chencc91e1c2020-02-28 13:26:17 +0800308 switch (evt) {
309 case DVR_PLAYBACK_EVENT_ERROR:
310 break;
311 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
312 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800313 DVR_PB_DG(1, "trans ok EVENT");
hualing chencc91e1c2020-02-28 13:26:17 +0800314 dvr_playback_get_status(handle, &(notify->play_status));
315 break;
316 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
317 break;
318 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
319 break;
320 case DVR_PLAYBACK_EVENT_NO_KEY:
321 break;
322 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800323 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800324 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2aba4022020-03-02 13:49:55 +0800325 dvr_playback_get_status(handle, &(notify->play_status));
hualing chencc91e1c2020-02-28 13:26:17 +0800326 break;
327 case DVR_PLAYBACK_EVENT_REACHED_END:
328 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800329 DVR_PB_DG(1, "reached end EVENT");
hualing chencc91e1c2020-02-28 13:26:17 +0800330 dvr_playback_get_status(handle, &(notify->play_status));
331 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800332 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen6e4bfa52020-03-13 14:37:11 +0800333 dvr_playback_get_status(handle, &(notify->play_status));
334 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800335 default:
336 break;
337 }
338 if (player->openParams.event_fn != NULL)
339 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800340 return DVR_SUCCESS;
341}
342static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle)
343{
344 DVR_Play_Notify_t notify;
345 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
346 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
347 //get play statue not here
348 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify);
349 return DVR_SUCCESS;
350}
351
hualing chen6e4bfa52020-03-13 14:37:11 +0800352static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle)
353{
354 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800355
hualing chen4b7c15d2020-04-07 16:13:48 +0800356 if (1) {
357 return DVR_SUCCESS;
358 }
hualing chena540a7e2020-03-27 16:44:05 +0800359 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800360 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800361 return DVR_FAILURE;
362 }
363
hualing chen6e4bfa52020-03-13 14:37:11 +0800364 if (player->send_time ==0) {
365 player->send_time = _dvr_time_getClock() + 1000;
366 } else if (player->send_time > _dvr_time_getClock()) {
367 return DVR_SUCCESS;
368 }
369 player->send_time = _dvr_time_getClock() + 1000;
370 DVR_Play_Notify_t notify;
371 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
372 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
373 //get play statue not here
374 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify);
375 return DVR_SUCCESS;
376}
377
hualing chencc91e1c2020-02-28 13:26:17 +0800378//check is ongoing segment
379static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
380
381 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800382 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800383
384 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800385 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800386 return DVR_FAILURE;
387 }
hualing chen87072a82020-03-12 16:20:12 +0800388 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800389 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800390 return DVR_FALSE;
391 }
hualing chencc91e1c2020-02-28 13:26:17 +0800392 return DVR_TRUE;
393}
hualing chen4b7c15d2020-04-07 16:13:48 +0800394
395
396static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
397 DVR_Playback_t *player = (DVR_Playback_t *) handle;
398 player->fffb_start = _dvr_time_getClock();
399 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
400 player->fffb_current = player->fffb_start;
401 //get segment current time pos
402 player->fffb_start_pcr = _dvr_get_cur_time(handle);
403 //player->fffb_current = -1;
404 //player->fffb_start = -1;
405 //player->fffb_start_pcr = -1;
406 player->next_fffb_time = _dvr_time_getClock();
407
408 return DVR_SUCCESS;
409}
410
hualing chen2aba4022020-03-02 13:49:55 +0800411static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
412 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800413 player->fffb_start = _dvr_time_getClock();
414 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
415 player->fffb_current = player->fffb_start;
416 //get segment current time pos
417 player->fffb_start_pcr = _dvr_get_cur_time(handle);
418 //player->fffb_current = -1;
419 //player->fffb_start = -1;
420 //player->fffb_start_pcr = -1;
hualing chen2aba4022020-03-02 13:49:55 +0800421 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800422 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800423 return DVR_SUCCESS;
424}
hualing chencc91e1c2020-02-28 13:26:17 +0800425//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800426static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
427
428 DVR_Playback_t *player = (DVR_Playback_t *) handle;
429 DVR_PlaybackSegmentInfo_t *segment;
430 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
431
hualing chena540a7e2020-03-27 16:44:05 +0800432 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800433 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800434 return DVR_FAILURE;
435 }
436
hualing chen87072a82020-03-12 16:20:12 +0800437 int found = 0;
438 int found_eq_id = 0;
439 list_for_each_entry(segment, &player->segment_list, head)
440 {
441 if (player->segment_is_open == DVR_FALSE) {
442 //get first segment from list, case segment is not open
443 if (!IS_FB(player->speed))
444 found = 1;
445 } else if (segment->segment_id == segmentid) {
446 //find cur segment, we need get next one
447 found_eq_id = 1;
448 if (!IS_FB(player->speed)) {
449 found = 1;
450 continue;
451 } else {
452 //if is fb mode.we need used pre segment
453 if (pre_segment != NULL) {
454 found = 1;
455 } else {
456 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800457 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800458 return DVR_FAILURE;
459 }
460 }
461 }
462 if (found == 1) {
463 found = 2;
464 break;
465 }
466 }
467 if (found != 2) {
468 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800469 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800470 return DVR_FAILURE;
471 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800472 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800473 return DVR_SUCCESS;
474}
475
476//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800477static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800478
hualing chen040df222020-01-17 13:35:02 +0800479 DVR_Playback_t *player = (DVR_Playback_t *) handle;
480 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800481 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800482
hualing chena540a7e2020-03-27 16:44:05 +0800483 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800484 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800485 return DVR_FAILURE;
486 }
487
hualing chen86e7d482020-01-16 15:13:33 +0800488 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800489 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800490
hualing chen040df222020-01-17 13:35:02 +0800491 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800492 {
hualing chencc91e1c2020-02-28 13:26:17 +0800493 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800494 //get first segment from list, case segment is not open
495 if (!IS_FB(player->speed))
496 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800497 } else if (segment->segment_id == player->cur_segment_id) {
498 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800499 found_eq_id = 1;
500 if (!IS_FB(player->speed)) {
501 found = 1;
502 continue;
503 } else {
504 //if is fb mode.we need used pre segment
505 if (pre_segment != NULL) {
506 found = 1;
507 } else {
508 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800509 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800510 return DVR_FAILURE;
511 }
512 }
hualing chen86e7d482020-01-16 15:13:33 +0800513 }
514 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800515 if (IS_FB(player->speed)) {
516 //used pre segment
517 segment = pre_segment;
518 }
hualing chencc91e1c2020-02-28 13:26:17 +0800519 //save segment info
520 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800521 player->last_segment.segment_id = player->cur_segment.segment_id;
522 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800523 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
524 //pids
525 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
526
hualing chen5cbe1a62020-02-10 16:36:36 +0800527 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800528 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800529 player->cur_segment_id = segment->segment_id;
530 player->cur_segment.segment_id = segment->segment_id;
531 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800532 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 +0800533 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800534 //pids
hualing chen040df222020-01-17 13:35:02 +0800535 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800536 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800537 break;
hualing chen86e7d482020-01-16 15:13:33 +0800538 }
hualing chen2aba4022020-03-02 13:49:55 +0800539 pre_segment = segment;
540 }
541 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
542 //used the last one segment to open
543 //get segment info
544 player->segment_is_open = DVR_TRUE;
545 player->cur_segment_id = pre_segment->segment_id;
546 player->cur_segment.segment_id = pre_segment->segment_id;
547 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800548 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 +0800549 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
550 //pids
551 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
552 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800553 }
554 if (found != 2) {
555 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800556 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800557 }
558 return DVR_SUCCESS;
559}
hualing chen040df222020-01-17 13:35:02 +0800560//open next segment to play,if reach list end return errro.
561static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800562{
hualing chen040df222020-01-17 13:35:02 +0800563 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800564 Segment_OpenParams_t params;
565 int ret = DVR_SUCCESS;
566
hualing chena540a7e2020-03-27 16:44:05 +0800567 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800568 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800569 return DVR_FAILURE;
570 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800571 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800572
573 ret = _dvr_get_next_segmentId(handle);
574 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800575 DVR_PB_DG(1, "not found segment info");
576 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800577 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800578 }
579
580 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800581 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800582 segment_close(player->r_handle);
583 player->r_handle = NULL;
584 }
585
586 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800587 //cp chur segment path to location
588 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800589 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800590 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800591 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
592
hualing chen86e7d482020-01-16 15:13:33 +0800593 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800594 if (ret == DVR_FAILURE) {
595 DVR_PB_DG(1, "open segment error");
596 }
hualing chen87072a82020-03-12 16:20:12 +0800597 pthread_mutex_unlock(&player->segment_lock);
598 int total = _dvr_get_end_time( handle);
599 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800600 if (IS_FB(player->speed)) {
601 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen266b9502020-04-04 17:39:39 +0800602 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800603 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800604 }
hualing chen87072a82020-03-12 16:20:12 +0800605 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800606 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800607 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800608 return ret;
609}
610
hualing chen5cbe1a62020-02-10 16:36:36 +0800611//open next segment to play,if reach list end return errro.
612static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
613{
614 DVR_Playback_t *player = (DVR_Playback_t *) handle;
615 Segment_OpenParams_t params;
616 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800617 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800618 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800619 return DVR_FAILURE;
620 }
hualing chencc91e1c2020-02-28 13:26:17 +0800621 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800622 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800623 }
hualing chencc91e1c2020-02-28 13:26:17 +0800624 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800625 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800626 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800627 return DVR_FAILURE;
628 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800629 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800630 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800631
632 DVR_PlaybackSegmentInfo_t *segment;
633
634 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800635
hualing chen5cbe1a62020-02-10 16:36:36 +0800636 list_for_each_entry(segment, &player->segment_list, head)
637 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800638 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 +0800639 if (segment->segment_id == segment_id) {
640 found = 1;
641 }
642 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800643 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 +0800644 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800645 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800646 player->cur_segment_id = segment->segment_id;
647 player->cur_segment.segment_id = segment->segment_id;
648 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800649 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800650 //pids
651 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800652 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 +0800653 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800654 }
655 }
hualing chencc91e1c2020-02-28 13:26:17 +0800656 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800657 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800658 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800659 return DVR_FAILURE;
660 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800661 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800662 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800663 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800664 params.segment_id = (uint64_t)player->cur_segment.segment_id;
665 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800666 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 +0800667 if (player->r_handle != NULL) {
668 segment_close(player->r_handle);
669 player->r_handle = NULL;
670 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800671 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800672 if (ret == DVR_FAILURE) {
673 DVR_PB_DG(1, "segment opne error");
674 }
hualing chen2aba4022020-03-02 13:49:55 +0800675 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800676 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800677
hualing chen4b7c15d2020-04-07 16:13:48 +0800678 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 +0800679 return ret;
680}
681
682
683//get play info by segment id
684static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
685 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800686 am_tsplayer_video_params *vparam,
687 am_tsplayer_audio_params *aparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800688
689 DVR_Playback_t *player = (DVR_Playback_t *) handle;
690 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800691 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800692 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800693 return DVR_FAILURE;
694 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800695
696 int found = 0;
697
698 list_for_each_entry(segment, &player->segment_list, head)
699 {
hualing chen87072a82020-03-12 16:20:12 +0800700 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800701 //get first segment from list
702 found = 1;
703 }
704 if (segment->segment_id == segment_id) {
705 found = 1;
706 }
707 if (found == 1) {
708 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800709 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800710 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800711 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800712 player->cur_segment.segment_id = segment->segment_id;
713 player->cur_segment.flags = segment->flags;
714 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800715 player->cur_segment.pids.video.pid = segment->pids.video.pid;
716 player->cur_segment.pids.video.format = segment->pids.video.format;
717 player->cur_segment.pids.video.type = segment->pids.video.type;
718 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
719 player->cur_segment.pids.audio.format = segment->pids.audio.format;
720 player->cur_segment.pids.audio.type = segment->pids.audio.type;
721 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
722 player->cur_segment.pids.ad.format = segment->pids.ad.format;
723 player->cur_segment.pids.ad.type = segment->pids.ad.type;
724 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800725 //
hualing chen2aba4022020-03-02 13:49:55 +0800726 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800727 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800728 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800729 aparam->pid = segment->pids.audio.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800730 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 +0800731 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800732 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800733 }
734 }
hualing chencc91e1c2020-02-28 13:26:17 +0800735 if (found != 2) {
736 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800737 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800738 return DVR_FAILURE;
739 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800740
741 return DVR_SUCCESS;
742}
hualing chencc91e1c2020-02-28 13:26:17 +0800743static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
744 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800745 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800746 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800747 return DVR_FAILURE;
748 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800749
hualing chencc91e1c2020-02-28 13:26:17 +0800750 //compare cur segment
751 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
752 {
753 //check video pids, stop or restart
754 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
755 //check audio pids stop or restart
756 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
757 //check sub audio pids stop or restart
758 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
759 //check pcr pids stop or restart
760 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
761 }
hualing chena540a7e2020-03-27 16:44:05 +0800762 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800763}
hualing chen5cbe1a62020-02-10 16:36:36 +0800764
hualing chencc91e1c2020-02-28 13:26:17 +0800765static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
766{
767 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800768 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800769 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800770 return DVR_FAILURE;
771 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800772 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 +0800773 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
774 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800775 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800776 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800777 AmTsPlayer_showVideo(player->handle);
778 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800779 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
780 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800781 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800782 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800783 AmTsPlayer_hideVideo(player->handle);
784 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800785 }
786 return DVR_SUCCESS;
787}
hualing chena540a7e2020-03-27 16:44:05 +0800788static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
789 DVR_Playback_t *player = (DVR_Playback_t *) handle;
790 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800791 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800792 return DVR_TRUE;
793 }
hualing chen266b9502020-04-04 17:39:39 +0800794 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chena540a7e2020-03-27 16:44:05 +0800795 if (player->first_frame == 1) {
796 return DVR_TRUE;
797 } else {
798 return DVR_FALSE;
799 }
800 } else {
801 return DVR_TRUE;
802 }
803}
hualing chen86e7d482020-01-16 15:13:33 +0800804static void* _dvr_playback_thread(void *arg)
805{
hualing chen040df222020-01-17 13:35:02 +0800806 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800807 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800808 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800809 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800810 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800811
hualing chen6d24aa92020-03-23 18:43:47 +0800812 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800813 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800814 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800815 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800816 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
817
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800818 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800819 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800820 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800821
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800822 if (player->is_secure_mode) {
823 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800824 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800825 return NULL;
826 }
827 }
hualing chen86e7d482020-01-16 15:13:33 +0800828 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800829 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800830 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800831 return NULL;
832 }
hualing chen2aba4022020-03-02 13:49:55 +0800833 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
834 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800835
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800836 dec_bufs.buf_data = malloc(dec_buf_size);
837 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800838 DVR_PB_DG(1, "Malloc dec buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800839 return NULL;
840 }
841 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
842 dec_bufs.buf_size = dec_buf_size;
843
hualing chencc91e1c2020-02-28 13:26:17 +0800844 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800845 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
846 }
hualing chen86e7d482020-01-16 15:13:33 +0800847
hualing chen86e7d482020-01-16 15:13:33 +0800848 if (ret != DVR_SUCCESS) {
849 if (buf != NULL) {
850 free(buf);
851 buf = NULL;
852 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800853 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800854 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800855 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800856 }
hualing chencc91e1c2020-02-28 13:26:17 +0800857 //get play statue not here
858 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
859 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800860 //set video show
861 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800862
hualing chen86e7d482020-01-16 15:13:33 +0800863 int trick_stat = 0;
864 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800865
hualing chen86e7d482020-01-16 15:13:33 +0800866 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800867 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800868
hualing chen2aba4022020-03-02 13:49:55 +0800869 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
870 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800871 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800872 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen31140872020-03-25 12:29:26 +0800873 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800874 {
hualing chen2aba4022020-03-02 13:49:55 +0800875 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
876 if (trick_stat > 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800877 DVR_PB_DG(1, "trick stat[%d] is > 0", trick_stat);
hualing chen87072a82020-03-12 16:20:12 +0800878 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 +0800879 //check last cmd
880 if(player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800881 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800882 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
883 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800884 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
885 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800886 DVR_PB_DG(1, "pause play-------");
hualing chen2aba4022020-03-02 13:49:55 +0800887 //need change to pause state
888 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
889 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800890 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800891 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800892 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800893 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800894 AmTsPlayer_pauseVideoDecoding(player->handle);
895 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800896 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800897 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +0800898 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800899 }
900 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
901 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800902 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800903 //restart play stream if speed > 2
904 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
905 _dvr_time_getClock() < player->next_fffb_time) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800906 DVR_PB_DG(1, "fffb timeout----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 +0800907 //used timeout wait need lock first,so we unlock and lock
908 //pthread_mutex_unlock(&player->lock);
909 //pthread_mutex_lock(&player->lock);
910 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
911 pthread_mutex_unlock(&player->lock);
912 continue;
913 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800914 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
hualing chen2aba4022020-03-02 13:49:55 +0800915 pthread_mutex_unlock(&player->lock);
916 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800917 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800918 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
919 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800920 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
921 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800922 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800923 }else if (player->fffb_play == DVR_TRUE){
924 //for first into fffb when reset speed
925 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
926 _dvr_time_getClock() < player->next_fffb_time) {
927 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);
928 //used timeout wait need lock first,so we unlock and lock
929 //pthread_mutex_unlock(&player->lock);
930 //pthread_mutex_lock(&player->lock);
931 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
932 pthread_mutex_unlock(&player->lock);
933 continue;
934 }
935 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
936 pthread_mutex_unlock(&player->lock);
937 goto_rewrite = DVR_FALSE;
938 real_read = 0;
939 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
940 player->first_frame = 0;
941 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
942 pthread_mutex_lock(&player->lock);
943 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +0800944 }
hualing chenb31a6c62020-01-13 17:27:00 +0800945 }
hualing chen86e7d482020-01-16 15:13:33 +0800946
hualing chen87072a82020-03-12 16:20:12 +0800947 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800948 //check is need send time send end
949 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800950 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
951 pthread_mutex_unlock(&player->lock);
952 continue;
953 }
hualing chen266b9502020-04-04 17:39:39 +0800954 //when seek action is done. we need drop write timeout data.
955 if (player->drop_ts == DVR_TRUE) {
956 goto_rewrite = DVR_FALSE;
957 real_read = 0;
958 player->drop_ts = DVR_FALSE;
959 }
hualing chen2aba4022020-03-02 13:49:55 +0800960 if (goto_rewrite == DVR_TRUE) {
961 goto_rewrite = DVR_FALSE;
962 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800963 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +0800964 goto rewrite;
965 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800966 //.check is need send time send end
967 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen4b7c15d2020-04-07 16:13:48 +0800968 pthread_mutex_lock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800969 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen4b7c15d2020-04-07 16:13:48 +0800970 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800971 pthread_mutex_unlock(&player->lock);
972 //if on fb mode and read file end , we need calculate pos to retry read.
973 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800974 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 +0800975 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
976 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +0800977 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
978 pthread_mutex_unlock(&player->lock);
979 continue;
980 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800981 //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 +0800982 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +0800983 //file end.need to play next segment
hualing chen040df222020-01-17 13:35:02 +0800984 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +0800985 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +0800986 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +0800987
988 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +0800989 if (ret != DVR_SUCCESS &&
990 (delay <= MIN_TSPLAYER_DELAY_TIME ||
991 delay > MAX_CACHE_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +0800992 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen041c4092020-04-05 15:11:50 +0800993 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) {
hualing chena540a7e2020-03-27 16:44:05 +0800994 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +0800995 DVR_Play_Notify_t notify;
996 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
997 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
998 //get play statue not here
999 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen31140872020-03-25 12:29:26 +08001000 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify);
1001 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen4b7c15d2020-04-07 16:13:48 +08001002 DVR_PB_DG(1, "playback is send end delay:[%d]", delay);
hualing chen31140872020-03-25 12:29:26 +08001003 pthread_mutex_lock(&player->lock);
1004 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1005 pthread_mutex_unlock(&player->lock);
1006 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001007 } else if (ret != DVR_SUCCESS) {
1008 //not send event and pause,sleep and go to next time to recheck
hualing chen4b7c15d2020-04-07 16:13:48 +08001009 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001010 pthread_mutex_lock(&player->lock);
1011 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1012 pthread_mutex_unlock(&player->lock);
1013 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001014 }
hualing chen31140872020-03-25 12:29:26 +08001015 //change next segment success case
hualing chencc91e1c2020-02-28 13:26:17 +08001016 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
1017 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001018 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001019 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1020 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001021 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001022 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001023 }
1024 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001025 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001026 wbufs.buf_data = buf;
hualing chena540a7e2020-03-27 16:44:05 +08001027 //check read data len,iflen < 0, we need continue
1028 if (wbufs.buf_size == 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001029 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001030 real_read = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001031 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001032 }
hualing chen266b9502020-04-04 17:39:39 +08001033 //if need write whole block size, we need check read buf len is eq block size.
1034 if (b_writed_whole_block == DVR_TRUE) {
1035 //buf_len is block size value.
1036 if (real_read < buf_len) {
1037 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001038 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001039 pthread_mutex_lock(&player->lock);
1040 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1041 pthread_mutex_unlock(&player->lock);
1042 continue;
1043 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001044 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 +08001045 }
1046 }
1047
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001048 if (player->dec_func) {
1049 DVR_CryptoParams_t crypto_params;
1050
1051 memset(&crypto_params, 0, sizeof(crypto_params));
1052 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1053 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1054 crypto_params.segment_id = player->cur_segment.segment_id;
1055 crypto_params.offset = segment_tell_position(player->r_handle);
1056
1057 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1058 crypto_params.input_buffer.addr = (size_t)buf;
1059 crypto_params.input_buffer.size = real_read;
1060
1061 if (player->is_secure_mode) {
1062 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1063 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1064 crypto_params.output_buffer.size = dec_buf_size;
1065 ret = player->dec_func(&crypto_params, player->dec_userdata);
1066 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001067 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001068 } else {
1069 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1070 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1071 crypto_params.output_buffer.size = dec_buf_size;
1072 ret = player->dec_func(&crypto_params, player->dec_userdata);
1073 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001074 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001075 }
1076 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001077 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001078 }
pengfei.liufda2a972020-04-09 14:47:15 +08001079 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001080 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001081rewrite:
hualing chen041c4092020-04-05 15:11:50 +08001082
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001083 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1084 if (ret == AM_TSPLAYER_OK) {
hualing chena540a7e2020-03-27 16:44:05 +08001085 real_read = 0;
1086 write_success++;
1087 continue;
hualing chen87072a82020-03-12 16:20:12 +08001088 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001089 DVR_PB_DG(1, "write time out write_success:%d", write_success);
hualing chena540a7e2020-03-27 16:44:05 +08001090 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001091 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001092 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001093 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001094 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001095 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001096 break;
1097 }
hualing chen2aba4022020-03-02 13:49:55 +08001098 goto_rewrite = DVR_TRUE;
1099 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001100 }
1101 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001102 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001103 free(buf);
1104 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001105 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001106}
1107
1108
hualing chen040df222020-01-17 13:35:02 +08001109static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001110{
hualing chen040df222020-01-17 13:35:02 +08001111 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001112
1113 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001114 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001115 return DVR_FAILURE;
1116 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001117 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001118 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001119 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001120 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001121 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001122 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001123 if (rc < 0)
1124 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001125 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001126}
1127
1128
hualing chen040df222020-01-17 13:35:02 +08001129static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001130{
hualing chen040df222020-01-17 13:35:02 +08001131 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001132
1133 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001134 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001135 return DVR_FAILURE;
1136 }
1137
hualing chen4b7c15d2020-04-07 16:13:48 +08001138 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001139 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001140 {
1141 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001142 _dvr_playback_sendSignal(handle);
hualing chencc91e1c2020-02-28 13:26:17 +08001143 //pthread_cond_signal(&player->cond);
hualing chen86e7d482020-01-16 15:13:33 +08001144 pthread_join(player->playback_thread, NULL);
1145 }
1146 if (player->r_handle) {
1147 segment_close(player->r_handle);
1148 player->r_handle = NULL;
1149 }
1150 return 0;
1151}
1152
hualing chenb31a6c62020-01-13 17:27:00 +08001153/**\brief Open an dvr palyback
1154 * \param[out] p_handle dvr playback addr
1155 * \param[in] params dvr playback open parameters
1156 * \retval DVR_SUCCESS On success
1157 * \return Error code
1158 */
hualing chen040df222020-01-17 13:35:02 +08001159int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001160
hualing chen040df222020-01-17 13:35:02 +08001161 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001162 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001163
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001164 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001165
hualing chen86e7d482020-01-16 15:13:33 +08001166 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001167 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001168 pthread_condattr_init(&cattr);
1169 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1170 pthread_cond_init(&player->cond, &cattr);
1171 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001172
hualing chen5cbe1a62020-02-10 16:36:36 +08001173 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001174 INIT_LIST_HEAD(&player->segment_list);
1175 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1176 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001177 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001178 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001179 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001180 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001181 player->speed = 1.0f;
hualing chen2aba4022020-03-02 13:49:55 +08001182
hualing chen86e7d482020-01-16 15:13:33 +08001183 //store open params
hualing chen040df222020-01-17 13:35:02 +08001184 player->openParams.dmx_dev_id = params->dmx_dev_id;
1185 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001186 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001187 player->openParams.event_fn = params->event_fn;
1188 player->openParams.event_userdata = params->event_userdata;
1189
hualing chen5cbe1a62020-02-10 16:36:36 +08001190 player->has_pids = params->has_pids;
1191
hualing chen2aba4022020-03-02 13:49:55 +08001192 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001193
1194 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1195 //for test get callback
1196 if (0 && player->player_callback_func == NULL) {
1197 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1198 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001199 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 +08001200 }
1201 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001202
hualing chen86e7d482020-01-16 15:13:33 +08001203 //init has audio and video
1204 player->has_video = DVR_FALSE;
1205 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001206 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001207 player->last_segment_id = 0LL;
1208 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001209
hualing chen5cbe1a62020-02-10 16:36:36 +08001210 //init ff fb time
1211 player->fffb_current = -1;
1212 player->fffb_start =-1;
1213 player->fffb_start_pcr = -1;
1214 //seek time
1215 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001216 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001217
1218 //init secure stuff
1219 player->dec_func = NULL;
1220 player->dec_userdata = NULL;
1221 player->is_secure_mode = 0;
1222 player->secure_buffer = NULL;
1223 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001224 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001225
hualing chen4b7c15d2020-04-07 16:13:48 +08001226 player->fffb_play = DVR_FALSE;
1227
1228 player->last_send_time_id = UINT64_MAX;
1229 player->last_cur_time = 0;
1230
hualing chen86e7d482020-01-16 15:13:33 +08001231 *p_handle = player;
1232 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001233}
1234
1235/**\brief Close an dvr palyback
1236 * \param[in] handle playback handle
1237 * \retval DVR_SUCCESS On success
1238 * \return Error code
1239 */
hualing chen040df222020-01-17 13:35:02 +08001240int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001241
hualing chen86e7d482020-01-16 15:13:33 +08001242 DVR_ASSERT(handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001243
hualing chen040df222020-01-17 13:35:02 +08001244 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001245 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001246 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001247 return DVR_FAILURE;
1248 }
1249
hualing chencc91e1c2020-02-28 13:26:17 +08001250 if (player->state != DVR_PLAYBACK_STATE_STOP)
1251 {
1252 dvr_playback_stop(handle, DVR_TRUE);
1253 }
hualing chena540a7e2020-03-27 16:44:05 +08001254 //AmTsPlayer_resumeVideoDecoding(player->handle);
1255 //AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001256 pthread_mutex_destroy(&player->lock);
1257 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001258
1259 if (player) {
1260 free(player);
1261 player = NULL;
1262 }
hualing chen86e7d482020-01-16 15:13:33 +08001263 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001264}
1265
hualing chenb31a6c62020-01-13 17:27:00 +08001266/**\brief Start play audio and video, used start auido api and start video api
1267 * \param[in] handle playback handle
1268 * \param[in] params audio playback params,contains fmt and pid...
1269 * \retval DVR_SUCCESS On success
1270 * \return Error code
1271 */
hualing chen040df222020-01-17 13:35:02 +08001272int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1273 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001274 am_tsplayer_video_params vparams;
1275 am_tsplayer_audio_params aparams;
hualing chena540a7e2020-03-27 16:44:05 +08001276
1277 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001278 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001279 return DVR_FAILURE;
1280 }
hualing chencc91e1c2020-02-28 13:26:17 +08001281 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001282 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001283
hualing chena540a7e2020-03-27 16:44:05 +08001284 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001285 //can used start api to resume playback
1286 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1287 return dvr_playback_resume(handle);
1288 }
hualing chen87072a82020-03-12 16:20:12 +08001289 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001290 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001291 return DVR_SUCCESS;
1292 }
hualing chen86e7d482020-01-16 15:13:33 +08001293 player->play_flag = flag;
hualing chen5cbe1a62020-02-10 16:36:36 +08001294 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001295 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001296 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001297 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001298 //start audio and video
1299 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1300 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001301 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001302 pthread_mutex_unlock(&player->lock);
1303 DVR_Play_Notify_t notify;
1304 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1305 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1306 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1307 notify.info.transition_failed_data.segment_id = segment_id;
1308 //get play statue not here
1309 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify);
hualing chen86e7d482020-01-16 15:13:33 +08001310 return -1;
1311 }
hualing chen31140872020-03-25 12:29:26 +08001312
hualing chencc91e1c2020-02-28 13:26:17 +08001313 {
hualing chen86e7d482020-01-16 15:13:33 +08001314 if (VALID_PID(vparams.pid)) {
1315 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001316 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001317 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001318 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001319 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1320 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001321 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001322 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001323 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001324 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001325 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001326 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001327 }
1328 AmTsPlayer_setVideoParams(player->handle, &vparams);
1329 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001330 }
hualing chena540a7e2020-03-27 16:44:05 +08001331
hualing chen4b7c15d2020-04-07 16:13:48 +08001332 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1333 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001334 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1335 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1336 player->cmd.state = DVR_PLAYBACK_STATE_START;
1337 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001338 } else {
1339 player->cmd.last_cmd = player->cmd.cur_cmd;
1340 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001341 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001342 //set fast play
hualing chen4b7c15d2020-04-07 16:13:48 +08001343 DVR_PB_DG(1, "dvr start fast mode");
hualing chen31140872020-03-25 12:29:26 +08001344 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001345 } else {
1346 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001347 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08001348 player->has_audio = DVR_TRUE;
1349 AmTsPlayer_setAudioParams(player->handle, &aparams);
1350 AmTsPlayer_startAudioDecoding(player->handle);
1351 }
hualing chen31140872020-03-25 12:29:26 +08001352 }
hualing chencc91e1c2020-02-28 13:26:17 +08001353 player->cmd.state = DVR_PLAYBACK_STATE_START;
1354 player->state = DVR_PLAYBACK_STATE_START;
1355 }
hualing chen86e7d482020-01-16 15:13:33 +08001356 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001357 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001358 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001359 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001360 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001361}
hualing chen040df222020-01-17 13:35:02 +08001362/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001363 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001364 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001365 * \retval DVR_SUCCESS On success
1366 * \return Error code
1367 */
hualing chen040df222020-01-17 13:35:02 +08001368int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1369 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001370
hualing chena540a7e2020-03-27 16:44:05 +08001371 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001372 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001373 return DVR_FAILURE;
1374 }
1375
hualing chen4b7c15d2020-04-07 16:13:48 +08001376 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001377 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001378
hualing chen040df222020-01-17 13:35:02 +08001379 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1380 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001381
hualing chen86e7d482020-01-16 15:13:33 +08001382 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001383 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001384 //cp location
hualing chen040df222020-01-17 13:35:02 +08001385 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001386
hualing chen4b7c15d2020-04-07 16:13:48 +08001387 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 +08001388 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001389
1390 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001391 segment->pids.video.pid = info->pids.video.pid;
1392 segment->pids.video.format = info->pids.video.format;
1393 segment->pids.video.type = info->pids.video.type;
1394
hualing chen2aba4022020-03-02 13:49:55 +08001395 segment->pids.audio.pid = info->pids.audio.pid;
1396 segment->pids.audio.format = info->pids.audio.format;
1397 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001398
hualing chen2aba4022020-03-02 13:49:55 +08001399 segment->pids.ad.pid = info->pids.ad.pid;
1400 segment->pids.ad.format = info->pids.ad.format;
1401 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001402
1403 segment->pids.pcr.pid = info->pids.pcr.pid;
1404
hualing chen4b7c15d2020-04-07 16:13:48 +08001405 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 +08001406 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001407 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001408 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001409 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001410
hualing chen5cbe1a62020-02-10 16:36:36 +08001411 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001412}
hualing chen040df222020-01-17 13:35:02 +08001413/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001414 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001415 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001416 * \retval DVR_SUCCESS On success
1417 * \return Error code
1418 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001419int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001420 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001421 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001422 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001423 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001424 return DVR_FAILURE;
1425 }
1426
hualing chencc91e1c2020-02-28 13:26:17 +08001427 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001428 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001429 return DVR_FAILURE;
1430 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001431 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001432 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001433 DVR_PlaybackSegmentInfo_t *segment = NULL;
1434 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1435 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001436 {
hualing chen040df222020-01-17 13:35:02 +08001437 if (segment->segment_id == segment_id) {
1438 list_del(&segment->head);
1439 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001440 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001441 }
hualing chen86e7d482020-01-16 15:13:33 +08001442 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001443 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001444 pthread_mutex_unlock(&player->lock);
1445
1446 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001447}
hualing chen040df222020-01-17 13:35:02 +08001448/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001449 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001450 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001451 * \retval DVR_SUCCESS On success
1452 * \return Error code
1453 */
hualing chen040df222020-01-17 13:35:02 +08001454int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001455 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001456 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001457 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001458 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001459 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001460 return DVR_FAILURE;
1461 }
1462
hualing chen040df222020-01-17 13:35:02 +08001463 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001464 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001465 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001466 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001467 {
hualing chen040df222020-01-17 13:35:02 +08001468 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001469 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001470 }
hualing chen86e7d482020-01-16 15:13:33 +08001471 // if encramble to free, only set flag and return;
1472
1473 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001474 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001475 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1476 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001477 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001478 AmTsPlayer_hideVideo(player->handle);
1479 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001480 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1481 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001482 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001483 AmTsPlayer_showVideo(player->handle);
1484 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001485 } else {
1486 //do nothing
1487 }
1488 } else {
1489 //do nothing
1490 }
1491 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001492 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001493 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001494 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001495 pthread_mutex_unlock(&player->lock);
1496 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001497}
1498
1499
hualing chen5cbe1a62020-02-10 16:36:36 +08001500static 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 +08001501 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001502 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001503 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001504 return DVR_FAILURE;
1505 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001506 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001507 if (now_pid.pid == set_pid.pid) {
1508 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001509 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001510 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001511 if (VALID_PID(now_pid.pid)) {
1512 //stop now stream
1513 if (type == 0) {
1514 //stop vieo
hualing chen4b7c15d2020-04-07 16:13:48 +08001515 DVR_PB_DG(1, "stop video");
hualing chen2aba4022020-03-02 13:49:55 +08001516 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001517 player->has_video = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001518 } else if (type == 1) {
1519 //stop audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001520 DVR_PB_DG(1, "stop audio");
hualing chen2aba4022020-03-02 13:49:55 +08001521 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001522 player->has_audio = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001523 } else if (type == 2) {
1524 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001525 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001526 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001527 } else if (type == 3) {
1528 //pcr
1529 }
1530 }
1531 if (VALID_PID(set_pid.pid)) {
1532 //start
1533 if (type == 0) {
1534 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001535 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001536 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001537 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001538 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001539 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001540 AmTsPlayer_setVideoParams(player->handle, &vparams);
1541 AmTsPlayer_startVideoDecoding(player->handle);
1542 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001543 } else if (type == 1) {
1544 //start audio
hualing chen2aba4022020-03-02 13:49:55 +08001545 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001546 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001547 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001548 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001549 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001550 AmTsPlayer_setAudioParams(player->handle, &aparams);
1551 AmTsPlayer_startAudioDecoding(player->handle);
1552 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001553 } else if (type == 2) {
hualing chen2aba4022020-03-02 13:49:55 +08001554 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001555 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001556 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001557 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001558 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chena540a7e2020-03-27 16:44:05 +08001559 AmTsPlayer_setADParams(player->handle, &aparams);
1560 AmTsPlayer_enableADMix(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001561 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001562 } else if (type == 3) {
1563 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001564 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001565 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001566 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001567 //audio and video all close
1568 if (!player->has_audio && !player->has_video) {
1569 player->state = DVR_PLAYBACK_STATE_STOP;
1570 }
hualing chen86e7d482020-01-16 15:13:33 +08001571 }
1572 }
1573 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001574}
hualing chen5cbe1a62020-02-10 16:36:36 +08001575/**\brief dvr play back update segment pids
1576 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001577 * add pid stream and stop remove pid stream.
1578 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001579 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001580 * \retval DVR_SUCCESS On success
1581 * \return Error code
1582 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001583int 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 +08001584 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001585 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001586 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001587 return DVR_FAILURE;
1588 }
1589
hualing chen040df222020-01-17 13:35:02 +08001590 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001591 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001592 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001593 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 +08001594
hualing chen040df222020-01-17 13:35:02 +08001595 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001596 {
hualing chen040df222020-01-17 13:35:02 +08001597 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001598
1599 if (player->cur_segment_id == segment_id) {
1600 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1601 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1602 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001603 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001604 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001605 return 0;
1606 }
1607
1608 //if segment is on going segment,we need stop start stream
1609 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001610 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001611 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001612 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001613 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001614 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001615 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001616 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001617 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001618 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1619 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001620 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1621 //if state is pause, we need process at resume api. we only record change info
1622 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1623 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1624 if (VALID_PID(segment->pids.video.pid)
1625 && VALID_PID(p_pids->video.pid)
1626 && segment->pids.video.pid != p_pids->video.pid) {
1627 //restart video
1628 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1629 }
1630 if (!VALID_PID(segment->pids.video.pid)
1631 && VALID_PID(p_pids->video.pid)
1632 && segment->pids.video.pid != p_pids->video.pid) {
1633 //start video
1634 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1635 }
1636 if (VALID_PID(segment->pids.video.pid)
1637 && !VALID_PID(p_pids->video.pid)
1638 && segment->pids.video.pid != p_pids->video.pid) {
1639 //stop video
1640 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1641 }
1642 if (VALID_PID(segment->pids.audio.pid)
1643 && VALID_PID(p_pids->audio.pid)
1644 && segment->pids.audio.pid != p_pids->audio.pid) {
1645 //restart audio
1646 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1647 }
1648 if (!VALID_PID(segment->pids.audio.pid)
1649 && VALID_PID(p_pids->audio.pid)
1650 && segment->pids.audio.pid != p_pids->audio.pid) {
1651 //start audio
1652 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1653 }
1654 if (VALID_PID(segment->pids.audio.pid)
1655 && !VALID_PID(p_pids->audio.pid)
1656 && segment->pids.audio.pid != p_pids->audio.pid) {
1657 //stop audio
1658 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1659 }
1660 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1661 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1662 //do nothing
1663 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1664 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1665 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1666 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1667 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1668 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1669 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1670 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1671 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1672 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1673 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1674 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1675 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1676 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1677 } else {
1678 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1679 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1680 }
1681
1682 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1683 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1684 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1685 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1686 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1687 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1688 //not occur this case
1689 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1690 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1691 } else {
1692 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1693 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1694 }
1695
1696 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1697 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1698 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1699 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1700 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1701 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1702 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1703 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1704 } else {
1705 //not occur this case
1706 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1707 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1708 }
1709 }
1710 }
hualing chene10666f2020-04-14 13:58:37 +08001711 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08001712 }
hualing chen86e7d482020-01-16 15:13:33 +08001713 //save pids info
hualing chen040df222020-01-17 13:35:02 +08001714 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +08001715 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001716 }
hualing chen86e7d482020-01-16 15:13:33 +08001717 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001718 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001719 pthread_mutex_unlock(&player->lock);
1720 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001721}
1722/**\brief Stop play, will stop video and audio
1723 * \param[in] handle playback handle
1724 * \param[in] clear is clear last frame
1725 * \retval DVR_SUCCESS On success
1726 * \return Error code
1727 */
hualing chen040df222020-01-17 13:35:02 +08001728int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1729 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001730
1731 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001732 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001733 return DVR_FAILURE;
1734 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001735 DVR_PB_DG(1, "lock");
hualing chen87072a82020-03-12 16:20:12 +08001736 _stop_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001737 pthread_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001738 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001739 if (player->has_video) {
1740 AmTsPlayer_resumeVideoDecoding(player->handle);
1741 }
1742 if (player->has_audio) {
1743 AmTsPlayer_resumeAudioDecoding(player->handle);
1744 }
1745 if (player->has_video) {
1746 player->has_video = DVR_FALSE;
1747 AmTsPlayer_showVideo(player->handle);
1748 AmTsPlayer_stopVideoDecoding(player->handle);
1749 }
1750 if (player->has_audio) {
1751 player->has_audio = DVR_FALSE;
1752 AmTsPlayer_stopAudioDecoding(player->handle);
1753 }
1754
hualing chen86e7d482020-01-16 15:13:33 +08001755 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001756 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1757 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1758 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001759 player->cur_segment_id = UINT64_MAX;
1760 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001761 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001762 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001763 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001764}
1765/**\brief Start play audio
1766 * \param[in] handle playback handle
1767 * \param[in] params audio playback params,contains fmt and pid...
1768 * \retval DVR_SUCCESS On success
1769 * \return Error code
1770 */
hualing chen2aba4022020-03-02 13:49:55 +08001771
1772int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001773 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001774
1775 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001776 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001777 return DVR_FAILURE;
1778 }
hualing chen86e7d482020-01-16 15:13:33 +08001779 _start_playback_thread(handle);
1780 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001781 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001782 pthread_mutex_lock(&player->lock);
1783 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001784 AmTsPlayer_setAudioParams(player->handle, param);
1785 AmTsPlayer_startAudioDecoding(player->handle);
1786 //playback_device_audio_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001787 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001788 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1789 player->cmd.state = DVR_PLAYBACK_STATE_START;
1790 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001791 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001792 pthread_mutex_unlock(&player->lock);
1793 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001794}
1795/**\brief Stop play audio
1796 * \param[in] handle playback handle
1797 * \retval DVR_SUCCESS On success
1798 * \return Error code
1799 */
hualing chen040df222020-01-17 13:35:02 +08001800int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1801 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001802
1803 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001804 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001805 return DVR_FAILURE;
1806 }
1807
hualing chen4b7c15d2020-04-07 16:13:48 +08001808 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001809 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001810
hualing chen2aba4022020-03-02 13:49:55 +08001811 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001812 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001813 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1814 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001815 //destory thread
1816 _stop_playback_thread(handle);
1817 } else {
1818 //do nothing.video is playing
1819 }
hualing chen87072a82020-03-12 16:20:12 +08001820 player->has_audio = DVR_FALSE;
1821
1822 AmTsPlayer_stopAudioDecoding(player->handle);
1823 player->cmd.last_cmd = player->cmd.cur_cmd;
1824 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
1825
hualing chen4b7c15d2020-04-07 16:13:48 +08001826 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001827 pthread_mutex_unlock(&player->lock);
1828 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001829}
1830/**\brief Start play video
1831 * \param[in] handle playback handle
1832 * \param[in] params video playback params,contains fmt and pid...
1833 * \retval DVR_SUCCESS On success
1834 * \return Error code
1835 */
hualing chen2aba4022020-03-02 13:49:55 +08001836int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001837 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001838
1839 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001840 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001841 return DVR_FAILURE;
1842 }
1843
hualing chen86e7d482020-01-16 15:13:33 +08001844 _start_playback_thread(handle);
1845 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001846 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001847 pthread_mutex_lock(&player->lock);
1848 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001849 AmTsPlayer_setVideoParams(player->handle, param);
1850 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001851
1852 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001853 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08001854 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001855 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08001856 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1857 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08001858 }
1859 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001860 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
1861 player->cmd.state = DVR_PLAYBACK_STATE_START;
1862 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001863 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001864 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001865 return DVR_SUCCESS;
1866}
1867/**\brief Stop play video
1868 * \param[in] handle playback handle
1869 * \retval DVR_SUCCESS On success
1870 * \return Error code
1871 */
hualing chen040df222020-01-17 13:35:02 +08001872int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
1873 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001874
1875 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001876 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001877 return DVR_FAILURE;
1878 }
1879
hualing chen4b7c15d2020-04-07 16:13:48 +08001880 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001881 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001882
1883 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001884 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1885 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001886 //destory thread
1887 _stop_playback_thread(handle);
1888 } else {
1889 //do nothing.audio is playing
1890 }
hualing chen87072a82020-03-12 16:20:12 +08001891 player->has_video = DVR_FALSE;
1892
1893 AmTsPlayer_stopVideoDecoding(player->handle);
1894 //playback_device_video_stop(player->handle);
1895
1896 player->cmd.last_cmd = player->cmd.cur_cmd;
1897 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
1898
hualing chen4b7c15d2020-04-07 16:13:48 +08001899 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001900 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001901 return DVR_SUCCESS;
1902}
1903/**\brief Pause play
1904 * \param[in] handle playback handle
1905 * \param[in] flush whether its internal buffers should be flushed
1906 * \retval DVR_SUCCESS On success
1907 * \return Error code
1908 */
hualing chen040df222020-01-17 13:35:02 +08001909int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
1910 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001911
1912 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001913 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001914 return DVR_FAILURE;
1915 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001916 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001917 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001918 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08001919 if (player->has_video)
1920 AmTsPlayer_pauseVideoDecoding(player->handle);
1921 if (player->has_video)
1922 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001923
1924 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001925 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1926 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1927 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1928 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001929 } else {
1930 player->cmd.last_cmd = player->cmd.cur_cmd;
1931 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1932 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1933 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001934 }
hualing chen86e7d482020-01-16 15:13:33 +08001935 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001936 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08001937
hualing chen86e7d482020-01-16 15:13:33 +08001938 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001939}
1940
hualing chen5cbe1a62020-02-10 16:36:36 +08001941//not add lock
1942static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
1943{
1944 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1945
hualing chena540a7e2020-03-27 16:44:05 +08001946 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 chen5cbe1a62020-02-10 16:36:36 +08001951 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08001952 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08001953 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001954 am_tsplayer_video_params vparams;
1955 am_tsplayer_audio_params aparams;
hualing chencc91e1c2020-02-28 13:26:17 +08001956 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08001957
1958 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08001959 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08001960 pthread_mutex_unlock(&player->lock);
1961
1962 switch (cmd) {
1963 case DVR_PLAYBACK_CMD_AVRESTART:
1964 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08001965 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08001966 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001967 break;
1968 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001969 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1970 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001971 break;
1972 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001973 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001974 break;
1975 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001976 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001977 break;
1978 case DVR_PLAYBACK_CMD_ARESTART:
1979 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08001980 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1981 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001982 break;
1983 case DVR_PLAYBACK_CMD_ASTART:
hualing chen2aba4022020-03-02 13:49:55 +08001984 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001985 break;
1986 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001987 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001988 break;
1989 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001990 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1991 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1992 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001993 break;
1994 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001995 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1996 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001997 break;
1998 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001999 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2000 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2001 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002002 break;
2003 case DVR_PLAYBACK_CMD_STOP:
2004 break;
2005 case DVR_PLAYBACK_CMD_START:
2006 break;
2007 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002008 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2009 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
2010 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002011 break;
2012 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002013 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2014 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
2015 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002016 break;
2017 case DVR_PLAYBACK_CMD_FF:
2018 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002019 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002020 break;
2021 default:
2022 break;
2023 }
2024 return DVR_SUCCESS;
2025}
2026
2027/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002028 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002029 * \retval DVR_SUCCESS On success
2030 * \return Error code
2031 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002032int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2033 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2034
hualing chena540a7e2020-03-27 16:44:05 +08002035 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002036 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002037 return DVR_FAILURE;
2038 }
2039
hualing chen5cbe1a62020-02-10 16:36:36 +08002040 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002041 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002042 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002043 if (player->has_video) {
2044 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2045 AmTsPlayer_resumeVideoDecoding(player->handle);
2046 }
2047 if (player->has_audio) {
2048 AmTsPlayer_resumeAudioDecoding(player->handle);
2049 }
2050 //check is has audio param,if has audio .we need start audio,
2051 //we will stop audio when ff fb, if reach end, we will pause.so we need
2052 //start audio when resume play
2053
2054 am_tsplayer_video_params vparams;
2055 am_tsplayer_audio_params aparams;
2056 uint64_t segmentid = player->cur_segment_id;
2057 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
2058 //valid audio pid, start audio
2059 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid)) {
2060 player->has_audio = DVR_TRUE;
2061 AmTsPlayer_setAudioParams(player->handle, &aparams);
2062 AmTsPlayer_startAudioDecoding(player->handle);
2063 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002064 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d", aparams.pid, player->has_audio);
hualing chen266b9502020-04-04 17:39:39 +08002065 }
hualing chen87072a82020-03-12 16:20:12 +08002066 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2067 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2068 player->cmd.state = DVR_PLAYBACK_STATE_START;
2069 player->state = DVR_PLAYBACK_STATE_START;
2070 } else {
2071 player->cmd.last_cmd = player->cmd.cur_cmd;
2072 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2073 player->cmd.state = DVR_PLAYBACK_STATE_START;
2074 player->state = DVR_PLAYBACK_STATE_START;
2075 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002076 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002077 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002078 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
2079 if (player->has_video)
2080 AmTsPlayer_resumeVideoDecoding(player->handle);
2081 if (player->has_audio)
2082 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002083 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002084 player->cmd.state = DVR_PLAYBACK_STATE_START;
2085 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002086 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002087 } else {
2088 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2089 {
2090 pthread_mutex_lock(&player->lock);
2091 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002092 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002093 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2094 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2095 pthread_mutex_unlock(&player->lock);
2096 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002097 }
2098 return DVR_SUCCESS;
2099}
2100
hualing chena540a7e2020-03-27 16:44:05 +08002101static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2102
2103 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2104 DVR_PlaybackSegmentInfo_t *segment = NULL;
2105 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2106 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2107
2108 list_for_each_entry(segment, &player->segment_list, head)
2109 {
2110 if (segment->segment_id == segment_id) {
2111 cur_segment = segment;
2112 }
2113 if (segment->segment_id == set_seg_id) {
2114 set_segment = segment;
2115 }
2116 if (cur_segment != NULL && set_segment != NULL) {
2117 break;
2118 }
2119 }
2120 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002121 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002122 return DVR_TRUE;
2123 }
2124 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2125 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2126 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2127 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002128 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 +08002129 return DVR_TRUE;
2130 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002131 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002132 return DVR_FALSE;
2133}
2134
hualing chen5cbe1a62020-02-10 16:36:36 +08002135/**\brief seek
2136 * \param[in] handle playback handle
2137 * \param[in] time_offset time offset base cur segment
2138 * \retval DVR_SUCCESS On success
2139 * \return Error code
2140 */
hualing chencc91e1c2020-02-28 13:26:17 +08002141int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002142 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002143
2144 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002145 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002146 return DVR_FAILURE;
2147 }
2148
hualing chen4b7c15d2020-04-07 16:13:48 +08002149 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 +08002150 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002151
hualing chen86e7d482020-01-16 15:13:33 +08002152 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002153 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002154 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002155
hualing chen5cbe1a62020-02-10 16:36:36 +08002156 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002157 int ret = _dvr_open_segment(handle, segment_id);
2158 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002159 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002160 pthread_mutex_unlock(&player->lock);
2161 return DVR_FAILURE;
2162 }
2163 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2164 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002165 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002166 //pthread_mutex_unlock(&player->lock);
2167 //return DVR_SUCCESS;
2168 time_offset = _dvr_get_end_time(handle);
2169 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002170 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chen87072a82020-03-12 16:20:12 +08002171 pthread_mutex_unlock(&player->lock);
2172 return DVR_FAILURE;
2173 }
2174 }
2175
hualing chen4b7c15d2020-04-07 16:13:48 +08002176 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 +08002177 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002178 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2179 //forward playback.not seek end of file
2180 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2181 //default -2000ms
2182 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2183 }
hualing chen86e7d482020-01-16 15:13:33 +08002184 }
hualing chen2aba4022020-03-02 13:49:55 +08002185 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002186 player->drop_ts = DVR_TRUE;
2187 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002188 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 +08002189 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002190 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002191
hualing chen2aba4022020-03-02 13:49:55 +08002192 _dvr_get_end_time(handle);
2193 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002194 player->fffb_current = _dvr_time_getClock();
2195 player->fffb_start = player->fffb_current;
2196 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2197 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002198 //pause state if need to replayer false
2199 if (player->state == DVR_PLAYBACK_STATE_STOP ||
2200 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002201 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002202 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002203 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002204 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002205 }
hualing chen86e7d482020-01-16 15:13:33 +08002206 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002207 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 +08002208 if (player->has_video) {
2209 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002210 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002211 }
2212
2213 if (player->has_audio) {
2214 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002215 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002216 }
hualing chen86e7d482020-01-16 15:13:33 +08002217 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002218 am_tsplayer_video_params vparams;
2219 am_tsplayer_audio_params aparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002220
hualing chen040df222020-01-17 13:35:02 +08002221 player->cur_segment_id = segment_id;
2222
2223 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002224 //get segment info and audio video pid fmt ;
2225 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08002226 //start audio and video
2227 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2228 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002229 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 +08002230 pthread_mutex_unlock(&player->lock);
2231 return -1;
2232 }
2233 //add
hualing chen040df222020-01-17 13:35:02 +08002234 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002235 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002236 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002237 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chen31140872020-03-25 12:29:26 +08002238 player->speed > 1.0f||
2239 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002240 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002241 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002242 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002243 }
hualing chen2aba4022020-03-02 13:49:55 +08002244 AmTsPlayer_setVideoParams(player->handle, &vparams);
2245 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002246 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002247 }
hualing chen86e7d482020-01-16 15:13:33 +08002248 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002249 DVR_PB_DG(1, "start audio seek");
hualing chen2aba4022020-03-02 13:49:55 +08002250 AmTsPlayer_setAudioParams(player->handle, &aparams);
2251 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002252 player->has_audio = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002253 }
hualing chen86e7d482020-01-16 15:13:33 +08002254 }
hualing chen2aba4022020-03-02 13:49:55 +08002255 if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
2256 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2257 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2258 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
2259 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))) {
2260 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2261 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002262 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002263 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2264 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002265 player->speed > 1.0f||
2266 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002267 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002268 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002269 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002270 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002271 player->cmd.last_cmd = player->cmd.cur_cmd;
2272 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2273 player->cmd.state = DVR_PLAYBACK_STATE_START;
2274 player->state = DVR_PLAYBACK_STATE_START;
2275 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002276 player->last_send_time_id = UINT64_MAX;
2277 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002278 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002279
2280 return DVR_SUCCESS;
2281}
hualing chen5cbe1a62020-02-10 16:36:36 +08002282
hualing chen5cbe1a62020-02-10 16:36:36 +08002283static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2284 //get cur time of segment
2285 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002286
2287 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002288 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002289 return DVR_FAILURE;
2290 }
2291
hualing chen31140872020-03-25 12:29:26 +08002292 int64_t cache = 0;//defalut es buf cache 500ms
2293 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002294 pthread_mutex_lock(&player->segment_lock);
2295 uint64_t cur = segment_tell_current_time(player->r_handle);
2296 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002297 DVR_PB_DG(1, "get cur time [%lld] cache:%lld cur id [%lld]", cur, cache, player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002298 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2299 cache = 0;
2300 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002301 int cur_time = (int)(cur > cache ? cur - cache : 0);
2302 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002303}
2304
2305//get current segment current pcr time of read pos
2306static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2307 //get cur time of segment
2308 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002309
2310 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002311 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002312 return DVR_FAILURE;
2313 }
2314
hualing chen2aba4022020-03-02 13:49:55 +08002315 pthread_mutex_lock(&player->segment_lock);
2316 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002317 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002318 pthread_mutex_unlock(&player->segment_lock);
2319 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002320}
2321
hualing chen4b7c15d2020-04-07 16:13:48 +08002322#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002323//start replay
2324static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2325
2326 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2327 //calculate pcr seek time
2328 int t_diff = 0;
2329 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002330
2331 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002332 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002333 return DVR_FAILURE;
2334 }
2335
hualing chen5cbe1a62020-02-10 16:36:36 +08002336 if (player->fffb_start == -1) {
2337 //set fffb start time ms
2338 player->fffb_start = _dvr_time_getClock();
2339 player->fffb_current = player->fffb_start;
2340 //get segment current time pos
2341 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002342 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 +08002343 t_diff = 0;
hualing chen2aba4022020-03-02 13:49:55 +08002344 //default first time 1ms seek
hualing chen87072a82020-03-12 16:20:12 +08002345 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002346 } else {
2347 player->fffb_current = _dvr_time_getClock();
2348 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002349 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002350 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002351 if (seek_time <= 0) {
2352 //need seek to pre one segment
2353 seek_time = 0;
2354 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002355 //seek segment pos
2356 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002357 pthread_mutex_lock(&player->segment_lock);
hualing chen041c4092020-04-05 15:11:50 +08002358 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2359 seek_time = 0;
2360 }
hualing chen2aba4022020-03-02 13:49:55 +08002361 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002362 } else {
2363 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002364 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002365 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002366 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 +08002367 }
hualing chen2aba4022020-03-02 13:49:55 +08002368 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002369}
2370
2371
2372//start replay
2373static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2374 //
2375 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002376
2377 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002378 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002379 return DVR_FAILURE;
2380 }
2381
hualing chen5cbe1a62020-02-10 16:36:36 +08002382 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002383 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002384 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002385 AmTsPlayer_stopVideoDecoding(player->handle);
2386 }
2387 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002388 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002389 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002390 AmTsPlayer_stopAudioDecoding(player->handle);
2391 }
2392
hualing chen5cbe1a62020-02-10 16:36:36 +08002393 //start video and audio
2394
hualing chen2aba4022020-03-02 13:49:55 +08002395 am_tsplayer_video_params vparams;
2396 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002397 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002398
2399 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002400 //pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002401 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2402 //start audio and video
2403 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2404 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002405 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002406 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002407 return -1;
2408 }
2409
2410 if (VALID_PID(vparams.pid)) {
2411 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002412 DVR_PB_DG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08002413 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002414 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2415 AmTsPlayer_setVideoParams(player->handle, &vparams);
2416 AmTsPlayer_startVideoDecoding(player->handle);
2417 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002418 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002419 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002420 }
hualing chena540a7e2020-03-27 16:44:05 +08002421 if (0 && VALID_PID(aparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002422 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002423 DVR_PB_DG(1, "fffb start audio");
hualing chen2aba4022020-03-02 13:49:55 +08002424 AmTsPlayer_setAudioParams(player->handle, &aparams);
2425 AmTsPlayer_startAudioDecoding(player->handle);
2426 //playback_device_audio_start(player->handle , &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002427 }
hualing chen31140872020-03-25 12:29:26 +08002428 //fffb mode need stop fast;
2429 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002430
hualing chencc91e1c2020-02-28 13:26:17 +08002431 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002432 return 0;
2433}
2434
2435static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2436 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002437
2438 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002439 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002440 return DVR_FAILURE;
2441 }
2442
2443 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002444 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002445 pthread_mutex_lock(&player->lock);
2446
hualing chen2aba4022020-03-02 13:49:55 +08002447 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002448 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 +08002449
hualing chen87072a82020-03-12 16:20:12 +08002450 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2451 //seek time set 0
2452 seek_time = 0;
2453 }
hualing chen041c4092020-04-05 15:11:50 +08002454 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002455 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2456 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002457 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002458 pthread_mutex_unlock(&player->lock);
2459 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002460 //send event here and pause
2461 DVR_Play_Notify_t notify;
2462 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002463 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002464 //get play statue not here
2465 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify);
hualing chen4b7c15d2020-04-07 16:13:48 +08002466 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 +08002467 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002468 return DVR_SUCCESS;
2469 }
hualing chen87072a82020-03-12 16:20:12 +08002470 _dvr_playback_sent_transition_ok(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002471 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002472 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002473 }
2474 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002475 _dvr_playback_fffb_replay(handle);
2476
2477 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002478 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002479
hualing chen5cbe1a62020-02-10 16:36:36 +08002480 return DVR_SUCCESS;
2481}
2482
hualing chen87072a82020-03-12 16:20:12 +08002483//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002484static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002485 //
2486 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002487
2488 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002489 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002490 return DVR_FAILURE;
2491 }
2492
hualing chen5cbe1a62020-02-10 16:36:36 +08002493 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002494 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002495 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002496 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002497 }
2498
2499 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002500 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002501 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002502 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002503 //start video and audio
2504
hualing chen2aba4022020-03-02 13:49:55 +08002505 am_tsplayer_video_params vparams;
2506 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002507 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002508
2509 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002510 DVR_PB_DG(1, "into");
hualing chen5cbe1a62020-02-10 16:36:36 +08002511 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2512 //start audio and video
2513 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002514 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002515 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002516 return -1;
2517 }
2518
2519 if (VALID_PID(vparams.pid)) {
2520 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002521 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002522 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002523 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002524 }
hualing chen266b9502020-04-04 17:39:39 +08002525 else {
hualing chen2aba4022020-03-02 13:49:55 +08002526 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002527 }
hualing chen2aba4022020-03-02 13:49:55 +08002528 AmTsPlayer_setVideoParams(player->handle, &vparams);
2529 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002530 }
hualing chena540a7e2020-03-27 16:44:05 +08002531
2532 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002533 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002534 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002535 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002536 if (VALID_PID(aparams.pid)) {
2537 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002538 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08002539 AmTsPlayer_startAudioDecoding(player->handle);
2540 AmTsPlayer_setAudioParams(player->handle, &aparams);
hualing chena540a7e2020-03-27 16:44:05 +08002541 }
hualing chen31140872020-03-25 12:29:26 +08002542 AmTsPlayer_stopFast(player->handle);
2543 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2544 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2545 }
hualing chen2aba4022020-03-02 13:49:55 +08002546 player->cmd.last_cmd = player->cmd.cur_cmd;
2547 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002548 player->cmd.state = DVR_PLAYBACK_STATE_START;
2549 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002550 return 0;
2551}
2552
2553
hualing chenb31a6c62020-01-13 17:27:00 +08002554/**\brief Set play speed
2555 * \param[in] handle playback handle
2556 * \param[in] speed playback speed
2557 * \retval DVR_SUCCESS On success
2558 * \return Error code
2559 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002560int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2561
2562 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002563
2564 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002565 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002566 return DVR_FAILURE;
2567 }
2568
hualing chen4b7c15d2020-04-07 16:13:48 +08002569 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002570 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002571 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002572 return DVR_FAILURE;
2573 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002574 pthread_mutex_lock(&player->lock);
2575 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2576 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2577 player->cmd.last_cmd = player->cmd.cur_cmd;
2578 }
hualing chen31140872020-03-25 12:29:26 +08002579 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002580 IS_KERNEL_SPEED(speed.speed.speed)) {
2581 //case 1. cur speed is 100,set 200 50 25 12 .
2582 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2583 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002584 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002585 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2586 // resume audio and stop fast play
2587 AmTsPlayer_stopFast(player->handle);
2588 pthread_mutex_unlock(&player->lock);
2589 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2590 pthread_mutex_lock(&player->lock);
2591 } else {
2592 //set play speed and if audio is start, stop audio.
2593 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002594 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002595 AmTsPlayer_stopAudioDecoding(player->handle);
2596 player->has_audio = DVR_FALSE;
2597 }
2598 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002599 }
hualing chena540a7e2020-03-27 16:44:05 +08002600 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002601 player->cmd.speed.speed = speed.speed;
2602 player->speed = (float)speed.speed.speed/(float)100;
2603 pthread_mutex_unlock(&player->lock);
2604 return DVR_SUCCESS;
2605 }
2606 //case 2. not start play
2607 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2608 //only set speed.and return;
hualing chena540a7e2020-03-27 16:44:05 +08002609 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002610 player->cmd.speed.speed = speed.speed;
2611 player->speed = (float)speed.speed.speed/(float)100;
2612 pthread_mutex_unlock(&player->lock);
2613 return DVR_SUCCESS;
hualing chen87072a82020-03-12 16:20:12 +08002614 }
hualing chen31140872020-03-25 12:29:26 +08002615 //case 3 fffb mode
2616 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2617 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2618 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002619 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002620 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002621 player->cmd.speed.speed = speed.speed;
2622 player->speed = (float)speed.speed.speed/(float)100;
2623 _dvr_playback_replay(handle, DVR_FALSE);
2624 pthread_mutex_unlock(&player->lock);
2625 return DVR_SUCCESS;
2626 }
2627 }
2628 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002629 IS_KERNEL_SPEED(speed.speed.speed)) {
2630 //case 1. cur speed is kernel support speed,set kernel speed.
2631 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002632 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002633 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2634 // resume audio and stop fast play
2635 AmTsPlayer_stopFast(player->handle);
2636 pthread_mutex_unlock(&player->lock);
2637 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2638 pthread_mutex_lock(&player->lock);
2639 } else {
2640 //set play speed and if audio is start, stop audio.
2641 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002642 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002643 AmTsPlayer_stopAudioDecoding(player->handle);
2644 player->has_audio = DVR_FALSE;
2645 }
2646 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
2647 }
hualing chena540a7e2020-03-27 16:44:05 +08002648 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002649 player->cmd.speed.speed = speed.speed;
2650 player->speed = (float)speed.speed.speed/(float)100;
2651 pthread_mutex_unlock(&player->lock);
2652 return DVR_SUCCESS;
2653 }
2654 //case 2 fffb mode
2655 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2656 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2657 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002658 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002659 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002660 player->cmd.speed.speed = speed.speed;
2661 player->speed = (float)speed.speed.speed/(float)100;
2662 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2663 pthread_mutex_unlock(&player->lock);
2664 return DVR_SUCCESS;
2665 }
hualing chen31140872020-03-25 12:29:26 +08002666 }
hualing chena540a7e2020-03-27 16:44:05 +08002667 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2668 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chen87072a82020-03-12 16:20:12 +08002669 } else {
hualing chen31140872020-03-25 12:29:26 +08002670 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002671 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2672 else
2673 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08002674 player->fffb_play = DVR_TRUE;
2675 }
2676 DVR_Bool_t init_last_time = DVR_FALSE;
2677 if (player->speed > 0.0f && speed.speed.speed < 0) {
2678 init_last_time = DVR_TRUE;
2679 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
2680 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002681 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002682 player->cmd.speed.mode = speed.mode;
2683 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002684 player->speed = (float)speed.speed.speed/(float)100;
hualing chen4b7c15d2020-04-07 16:13:48 +08002685#if 0
2686 if (abs((int)(player->speed)) > 1) {
2687 //seek speed*1000 ms at fb mode
2688 pthread_mutex_lock(&player->segment_lock);
2689 uint64_t cur = segment_tell_current_time(player->r_handle);
2690 int diff = abs((int)(player->speed * 1000));
2691 DVR_PB_DG(1, " cur:%ull diff:%d", cur, diff);
2692 if (cur > diff)
2693 cur = cur - diff;
2694 else
2695 cur = 0;
2696 segment_seek(player->r_handle, cur, player->openParams.block_size);
2697 pthread_mutex_unlock(&player->segment_lock);
2698 }
2699#endif
hualing chen31140872020-03-25 12:29:26 +08002700 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08002701 _dvr_init_fffb_t(handle);
2702 if (init_last_time == DVR_TRUE)
2703 player->last_send_time_id = UINT64_MAX;
2704
hualing chen87072a82020-03-12 16:20:12 +08002705 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002706 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2707 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002708 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002709 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08002710 _dvr_playback_replay(handle, DVR_FALSE);
2711 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2712 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2713 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08002714 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08002715 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002716 //need exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002717 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002718 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002719 return DVR_SUCCESS;
2720}
2721/**\brief Get playback status
2722 * \param[in] handle playback handle
2723 * \param[out] p_status playback status
2724 * \retval DVR_SUCCESS On success
2725 * \return Error code
2726 */
hualing chen040df222020-01-17 13:35:02 +08002727int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002728 DVR_PlaybackStatus_t *p_status) {
2729//
2730 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002731
2732 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002733 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002734 return DVR_FAILURE;
2735 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002736
2737 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002738 //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 +08002739 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2740 player->state == DVR_PLAYBACK_STATE_START) {
2741 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2742 }
hualing chen041c4092020-04-05 15:11:50 +08002743
hualing chencc91e1c2020-02-28 13:26:17 +08002744 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002745 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002746 if (player->last_send_time_id == UINT64_MAX) {
2747 player->last_send_time_id = player->cur_segment_id;
2748 player->last_cur_time = p_status->time_cur;
2749 }
2750 if (player->last_send_time_id == player->cur_segment_id) {
2751 if (player->speed > 0.0f ) {
2752 //ff
2753 if (p_status->time_cur < player->last_cur_time ) {
2754 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);
2755 p_status->time_cur = player->last_cur_time;
2756 } else {
2757 player->last_cur_time = p_status->time_cur;
2758 }
2759 } else if (player->speed < -1.0f){
2760 //fb
2761 if (p_status->time_cur > player->last_cur_time ) {
2762 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 );
2763 p_status->time_cur = player->last_cur_time;
2764 } else {
2765 player->last_cur_time = p_status->time_cur;
2766 }
2767 }
2768 } else {
2769 player->last_cur_time = p_status->time_cur;
2770 }
2771 player->last_send_time_id = player->cur_segment_id;
hualing chen041c4092020-04-05 15:11:50 +08002772 p_status->segment_id = player->cur_segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08002773
hualing chen5cbe1a62020-02-10 16:36:36 +08002774 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08002775 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08002776 p_status->flags = player->cur_segment.flags;
hualing chen4b7c15d2020-04-07 16:13:48 +08002777 DVR_PB_DG(1, "player state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]",
hualing chen6d24aa92020-03-23 18:43:47 +08002778 _dvr_playback_state_toString(player->state),
2779 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08002780 p_status->time_cur, p_status->time_end,
2781 p_status->segment_id,player->play_flag,
2782 player->speed);
hualing chenb31a6c62020-01-13 17:27:00 +08002783 return DVR_SUCCESS;
2784}
2785
hualing chen040df222020-01-17 13:35:02 +08002786void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
2787 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002788 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
2789 DVR_PB_DG(1, "segment flag: %d", segment->flags);
2790 DVR_PB_DG(1, "segment location: [%s]", segment->location);
2791 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
2792 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
2793 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
2794 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 +08002795 }
hualing chenb31a6c62020-01-13 17:27:00 +08002796}
2797
hualing chen5cbe1a62020-02-10 16:36:36 +08002798int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002799 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08002800
hualing chena540a7e2020-03-27 16:44:05 +08002801 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002802 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002803 return DVR_FAILURE;
2804 }
2805
hualing chen040df222020-01-17 13:35:02 +08002806 DVR_PlaybackSegmentInfo_t *segment;
2807 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002808 {
hualing chen040df222020-01-17 13:35:02 +08002809 if (segment_id >= 0) {
2810 if (segment->segment_id == segment_id) {
2811 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002812 break;
2813 }
2814 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08002815 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08002816 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002817 }
2818 }
2819 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002820}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002821
pengfei.liu27cc4ec2020-04-03 16:28:16 +08002822int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002823{
2824 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2825 DVR_RETURN_IF_FALSE(player);
2826 DVR_RETURN_IF_FALSE(func);
2827
hualing chen4b7c15d2020-04-07 16:13:48 +08002828 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002829 pthread_mutex_lock(&player->lock);
2830
2831 player->dec_func = func;
2832 player->dec_userdata = userdata;
2833
2834 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002835 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002836 return DVR_SUCCESS;
2837}
2838
2839int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
2840{
2841 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2842 DVR_RETURN_IF_FALSE(player);
2843 DVR_RETURN_IF_FALSE(p_secure_buf);
2844 DVR_RETURN_IF_FALSE(len);
2845
hualing chen4b7c15d2020-04-07 16:13:48 +08002846 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002847 pthread_mutex_lock(&player->lock);
2848
2849 player->is_secure_mode = 1;
2850 player->secure_buffer = p_secure_buf;
2851 player->secure_buffer_size = len;
2852
2853 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002854 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002855 return DVR_SUCCESS;
2856}