blob: 0572af2137057a39b7f115b0754f01e0c82944c9 [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
hualing chen7a56cba2020-04-14 14:09:27 +0800756 DVR_PB_DG(1, ":last apid: %d set apid: %d", player->last_segment.pids.audio.pid,player->cur_segment.pids.audio.pid);
hualing chencc91e1c2020-02-28 13:26:17 +0800757 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
758 //check sub audio pids stop or restart
759 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
760 //check pcr pids stop or restart
761 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
762 }
hualing chena540a7e2020-03-27 16:44:05 +0800763 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800764}
hualing chen5cbe1a62020-02-10 16:36:36 +0800765
hualing chencc91e1c2020-02-28 13:26:17 +0800766static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
767{
768 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800769 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800770 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800771 return DVR_FAILURE;
772 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800773 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 +0800774 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
775 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800776 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800777 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800778 AmTsPlayer_showVideo(player->handle);
779 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800780 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
781 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800782 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800783 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800784 AmTsPlayer_hideVideo(player->handle);
785 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800786 }
787 return DVR_SUCCESS;
788}
hualing chena540a7e2020-03-27 16:44:05 +0800789static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
790 DVR_Playback_t *player = (DVR_Playback_t *) handle;
791 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800792 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800793 return DVR_TRUE;
794 }
hualing chen266b9502020-04-04 17:39:39 +0800795 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chena540a7e2020-03-27 16:44:05 +0800796 if (player->first_frame == 1) {
797 return DVR_TRUE;
798 } else {
799 return DVR_FALSE;
800 }
801 } else {
802 return DVR_TRUE;
803 }
804}
hualing chen86e7d482020-01-16 15:13:33 +0800805static void* _dvr_playback_thread(void *arg)
806{
hualing chen040df222020-01-17 13:35:02 +0800807 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800808 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800809 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800810 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800811 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800812
hualing chen6d24aa92020-03-23 18:43:47 +0800813 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800814 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800815 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800816 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800817 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
818
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800819 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800820 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800821 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800822
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800823 if (player->is_secure_mode) {
824 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800825 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800826 return NULL;
827 }
828 }
hualing chen86e7d482020-01-16 15:13:33 +0800829 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800830 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800831 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800832 return NULL;
833 }
hualing chen2aba4022020-03-02 13:49:55 +0800834 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
835 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800836
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800837 dec_bufs.buf_data = malloc(dec_buf_size);
838 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800839 DVR_PB_DG(1, "Malloc dec buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800840 return NULL;
841 }
842 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
843 dec_bufs.buf_size = dec_buf_size;
844
hualing chencc91e1c2020-02-28 13:26:17 +0800845 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800846 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
847 }
hualing chen86e7d482020-01-16 15:13:33 +0800848
hualing chen86e7d482020-01-16 15:13:33 +0800849 if (ret != DVR_SUCCESS) {
850 if (buf != NULL) {
851 free(buf);
852 buf = NULL;
853 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800854 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800855 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800856 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800857 }
hualing chencc91e1c2020-02-28 13:26:17 +0800858 //get play statue not here
859 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
860 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800861 //set video show
862 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800863
hualing chen86e7d482020-01-16 15:13:33 +0800864 int trick_stat = 0;
865 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800866
hualing chen86e7d482020-01-16 15:13:33 +0800867 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800868 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800869
hualing chen2aba4022020-03-02 13:49:55 +0800870 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
871 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800872 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800873 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen31140872020-03-25 12:29:26 +0800874 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800875 {
hualing chen2aba4022020-03-02 13:49:55 +0800876 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
877 if (trick_stat > 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800878 DVR_PB_DG(1, "trick stat[%d] is > 0", trick_stat);
hualing chen87072a82020-03-12 16:20:12 +0800879 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 +0800880 //check last cmd
881 if(player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800882 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800883 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
884 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800885 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
886 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800887 DVR_PB_DG(1, "pause play-------");
hualing chen2aba4022020-03-02 13:49:55 +0800888 //need change to pause state
889 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
890 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800891 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800892 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800893 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800894 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800895 AmTsPlayer_pauseVideoDecoding(player->handle);
896 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800897 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800898 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +0800899 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800900 }
901 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
902 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800903 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800904 //restart play stream if speed > 2
905 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
906 _dvr_time_getClock() < player->next_fffb_time) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800907 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 +0800908 //used timeout wait need lock first,so we unlock and lock
909 //pthread_mutex_unlock(&player->lock);
910 //pthread_mutex_lock(&player->lock);
911 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
912 pthread_mutex_unlock(&player->lock);
913 continue;
914 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800915 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
hualing chen2aba4022020-03-02 13:49:55 +0800916 pthread_mutex_unlock(&player->lock);
917 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800918 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800919 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
920 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800921 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
922 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800923 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800924 }else if (player->fffb_play == DVR_TRUE){
925 //for first into fffb when reset speed
926 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
927 _dvr_time_getClock() < player->next_fffb_time) {
928 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);
929 //used timeout wait need lock first,so we unlock and lock
930 //pthread_mutex_unlock(&player->lock);
931 //pthread_mutex_lock(&player->lock);
932 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
933 pthread_mutex_unlock(&player->lock);
934 continue;
935 }
936 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
937 pthread_mutex_unlock(&player->lock);
938 goto_rewrite = DVR_FALSE;
939 real_read = 0;
940 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
941 player->first_frame = 0;
942 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
943 pthread_mutex_lock(&player->lock);
944 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +0800945 }
hualing chenb31a6c62020-01-13 17:27:00 +0800946 }
hualing chen86e7d482020-01-16 15:13:33 +0800947
hualing chen87072a82020-03-12 16:20:12 +0800948 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800949 //check is need send time send end
950 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800951 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
952 pthread_mutex_unlock(&player->lock);
953 continue;
954 }
hualing chen266b9502020-04-04 17:39:39 +0800955 //when seek action is done. we need drop write timeout data.
956 if (player->drop_ts == DVR_TRUE) {
957 goto_rewrite = DVR_FALSE;
958 real_read = 0;
959 player->drop_ts = DVR_FALSE;
960 }
hualing chen2aba4022020-03-02 13:49:55 +0800961 if (goto_rewrite == DVR_TRUE) {
962 goto_rewrite = DVR_FALSE;
963 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800964 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +0800965 goto rewrite;
966 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800967 //.check is need send time send end
968 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen4b7c15d2020-04-07 16:13:48 +0800969 pthread_mutex_lock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800970 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen4b7c15d2020-04-07 16:13:48 +0800971 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800972 pthread_mutex_unlock(&player->lock);
973 //if on fb mode and read file end , we need calculate pos to retry read.
974 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800975 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 +0800976 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
977 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +0800978 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
979 pthread_mutex_unlock(&player->lock);
980 continue;
981 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800982 //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 +0800983 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +0800984 //file end.need to play next segment
hualing chen040df222020-01-17 13:35:02 +0800985 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +0800986 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +0800987 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +0800988
989 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +0800990 if (ret != DVR_SUCCESS &&
991 (delay <= MIN_TSPLAYER_DELAY_TIME ||
992 delay > MAX_CACHE_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +0800993 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen041c4092020-04-05 15:11:50 +0800994 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) {
hualing chena540a7e2020-03-27 16:44:05 +0800995 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +0800996 DVR_Play_Notify_t notify;
997 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
998 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
999 //get play statue not here
1000 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen31140872020-03-25 12:29:26 +08001001 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify);
1002 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen4b7c15d2020-04-07 16:13:48 +08001003 DVR_PB_DG(1, "playback is send end delay:[%d]", delay);
hualing chen31140872020-03-25 12:29:26 +08001004 pthread_mutex_lock(&player->lock);
1005 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1006 pthread_mutex_unlock(&player->lock);
1007 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001008 } else if (ret != DVR_SUCCESS) {
1009 //not send event and pause,sleep and go to next time to recheck
hualing chen4b7c15d2020-04-07 16:13:48 +08001010 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001011 pthread_mutex_lock(&player->lock);
1012 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1013 pthread_mutex_unlock(&player->lock);
1014 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001015 }
hualing chen31140872020-03-25 12:29:26 +08001016 //change next segment success case
hualing chencc91e1c2020-02-28 13:26:17 +08001017 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
1018 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001019 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001020 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1021 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001022 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001023 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001024 }
1025 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001026 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001027 wbufs.buf_data = buf;
hualing chena540a7e2020-03-27 16:44:05 +08001028 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001029 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001030 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001031 real_read = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001032 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001033 }
hualing chen266b9502020-04-04 17:39:39 +08001034 //if need write whole block size, we need check read buf len is eq block size.
1035 if (b_writed_whole_block == DVR_TRUE) {
1036 //buf_len is block size value.
1037 if (real_read < buf_len) {
1038 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001039 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001040 pthread_mutex_lock(&player->lock);
1041 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1042 pthread_mutex_unlock(&player->lock);
1043 continue;
1044 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001045 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 +08001046 }
1047 }
1048
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001049 if (player->dec_func) {
1050 DVR_CryptoParams_t crypto_params;
1051
1052 memset(&crypto_params, 0, sizeof(crypto_params));
1053 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1054 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1055 crypto_params.segment_id = player->cur_segment.segment_id;
1056 crypto_params.offset = segment_tell_position(player->r_handle);
1057
1058 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1059 crypto_params.input_buffer.addr = (size_t)buf;
1060 crypto_params.input_buffer.size = real_read;
1061
1062 if (player->is_secure_mode) {
1063 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1064 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1065 crypto_params.output_buffer.size = dec_buf_size;
1066 ret = player->dec_func(&crypto_params, player->dec_userdata);
1067 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001068 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001069 } else {
1070 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1071 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1072 crypto_params.output_buffer.size = dec_buf_size;
1073 ret = player->dec_func(&crypto_params, player->dec_userdata);
1074 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001075 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001076 }
1077 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001078 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001079 }
pengfei.liufda2a972020-04-09 14:47:15 +08001080 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001081 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001082rewrite:
hualing chen041c4092020-04-05 15:11:50 +08001083
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001084 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1085 if (ret == AM_TSPLAYER_OK) {
hualing chena540a7e2020-03-27 16:44:05 +08001086 real_read = 0;
1087 write_success++;
1088 continue;
hualing chen87072a82020-03-12 16:20:12 +08001089 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001090 DVR_PB_DG(1, "write time out write_success:%d", write_success);
hualing chena540a7e2020-03-27 16:44:05 +08001091 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001092 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001093 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001094 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001095 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001096 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001097 break;
1098 }
hualing chen2aba4022020-03-02 13:49:55 +08001099 goto_rewrite = DVR_TRUE;
1100 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001101 }
1102 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001103 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001104 free(buf);
1105 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001106 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001107}
1108
1109
hualing chen040df222020-01-17 13:35:02 +08001110static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001111{
hualing chen040df222020-01-17 13:35:02 +08001112 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001113
1114 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001115 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001116 return DVR_FAILURE;
1117 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001118 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001119 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001120 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001121 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001122 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001123 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001124 if (rc < 0)
1125 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001126 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001127}
1128
1129
hualing chen040df222020-01-17 13:35:02 +08001130static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001131{
hualing chen040df222020-01-17 13:35:02 +08001132 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001133
1134 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001135 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001136 return DVR_FAILURE;
1137 }
1138
hualing chen4b7c15d2020-04-07 16:13:48 +08001139 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001140 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001141 {
1142 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001143 _dvr_playback_sendSignal(handle);
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 }
hualing chen7a56cba2020-04-14 14:09:27 +08001150 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001151 return 0;
1152}
1153
hualing chenb31a6c62020-01-13 17:27:00 +08001154/**\brief Open an dvr palyback
1155 * \param[out] p_handle dvr playback addr
1156 * \param[in] params dvr playback open parameters
1157 * \retval DVR_SUCCESS On success
1158 * \return Error code
1159 */
hualing chen040df222020-01-17 13:35:02 +08001160int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001161
hualing chen040df222020-01-17 13:35:02 +08001162 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001163 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001164
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001165 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001166
hualing chen86e7d482020-01-16 15:13:33 +08001167 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001168 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001169 pthread_condattr_init(&cattr);
1170 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1171 pthread_cond_init(&player->cond, &cattr);
1172 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001173
hualing chen5cbe1a62020-02-10 16:36:36 +08001174 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001175 INIT_LIST_HEAD(&player->segment_list);
1176 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1177 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001178 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001179 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001180 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001181 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001182 player->speed = 1.0f;
hualing chen2aba4022020-03-02 13:49:55 +08001183
hualing chen86e7d482020-01-16 15:13:33 +08001184 //store open params
hualing chen040df222020-01-17 13:35:02 +08001185 player->openParams.dmx_dev_id = params->dmx_dev_id;
1186 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001187 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001188 player->openParams.event_fn = params->event_fn;
1189 player->openParams.event_userdata = params->event_userdata;
1190
hualing chen5cbe1a62020-02-10 16:36:36 +08001191 player->has_pids = params->has_pids;
1192
hualing chen2aba4022020-03-02 13:49:55 +08001193 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001194
1195 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1196 //for test get callback
1197 if (0 && player->player_callback_func == NULL) {
1198 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1199 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001200 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 +08001201 }
1202 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001203
hualing chen86e7d482020-01-16 15:13:33 +08001204 //init has audio and video
1205 player->has_video = DVR_FALSE;
1206 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001207 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001208 player->last_segment_id = 0LL;
1209 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001210
hualing chen5cbe1a62020-02-10 16:36:36 +08001211 //init ff fb time
1212 player->fffb_current = -1;
1213 player->fffb_start =-1;
1214 player->fffb_start_pcr = -1;
1215 //seek time
1216 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001217 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001218
1219 //init secure stuff
1220 player->dec_func = NULL;
1221 player->dec_userdata = NULL;
1222 player->is_secure_mode = 0;
1223 player->secure_buffer = NULL;
1224 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001225 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001226
hualing chen4b7c15d2020-04-07 16:13:48 +08001227 player->fffb_play = DVR_FALSE;
1228
1229 player->last_send_time_id = UINT64_MAX;
1230 player->last_cur_time = 0;
1231
hualing chen86e7d482020-01-16 15:13:33 +08001232 *p_handle = player;
1233 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001234}
1235
1236/**\brief Close an dvr palyback
1237 * \param[in] handle playback handle
1238 * \retval DVR_SUCCESS On success
1239 * \return Error code
1240 */
hualing chen040df222020-01-17 13:35:02 +08001241int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001242
hualing chen86e7d482020-01-16 15:13:33 +08001243 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001244 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001245 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001246 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001247 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001248 return DVR_FAILURE;
1249 }
1250
hualing chencc91e1c2020-02-28 13:26:17 +08001251 if (player->state != DVR_PLAYBACK_STATE_STOP)
1252 {
1253 dvr_playback_stop(handle, DVR_TRUE);
1254 }
hualing chen7a56cba2020-04-14 14:09:27 +08001255 DVR_PB_DG(1, ":into");
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 chen7a56cba2020-04-14 14:09:27 +08001263 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001264 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001265}
1266
hualing chenb31a6c62020-01-13 17:27:00 +08001267/**\brief Start play audio and video, used start auido api and start video api
1268 * \param[in] handle playback handle
1269 * \param[in] params audio playback params,contains fmt and pid...
1270 * \retval DVR_SUCCESS On success
1271 * \return Error code
1272 */
hualing chen040df222020-01-17 13:35:02 +08001273int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1274 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001275 am_tsplayer_video_params vparams;
1276 am_tsplayer_audio_params aparams;
hualing chena540a7e2020-03-27 16:44:05 +08001277
1278 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001279 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001280 return DVR_FAILURE;
1281 }
hualing chencc91e1c2020-02-28 13:26:17 +08001282 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001283 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001284
hualing chena540a7e2020-03-27 16:44:05 +08001285 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001286 //can used start api to resume playback
1287 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1288 return dvr_playback_resume(handle);
1289 }
hualing chen87072a82020-03-12 16:20:12 +08001290 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001291 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001292 return DVR_SUCCESS;
1293 }
hualing chen86e7d482020-01-16 15:13:33 +08001294 player->play_flag = flag;
hualing chen5cbe1a62020-02-10 16:36:36 +08001295 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001296 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001297 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001298 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001299 //start audio and video
1300 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1301 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001302 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001303 pthread_mutex_unlock(&player->lock);
1304 DVR_Play_Notify_t notify;
1305 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1306 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1307 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1308 notify.info.transition_failed_data.segment_id = segment_id;
1309 //get play statue not here
1310 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify);
hualing chen86e7d482020-01-16 15:13:33 +08001311 return -1;
1312 }
hualing chen31140872020-03-25 12:29:26 +08001313
hualing chencc91e1c2020-02-28 13:26:17 +08001314 {
hualing chen86e7d482020-01-16 15:13:33 +08001315 if (VALID_PID(vparams.pid)) {
1316 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001317 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001318 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001319 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001320 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1321 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001322 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001323 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001324 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001325 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001326 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001327 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001328 }
1329 AmTsPlayer_setVideoParams(player->handle, &vparams);
1330 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001331 }
hualing chena540a7e2020-03-27 16:44:05 +08001332
hualing chen4b7c15d2020-04-07 16:13:48 +08001333 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1334 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001335 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1336 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1337 player->cmd.state = DVR_PLAYBACK_STATE_START;
1338 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001339 } else {
1340 player->cmd.last_cmd = player->cmd.cur_cmd;
1341 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001342 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001343 //set fast play
hualing chen4b7c15d2020-04-07 16:13:48 +08001344 DVR_PB_DG(1, "dvr start fast mode");
hualing chen31140872020-03-25 12:29:26 +08001345 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001346 } else {
1347 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001348 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08001349 player->has_audio = DVR_TRUE;
1350 AmTsPlayer_setAudioParams(player->handle, &aparams);
1351 AmTsPlayer_startAudioDecoding(player->handle);
1352 }
hualing chen31140872020-03-25 12:29:26 +08001353 }
hualing chencc91e1c2020-02-28 13:26:17 +08001354 player->cmd.state = DVR_PLAYBACK_STATE_START;
1355 player->state = DVR_PLAYBACK_STATE_START;
1356 }
hualing chen86e7d482020-01-16 15:13:33 +08001357 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001358 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001359 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001360 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001361 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001362}
hualing chen040df222020-01-17 13:35:02 +08001363/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001364 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001365 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001366 * \retval DVR_SUCCESS On success
1367 * \return Error code
1368 */
hualing chen040df222020-01-17 13:35:02 +08001369int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1370 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001371
hualing chena540a7e2020-03-27 16:44:05 +08001372 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001373 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001374 return DVR_FAILURE;
1375 }
1376
hualing chen4b7c15d2020-04-07 16:13:48 +08001377 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001378 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001379
hualing chen040df222020-01-17 13:35:02 +08001380 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1381 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001382
hualing chen86e7d482020-01-16 15:13:33 +08001383 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001384 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001385 //cp location
hualing chen040df222020-01-17 13:35:02 +08001386 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001387
hualing chen4b7c15d2020-04-07 16:13:48 +08001388 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 +08001389 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001390
1391 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001392 segment->pids.video.pid = info->pids.video.pid;
1393 segment->pids.video.format = info->pids.video.format;
1394 segment->pids.video.type = info->pids.video.type;
1395
hualing chen2aba4022020-03-02 13:49:55 +08001396 segment->pids.audio.pid = info->pids.audio.pid;
1397 segment->pids.audio.format = info->pids.audio.format;
1398 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001399
hualing chen2aba4022020-03-02 13:49:55 +08001400 segment->pids.ad.pid = info->pids.ad.pid;
1401 segment->pids.ad.format = info->pids.ad.format;
1402 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001403
1404 segment->pids.pcr.pid = info->pids.pcr.pid;
1405
hualing chen4b7c15d2020-04-07 16:13:48 +08001406 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 +08001407 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001408 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001409 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001410 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001411
hualing chen5cbe1a62020-02-10 16:36:36 +08001412 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001413}
hualing chen040df222020-01-17 13:35:02 +08001414/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001415 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001416 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001417 * \retval DVR_SUCCESS On success
1418 * \return Error code
1419 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001420int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001421 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001422 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001423 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001424 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001425 return DVR_FAILURE;
1426 }
1427
hualing chencc91e1c2020-02-28 13:26:17 +08001428 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001429 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001430 return DVR_FAILURE;
1431 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001432 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001433 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001434 DVR_PlaybackSegmentInfo_t *segment = NULL;
1435 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1436 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001437 {
hualing chen040df222020-01-17 13:35:02 +08001438 if (segment->segment_id == segment_id) {
1439 list_del(&segment->head);
1440 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001441 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001442 }
hualing chen86e7d482020-01-16 15:13:33 +08001443 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001444 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001445 pthread_mutex_unlock(&player->lock);
1446
1447 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001448}
hualing chen040df222020-01-17 13:35:02 +08001449/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001450 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001451 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001452 * \retval DVR_SUCCESS On success
1453 * \return Error code
1454 */
hualing chen040df222020-01-17 13:35:02 +08001455int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001456 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001457 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001458 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001459 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001460 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001461 return DVR_FAILURE;
1462 }
1463
hualing chen040df222020-01-17 13:35:02 +08001464 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001465 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001466 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001467 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001468 {
hualing chen040df222020-01-17 13:35:02 +08001469 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001470 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001471 }
hualing chen86e7d482020-01-16 15:13:33 +08001472 // if encramble to free, only set flag and return;
1473
1474 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001475 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001476 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1477 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001478 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001479 AmTsPlayer_hideVideo(player->handle);
1480 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001481 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1482 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001483 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001484 AmTsPlayer_showVideo(player->handle);
1485 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001486 } else {
1487 //do nothing
1488 }
1489 } else {
1490 //do nothing
1491 }
1492 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001493 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001494 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001495 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001496 pthread_mutex_unlock(&player->lock);
1497 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001498}
1499
1500
hualing chen5cbe1a62020-02-10 16:36:36 +08001501static 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 +08001502 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001503 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001504 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001505 return DVR_FAILURE;
1506 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001507 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001508 if (now_pid.pid == set_pid.pid) {
1509 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001510 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001511 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001512 if (VALID_PID(now_pid.pid)) {
1513 //stop now stream
1514 if (type == 0) {
1515 //stop vieo
hualing chen4b7c15d2020-04-07 16:13:48 +08001516 DVR_PB_DG(1, "stop video");
hualing chen2aba4022020-03-02 13:49:55 +08001517 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001518 player->has_video = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001519 } else if (type == 1) {
1520 //stop audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001521 DVR_PB_DG(1, "stop audio");
hualing chen2aba4022020-03-02 13:49:55 +08001522 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001523 player->has_audio = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001524 } else if (type == 2) {
1525 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001526 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001527 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001528 } else if (type == 3) {
1529 //pcr
1530 }
1531 }
1532 if (VALID_PID(set_pid.pid)) {
1533 //start
1534 if (type == 0) {
1535 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001536 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001537 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001538 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001539 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001540 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001541 AmTsPlayer_setVideoParams(player->handle, &vparams);
1542 AmTsPlayer_startVideoDecoding(player->handle);
1543 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001544 } else if (type == 1) {
1545 //start audio
hualing chen2aba4022020-03-02 13:49:55 +08001546 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001547 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001548 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001549 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001550 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001551 AmTsPlayer_setAudioParams(player->handle, &aparams);
1552 AmTsPlayer_startAudioDecoding(player->handle);
1553 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001554 } else if (type == 2) {
hualing chen2aba4022020-03-02 13:49:55 +08001555 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001556 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001557 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001558 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001559 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chena540a7e2020-03-27 16:44:05 +08001560 AmTsPlayer_setADParams(player->handle, &aparams);
1561 AmTsPlayer_enableADMix(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001562 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001563 } else if (type == 3) {
1564 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001565 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001566 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001567 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001568 //audio and video all close
1569 if (!player->has_audio && !player->has_video) {
1570 player->state = DVR_PLAYBACK_STATE_STOP;
1571 }
hualing chen86e7d482020-01-16 15:13:33 +08001572 }
1573 }
1574 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001575}
hualing chen5cbe1a62020-02-10 16:36:36 +08001576/**\brief dvr play back update segment pids
1577 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001578 * add pid stream and stop remove pid stream.
1579 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001580 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001581 * \retval DVR_SUCCESS On success
1582 * \return Error code
1583 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001584int 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 +08001585 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001586 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001587 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001588 return DVR_FAILURE;
1589 }
1590
hualing chen040df222020-01-17 13:35:02 +08001591 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001592 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001593 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001594 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 +08001595
hualing chen040df222020-01-17 13:35:02 +08001596 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001597 {
hualing chen040df222020-01-17 13:35:02 +08001598 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001599
1600 if (player->cur_segment_id == segment_id) {
1601 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1602 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1603 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001604 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001605 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001606 return 0;
1607 }
1608
1609 //if segment is on going segment,we need stop start stream
1610 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001611 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001612 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001613 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001614 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001615 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001616 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001617 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001618 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001619 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1620 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001621 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1622 //if state is pause, we need process at resume api. we only record change info
1623 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1624 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1625 if (VALID_PID(segment->pids.video.pid)
1626 && VALID_PID(p_pids->video.pid)
1627 && segment->pids.video.pid != p_pids->video.pid) {
1628 //restart video
1629 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1630 }
1631 if (!VALID_PID(segment->pids.video.pid)
1632 && VALID_PID(p_pids->video.pid)
1633 && segment->pids.video.pid != p_pids->video.pid) {
1634 //start video
1635 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1636 }
1637 if (VALID_PID(segment->pids.video.pid)
1638 && !VALID_PID(p_pids->video.pid)
1639 && segment->pids.video.pid != p_pids->video.pid) {
1640 //stop video
1641 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1642 }
1643 if (VALID_PID(segment->pids.audio.pid)
1644 && VALID_PID(p_pids->audio.pid)
1645 && segment->pids.audio.pid != p_pids->audio.pid) {
1646 //restart audio
1647 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1648 }
1649 if (!VALID_PID(segment->pids.audio.pid)
1650 && VALID_PID(p_pids->audio.pid)
1651 && segment->pids.audio.pid != p_pids->audio.pid) {
1652 //start audio
1653 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1654 }
1655 if (VALID_PID(segment->pids.audio.pid)
1656 && !VALID_PID(p_pids->audio.pid)
1657 && segment->pids.audio.pid != p_pids->audio.pid) {
1658 //stop audio
1659 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1660 }
1661 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1662 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1663 //do nothing
1664 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1665 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1666 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1667 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1668 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1669 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1670 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1671 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1672 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1673 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1674 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1675 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1676 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1677 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1678 } else {
1679 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1680 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1681 }
1682
1683 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1684 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1685 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1686 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1687 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1688 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1689 //not occur this case
1690 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1691 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1692 } else {
1693 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1694 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1695 }
1696
1697 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1698 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1699 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1700 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1701 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1702 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1703 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1704 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1705 } else {
1706 //not occur this case
1707 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1708 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1709 }
1710 }
1711 }
1712 }
hualing chen86e7d482020-01-16 15:13:33 +08001713 //save pids info
hualing chen7a56cba2020-04-14 14:09:27 +08001714 DVR_PB_DG(1, ":apid :%d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08001715 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen7a56cba2020-04-14 14:09:27 +08001716 DVR_PB_DG(1, ":cp apid :%d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001717 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001718 }
hualing chen86e7d482020-01-16 15:13:33 +08001719 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001720 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001721 pthread_mutex_unlock(&player->lock);
1722 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001723}
1724/**\brief Stop play, will stop video and audio
1725 * \param[in] handle playback handle
1726 * \param[in] clear is clear last frame
1727 * \retval DVR_SUCCESS On success
1728 * \return Error code
1729 */
hualing chen040df222020-01-17 13:35:02 +08001730int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1731 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001732
1733 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001734 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001735 return DVR_FAILURE;
1736 }
hualing chen7a56cba2020-04-14 14:09:27 +08001737 DVR_PB_DG(1, ":into");
hualing chen87072a82020-03-12 16:20:12 +08001738 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001739 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001740 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08001741 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08001742 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001743 if (player->has_video) {
1744 AmTsPlayer_resumeVideoDecoding(player->handle);
1745 }
1746 if (player->has_audio) {
1747 AmTsPlayer_resumeAudioDecoding(player->handle);
1748 }
hualing chen7a56cba2020-04-14 14:09:27 +08001749 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001750 if (player->has_video) {
1751 player->has_video = DVR_FALSE;
1752 AmTsPlayer_showVideo(player->handle);
1753 AmTsPlayer_stopVideoDecoding(player->handle);
1754 }
hualing chen7a56cba2020-04-14 14:09:27 +08001755 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001756 if (player->has_audio) {
1757 player->has_audio = DVR_FALSE;
1758 AmTsPlayer_stopAudioDecoding(player->handle);
1759 }
hualing chen7a56cba2020-04-14 14:09:27 +08001760 DVR_PB_DG(1, ":into");
hualing chen266b9502020-04-04 17:39:39 +08001761
hualing chen86e7d482020-01-16 15:13:33 +08001762 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001763 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1764 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1765 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001766 player->cur_segment_id = UINT64_MAX;
1767 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001768 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001769 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001770 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001771}
1772/**\brief Start play audio
1773 * \param[in] handle playback handle
1774 * \param[in] params audio playback params,contains fmt and pid...
1775 * \retval DVR_SUCCESS On success
1776 * \return Error code
1777 */
hualing chen2aba4022020-03-02 13:49:55 +08001778
1779int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001780 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001781
1782 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001783 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001784 return DVR_FAILURE;
1785 }
hualing chen86e7d482020-01-16 15:13:33 +08001786 _start_playback_thread(handle);
1787 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001788 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001789 pthread_mutex_lock(&player->lock);
1790 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001791 AmTsPlayer_setAudioParams(player->handle, param);
1792 AmTsPlayer_startAudioDecoding(player->handle);
1793 //playback_device_audio_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001794 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001795 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1796 player->cmd.state = DVR_PLAYBACK_STATE_START;
1797 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001798 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001799 pthread_mutex_unlock(&player->lock);
1800 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001801}
1802/**\brief Stop play audio
1803 * \param[in] handle playback handle
1804 * \retval DVR_SUCCESS On success
1805 * \return Error code
1806 */
hualing chen040df222020-01-17 13:35:02 +08001807int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1808 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001809
1810 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001811 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001812 return DVR_FAILURE;
1813 }
1814
hualing chen2aba4022020-03-02 13:49:55 +08001815 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001816 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001817 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1818 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001819 //destory thread
1820 _stop_playback_thread(handle);
1821 } else {
1822 //do nothing.video is playing
1823 }
hualing chen7a56cba2020-04-14 14:09:27 +08001824 DVR_PB_DG(1, "lock");
1825 pthread_mutex_lock(&player->lock);
1826
hualing chen87072a82020-03-12 16:20:12 +08001827 player->has_audio = DVR_FALSE;
1828
1829 AmTsPlayer_stopAudioDecoding(player->handle);
1830 player->cmd.last_cmd = player->cmd.cur_cmd;
1831 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
1832
hualing chen4b7c15d2020-04-07 16:13:48 +08001833 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001834 pthread_mutex_unlock(&player->lock);
1835 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001836}
1837/**\brief Start play video
1838 * \param[in] handle playback handle
1839 * \param[in] params video playback params,contains fmt and pid...
1840 * \retval DVR_SUCCESS On success
1841 * \return Error code
1842 */
hualing chen2aba4022020-03-02 13:49:55 +08001843int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001844 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001845
1846 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001847 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001848 return DVR_FAILURE;
1849 }
1850
hualing chen86e7d482020-01-16 15:13:33 +08001851 _start_playback_thread(handle);
1852 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08001853 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001854 pthread_mutex_lock(&player->lock);
1855 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001856 AmTsPlayer_setVideoParams(player->handle, param);
1857 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001858
1859 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001860 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08001861 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001862 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08001863 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1864 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08001865 }
1866 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001867 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
1868 player->cmd.state = DVR_PLAYBACK_STATE_START;
1869 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08001870 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001871 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001872 return DVR_SUCCESS;
1873}
1874/**\brief Stop play video
1875 * \param[in] handle playback handle
1876 * \retval DVR_SUCCESS On success
1877 * \return Error code
1878 */
hualing chen040df222020-01-17 13:35:02 +08001879int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
1880 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001881
1882 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001883 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001884 return DVR_FAILURE;
1885 }
1886
hualing chen86e7d482020-01-16 15:13:33 +08001887 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001888 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1889 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001890 //destory thread
1891 _stop_playback_thread(handle);
1892 } else {
1893 //do nothing.audio is playing
1894 }
hualing chen7a56cba2020-04-14 14:09:27 +08001895
1896 DVR_PB_DG(1, "lock");
1897 pthread_mutex_lock(&player->lock);
1898
hualing chen87072a82020-03-12 16:20:12 +08001899 player->has_video = DVR_FALSE;
1900
1901 AmTsPlayer_stopVideoDecoding(player->handle);
1902 //playback_device_video_stop(player->handle);
1903
1904 player->cmd.last_cmd = player->cmd.cur_cmd;
1905 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
1906
hualing chen4b7c15d2020-04-07 16:13:48 +08001907 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001908 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001909 return DVR_SUCCESS;
1910}
1911/**\brief Pause play
1912 * \param[in] handle playback handle
1913 * \param[in] flush whether its internal buffers should be flushed
1914 * \retval DVR_SUCCESS On success
1915 * \return Error code
1916 */
hualing chen040df222020-01-17 13:35:02 +08001917int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
1918 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001919
1920 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001921 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001922 return DVR_FAILURE;
1923 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001924 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001925 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001926 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08001927 if (player->has_video)
1928 AmTsPlayer_pauseVideoDecoding(player->handle);
1929 if (player->has_video)
1930 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001931
1932 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001933 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1934 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1935 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1936 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001937 } else {
1938 player->cmd.last_cmd = player->cmd.cur_cmd;
1939 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1940 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1941 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001942 }
hualing chen86e7d482020-01-16 15:13:33 +08001943 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001944 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08001945
hualing chen86e7d482020-01-16 15:13:33 +08001946 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001947}
1948
hualing chen5cbe1a62020-02-10 16:36:36 +08001949//not add lock
1950static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
1951{
1952 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1953
hualing chena540a7e2020-03-27 16:44:05 +08001954 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001955 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001956 return DVR_FAILURE;
1957 }
1958
hualing chen5cbe1a62020-02-10 16:36:36 +08001959 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08001960 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08001961 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001962 am_tsplayer_video_params vparams;
1963 am_tsplayer_audio_params aparams;
hualing chencc91e1c2020-02-28 13:26:17 +08001964 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08001965
1966 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08001967 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08001968 pthread_mutex_unlock(&player->lock);
1969
1970 switch (cmd) {
1971 case DVR_PLAYBACK_CMD_AVRESTART:
1972 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08001973 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08001974 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001975 break;
1976 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001977 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1978 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001979 break;
1980 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001981 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001982 break;
1983 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001984 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001985 break;
1986 case DVR_PLAYBACK_CMD_ARESTART:
1987 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08001988 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1989 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001990 break;
1991 case DVR_PLAYBACK_CMD_ASTART:
hualing chen2aba4022020-03-02 13:49:55 +08001992 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001993 break;
1994 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001995 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001996 break;
1997 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001998 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1999 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2000 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002001 break;
2002 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002003 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2004 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002005 break;
2006 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002007 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2008 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2009 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002010 break;
2011 case DVR_PLAYBACK_CMD_STOP:
2012 break;
2013 case DVR_PLAYBACK_CMD_START:
2014 break;
2015 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002016 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2017 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
2018 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002019 break;
2020 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002021 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2022 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
2023 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002024 break;
2025 case DVR_PLAYBACK_CMD_FF:
2026 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002027 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002028 break;
2029 default:
2030 break;
2031 }
2032 return DVR_SUCCESS;
2033}
2034
2035/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002036 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002037 * \retval DVR_SUCCESS On success
2038 * \return Error code
2039 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002040int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2041 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2042
hualing chena540a7e2020-03-27 16:44:05 +08002043 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002044 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002045 return DVR_FAILURE;
2046 }
2047
hualing chen5cbe1a62020-02-10 16:36:36 +08002048 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002049 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002050 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002051 if (player->has_video) {
2052 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2053 AmTsPlayer_resumeVideoDecoding(player->handle);
2054 }
2055 if (player->has_audio) {
2056 AmTsPlayer_resumeAudioDecoding(player->handle);
2057 }
2058 //check is has audio param,if has audio .we need start audio,
2059 //we will stop audio when ff fb, if reach end, we will pause.so we need
2060 //start audio when resume play
2061
2062 am_tsplayer_video_params vparams;
2063 am_tsplayer_audio_params aparams;
2064 uint64_t segmentid = player->cur_segment_id;
2065 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
2066 //valid audio pid, start audio
2067 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid)) {
2068 player->has_audio = DVR_TRUE;
2069 AmTsPlayer_setAudioParams(player->handle, &aparams);
2070 AmTsPlayer_startAudioDecoding(player->handle);
2071 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002072 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d", aparams.pid, player->has_audio);
hualing chen266b9502020-04-04 17:39:39 +08002073 }
hualing chen87072a82020-03-12 16:20:12 +08002074 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2075 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2076 player->cmd.state = DVR_PLAYBACK_STATE_START;
2077 player->state = DVR_PLAYBACK_STATE_START;
2078 } else {
2079 player->cmd.last_cmd = player->cmd.cur_cmd;
2080 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2081 player->cmd.state = DVR_PLAYBACK_STATE_START;
2082 player->state = DVR_PLAYBACK_STATE_START;
2083 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002084 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002085 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002086 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
2087 if (player->has_video)
2088 AmTsPlayer_resumeVideoDecoding(player->handle);
2089 if (player->has_audio)
2090 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002091 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002092 player->cmd.state = DVR_PLAYBACK_STATE_START;
2093 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002094 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002095 } else {
2096 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2097 {
2098 pthread_mutex_lock(&player->lock);
2099 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002100 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002101 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2102 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2103 pthread_mutex_unlock(&player->lock);
2104 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002105 }
2106 return DVR_SUCCESS;
2107}
2108
hualing chena540a7e2020-03-27 16:44:05 +08002109static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2110
2111 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2112 DVR_PlaybackSegmentInfo_t *segment = NULL;
2113 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2114 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2115
2116 list_for_each_entry(segment, &player->segment_list, head)
2117 {
2118 if (segment->segment_id == segment_id) {
2119 cur_segment = segment;
2120 }
2121 if (segment->segment_id == set_seg_id) {
2122 set_segment = segment;
2123 }
2124 if (cur_segment != NULL && set_segment != NULL) {
2125 break;
2126 }
2127 }
2128 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002129 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002130 return DVR_TRUE;
2131 }
2132 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2133 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2134 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2135 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002136 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 +08002137 return DVR_TRUE;
2138 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002139 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002140 return DVR_FALSE;
2141}
2142
hualing chen5cbe1a62020-02-10 16:36:36 +08002143/**\brief seek
2144 * \param[in] handle playback handle
2145 * \param[in] time_offset time offset base cur segment
2146 * \retval DVR_SUCCESS On success
2147 * \return Error code
2148 */
hualing chencc91e1c2020-02-28 13:26:17 +08002149int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002150 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002151
2152 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002153 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002154 return DVR_FAILURE;
2155 }
2156
hualing chen4b7c15d2020-04-07 16:13:48 +08002157 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 +08002158 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002159
hualing chen86e7d482020-01-16 15:13:33 +08002160 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002161 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002162 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002163
hualing chen5cbe1a62020-02-10 16:36:36 +08002164 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002165 int ret = _dvr_open_segment(handle, segment_id);
2166 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002167 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002168 pthread_mutex_unlock(&player->lock);
2169 return DVR_FAILURE;
2170 }
2171 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2172 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002173 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002174 //pthread_mutex_unlock(&player->lock);
2175 //return DVR_SUCCESS;
2176 time_offset = _dvr_get_end_time(handle);
2177 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002178 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chen87072a82020-03-12 16:20:12 +08002179 pthread_mutex_unlock(&player->lock);
2180 return DVR_FAILURE;
2181 }
2182 }
2183
hualing chen4b7c15d2020-04-07 16:13:48 +08002184 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 +08002185 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002186 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2187 //forward playback.not seek end of file
2188 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2189 //default -2000ms
2190 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2191 }
hualing chen86e7d482020-01-16 15:13:33 +08002192 }
hualing chen2aba4022020-03-02 13:49:55 +08002193 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002194 player->drop_ts = DVR_TRUE;
2195 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002196 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 +08002197 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002198 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002199
hualing chen2aba4022020-03-02 13:49:55 +08002200 _dvr_get_end_time(handle);
2201 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002202 player->fffb_current = _dvr_time_getClock();
2203 player->fffb_start = player->fffb_current;
2204 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2205 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002206 //pause state if need to replayer false
2207 if (player->state == DVR_PLAYBACK_STATE_STOP ||
2208 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002209 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002210 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002211 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002212 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002213 }
hualing chen86e7d482020-01-16 15:13:33 +08002214 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002215 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 +08002216 if (player->has_video) {
2217 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002218 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002219 }
2220
2221 if (player->has_audio) {
2222 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002223 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002224 }
hualing chen86e7d482020-01-16 15:13:33 +08002225 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002226 am_tsplayer_video_params vparams;
2227 am_tsplayer_audio_params aparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002228
hualing chen040df222020-01-17 13:35:02 +08002229 player->cur_segment_id = segment_id;
2230
2231 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002232 //get segment info and audio video pid fmt ;
2233 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08002234 //start audio and video
2235 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2236 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002237 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 +08002238 pthread_mutex_unlock(&player->lock);
2239 return -1;
2240 }
2241 //add
hualing chen040df222020-01-17 13:35:02 +08002242 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002243 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002244 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002245 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chen31140872020-03-25 12:29:26 +08002246 player->speed > 1.0f||
2247 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002248 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002249 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002250 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002251 }
hualing chen2aba4022020-03-02 13:49:55 +08002252 AmTsPlayer_setVideoParams(player->handle, &vparams);
2253 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002254 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002255 }
hualing chen86e7d482020-01-16 15:13:33 +08002256 if (VALID_PID(aparams.pid)) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002257 DVR_PB_DG(1, "start audio seek");
hualing chen2aba4022020-03-02 13:49:55 +08002258 AmTsPlayer_setAudioParams(player->handle, &aparams);
2259 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002260 player->has_audio = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002261 }
hualing chen86e7d482020-01-16 15:13:33 +08002262 }
hualing chen2aba4022020-03-02 13:49:55 +08002263 if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
2264 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2265 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2266 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
2267 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))) {
2268 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2269 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002270 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002271 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2272 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002273 player->speed > 1.0f||
2274 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002275 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002276 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002277 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002278 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002279 player->cmd.last_cmd = player->cmd.cur_cmd;
2280 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2281 player->cmd.state = DVR_PLAYBACK_STATE_START;
2282 player->state = DVR_PLAYBACK_STATE_START;
2283 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002284 player->last_send_time_id = UINT64_MAX;
2285 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002286 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002287
2288 return DVR_SUCCESS;
2289}
hualing chen5cbe1a62020-02-10 16:36:36 +08002290
hualing chen5cbe1a62020-02-10 16:36:36 +08002291static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2292 //get cur time of segment
2293 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002294
2295 if (player == NULL || player->handle == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002296 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002297 return DVR_FAILURE;
2298 }
2299
hualing chen31140872020-03-25 12:29:26 +08002300 int64_t cache = 0;//defalut es buf cache 500ms
2301 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002302 pthread_mutex_lock(&player->segment_lock);
2303 uint64_t cur = segment_tell_current_time(player->r_handle);
2304 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002305 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 +08002306 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2307 cache = 0;
2308 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002309 int cur_time = (int)(cur > cache ? cur - cache : 0);
2310 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002311}
2312
2313//get current segment current pcr time of read pos
2314static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2315 //get cur time of segment
2316 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002317
2318 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002319 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002320 return DVR_FAILURE;
2321 }
2322
hualing chen2aba4022020-03-02 13:49:55 +08002323 pthread_mutex_lock(&player->segment_lock);
2324 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002325 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002326 pthread_mutex_unlock(&player->segment_lock);
2327 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002328}
2329
hualing chen4b7c15d2020-04-07 16:13:48 +08002330#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002331//start replay
2332static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2333
2334 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2335 //calculate pcr seek time
2336 int t_diff = 0;
2337 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002338
2339 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002340 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002341 return DVR_FAILURE;
2342 }
2343
hualing chen5cbe1a62020-02-10 16:36:36 +08002344 if (player->fffb_start == -1) {
2345 //set fffb start time ms
2346 player->fffb_start = _dvr_time_getClock();
2347 player->fffb_current = player->fffb_start;
2348 //get segment current time pos
2349 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002350 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 +08002351 t_diff = 0;
hualing chen2aba4022020-03-02 13:49:55 +08002352 //default first time 1ms seek
hualing chen87072a82020-03-12 16:20:12 +08002353 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002354 } else {
2355 player->fffb_current = _dvr_time_getClock();
2356 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002357 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002358 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002359 if (seek_time <= 0) {
2360 //need seek to pre one segment
2361 seek_time = 0;
2362 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002363 //seek segment pos
2364 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002365 pthread_mutex_lock(&player->segment_lock);
hualing chen041c4092020-04-05 15:11:50 +08002366 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2367 seek_time = 0;
2368 }
hualing chen2aba4022020-03-02 13:49:55 +08002369 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002370 } else {
2371 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002372 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002373 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002374 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 +08002375 }
hualing chen2aba4022020-03-02 13:49:55 +08002376 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002377}
2378
2379
2380//start replay
2381static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2382 //
2383 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002384
2385 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002386 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002387 return DVR_FAILURE;
2388 }
2389
hualing chen5cbe1a62020-02-10 16:36:36 +08002390 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002391 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002392 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002393 AmTsPlayer_stopVideoDecoding(player->handle);
2394 }
2395 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002396 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002397 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002398 AmTsPlayer_stopAudioDecoding(player->handle);
2399 }
2400
hualing chen5cbe1a62020-02-10 16:36:36 +08002401 //start video and audio
2402
hualing chen2aba4022020-03-02 13:49:55 +08002403 am_tsplayer_video_params vparams;
2404 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002405 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002406
2407 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002408 //pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002409 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2410 //start audio and video
2411 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2412 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002413 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002414 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002415 return -1;
2416 }
2417
2418 if (VALID_PID(vparams.pid)) {
2419 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002420 DVR_PB_DG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08002421 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002422 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2423 AmTsPlayer_setVideoParams(player->handle, &vparams);
2424 AmTsPlayer_startVideoDecoding(player->handle);
2425 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002426 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002427 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002428 }
hualing chena540a7e2020-03-27 16:44:05 +08002429 if (0 && VALID_PID(aparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002430 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002431 DVR_PB_DG(1, "fffb start audio");
hualing chen2aba4022020-03-02 13:49:55 +08002432 AmTsPlayer_setAudioParams(player->handle, &aparams);
2433 AmTsPlayer_startAudioDecoding(player->handle);
2434 //playback_device_audio_start(player->handle , &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002435 }
hualing chen31140872020-03-25 12:29:26 +08002436 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08002437 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002438 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002439 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002440 return 0;
2441}
2442
2443static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2444 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002445
2446 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002447 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002448 return DVR_FAILURE;
2449 }
2450
2451 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002452 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002453 pthread_mutex_lock(&player->lock);
2454
hualing chen2aba4022020-03-02 13:49:55 +08002455 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002456 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 +08002457
hualing chen87072a82020-03-12 16:20:12 +08002458 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2459 //seek time set 0
2460 seek_time = 0;
2461 }
hualing chen041c4092020-04-05 15:11:50 +08002462 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002463 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2464 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002465 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002466 pthread_mutex_unlock(&player->lock);
2467 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002468 //send event here and pause
2469 DVR_Play_Notify_t notify;
2470 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002471 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002472 //get play statue not here
2473 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify);
hualing chen4b7c15d2020-04-07 16:13:48 +08002474 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 +08002475 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002476 return DVR_SUCCESS;
2477 }
hualing chen87072a82020-03-12 16:20:12 +08002478 _dvr_playback_sent_transition_ok(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002479 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002480 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002481 }
2482 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002483 _dvr_playback_fffb_replay(handle);
2484
2485 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002486 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002487
hualing chen5cbe1a62020-02-10 16:36:36 +08002488 return DVR_SUCCESS;
2489}
2490
hualing chen87072a82020-03-12 16:20:12 +08002491//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002492static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002493 //
2494 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002495
2496 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002497 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002498 return DVR_FAILURE;
2499 }
2500
hualing chen5cbe1a62020-02-10 16:36:36 +08002501 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002502 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002503 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002504 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002505 }
2506
2507 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002508 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002509 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002510 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002511 //start video and audio
2512
hualing chen2aba4022020-03-02 13:49:55 +08002513 am_tsplayer_video_params vparams;
2514 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002515 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002516
2517 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002518 DVR_PB_DG(1, "into");
hualing chen5cbe1a62020-02-10 16:36:36 +08002519 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2520 //start audio and video
2521 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002522 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002523 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002524 return -1;
2525 }
2526
2527 if (VALID_PID(vparams.pid)) {
2528 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002529 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002530 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002531 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002532 }
hualing chen266b9502020-04-04 17:39:39 +08002533 else {
hualing chen2aba4022020-03-02 13:49:55 +08002534 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002535 }
hualing chen2aba4022020-03-02 13:49:55 +08002536 AmTsPlayer_setVideoParams(player->handle, &vparams);
2537 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002538 }
hualing chena540a7e2020-03-27 16:44:05 +08002539
2540 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08002541 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08002542 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002543 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002544 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002545 if (VALID_PID(aparams.pid)) {
2546 player->has_audio = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002547 DVR_PB_DG(1, "start audio");
hualing chena540a7e2020-03-27 16:44:05 +08002548 AmTsPlayer_startAudioDecoding(player->handle);
2549 AmTsPlayer_setAudioParams(player->handle, &aparams);
hualing chena540a7e2020-03-27 16:44:05 +08002550 }
hualing chen7a56cba2020-04-14 14:09:27 +08002551 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002552 AmTsPlayer_stopFast(player->handle);
2553 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2554 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2555 }
hualing chen2aba4022020-03-02 13:49:55 +08002556 player->cmd.last_cmd = player->cmd.cur_cmd;
2557 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002558 player->cmd.state = DVR_PLAYBACK_STATE_START;
2559 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002560 return 0;
2561}
2562
2563
hualing chenb31a6c62020-01-13 17:27:00 +08002564/**\brief Set play speed
2565 * \param[in] handle playback handle
2566 * \param[in] speed playback speed
2567 * \retval DVR_SUCCESS On success
2568 * \return Error code
2569 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002570int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2571
2572 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002573
2574 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002575 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002576 return DVR_FAILURE;
2577 }
2578
hualing chen4b7c15d2020-04-07 16:13:48 +08002579 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002580 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002581 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002582 return DVR_FAILURE;
2583 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002584 pthread_mutex_lock(&player->lock);
2585 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2586 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2587 player->cmd.last_cmd = player->cmd.cur_cmd;
2588 }
hualing chen31140872020-03-25 12:29:26 +08002589 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002590 IS_KERNEL_SPEED(speed.speed.speed)) {
2591 //case 1. cur speed is 100,set 200 50 25 12 .
2592 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2593 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002594 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002595 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2596 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002597 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002598 AmTsPlayer_stopFast(player->handle);
2599 pthread_mutex_unlock(&player->lock);
2600 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2601 pthread_mutex_lock(&player->lock);
2602 } else {
2603 //set play speed and if audio is start, stop audio.
2604 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002605 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002606 AmTsPlayer_stopAudioDecoding(player->handle);
2607 player->has_audio = DVR_FALSE;
2608 }
2609 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002610 }
hualing chena540a7e2020-03-27 16:44:05 +08002611 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002612 player->cmd.speed.speed = speed.speed;
2613 player->speed = (float)speed.speed.speed/(float)100;
2614 pthread_mutex_unlock(&player->lock);
2615 return DVR_SUCCESS;
2616 }
2617 //case 2. not start play
2618 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2619 //only set speed.and return;
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 pthread_mutex_unlock(&player->lock);
2624 return DVR_SUCCESS;
hualing chen87072a82020-03-12 16:20:12 +08002625 }
hualing chen31140872020-03-25 12:29:26 +08002626 //case 3 fffb mode
2627 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2628 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2629 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002630 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002631 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002632 player->cmd.speed.speed = speed.speed;
2633 player->speed = (float)speed.speed.speed/(float)100;
2634 _dvr_playback_replay(handle, DVR_FALSE);
2635 pthread_mutex_unlock(&player->lock);
2636 return DVR_SUCCESS;
2637 }
2638 }
2639 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002640 IS_KERNEL_SPEED(speed.speed.speed)) {
2641 //case 1. cur speed is kernel support speed,set kernel speed.
2642 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002643 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002644 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2645 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002646 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002647 AmTsPlayer_stopFast(player->handle);
2648 pthread_mutex_unlock(&player->lock);
2649 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2650 pthread_mutex_lock(&player->lock);
2651 } else {
2652 //set play speed and if audio is start, stop audio.
2653 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002654 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002655 AmTsPlayer_stopAudioDecoding(player->handle);
2656 player->has_audio = DVR_FALSE;
2657 }
2658 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
2659 }
hualing chena540a7e2020-03-27 16:44:05 +08002660 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002661 player->cmd.speed.speed = speed.speed;
2662 player->speed = (float)speed.speed.speed/(float)100;
2663 pthread_mutex_unlock(&player->lock);
2664 return DVR_SUCCESS;
2665 }
2666 //case 2 fffb mode
2667 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2668 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2669 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002670 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002671 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002672 player->cmd.speed.speed = speed.speed;
2673 player->speed = (float)speed.speed.speed/(float)100;
2674 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2675 pthread_mutex_unlock(&player->lock);
2676 return DVR_SUCCESS;
2677 }
hualing chen31140872020-03-25 12:29:26 +08002678 }
hualing chena540a7e2020-03-27 16:44:05 +08002679 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2680 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chen87072a82020-03-12 16:20:12 +08002681 } else {
hualing chen31140872020-03-25 12:29:26 +08002682 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002683 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2684 else
2685 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08002686 player->fffb_play = DVR_TRUE;
2687 }
2688 DVR_Bool_t init_last_time = DVR_FALSE;
2689 if (player->speed > 0.0f && speed.speed.speed < 0) {
2690 init_last_time = DVR_TRUE;
2691 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
2692 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002693 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002694 player->cmd.speed.mode = speed.mode;
2695 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002696 player->speed = (float)speed.speed.speed/(float)100;
hualing chen4b7c15d2020-04-07 16:13:48 +08002697#if 0
2698 if (abs((int)(player->speed)) > 1) {
2699 //seek speed*1000 ms at fb mode
2700 pthread_mutex_lock(&player->segment_lock);
2701 uint64_t cur = segment_tell_current_time(player->r_handle);
2702 int diff = abs((int)(player->speed * 1000));
2703 DVR_PB_DG(1, " cur:%ull diff:%d", cur, diff);
2704 if (cur > diff)
2705 cur = cur - diff;
2706 else
2707 cur = 0;
2708 segment_seek(player->r_handle, cur, player->openParams.block_size);
2709 pthread_mutex_unlock(&player->segment_lock);
2710 }
2711#endif
hualing chen31140872020-03-25 12:29:26 +08002712 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08002713 _dvr_init_fffb_t(handle);
2714 if (init_last_time == DVR_TRUE)
2715 player->last_send_time_id = UINT64_MAX;
2716
hualing chen87072a82020-03-12 16:20:12 +08002717 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002718 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2719 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002720 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002721 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08002722 _dvr_playback_replay(handle, DVR_FALSE);
2723 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2724 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2725 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08002726 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08002727 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002728 //need exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002729 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002730 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002731 return DVR_SUCCESS;
2732}
2733/**\brief Get playback status
2734 * \param[in] handle playback handle
2735 * \param[out] p_status playback status
2736 * \retval DVR_SUCCESS On success
2737 * \return Error code
2738 */
hualing chen040df222020-01-17 13:35:02 +08002739int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002740 DVR_PlaybackStatus_t *p_status) {
2741//
2742 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002743
2744 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002745 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002746 return DVR_FAILURE;
2747 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002748
2749 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002750 //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 +08002751 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2752 player->state == DVR_PLAYBACK_STATE_START) {
2753 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2754 }
hualing chen041c4092020-04-05 15:11:50 +08002755
hualing chencc91e1c2020-02-28 13:26:17 +08002756 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002757 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002758 if (player->last_send_time_id == UINT64_MAX) {
2759 player->last_send_time_id = player->cur_segment_id;
2760 player->last_cur_time = p_status->time_cur;
2761 }
2762 if (player->last_send_time_id == player->cur_segment_id) {
2763 if (player->speed > 0.0f ) {
2764 //ff
2765 if (p_status->time_cur < player->last_cur_time ) {
2766 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);
2767 p_status->time_cur = player->last_cur_time;
2768 } else {
2769 player->last_cur_time = p_status->time_cur;
2770 }
2771 } else if (player->speed < -1.0f){
2772 //fb
2773 if (p_status->time_cur > player->last_cur_time ) {
2774 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 );
2775 p_status->time_cur = player->last_cur_time;
2776 } else {
2777 player->last_cur_time = p_status->time_cur;
2778 }
2779 }
2780 } else {
2781 player->last_cur_time = p_status->time_cur;
2782 }
2783 player->last_send_time_id = player->cur_segment_id;
hualing chen041c4092020-04-05 15:11:50 +08002784 p_status->segment_id = player->cur_segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08002785
hualing chen5cbe1a62020-02-10 16:36:36 +08002786 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08002787 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08002788 p_status->flags = player->cur_segment.flags;
hualing chen4b7c15d2020-04-07 16:13:48 +08002789 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 +08002790 _dvr_playback_state_toString(player->state),
2791 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08002792 p_status->time_cur, p_status->time_end,
2793 p_status->segment_id,player->play_flag,
2794 player->speed);
hualing chenb31a6c62020-01-13 17:27:00 +08002795 return DVR_SUCCESS;
2796}
2797
hualing chen040df222020-01-17 13:35:02 +08002798void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
2799 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002800 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
2801 DVR_PB_DG(1, "segment flag: %d", segment->flags);
2802 DVR_PB_DG(1, "segment location: [%s]", segment->location);
2803 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
2804 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
2805 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
2806 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 +08002807 }
hualing chenb31a6c62020-01-13 17:27:00 +08002808}
2809
hualing chen5cbe1a62020-02-10 16:36:36 +08002810int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002811 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08002812
hualing chena540a7e2020-03-27 16:44:05 +08002813 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002814 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002815 return DVR_FAILURE;
2816 }
2817
hualing chen040df222020-01-17 13:35:02 +08002818 DVR_PlaybackSegmentInfo_t *segment;
2819 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002820 {
hualing chen040df222020-01-17 13:35:02 +08002821 if (segment_id >= 0) {
2822 if (segment->segment_id == segment_id) {
2823 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002824 break;
2825 }
2826 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08002827 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08002828 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002829 }
2830 }
2831 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002832}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002833
pengfei.liu27cc4ec2020-04-03 16:28:16 +08002834int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002835{
2836 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2837 DVR_RETURN_IF_FALSE(player);
2838 DVR_RETURN_IF_FALSE(func);
2839
hualing chen4b7c15d2020-04-07 16:13:48 +08002840 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002841 pthread_mutex_lock(&player->lock);
2842
2843 player->dec_func = func;
2844 player->dec_userdata = userdata;
2845
2846 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002847 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002848 return DVR_SUCCESS;
2849}
2850
2851int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
2852{
2853 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2854 DVR_RETURN_IF_FALSE(player);
2855 DVR_RETURN_IF_FALSE(p_secure_buf);
2856 DVR_RETURN_IF_FALSE(len);
2857
hualing chen4b7c15d2020-04-07 16:13:48 +08002858 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002859 pthread_mutex_lock(&player->lock);
2860
2861 player->is_secure_mode = 1;
2862 player->secure_buffer = p_secure_buf;
2863 player->secure_buffer_size = len;
2864
2865 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002866 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08002867 return DVR_SUCCESS;
2868}