blob: 6584c0f623312eb396e51c2b2d8eee2f6b34d6ff [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 chena540a7e2020-03-27 16:44:05 +080017
hualing chenb31a6c62020-01-13 17:27:00 +080018#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080019
20
21#define FF_SPEED (2.0f)
22#define FB_SPEED (-1.0f)
23#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
24#define IS_FB(_SPEED_) ((_SPEED_) < FB_SPEED)
25
26#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))
27#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
28
hualing chenb31a6c62020-01-13 17:27:00 +080029
hualing chen2aba4022020-03-02 13:49:55 +080030#define FFFB_SLEEP_TIME 1000
hualing chen2aba4022020-03-02 13:49:55 +080031#define FB_DEFAULT_LEFT_TIME (2000)
hualing chen31140872020-03-25 12:29:26 +080032//if tsplayer delay time < 200 and no data can read, we will pause
33#define MIN_TSPLAYER_DELAY_TIME (200)
34
hualing chena540a7e2020-03-27 16:44:05 +080035static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080036//
37static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chencc91e1c2020-02-28 13:26:17 +080038static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type);
39static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
40static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080041static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080042static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
43
hualing chen6d24aa92020-03-23 18:43:47 +080044static char* _dvr_playback_state_toString(int stat)
45{
46 char *string[DVR_PLAYBACK_STATE_FB+1]={
47 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080048 "stop",
hualing chen31140872020-03-25 12:29:26 +080049 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080050 "ff",
51 "fb"
52 };
53
54 if (stat > DVR_PLAYBACK_STATE_FB) {
55 return "unkown";
56 } else {
57 return string[stat];
58 }
59}
hualing chena540a7e2020-03-27 16:44:05 +080060
61static DVR_Bool_t _dvr_support_speed(int speed) {
62
63 DVR_Bool_t ret = DVR_FALSE;
64
65 switch (speed) {
66 case PLAYBACK_SPEED_FBX2:
67 case PLAYBACK_SPEED_FBX4:
68 case PLAYBACK_SPEED_FBX8:
69 case PLAYBACK_SPEED_S2:
70 case PLAYBACK_SPEED_S4:
71 case PLAYBACK_SPEED_S8:
72 case PLAYBACK_SPEED_X1:
73 case PLAYBACK_SPEED_X2:
74 case PLAYBACK_SPEED_X4:
75 case PLAYBACK_SPEED_X8:
76 case PLAYBACK_SPEED_X3:
77 case PLAYBACK_SPEED_X5:
78 case PLAYBACK_SPEED_X6:
79 case PLAYBACK_SPEED_X7:
80 ret = DVR_TRUE;
81 break;
82 default:
83 DVR_DEBUG(1, "not support speed is set [%d]", speed);
84 break;
85 }
86 return ret;
87}
hualing chen6e4bfa52020-03-13 14:37:11 +080088void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
89{
90 DVR_DEBUG(1, "in callback test ");
91 DVR_Playback_t *player = NULL;
92 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +080093 player = (DVR_Playback_t *) user_data;
94 DVR_DEBUG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +080095 }
96 switch (event->type) {
97 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
98 {
99 DVR_DEBUG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
100 event->event.video_format.frame_width,
101 event->event.video_format.frame_height,
102 event->event.video_format.frame_rate);
103 break;
104 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800105 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
106 {
107 DVR_DEBUG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800108 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800109 break;
110 }
111 default:
112 break;
113 }
114}
hualing chen2aba4022020-03-02 13:49:55 +0800115void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
116{
hualing chen6e4bfa52020-03-13 14:37:11 +0800117 DVR_Playback_t *player = NULL;
118 if (user_data != NULL) {
119 player = (DVR_Playback_t *) user_data;
hualing chen31140872020-03-25 12:29:26 +0800120 DVR_DEBUG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800121 }
hualing chen2aba4022020-03-02 13:49:55 +0800122 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800123 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
124 {
125 DVR_DEBUG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
126 event->event.video_format.frame_width,
127 event->event.video_format.frame_height,
128 event->event.video_format.frame_rate);
129 break;
130 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800131 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
132 {
133 DVR_DEBUG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800134 if (player != NULL)
135 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800136 break;
137 }
138 default:
hualing chen6d24aa92020-03-23 18:43:47 +0800139 DVR_DEBUG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800140 break;
141 }
142 if (player&&player->player_callback_func) {
hualing chen6d24aa92020-03-23 18:43:47 +0800143 DVR_DEBUG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800144 player->player_callback_func(player->player_callback_userdata, event);
145 } else if (player == NULL){
146 DVR_DEBUG(1, "player is null, get userdata error\n");
147 } else {
148 DVR_DEBUG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800149 }
150}
hualing chencc91e1c2020-02-28 13:26:17 +0800151
hualing chen5cbe1a62020-02-10 16:36:36 +0800152//convert video and audio fmt
153static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
154 int format = 0;
155 if (is_audio == DVR_FALSE) {
156 //for video fmt
157 switch (fmt)
158 {
159 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800160 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800161 break;
162 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800163 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800164 break;
165 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800166 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800167 break;
168 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800169 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800170 break;
hualing chena540a7e2020-03-27 16:44:05 +0800171 case DVR_VIDEO_FORMAT_VP9:
172 format = AV_VIDEO_CODEC_VP9;
173 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800174 }
175 } else {
176 //for audio fmt
177 switch (fmt)
178 {
179 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800180 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800181 break;
182 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800183 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800184 break;
185 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800186 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800187 break;
188 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800189 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800190 break;
hualing chena540a7e2020-03-27 16:44:05 +0800191 case DVR_AUDIO_FORMAT_AAC:
192 format = AV_AUDIO_CODEC_AAC;
193 break;
194 case DVR_AUDIO_FORMAT_LATM:
195 format = AV_AUDIO_CODEC_LATM;
196 break;
197 case DVR_AUDIO_FORMAT_PCM:
198 format = AV_AUDIO_CODEC_PCM;
199 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800200 }
201 }
202 return format;
203}
hualing chen040df222020-01-17 13:35:02 +0800204static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800205{
hualing chen040df222020-01-17 13:35:02 +0800206 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800207
hualing chena540a7e2020-03-27 16:44:05 +0800208 if (player == NULL || player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800209 return -1;
210
hualing chena540a7e2020-03-27 16:44:05 +0800211 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800212}
hualing chena540a7e2020-03-27 16:44:05 +0800213
hualing chen5cbe1a62020-02-10 16:36:36 +0800214//get sys time ms
215static int _dvr_time_getClock(void)
216{
217 struct timespec ts;
218 int ms;
219
220 clock_gettime(CLOCK_MONOTONIC, &ts);
221 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
222
223 return ms;
224}
hualing chen86e7d482020-01-16 15:13:33 +0800225
hualing chenb31a6c62020-01-13 17:27:00 +0800226
227//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800228static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800229{
hualing chen040df222020-01-17 13:35:02 +0800230 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800231
hualing chena540a7e2020-03-27 16:44:05 +0800232
233 if (player == NULL) {
234 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
235 return DVR_FAILURE;
236 }
237
hualing chen86e7d482020-01-16 15:13:33 +0800238 struct timespec ts;
239 clock_gettime(CLOCK_MONOTONIC, &ts);
240 //ms为毫秒,换算成秒
241 ts.tv_sec += ms/1000;
242 //在outtime的基础上,增加ms毫秒
243 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
244 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
245 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
246 //us的值有可能超过1秒,
247 ts.tv_sec += us / 1000000;
248 us = us % 1000000;
249 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800250 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
251 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800252}
hualing chen31140872020-03-25 12:29:26 +0800253//get tsplay delay time ms
254static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
255 DVR_Playback_t *player = (DVR_Playback_t *) handle;
256 int64_t cache = 0;
257 if (player == NULL || player->handle == NULL) {
258 DVR_DEBUG(1, "tsplayer delay time error, handle is NULL");
259 return 0;
260 }
261 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chena540a7e2020-03-27 16:44:05 +0800262 DVR_DEBUG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800263 return cache;
264}
hualing chenb31a6c62020-01-13 17:27:00 +0800265//send signal
hualing chen040df222020-01-17 13:35:02 +0800266static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800267{
hualing chen87072a82020-03-12 16:20:12 +0800268 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800269
270 if (player == NULL) {
271 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
272 return DVR_FAILURE;
273 }
274
hualing chen87072a82020-03-12 16:20:12 +0800275 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800276 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800277 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800278 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800279}
280
hualing chencc91e1c2020-02-28 13:26:17 +0800281//send playback event
282static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify) {
283
284 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800285
286 if (player == NULL) {
287 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
288 return DVR_FAILURE;
289 }
290
hualing chencc91e1c2020-02-28 13:26:17 +0800291 switch (evt) {
292 case DVR_PLAYBACK_EVENT_ERROR:
293 break;
294 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
295 //GET STATE
296 DVR_DEBUG(1, "trans ok----");
297 dvr_playback_get_status(handle, &(notify->play_status));
298 break;
299 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
300 break;
301 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
302 break;
303 case DVR_PLAYBACK_EVENT_NO_KEY:
304 break;
305 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800306 //GET STATE
307 DVR_DEBUG(1, "reached begin---");
308 dvr_playback_get_status(handle, &(notify->play_status));
hualing chencc91e1c2020-02-28 13:26:17 +0800309 break;
310 case DVR_PLAYBACK_EVENT_REACHED_END:
311 //GET STATE
312 DVR_DEBUG(1, "reached end---");
313 dvr_playback_get_status(handle, &(notify->play_status));
314 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800315 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
316 //DVR_DEBUG(1, "send playtime---");
317 dvr_playback_get_status(handle, &(notify->play_status));
318 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800319 default:
320 break;
321 }
322 if (player->openParams.event_fn != NULL)
323 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800324 return DVR_SUCCESS;
325}
326static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle)
327{
328 DVR_Play_Notify_t notify;
329 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
330 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
331 //get play statue not here
332 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify);
333 return DVR_SUCCESS;
334}
335
hualing chen6e4bfa52020-03-13 14:37:11 +0800336static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle)
337{
338 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800339
340 if (player == NULL) {
341 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
342 return DVR_FAILURE;
343 }
344
hualing chen6e4bfa52020-03-13 14:37:11 +0800345 if (player->send_time ==0) {
346 player->send_time = _dvr_time_getClock() + 1000;
347 } else if (player->send_time > _dvr_time_getClock()) {
348 return DVR_SUCCESS;
349 }
350 player->send_time = _dvr_time_getClock() + 1000;
351 DVR_Play_Notify_t notify;
352 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
353 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
354 //get play statue not here
355 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify);
356 return DVR_SUCCESS;
357}
358
hualing chencc91e1c2020-02-28 13:26:17 +0800359//check is ongoing segment
360static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
361
362 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800363 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800364
365 if (player == NULL) {
366 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
367 return DVR_FAILURE;
368 }
hualing chen87072a82020-03-12 16:20:12 +0800369 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800370 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800371 return DVR_FALSE;
372 }
hualing chencc91e1c2020-02-28 13:26:17 +0800373 return DVR_TRUE;
374}
hualing chen2aba4022020-03-02 13:49:55 +0800375static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
376 DVR_Playback_t *player = (DVR_Playback_t *) handle;
377 player->fffb_current = -1;
378 player->fffb_start = -1;
379 player->fffb_start_pcr = -1;
380 player->next_fffb_time = _dvr_time_getClock();
381 return DVR_SUCCESS;
382}
hualing chencc91e1c2020-02-28 13:26:17 +0800383//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800384static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
385
386 DVR_Playback_t *player = (DVR_Playback_t *) handle;
387 DVR_PlaybackSegmentInfo_t *segment;
388 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
389
hualing chena540a7e2020-03-27 16:44:05 +0800390 if (player == NULL) {
391 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
392 return DVR_FAILURE;
393 }
394
hualing chen87072a82020-03-12 16:20:12 +0800395 int found = 0;
396 int found_eq_id = 0;
397 list_for_each_entry(segment, &player->segment_list, head)
398 {
399 if (player->segment_is_open == DVR_FALSE) {
400 //get first segment from list, case segment is not open
401 if (!IS_FB(player->speed))
402 found = 1;
403 } else if (segment->segment_id == segmentid) {
404 //find cur segment, we need get next one
405 found_eq_id = 1;
406 if (!IS_FB(player->speed)) {
407 found = 1;
408 continue;
409 } else {
410 //if is fb mode.we need used pre segment
411 if (pre_segment != NULL) {
412 found = 1;
413 } else {
414 //not find next id.
415 DVR_DEBUG(1, "not has find next segment on fb mode");
416 return DVR_FAILURE;
417 }
418 }
419 }
420 if (found == 1) {
421 found = 2;
422 break;
423 }
424 }
425 if (found != 2) {
426 //list is null or reache list end
427 DVR_DEBUG(1, "not found next segment return failure");
428 return DVR_FAILURE;
429 }
430 DVR_DEBUG(1, "found next segment return success");
431 return DVR_SUCCESS;
432}
433
434//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800435static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800436
hualing chen040df222020-01-17 13:35:02 +0800437 DVR_Playback_t *player = (DVR_Playback_t *) handle;
438 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800439 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800440
hualing chena540a7e2020-03-27 16:44:05 +0800441 if (player == NULL) {
442 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
443 return DVR_FAILURE;
444 }
445
hualing chen86e7d482020-01-16 15:13:33 +0800446 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800447 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800448
hualing chen040df222020-01-17 13:35:02 +0800449 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800450 {
hualing chencc91e1c2020-02-28 13:26:17 +0800451 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800452 //get first segment from list, case segment is not open
453 if (!IS_FB(player->speed))
454 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800455 } else if (segment->segment_id == player->cur_segment_id) {
456 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800457 found_eq_id = 1;
458 if (!IS_FB(player->speed)) {
459 found = 1;
460 continue;
461 } else {
462 //if is fb mode.we need used pre segment
463 if (pre_segment != NULL) {
464 found = 1;
465 } else {
466 //not find next id.
467 DVR_DEBUG(1, "not find next segment on fb mode");
468 return DVR_FAILURE;
469 }
470 }
hualing chen86e7d482020-01-16 15:13:33 +0800471 }
472 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800473 if (IS_FB(player->speed)) {
474 //used pre segment
475 segment = pre_segment;
476 }
hualing chencc91e1c2020-02-28 13:26:17 +0800477 //save segment info
478 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800479 player->last_segment.segment_id = player->cur_segment.segment_id;
480 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800481 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
482 //pids
483 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
484
hualing chen5cbe1a62020-02-10 16:36:36 +0800485 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800486 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800487 player->cur_segment_id = segment->segment_id;
488 player->cur_segment.segment_id = segment->segment_id;
489 player->cur_segment.flags = segment->flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800490 DVR_DEBUG(1, "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 +0800491 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800492 //pids
hualing chen040df222020-01-17 13:35:02 +0800493 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800494 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800495 break;
hualing chen86e7d482020-01-16 15:13:33 +0800496 }
hualing chen2aba4022020-03-02 13:49:55 +0800497 pre_segment = segment;
498 }
499 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
500 //used the last one segment to open
501 //get segment info
502 player->segment_is_open = DVR_TRUE;
503 player->cur_segment_id = pre_segment->segment_id;
504 player->cur_segment.segment_id = pre_segment->segment_id;
505 player->cur_segment.flags = pre_segment->flags;
506 DVR_DEBUG(1, "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);
507 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
508 //pids
509 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
510 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800511 }
512 if (found != 2) {
513 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800514 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800515 }
516 return DVR_SUCCESS;
517}
hualing chen040df222020-01-17 13:35:02 +0800518//open next segment to play,if reach list end return errro.
519static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800520{
hualing chen040df222020-01-17 13:35:02 +0800521 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800522 Segment_OpenParams_t params;
523 int ret = DVR_SUCCESS;
524
hualing chena540a7e2020-03-27 16:44:05 +0800525 if (player == NULL) {
526 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
527 return DVR_FAILURE;
528 }
529
530 ret = _dvr_get_next_segmentId(handle);
531 if (ret == DVR_FAILURE) {
hualing chen040df222020-01-17 13:35:02 +0800532 DVR_DEBUG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800533 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800534 }
535
536 if (player->r_handle != NULL) {
537 segment_close(player->r_handle);
538 player->r_handle = NULL;
539 }
540
541 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800542 //cp chur segment path to location
543 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800544 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800545 params.mode = SEGMENT_MODE_READ;
hualing chencc91e1c2020-02-28 13:26:17 +0800546 DVR_DEBUG(1, "open segment info[%s][%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen2aba4022020-03-02 13:49:55 +0800547 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +0800548 ret = segment_open(&params, &(player->r_handle));
hualing chen87072a82020-03-12 16:20:12 +0800549 pthread_mutex_unlock(&player->segment_lock);
550 int total = _dvr_get_end_time( handle);
551 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800552 if (IS_FB(player->speed)) {
553 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen87072a82020-03-12 16:20:12 +0800554 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800555 }
hualing chen87072a82020-03-12 16:20:12 +0800556 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800557 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800558 DVR_DEBUG(1, "next player->dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800559 return ret;
560}
561
hualing chen5cbe1a62020-02-10 16:36:36 +0800562//open next segment to play,if reach list end return errro.
563static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
564{
565 DVR_Playback_t *player = (DVR_Playback_t *) handle;
566 Segment_OpenParams_t params;
567 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800568 if (player == NULL) {
569 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
570 return DVR_FAILURE;
571 }
hualing chencc91e1c2020-02-28 13:26:17 +0800572 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800573 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800574 }
hualing chencc91e1c2020-02-28 13:26:17 +0800575 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800576 if (id < 0) {
577 DVR_DEBUG(1, "not found segment info");
578 return DVR_FAILURE;
579 }
hualing chencc91e1c2020-02-28 13:26:17 +0800580 DVR_DEBUG(1, "start found segment[%lld][%lld] info", id,segment_id);
hualing chen2aba4022020-03-02 13:49:55 +0800581 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800582
583 DVR_PlaybackSegmentInfo_t *segment;
584
585 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800586
hualing chen5cbe1a62020-02-10 16:36:36 +0800587 list_for_each_entry(segment, &player->segment_list, head)
588 {
hualing chencc91e1c2020-02-28 13:26:17 +0800589 DVR_DEBUG(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 +0800590 if (segment->segment_id == segment_id) {
591 found = 1;
592 }
593 if (found == 1) {
hualing chencc91e1c2020-02-28 13:26:17 +0800594 DVR_DEBUG(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 +0800595 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800596 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800597 player->cur_segment_id = segment->segment_id;
598 player->cur_segment.segment_id = segment->segment_id;
599 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800600 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800601 //pids
602 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +0800603 DVR_DEBUG(1, "cur found location [%s]id[%lld]flag[%x]", player->cur_segment.location, player->cur_segment.segment_id,player->cur_segment.flags);
604 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800605 }
606 }
hualing chencc91e1c2020-02-28 13:26:17 +0800607 if (found == 0) {
608 DVR_DEBUG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800609 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800610 return DVR_FAILURE;
611 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800612 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800613 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800614 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800615 params.segment_id = (uint64_t)player->cur_segment.segment_id;
616 params.mode = SEGMENT_MODE_READ;
hualing chencc91e1c2020-02-28 13:26:17 +0800617 DVR_DEBUG(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 +0800618 if (player->r_handle != NULL) {
619 segment_close(player->r_handle);
620 player->r_handle = NULL;
621 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800622 ret = segment_open(&params, &(player->r_handle));
hualing chen2aba4022020-03-02 13:49:55 +0800623 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800624 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800625
626 DVR_DEBUG(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 +0800627 return ret;
628}
629
630
631//get play info by segment id
632static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
633 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800634 am_tsplayer_video_params *vparam,
635 am_tsplayer_audio_params *aparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800636
637 DVR_Playback_t *player = (DVR_Playback_t *) handle;
638 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800639 if (player == NULL) {
640 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
641 return DVR_FAILURE;
642 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800643
644 int found = 0;
645
646 list_for_each_entry(segment, &player->segment_list, head)
647 {
hualing chen87072a82020-03-12 16:20:12 +0800648 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800649 //get first segment from list
650 found = 1;
651 }
652 if (segment->segment_id == segment_id) {
653 found = 1;
654 }
655 if (found == 1) {
656 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800657 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800658 player->cur_segment_id = segment->segment_id;
659 DVR_DEBUG(1, "get play info id [%lld]", player->cur_segment_id);
660 player->cur_segment.segment_id = segment->segment_id;
661 player->cur_segment.flags = segment->flags;
662 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800663 player->cur_segment.pids.video.pid = segment->pids.video.pid;
664 player->cur_segment.pids.video.format = segment->pids.video.format;
665 player->cur_segment.pids.video.type = segment->pids.video.type;
666 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
667 player->cur_segment.pids.audio.format = segment->pids.audio.format;
668 player->cur_segment.pids.audio.type = segment->pids.audio.type;
669 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
670 player->cur_segment.pids.ad.format = segment->pids.ad.format;
671 player->cur_segment.pids.ad.type = segment->pids.ad.type;
672 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800673 //
hualing chen2aba4022020-03-02 13:49:55 +0800674 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800675 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800676 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800677 aparam->pid = segment->pids.audio.pid;
hualing chena540a7e2020-03-27 16:44:05 +0800678 DVR_DEBUG(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 +0800679 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800680 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800681 }
682 }
hualing chencc91e1c2020-02-28 13:26:17 +0800683 if (found != 2) {
684 //list is null or reache list end
685 DVR_DEBUG(1, "get play info fail");
686 return DVR_FAILURE;
687 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800688
689 return DVR_SUCCESS;
690}
hualing chencc91e1c2020-02-28 13:26:17 +0800691static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
692 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800693 if (player == NULL) {
694 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
695 return DVR_FAILURE;
696 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800697
hualing chencc91e1c2020-02-28 13:26:17 +0800698 //compare cur segment
699 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
700 {
701 //check video pids, stop or restart
702 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
703 //check audio pids stop or restart
704 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
705 //check sub audio pids stop or restart
706 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
707 //check pcr pids stop or restart
708 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
709 }
hualing chena540a7e2020-03-27 16:44:05 +0800710 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800711}
hualing chen5cbe1a62020-02-10 16:36:36 +0800712
hualing chencc91e1c2020-02-28 13:26:17 +0800713static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
714{
715 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800716 if (player == NULL) {
717 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
718 return DVR_FAILURE;
719 }
720 DVR_DEBUG(1, "call %s flag[0x%x]id[%lld]last[0x%x][%llu]", __func__, 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 +0800721 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
722 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800723 //enable display
hualing chen2aba4022020-03-02 13:49:55 +0800724 DVR_DEBUG(1, "call %s unmute", __func__);
725 AmTsPlayer_showVideo(player->handle);
726 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800727 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
728 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800729 //disable display
hualing chencc91e1c2020-02-28 13:26:17 +0800730 DVR_DEBUG(1, "call %s mute", __func__);
hualing chen2aba4022020-03-02 13:49:55 +0800731 AmTsPlayer_hideVideo(player->handle);
732 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800733 }
734 return DVR_SUCCESS;
735}
hualing chena540a7e2020-03-27 16:44:05 +0800736static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
737 DVR_Playback_t *player = (DVR_Playback_t *) handle;
738 if (player == NULL) {
739 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
740 return DVR_TRUE;
741 }
742 if (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
743 if (player->first_frame == 1) {
744 return DVR_TRUE;
745 } else {
746 return DVR_FALSE;
747 }
748 } else {
749 return DVR_TRUE;
750 }
751}
hualing chen86e7d482020-01-16 15:13:33 +0800752static void* _dvr_playback_thread(void *arg)
753{
hualing chen040df222020-01-17 13:35:02 +0800754 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800755 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800756 am_tsplayer_input_buffer wbufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800757 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800758
hualing chen6d24aa92020-03-23 18:43:47 +0800759 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800760 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800761 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800762 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen86e7d482020-01-16 15:13:33 +0800763 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800764 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800765
hualing chen86e7d482020-01-16 15:13:33 +0800766 buf = malloc(buf_len);
hualing chen2aba4022020-03-02 13:49:55 +0800767 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
768 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800769
770 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800771 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
772 }
hualing chen86e7d482020-01-16 15:13:33 +0800773
hualing chen86e7d482020-01-16 15:13:33 +0800774 if (ret != DVR_SUCCESS) {
775 if (buf != NULL) {
776 free(buf);
777 buf = NULL;
778 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800779 DVR_DEBUG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800780 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800781 }
hualing chencc91e1c2020-02-28 13:26:17 +0800782 //get play statue not here
783 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
784 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800785 //set video show
786 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800787
hualing chen86e7d482020-01-16 15:13:33 +0800788 int trick_stat = 0;
789 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800790
hualing chen86e7d482020-01-16 15:13:33 +0800791 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800792 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800793
hualing chen2aba4022020-03-02 13:49:55 +0800794 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
795 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800796 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800797 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen31140872020-03-25 12:29:26 +0800798 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800799 {
hualing chen2aba4022020-03-02 13:49:55 +0800800 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
801 if (trick_stat > 0) {
802 DVR_DEBUG(1, "trick stat[%d] is > 0", trick_stat);
hualing chen87072a82020-03-12 16:20:12 +0800803 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 +0800804 //check last cmd
805 if(player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800806 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800807 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
808 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800809 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
810 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
811 DVR_DEBUG(1, "pause play-------");
812 //need change to pause state
813 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
814 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800815 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800816 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800817 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800818 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800819 AmTsPlayer_pauseVideoDecoding(player->handle);
820 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +0800821 }
822 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
823 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800824 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800825 //restart play stream if speed > 2
826 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
827 _dvr_time_getClock() < player->next_fffb_time) {
hualing chena540a7e2020-03-27 16:44:05 +0800828 DVR_DEBUG(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 +0800829 //used timeout wait need lock first,so we unlock and lock
830 //pthread_mutex_unlock(&player->lock);
831 //pthread_mutex_lock(&player->lock);
832 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
833 pthread_mutex_unlock(&player->lock);
834 continue;
835 }
hualing chen31140872020-03-25 12:29:26 +0800836 DVR_DEBUG(1, "fffb play-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
hualing chen2aba4022020-03-02 13:49:55 +0800837 pthread_mutex_unlock(&player->lock);
838 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800839 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800840 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
841 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800842 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
843 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800844 }
hualing chen2aba4022020-03-02 13:49:55 +0800845 }
hualing chenb31a6c62020-01-13 17:27:00 +0800846 }
hualing chen86e7d482020-01-16 15:13:33 +0800847
hualing chen87072a82020-03-12 16:20:12 +0800848 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800849 //check is need send time send end
850 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800851 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
852 pthread_mutex_unlock(&player->lock);
853 continue;
854 }
hualing chen2aba4022020-03-02 13:49:55 +0800855 if (goto_rewrite == DVR_TRUE) {
856 goto_rewrite = DVR_FALSE;
857 pthread_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +0800858 //DVR_DEBUG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +0800859 goto rewrite;
860 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800861 //.check is need send time send end
862 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800863
864 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
865 pthread_mutex_unlock(&player->lock);
866 //if on fb mode and read file end , we need calculate pos to retry read.
867 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chena540a7e2020-03-27 16:44:05 +0800868 DVR_DEBUG(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 +0800869 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
870 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +0800871 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
872 pthread_mutex_unlock(&player->lock);
873 continue;
874 }
hualing chen31140872020-03-25 12:29:26 +0800875 //DVR_DEBUG(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 +0800876 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +0800877 //file end.need to play next segment
hualing chen040df222020-01-17 13:35:02 +0800878 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +0800879 //init fffb time if change segment
880 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +0800881
882 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chena540a7e2020-03-27 16:44:05 +0800883 if (ret != DVR_SUCCESS && delay <= MIN_TSPLAYER_DELAY_TIME && _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) {
884 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +0800885 DVR_Play_Notify_t notify;
886 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
887 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
888 //get play statue not here
889 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen31140872020-03-25 12:29:26 +0800890 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify);
891 //continue,timeshift mode, when read end,need wait cur recording segment
892 DVR_DEBUG(1, "playback is send end");
893 pthread_mutex_lock(&player->lock);
894 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
895 pthread_mutex_unlock(&player->lock);
896 continue;
hualing chena540a7e2020-03-27 16:44:05 +0800897 } else if (ret != DVR_SUCCESS) {
898 //not send event and pause,sleep and go to next time to recheck
hualing chen31140872020-03-25 12:29:26 +0800899 pthread_mutex_lock(&player->lock);
900 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
901 pthread_mutex_unlock(&player->lock);
902 continue;
hualing chen86e7d482020-01-16 15:13:33 +0800903 }
hualing chen31140872020-03-25 12:29:26 +0800904 //change next segment success case
hualing chencc91e1c2020-02-28 13:26:17 +0800905 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
906 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +0800907 DVR_DEBUG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +0800908 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
hualing chena540a7e2020-03-27 16:44:05 +0800909 DVR_DEBUG(1, "_dvr_replay_changed_pid:end");
hualing chencc91e1c2020-02-28 13:26:17 +0800910 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +0800911 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +0800912 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800913 }
914 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +0800915 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +0800916 wbufs.buf_data = buf;
hualing chen31140872020-03-25 12:29:26 +0800917rewrite:
hualing chen86e7d482020-01-16 15:13:33 +0800918 //read data
919 //descramble data
920 //read data to inject
hualing chena540a7e2020-03-27 16:44:05 +0800921 //check read data len,iflen < 0, we need continue
922 if (wbufs.buf_size == 0 || wbufs.buf_data == NULL) {
923 DVR_DEBUG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +0800924 real_read = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +0800925 continue;
hualing chena540a7e2020-03-27 16:44:05 +0800926 }
927 if ( AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms) == AM_TSPLAYER_OK) {
928 real_read = 0;
929 write_success++;
930 continue;
hualing chen87072a82020-03-12 16:20:12 +0800931 } else {
hualing chena540a7e2020-03-27 16:44:05 +0800932 DVR_DEBUG(1, "write time out write_success:%d", write_success);
933 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800934 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +0800935 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +0800936 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800937 if (!player->is_running) {
hualing chen2aba4022020-03-02 13:49:55 +0800938 DVR_DEBUG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +0800939 break;
940 }
hualing chen2aba4022020-03-02 13:49:55 +0800941 goto_rewrite = DVR_TRUE;
942 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +0800943 }
944 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800945 DVR_DEBUG(1, "playback thread is end");
hualing chen86e7d482020-01-16 15:13:33 +0800946 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +0800947}
948
949
hualing chen040df222020-01-17 13:35:02 +0800950static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800951{
hualing chen040df222020-01-17 13:35:02 +0800952 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +0800953 DVR_DEBUG(1, "start thread------[%d]", player->is_running);
hualing chena540a7e2020-03-27 16:44:05 +0800954
955 if (player == NULL) {
956 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
957 return DVR_FAILURE;
958 }
959
hualing chencc91e1c2020-02-28 13:26:17 +0800960 if (player->is_running == DVR_TRUE) {
hualing chen86e7d482020-01-16 15:13:33 +0800961 return 0;
962 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800963 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +0800964 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +0800965 if (rc < 0)
966 player->is_running = DVR_FALSE;
hualing chencc91e1c2020-02-28 13:26:17 +0800967 DVR_DEBUG(1, "start thread------[%d] end", player->is_running);
hualing chen86e7d482020-01-16 15:13:33 +0800968 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800969}
970
971
hualing chen040df222020-01-17 13:35:02 +0800972static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800973{
hualing chen040df222020-01-17 13:35:02 +0800974 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800975
976 if (player == NULL) {
977 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
978 return DVR_FAILURE;
979 }
980
hualing chencc91e1c2020-02-28 13:26:17 +0800981 DVR_DEBUG(1, "stopthread------[%d]", player->is_running);
982 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +0800983 {
984 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800985 _dvr_playback_sendSignal(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800986 //pthread_cond_signal(&player->cond);
hualing chen86e7d482020-01-16 15:13:33 +0800987 pthread_join(player->playback_thread, NULL);
988 }
989 if (player->r_handle) {
990 segment_close(player->r_handle);
991 player->r_handle = NULL;
992 }
hualing chen87072a82020-03-12 16:20:12 +0800993 DVR_DEBUG(1, "stopthread------[%d]", player->is_running);
hualing chen86e7d482020-01-16 15:13:33 +0800994 return 0;
995}
996
hualing chenb31a6c62020-01-13 17:27:00 +0800997/**\brief Open an dvr palyback
998 * \param[out] p_handle dvr playback addr
999 * \param[in] params dvr playback open parameters
1000 * \retval DVR_SUCCESS On success
1001 * \return Error code
1002 */
hualing chen040df222020-01-17 13:35:02 +08001003int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001004
hualing chen040df222020-01-17 13:35:02 +08001005 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001006 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001007
hualing chen040df222020-01-17 13:35:02 +08001008 player = (DVR_Playback_t*)malloc(sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001009
hualing chen86e7d482020-01-16 15:13:33 +08001010 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001011 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001012 pthread_condattr_init(&cattr);
1013 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1014 pthread_cond_init(&player->cond, &cattr);
1015 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001016
hualing chen5cbe1a62020-02-10 16:36:36 +08001017 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001018 INIT_LIST_HEAD(&player->segment_list);
1019 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1020 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001021 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001022 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001023 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001024 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001025 player->speed = 1.0f;
hualing chen2aba4022020-03-02 13:49:55 +08001026
hualing chen86e7d482020-01-16 15:13:33 +08001027 //store open params
hualing chen040df222020-01-17 13:35:02 +08001028 player->openParams.dmx_dev_id = params->dmx_dev_id;
1029 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001030 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001031 player->openParams.event_fn = params->event_fn;
1032 player->openParams.event_userdata = params->event_userdata;
1033
hualing chen5cbe1a62020-02-10 16:36:36 +08001034 player->has_pids = params->has_pids;
1035
hualing chen2aba4022020-03-02 13:49:55 +08001036 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001037
1038 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1039 //for test get callback
1040 if (0 && player->player_callback_func == NULL) {
1041 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1042 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1043 DVR_DEBUG(1, "playback open get callback[%p][%p][%p][%p]",player->player_callback_func, player->player_callback_userdata, _dvr_tsplayer_callback_test,player);
1044 }
1045 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001046
hualing chen86e7d482020-01-16 15:13:33 +08001047 //init has audio and video
1048 player->has_video = DVR_FALSE;
1049 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001050 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001051 player->last_segment_id = 0LL;
1052 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001053
hualing chen5cbe1a62020-02-10 16:36:36 +08001054 //init ff fb time
1055 player->fffb_current = -1;
1056 player->fffb_start =-1;
1057 player->fffb_start_pcr = -1;
1058 //seek time
1059 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001060 player->send_time = 0;
hualing chen86e7d482020-01-16 15:13:33 +08001061 *p_handle = player;
1062 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001063}
1064
1065/**\brief Close an dvr palyback
1066 * \param[in] handle playback handle
1067 * \retval DVR_SUCCESS On success
1068 * \return Error code
1069 */
hualing chen040df222020-01-17 13:35:02 +08001070int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001071
hualing chen86e7d482020-01-16 15:13:33 +08001072 DVR_ASSERT(handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001073
hualing chen040df222020-01-17 13:35:02 +08001074 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +08001075 DVR_DEBUG(1, "func: %s, will resume", __func__);
hualing chena540a7e2020-03-27 16:44:05 +08001076
1077 if (player == NULL) {
1078 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1079 return DVR_FAILURE;
1080 }
1081
hualing chencc91e1c2020-02-28 13:26:17 +08001082 if (player->state != DVR_PLAYBACK_STATE_STOP)
1083 {
1084 dvr_playback_stop(handle, DVR_TRUE);
1085 }
hualing chena540a7e2020-03-27 16:44:05 +08001086 //AmTsPlayer_resumeVideoDecoding(player->handle);
1087 //AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001088 pthread_mutex_destroy(&player->lock);
1089 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001090
1091 if (player) {
1092 free(player);
1093 player = NULL;
1094 }
hualing chen86e7d482020-01-16 15:13:33 +08001095 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001096}
1097
hualing chenb31a6c62020-01-13 17:27:00 +08001098/**\brief Start play audio and video, used start auido api and start video api
1099 * \param[in] handle playback handle
1100 * \param[in] params audio playback params,contains fmt and pid...
1101 * \retval DVR_SUCCESS On success
1102 * \return Error code
1103 */
hualing chen040df222020-01-17 13:35:02 +08001104int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1105 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001106 am_tsplayer_video_params vparams;
1107 am_tsplayer_audio_params aparams;
hualing chena540a7e2020-03-27 16:44:05 +08001108
1109 if (player == NULL) {
1110 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1111 return DVR_FAILURE;
1112 }
hualing chencc91e1c2020-02-28 13:26:17 +08001113 uint64_t segment_id = player->cur_segment_id;
1114 DVR_DEBUG(1, "[%s][%p]segment_id:[%lld]",__func__, handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001115
hualing chena540a7e2020-03-27 16:44:05 +08001116 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001117 //can used start api to resume playback
1118 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1119 return dvr_playback_resume(handle);
1120 }
hualing chen87072a82020-03-12 16:20:12 +08001121 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
1122 DVR_DEBUG(1, "stat is start, not need into start play");
1123 return DVR_SUCCESS;
1124 }
hualing chen86e7d482020-01-16 15:13:33 +08001125 player->play_flag = flag;
hualing chen5cbe1a62020-02-10 16:36:36 +08001126 //get segment info and audio video pid fmt ;
hualing chen31140872020-03-25 12:29:26 +08001127 DVR_DEBUG(1, "lock func: %s %p flag:0x%x", __func__, handle, flag);
hualing chen86e7d482020-01-16 15:13:33 +08001128 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001129 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001130 //start audio and video
1131 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1132 //audio abnd video pis is all invalid, return error.
1133 DVR_DEBUG(0, "dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001134 DVR_DEBUG(1, "unlock func: %s", __func__);
1135 pthread_mutex_unlock(&player->lock);
1136 DVR_Play_Notify_t notify;
1137 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1138 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1139 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1140 notify.info.transition_failed_data.segment_id = segment_id;
1141 //get play statue not here
1142 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify);
hualing chen86e7d482020-01-16 15:13:33 +08001143 return -1;
1144 }
hualing chen31140872020-03-25 12:29:26 +08001145
hualing chencc91e1c2020-02-28 13:26:17 +08001146 {
hualing chen86e7d482020-01-16 15:13:33 +08001147 if (VALID_PID(vparams.pid)) {
1148 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001149 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001150 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1151 DVR_DEBUG(1, "set trick mode -pauselive flag--");
1152 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1153 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001154 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen31140872020-03-25 12:29:26 +08001155 DVR_DEBUG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001156 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001157 } else {
1158 DVR_DEBUG(1, "set trick mode ---none");
1159 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001160 }
1161 AmTsPlayer_setVideoParams(player->handle, &vparams);
1162 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001163 }
hualing chena540a7e2020-03-27 16:44:05 +08001164
hualing chen6d24aa92020-03-23 18:43:47 +08001165 DVR_DEBUG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
hualing chencc91e1c2020-02-28 13:26:17 +08001166 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1167 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1168 player->cmd.state = DVR_PLAYBACK_STATE_START;
1169 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001170 } else {
1171 player->cmd.last_cmd = player->cmd.cur_cmd;
1172 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001173 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001174 //set fast play
1175 DVR_DEBUG(1, "dvr start fast mode");
1176 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001177 } else {
1178 if (VALID_PID(aparams.pid)) {
1179 DVR_DEBUG(1, "%s :start audio---", __func__);
1180 player->has_audio = DVR_TRUE;
1181 AmTsPlayer_setAudioParams(player->handle, &aparams);
1182 AmTsPlayer_startAudioDecoding(player->handle);
1183 }
hualing chen31140872020-03-25 12:29:26 +08001184 }
hualing chencc91e1c2020-02-28 13:26:17 +08001185 player->cmd.state = DVR_PLAYBACK_STATE_START;
1186 player->state = DVR_PLAYBACK_STATE_START;
1187 }
hualing chen86e7d482020-01-16 15:13:33 +08001188 }
hualing chencc91e1c2020-02-28 13:26:17 +08001189 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001190 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001191 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001192 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001193}
hualing chen040df222020-01-17 13:35:02 +08001194/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001195 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001196 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001197 * \retval DVR_SUCCESS On success
1198 * \return Error code
1199 */
hualing chen040df222020-01-17 13:35:02 +08001200int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1201 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001202 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001203
hualing chena540a7e2020-03-27 16:44:05 +08001204 if (player == NULL) {
1205 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1206 return DVR_FAILURE;
1207 }
1208
hualing chencc91e1c2020-02-28 13:26:17 +08001209 DVR_DEBUG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001210 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001211
hualing chen040df222020-01-17 13:35:02 +08001212 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1213 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001214
hualing chen86e7d482020-01-16 15:13:33 +08001215 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001216 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001217 //cp location
hualing chen040df222020-01-17 13:35:02 +08001218 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001219
1220 DVR_DEBUG(1, "add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001221 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001222
1223 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001224 segment->pids.video.pid = info->pids.video.pid;
1225 segment->pids.video.format = info->pids.video.format;
1226 segment->pids.video.type = info->pids.video.type;
1227
hualing chen2aba4022020-03-02 13:49:55 +08001228 segment->pids.audio.pid = info->pids.audio.pid;
1229 segment->pids.audio.format = info->pids.audio.format;
1230 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001231
hualing chen2aba4022020-03-02 13:49:55 +08001232 segment->pids.ad.pid = info->pids.ad.pid;
1233 segment->pids.ad.format = info->pids.ad.format;
1234 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001235
1236 segment->pids.pcr.pid = info->pids.pcr.pid;
1237
1238 DVR_DEBUG(1, "lock func: %s pid [0x%x][0x%x][0x%x][0x%x]", __func__,segment->pids.video.pid,segment->pids.audio.pid, info->pids.video.pid,info->pids.audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001239 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001240 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001241 pthread_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001242 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chenb31a6c62020-01-13 17:27:00 +08001243
hualing chen5cbe1a62020-02-10 16:36:36 +08001244 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001245}
hualing chen040df222020-01-17 13:35:02 +08001246/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001247 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001248 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001249 * \retval DVR_SUCCESS On success
1250 * \return Error code
1251 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001252int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001253 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen5cbe1a62020-02-10 16:36:36 +08001254 DVR_DEBUG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001255
1256 if (player == NULL) {
1257 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1258 return DVR_FAILURE;
1259 }
1260
hualing chencc91e1c2020-02-28 13:26:17 +08001261 if (segment_id == player->cur_segment_id) {
1262 DVR_DEBUG(1, "not suport remove curren segment id: %lld", segment_id);
1263 return DVR_FAILURE;
1264 }
1265 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001266 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001267 DVR_PlaybackSegmentInfo_t *segment = NULL;
1268 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1269 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001270 {
hualing chen040df222020-01-17 13:35:02 +08001271 if (segment->segment_id == segment_id) {
1272 list_del(&segment->head);
1273 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001274 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001275 }
hualing chen86e7d482020-01-16 15:13:33 +08001276 }
hualing chencc91e1c2020-02-28 13:26:17 +08001277 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001278 pthread_mutex_unlock(&player->lock);
1279
1280 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001281}
hualing chen040df222020-01-17 13:35:02 +08001282/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001283 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001284 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001285 * \retval DVR_SUCCESS On success
1286 * \return Error code
1287 */
hualing chen040df222020-01-17 13:35:02 +08001288int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001289 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001290 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen5cbe1a62020-02-10 16:36:36 +08001291 DVR_DEBUG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chenb31a6c62020-01-13 17:27:00 +08001292
hualing chena540a7e2020-03-27 16:44:05 +08001293 if (player == NULL) {
1294 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1295 return DVR_FAILURE;
1296 }
1297
hualing chen040df222020-01-17 13:35:02 +08001298 DVR_PlaybackSegmentInfo_t *segment;
hualing chencc91e1c2020-02-28 13:26:17 +08001299 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001300 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001301 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001302 {
hualing chen040df222020-01-17 13:35:02 +08001303 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001304 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001305 }
hualing chen86e7d482020-01-16 15:13:33 +08001306 // if encramble to free, only set flag and return;
1307
1308 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001309 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001310 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1311 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001312 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001313 AmTsPlayer_hideVideo(player->handle);
1314 AmTsPlayer_setAudioMute(player->handle, 1, 1);
1315 //playback_device_mute_audio(player->handle, 1);
1316 //playback_device_mute_video(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001317 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1318 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001319 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001320 AmTsPlayer_showVideo(player->handle);
1321 AmTsPlayer_setAudioMute(player->handle, 0, 0);
1322 //playback_device_mute_audio(player->handle, 0);
1323 //playback_device_mute_video(player->handle, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001324 } else {
1325 //do nothing
1326 }
1327 } else {
1328 //do nothing
1329 }
1330 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001331 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001332 }
hualing chencc91e1c2020-02-28 13:26:17 +08001333 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001334 pthread_mutex_unlock(&player->lock);
1335 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001336}
1337
1338
hualing chen5cbe1a62020-02-10 16:36:36 +08001339static 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 +08001340 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001341 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001342
hualing chena540a7e2020-03-27 16:44:05 +08001343 if (player == NULL) {
1344 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1345 return DVR_FAILURE;
1346 }
1347
hualing chen86e7d482020-01-16 15:13:33 +08001348 if (now_pid.pid == set_pid.pid) {
1349 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001350 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001351 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001352 if (VALID_PID(now_pid.pid)) {
1353 //stop now stream
1354 if (type == 0) {
1355 //stop vieo
hualing chena540a7e2020-03-27 16:44:05 +08001356 DVR_DEBUG(1, "[%s]stop video",__func__);
hualing chen2aba4022020-03-02 13:49:55 +08001357 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001358 player->has_video = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001359 } else if (type == 1) {
1360 //stop audio
hualing chena540a7e2020-03-27 16:44:05 +08001361 DVR_DEBUG(1, "[%s]stop audio",__func__);
hualing chen2aba4022020-03-02 13:49:55 +08001362 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001363 player->has_audio = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001364 } else if (type == 2) {
1365 //stop sub audio
hualing chena540a7e2020-03-27 16:44:05 +08001366 DVR_DEBUG(1, "[%s]stop ad",__func__);
1367 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001368 } else if (type == 3) {
1369 //pcr
1370 }
1371 }
1372 if (VALID_PID(set_pid.pid)) {
1373 //start
1374 if (type == 0) {
1375 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001376 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001377 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001378 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001379 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001380 DVR_DEBUG(1, "[%s]start video pid[%d]fmt[%d]",__func__,vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001381 AmTsPlayer_setVideoParams(player->handle, &vparams);
1382 AmTsPlayer_startVideoDecoding(player->handle);
1383 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001384 } else if (type == 1) {
1385 //start audio
hualing chen2aba4022020-03-02 13:49:55 +08001386 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001387 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001388 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001389 player->has_audio = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001390 DVR_DEBUG(1, "[%s]start audio pid[%d]fmt[%d]",__func__,aparams.pid, aparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001391 AmTsPlayer_setAudioParams(player->handle, &aparams);
1392 AmTsPlayer_startAudioDecoding(player->handle);
1393 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001394 } else if (type == 2) {
hualing chen2aba4022020-03-02 13:49:55 +08001395 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001396 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001397 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001398 player->has_audio = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001399 DVR_DEBUG(1, "[%s]start ad audio pid[%d]fmt[%d]",__func__,aparams.pid, aparams.codectype);
1400 AmTsPlayer_setADParams(player->handle, &aparams);
1401 AmTsPlayer_enableADMix(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001402 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001403 } else if (type == 3) {
1404 //pcr
hualing chena540a7e2020-03-27 16:44:05 +08001405 DVR_DEBUG(1, "[%s]start set pcr [%d]",__func__, set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001406 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001407 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001408 //audio and video all close
1409 if (!player->has_audio && !player->has_video) {
1410 player->state = DVR_PLAYBACK_STATE_STOP;
1411 }
hualing chen86e7d482020-01-16 15:13:33 +08001412 }
1413 }
1414 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001415}
hualing chen5cbe1a62020-02-10 16:36:36 +08001416/**\brief dvr play back update segment pids
1417 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001418 * add pid stream and stop remove pid stream.
1419 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001420 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001421 * \retval DVR_SUCCESS On success
1422 * \return Error code
1423 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001424int 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 +08001425 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001426 DVR_DEBUG(1, "update segment id: %lld", segment_id);
1427 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001428
hualing chena540a7e2020-03-27 16:44:05 +08001429 if (player == NULL) {
1430 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1431 return DVR_FAILURE;
1432 }
1433
hualing chen040df222020-01-17 13:35:02 +08001434 DVR_PlaybackSegmentInfo_t *segment;
hualing chencc91e1c2020-02-28 13:26:17 +08001435 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001436 pthread_mutex_lock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001437 DVR_DEBUG(1, "get lock [%p] update segment id: %lld cur id %lld",handle, segment_id, player->cur_segment_id);
1438
hualing chen040df222020-01-17 13:35:02 +08001439 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001440 {
hualing chen040df222020-01-17 13:35:02 +08001441 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001442
1443 if (player->cur_segment_id == segment_id) {
1444 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1445 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1446 //do nothing when ff fb
1447 DVR_DEBUG(1, "now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001448 DVR_DEBUG(1, "unlock func: %s", __func__);
1449 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001450 return 0;
1451 }
1452
1453 //if segment is on going segment,we need stop start stream
1454 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001455 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001456 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001457 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001458 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001459 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001460 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001461 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001462 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001463 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1464 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001465 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1466 //if state is pause, we need process at resume api. we only record change info
1467 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1468 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1469 if (VALID_PID(segment->pids.video.pid)
1470 && VALID_PID(p_pids->video.pid)
1471 && segment->pids.video.pid != p_pids->video.pid) {
1472 //restart video
1473 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1474 }
1475 if (!VALID_PID(segment->pids.video.pid)
1476 && VALID_PID(p_pids->video.pid)
1477 && segment->pids.video.pid != p_pids->video.pid) {
1478 //start video
1479 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1480 }
1481 if (VALID_PID(segment->pids.video.pid)
1482 && !VALID_PID(p_pids->video.pid)
1483 && segment->pids.video.pid != p_pids->video.pid) {
1484 //stop video
1485 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1486 }
1487 if (VALID_PID(segment->pids.audio.pid)
1488 && VALID_PID(p_pids->audio.pid)
1489 && segment->pids.audio.pid != p_pids->audio.pid) {
1490 //restart audio
1491 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1492 }
1493 if (!VALID_PID(segment->pids.audio.pid)
1494 && VALID_PID(p_pids->audio.pid)
1495 && segment->pids.audio.pid != p_pids->audio.pid) {
1496 //start audio
1497 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1498 }
1499 if (VALID_PID(segment->pids.audio.pid)
1500 && !VALID_PID(p_pids->audio.pid)
1501 && segment->pids.audio.pid != p_pids->audio.pid) {
1502 //stop audio
1503 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1504 }
1505 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1506 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1507 //do nothing
1508 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1509 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1510 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1511 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1512 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1513 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1514 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1515 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1516 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1517 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1518 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1519 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1520 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1521 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1522 } else {
1523 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1524 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1525 }
1526
1527 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1528 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1529 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1530 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1531 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1532 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1533 //not occur this case
1534 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1535 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1536 } else {
1537 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1538 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1539 }
1540
1541 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1542 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1543 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1544 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1545 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1546 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1547 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1548 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1549 } else {
1550 //not occur this case
1551 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1552 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1553 }
1554 }
1555 }
1556 }
hualing chen86e7d482020-01-16 15:13:33 +08001557 //save pids info
hualing chen040df222020-01-17 13:35:02 +08001558 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +08001559 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001560 }
hualing chen86e7d482020-01-16 15:13:33 +08001561 }
hualing chencc91e1c2020-02-28 13:26:17 +08001562 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001563 pthread_mutex_unlock(&player->lock);
1564 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001565}
1566/**\brief Stop play, will stop video and audio
1567 * \param[in] handle playback handle
1568 * \param[in] clear is clear last frame
1569 * \retval DVR_SUCCESS On success
1570 * \return Error code
1571 */
hualing chen040df222020-01-17 13:35:02 +08001572int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1573 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001574
1575 if (player == NULL) {
1576 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1577 return DVR_FAILURE;
1578 }
1579
hualing chencc91e1c2020-02-28 13:26:17 +08001580 DVR_DEBUG(1, "---into-stop-----");
1581 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen87072a82020-03-12 16:20:12 +08001582 _stop_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001583 pthread_mutex_lock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001584 DVR_DEBUG(1, "---into-stop---1--");
hualing chen31140872020-03-25 12:29:26 +08001585 AmTsPlayer_stopFast(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001586 AmTsPlayer_resumeVideoDecoding(player->handle);
1587 AmTsPlayer_resumeAudioDecoding(player->handle);
1588 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001589 AmTsPlayer_stopVideoDecoding(player->handle);
1590 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001591 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001592 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1593 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1594 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001595 player->cur_segment_id = UINT64_MAX;
1596 player->segment_is_open = DVR_FALSE;
hualing chencc91e1c2020-02-28 13:26:17 +08001597 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001598 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001599 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001600}
1601/**\brief Start play audio
1602 * \param[in] handle playback handle
1603 * \param[in] params audio playback params,contains fmt and pid...
1604 * \retval DVR_SUCCESS On success
1605 * \return Error code
1606 */
hualing chen2aba4022020-03-02 13:49:55 +08001607
1608int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001609 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001610
1611 if (player == NULL) {
1612 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1613 return DVR_FAILURE;
1614 }
1615
hualing chencc91e1c2020-02-28 13:26:17 +08001616 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chen86e7d482020-01-16 15:13:33 +08001617 _start_playback_thread(handle);
1618 //start audio and video
hualing chencc91e1c2020-02-28 13:26:17 +08001619 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001620 pthread_mutex_lock(&player->lock);
1621 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001622 AmTsPlayer_setAudioParams(player->handle, param);
1623 AmTsPlayer_startAudioDecoding(player->handle);
1624 //playback_device_audio_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001625 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001626 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1627 player->cmd.state = DVR_PLAYBACK_STATE_START;
1628 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001629 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001630 pthread_mutex_unlock(&player->lock);
1631 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001632}
1633/**\brief Stop play audio
1634 * \param[in] handle playback handle
1635 * \retval DVR_SUCCESS On success
1636 * \return Error code
1637 */
hualing chen040df222020-01-17 13:35:02 +08001638int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1639 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001640
1641 if (player == NULL) {
1642 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1643 return DVR_FAILURE;
1644 }
1645
hualing chencc91e1c2020-02-28 13:26:17 +08001646 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001647 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001648
hualing chen2aba4022020-03-02 13:49:55 +08001649 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001650 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001651 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1652 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001653 //destory thread
1654 _stop_playback_thread(handle);
1655 } else {
1656 //do nothing.video is playing
1657 }
hualing chen87072a82020-03-12 16:20:12 +08001658 player->has_audio = DVR_FALSE;
1659
1660 AmTsPlayer_stopAudioDecoding(player->handle);
1661 player->cmd.last_cmd = player->cmd.cur_cmd;
1662 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
1663
hualing chencc91e1c2020-02-28 13:26:17 +08001664 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001665 pthread_mutex_unlock(&player->lock);
1666 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001667}
1668/**\brief Start play video
1669 * \param[in] handle playback handle
1670 * \param[in] params video playback params,contains fmt and pid...
1671 * \retval DVR_SUCCESS On success
1672 * \return Error code
1673 */
hualing chen2aba4022020-03-02 13:49:55 +08001674int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001675 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001676
1677 if (player == NULL) {
1678 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1679 return DVR_FAILURE;
1680 }
1681
hualing chen86e7d482020-01-16 15:13:33 +08001682 _start_playback_thread(handle);
1683 //start audio and video
hualing chencc91e1c2020-02-28 13:26:17 +08001684 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001685 pthread_mutex_lock(&player->lock);
1686 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08001687 AmTsPlayer_setVideoParams(player->handle, param);
1688 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001689
1690 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001691 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08001692 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen87072a82020-03-12 16:20:12 +08001693 DVR_DEBUG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08001694 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1695 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08001696 }
1697 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001698 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
1699 player->cmd.state = DVR_PLAYBACK_STATE_START;
1700 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001701 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001702 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001703 return DVR_SUCCESS;
1704}
1705/**\brief Stop play video
1706 * \param[in] handle playback handle
1707 * \retval DVR_SUCCESS On success
1708 * \return Error code
1709 */
hualing chen040df222020-01-17 13:35:02 +08001710int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
1711 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001712
1713 if (player == NULL) {
1714 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1715 return DVR_FAILURE;
1716 }
1717
hualing chencc91e1c2020-02-28 13:26:17 +08001718 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001719 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001720
1721 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001722 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1723 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001724 //destory thread
1725 _stop_playback_thread(handle);
1726 } else {
1727 //do nothing.audio is playing
1728 }
hualing chen87072a82020-03-12 16:20:12 +08001729 player->has_video = DVR_FALSE;
1730
1731 AmTsPlayer_stopVideoDecoding(player->handle);
1732 //playback_device_video_stop(player->handle);
1733
1734 player->cmd.last_cmd = player->cmd.cur_cmd;
1735 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
1736
hualing chencc91e1c2020-02-28 13:26:17 +08001737 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001738 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001739 return DVR_SUCCESS;
1740}
1741/**\brief Pause play
1742 * \param[in] handle playback handle
1743 * \param[in] flush whether its internal buffers should be flushed
1744 * \retval DVR_SUCCESS On success
1745 * \return Error code
1746 */
hualing chen040df222020-01-17 13:35:02 +08001747int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
1748 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001749 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chena540a7e2020-03-27 16:44:05 +08001750
1751 if (player == NULL) {
1752 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1753 return DVR_FAILURE;
1754 }
1755
hualing chen86e7d482020-01-16 15:13:33 +08001756 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001757 DVR_DEBUG(1, "get lock func: %s", __func__);
1758 AmTsPlayer_pauseVideoDecoding(player->handle);
1759 AmTsPlayer_pauseAudioDecoding(player->handle);
1760
1761 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001762 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1763 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1764 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1765 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001766 } else {
1767 player->cmd.last_cmd = player->cmd.cur_cmd;
1768 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1769 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1770 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001771 }
hualing chen86e7d482020-01-16 15:13:33 +08001772 pthread_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001773 DVR_DEBUG(1, "unlock func: %s", __func__);
1774
hualing chen86e7d482020-01-16 15:13:33 +08001775 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001776}
1777
hualing chen5cbe1a62020-02-10 16:36:36 +08001778//not add lock
1779static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
1780{
1781 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1782
hualing chena540a7e2020-03-27 16:44:05 +08001783 if (player == NULL) {
1784 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1785 return DVR_FAILURE;
1786 }
1787
hualing chen5cbe1a62020-02-10 16:36:36 +08001788 //get video params and audio params
hualing chencc91e1c2020-02-28 13:26:17 +08001789 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08001790 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001791 am_tsplayer_video_params vparams;
1792 am_tsplayer_audio_params aparams;
hualing chencc91e1c2020-02-28 13:26:17 +08001793 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08001794
1795 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
hualing chen87072a82020-03-12 16:20:12 +08001796 DVR_DEBUG(1, "unlock func: %s cmd: %d", __func__, cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08001797 pthread_mutex_unlock(&player->lock);
1798
1799 switch (cmd) {
1800 case DVR_PLAYBACK_CMD_AVRESTART:
1801 //av restart
hualing chen87072a82020-03-12 16:20:12 +08001802 DVR_DEBUG(1, "do_cmd avrestart");
1803 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001804 break;
1805 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001806 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1807 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001808 break;
1809 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001810 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001811 break;
1812 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001813 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001814 break;
1815 case DVR_PLAYBACK_CMD_ARESTART:
1816 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08001817 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1818 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001819 break;
1820 case DVR_PLAYBACK_CMD_ASTART:
hualing chen2aba4022020-03-02 13:49:55 +08001821 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001822 break;
1823 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001824 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001825 break;
1826 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001827 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1828 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1829 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001830 break;
1831 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001832 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1833 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001834 break;
1835 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001836 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1837 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1838 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001839 break;
1840 case DVR_PLAYBACK_CMD_STOP:
1841 break;
1842 case DVR_PLAYBACK_CMD_START:
1843 break;
1844 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001845 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1846 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
1847 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001848 break;
1849 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001850 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1851 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
1852 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001853 break;
1854 case DVR_PLAYBACK_CMD_FF:
1855 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08001856 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001857 break;
1858 default:
1859 break;
1860 }
1861 return DVR_SUCCESS;
1862}
1863
1864/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08001865 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08001866 * \retval DVR_SUCCESS On success
1867 * \return Error code
1868 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001869int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
1870 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1871
hualing chena540a7e2020-03-27 16:44:05 +08001872 if (player == NULL) {
1873 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1874 return DVR_FAILURE;
1875 }
1876
hualing chen5cbe1a62020-02-10 16:36:36 +08001877 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001878 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08001879 pthread_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001880 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001881 AmTsPlayer_resumeVideoDecoding(player->handle);
1882 AmTsPlayer_resumeAudioDecoding(player->handle);
1883 //playback_device_resume(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001884 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1885 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1886 player->cmd.state = DVR_PLAYBACK_STATE_START;
1887 player->state = DVR_PLAYBACK_STATE_START;
1888 } else {
1889 player->cmd.last_cmd = player->cmd.cur_cmd;
1890 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
1891 player->cmd.state = DVR_PLAYBACK_STATE_START;
1892 player->state = DVR_PLAYBACK_STATE_START;
1893 }
hualing chencc91e1c2020-02-28 13:26:17 +08001894 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08001895 pthread_mutex_unlock(&player->lock);
1896 } else {
hualing chen87072a82020-03-12 16:20:12 +08001897 AmTsPlayer_resumeVideoDecoding(player->handle);
1898 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001899 DVR_DEBUG(1, "func: %s, set start state", __func__);
1900 player->cmd.state = DVR_PLAYBACK_STATE_START;
1901 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08001902 _dvr_cmd(handle, player->cmd.cur_cmd);
1903 }
1904 return DVR_SUCCESS;
1905}
1906
hualing chena540a7e2020-03-27 16:44:05 +08001907static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
1908
1909 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1910 DVR_PlaybackSegmentInfo_t *segment = NULL;
1911 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
1912 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
1913
1914 list_for_each_entry(segment, &player->segment_list, head)
1915 {
1916 if (segment->segment_id == segment_id) {
1917 cur_segment = segment;
1918 }
1919 if (segment->segment_id == set_seg_id) {
1920 set_segment = segment;
1921 }
1922 if (cur_segment != NULL && set_segment != NULL) {
1923 break;
1924 }
1925 }
1926 if (cur_segment == NULL || set_segment == NULL) {
1927 DVR_DEBUG(1, "set segmen or cur segment is null");
1928 return DVR_TRUE;
1929 }
1930 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
1931 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
1932 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
1933 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
1934 DVR_DEBUG(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);
1935 return DVR_TRUE;
1936 }
1937 DVR_DEBUG(1, "%s:play info not change", __func__);
1938 return DVR_FALSE;
1939}
1940
hualing chen5cbe1a62020-02-10 16:36:36 +08001941/**\brief seek
1942 * \param[in] handle playback handle
1943 * \param[in] time_offset time offset base cur segment
1944 * \retval DVR_SUCCESS On success
1945 * \return Error code
1946 */
hualing chencc91e1c2020-02-28 13:26:17 +08001947int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08001948 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001949
1950 if (player == NULL) {
1951 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
1952 return DVR_FAILURE;
1953 }
1954
1955 DVR_DEBUG(1, "lock func: %s segment_id %llu cur id %llu time_offset %u cur end: %d", __func__, segment_id,player->cur_segment_id, (uint32_t)time_offset, _dvr_get_end_time(handle));
hualing chencc91e1c2020-02-28 13:26:17 +08001956 DVR_DEBUG(1, "[%s][%p]---player->state[%d]----",__func__, handle, player->state);
hualing chen86e7d482020-01-16 15:13:33 +08001957 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001958
hualing chen86e7d482020-01-16 15:13:33 +08001959 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08001960 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
1961 DVR_DEBUG(1, "[%s][%p]---player->state[%d]-replay[%d]--get lock-",__func__, handle, player->state, replay);
1962
hualing chen5cbe1a62020-02-10 16:36:36 +08001963 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08001964 int ret = _dvr_open_segment(handle, segment_id);
1965 if (ret ==DVR_FAILURE) {
1966 DVR_DEBUG(1, "seek error at open segment");
1967 pthread_mutex_unlock(&player->lock);
1968 return DVR_FAILURE;
1969 }
1970 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
1971 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
1972 DVR_DEBUG(1, "is ongoing segment when seek end, need return success");
1973 //pthread_mutex_unlock(&player->lock);
1974 //return DVR_SUCCESS;
1975 time_offset = _dvr_get_end_time(handle);
1976 } else {
1977 DVR_DEBUG(1, "is not ongoing segment when seek end, return failure");
1978 pthread_mutex_unlock(&player->lock);
1979 return DVR_FAILURE;
1980 }
1981 }
1982
hualing chencc91e1c2020-02-28 13:26:17 +08001983 DVR_DEBUG(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 +08001984 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08001985 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1986 //forward playback.not seek end of file
1987 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
1988 //default -2000ms
1989 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
1990 }
hualing chen86e7d482020-01-16 15:13:33 +08001991 }
hualing chen2aba4022020-03-02 13:49:55 +08001992 pthread_mutex_lock(&player->segment_lock);
1993 offset = segment_seek(player->r_handle, (uint64_t)time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08001994 DVR_DEBUG(0, "---seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
1995 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001996 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08001997
hualing chen2aba4022020-03-02 13:49:55 +08001998 _dvr_get_end_time(handle);
1999 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002000 player->fffb_current = _dvr_time_getClock();
2001 player->fffb_start = player->fffb_current;
2002 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2003 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002004 //pause state if need to replayer false
2005 if (player->state == DVR_PLAYBACK_STATE_STOP ||
2006 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002007 //only seek file,not start
hualing chencc91e1c2020-02-28 13:26:17 +08002008 DVR_DEBUG(1, "unlock func: %s", __func__);
2009 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002010 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002011 }
hualing chen86e7d482020-01-16 15:13:33 +08002012 //stop play
hualing chen2aba4022020-03-02 13:49:55 +08002013 DVR_DEBUG(0, "seek stop play, not inject data has video[%d]audio[%d]", player->has_video, player->has_audio);
hualing chen86e7d482020-01-16 15:13:33 +08002014 if (player->has_video)
hualing chen2aba4022020-03-02 13:49:55 +08002015 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002016 if (player->has_audio)
hualing chen2aba4022020-03-02 13:49:55 +08002017 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002018 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002019 am_tsplayer_video_params vparams;
2020 am_tsplayer_audio_params aparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002021
hualing chen040df222020-01-17 13:35:02 +08002022 player->cur_segment_id = segment_id;
2023
2024 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002025 //get segment info and audio video pid fmt ;
2026 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08002027 //start audio and video
2028 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2029 //audio abnd video pis is all invalid, return error.
2030 DVR_DEBUG(0, "seek start dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002031 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08002032 pthread_mutex_unlock(&player->lock);
2033 return -1;
2034 }
2035 //add
hualing chen040df222020-01-17 13:35:02 +08002036 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002037 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002038 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002039 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chen31140872020-03-25 12:29:26 +08002040 player->speed > 1.0f||
2041 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002042 //if is pause state. we need set trick mode.
hualing chen31140872020-03-25 12:29:26 +08002043 DVR_DEBUG(1, "[%s]seek set trick mode player->speed [%f]", __func__, player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002044 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002045 }
hualing chen2aba4022020-03-02 13:49:55 +08002046 AmTsPlayer_setVideoParams(player->handle, &vparams);
2047 AmTsPlayer_startVideoDecoding(player->handle);
2048 //playback_device_video_start(player->handle , &vparams);
hualing chenb31a6c62020-01-13 17:27:00 +08002049 }
hualing chen86e7d482020-01-16 15:13:33 +08002050 if (VALID_PID(aparams.pid)) {
hualing chena540a7e2020-03-27 16:44:05 +08002051 DVR_DEBUG(1, " func: %s start audio seek", __func__);
hualing chen2aba4022020-03-02 13:49:55 +08002052 AmTsPlayer_setAudioParams(player->handle, &aparams);
2053 AmTsPlayer_startAudioDecoding(player->handle);
2054 //playback_device_audio_start(player->handle , &aparams);
hualing chenb31a6c62020-01-13 17:27:00 +08002055 }
hualing chen86e7d482020-01-16 15:13:33 +08002056 }
hualing chen2aba4022020-03-02 13:49:55 +08002057 if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
2058 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2059 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2060 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
2061 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))) {
2062 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2063 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002064 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2065 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002066 player->speed > 1.0f||
2067 player->speed <= -1.0f) {
hualing chen87072a82020-03-12 16:20:12 +08002068 DVR_DEBUG(1, "not set cmd to seek");
2069 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002070 } else {
hualing chen87072a82020-03-12 16:20:12 +08002071 DVR_DEBUG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002072 player->cmd.last_cmd = player->cmd.cur_cmd;
2073 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2074 player->cmd.state = DVR_PLAYBACK_STATE_START;
2075 player->state = DVR_PLAYBACK_STATE_START;
2076 }
hualing chencc91e1c2020-02-28 13:26:17 +08002077 DVR_DEBUG(1, "unlock func: %s ---", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08002078 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002079
2080 return DVR_SUCCESS;
2081}
hualing chen5cbe1a62020-02-10 16:36:36 +08002082
2083//get current segment current pcr time of read pos
2084static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2085 //get cur time of segment
2086 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002087
2088 if (player == NULL || player->handle == NULL) {
2089 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2090 return DVR_FAILURE;
2091 }
2092
hualing chen31140872020-03-25 12:29:26 +08002093 int64_t cache = 0;//defalut es buf cache 500ms
2094 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002095 pthread_mutex_lock(&player->segment_lock);
2096 uint64_t cur = segment_tell_current_time(player->r_handle);
2097 pthread_mutex_unlock(&player->segment_lock);
2098 DVR_DEBUG(1, "get cur time [%lld]", cur);
hualing chen87072a82020-03-12 16:20:12 +08002099 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2100 cache = 0;
2101 }
hualing chen31140872020-03-25 12:29:26 +08002102 return (int)(cur > cache ? cur - cache : 0);
hualing chencc91e1c2020-02-28 13:26:17 +08002103}
2104
2105//get current segment current pcr time of read pos
2106static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2107 //get cur time of segment
2108 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002109
2110 if (player == NULL) {
2111 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2112 return DVR_FAILURE;
2113 }
2114
hualing chen2aba4022020-03-02 13:49:55 +08002115 pthread_mutex_lock(&player->segment_lock);
2116 uint64_t end = segment_tell_total_time(player->r_handle);
2117 DVR_DEBUG(1, "get tatal time [%lld]", end);
2118 pthread_mutex_unlock(&player->segment_lock);
2119 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002120}
2121
hualing chen87072a82020-03-12 16:20:12 +08002122#define FB_MIX_SEEK_TIME 1000
hualing chen5cbe1a62020-02-10 16:36:36 +08002123//start replay
2124static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2125
2126 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2127 //calculate pcr seek time
2128 int t_diff = 0;
2129 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002130
2131 if (player == NULL) {
2132 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2133 return DVR_FAILURE;
2134 }
2135
hualing chen5cbe1a62020-02-10 16:36:36 +08002136 if (player->fffb_start == -1) {
2137 //set fffb start time ms
2138 player->fffb_start = _dvr_time_getClock();
2139 player->fffb_current = player->fffb_start;
2140 //get segment current time pos
2141 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen31140872020-03-25 12:29:26 +08002142 DVR_DEBUG(1, "calculate seek posplayer->fffb_start_pcr[%d]ms, speed[%f]", player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002143 t_diff = 0;
hualing chen2aba4022020-03-02 13:49:55 +08002144 //default first time 1ms seek
hualing chen87072a82020-03-12 16:20:12 +08002145 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002146 } else {
2147 player->fffb_current = _dvr_time_getClock();
2148 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002149 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002150 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002151 if (seek_time <= 0) {
2152 //need seek to pre one segment
2153 seek_time = 0;
2154 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002155 //seek segment pos
2156 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002157 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002158 segment_seek(player->r_handle, seek_time);
hualing chen2aba4022020-03-02 13:49:55 +08002159 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002160 } else {
2161 //
2162 DVR_DEBUG(1, "segment not open,can not seek");
2163 }
hualing chen31140872020-03-25 12:29:26 +08002164 DVR_DEBUG(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 +08002165 }
hualing chen2aba4022020-03-02 13:49:55 +08002166 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002167}
2168
2169
2170//start replay
2171static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2172 //
2173 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002174
2175 if (player == NULL) {
2176 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2177 return DVR_FAILURE;
2178 }
2179
hualing chen5cbe1a62020-02-10 16:36:36 +08002180 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002181 if (player->has_video) {
2182 DVR_DEBUG(1, "fffb stop video");
2183 AmTsPlayer_stopVideoDecoding(player->handle);
2184 }
2185 if (player->has_audio) {
2186 DVR_DEBUG(1, "fffb stop audio");
2187 AmTsPlayer_stopAudioDecoding(player->handle);
2188 }
2189
hualing chen5cbe1a62020-02-10 16:36:36 +08002190 //start video and audio
2191
hualing chen2aba4022020-03-02 13:49:55 +08002192 am_tsplayer_video_params vparams;
2193 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002194 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002195
2196 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002197 //pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002198 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2199 //start audio and video
2200 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2201 //audio abnd video pis is all invalid, return error.
2202 DVR_DEBUG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002203 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002204 return -1;
2205 }
2206
2207 if (VALID_PID(vparams.pid)) {
2208 player->has_video = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08002209 DVR_DEBUG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08002210 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002211 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2212 AmTsPlayer_setVideoParams(player->handle, &vparams);
2213 AmTsPlayer_startVideoDecoding(player->handle);
2214 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002215 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002216 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002217 }
hualing chena540a7e2020-03-27 16:44:05 +08002218 if (0 && VALID_PID(aparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002219 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08002220 DVR_DEBUG(1, "fffb start audio");
2221 AmTsPlayer_setAudioParams(player->handle, &aparams);
2222 AmTsPlayer_startAudioDecoding(player->handle);
2223 //playback_device_audio_start(player->handle , &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002224 }
hualing chen31140872020-03-25 12:29:26 +08002225 //fffb mode need stop fast;
2226 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002227
hualing chencc91e1c2020-02-28 13:26:17 +08002228 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002229 return 0;
2230}
2231
2232static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2233 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002234
2235 if (player == NULL) {
2236 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2237 return DVR_FAILURE;
2238 }
2239
2240 player->first_frame = 0;
hualing chen31140872020-03-25 12:29:26 +08002241 DVR_DEBUG(1, "lock func: %s speed [%f]", __func__, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002242 pthread_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08002243 DVR_DEBUG(1, "get lock func: %s speed [%f]id [%lld]", __func__, player->speed, player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +08002244
hualing chen2aba4022020-03-02 13:49:55 +08002245 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen87072a82020-03-12 16:20:12 +08002246 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2247 //seek time set 0
2248 seek_time = 0;
2249 }
hualing chen2aba4022020-03-02 13:49:55 +08002250 if (seek_time == 0 && IS_FB(player->speed)) {
2251 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2252 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
2253 if (ret != DVR_SUCCESS) {
hualing chen87072a82020-03-12 16:20:12 +08002254 pthread_mutex_unlock(&player->lock);
2255 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002256 //send event here and pause
2257 DVR_Play_Notify_t notify;
2258 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002259 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002260 //get play statue not here
2261 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify);
hualing chen31140872020-03-25 12:29:26 +08002262 DVR_DEBUG(1, "*******************send begin event func: %s speed [%f] cur [%d]", __func__, player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08002263 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002264 return DVR_SUCCESS;
2265 }
hualing chen87072a82020-03-12 16:20:12 +08002266 _dvr_playback_sent_transition_ok(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002267 _dvr_init_fffb_time(handle);
hualing chen31140872020-03-25 12:29:26 +08002268 DVR_DEBUG(1, "*******************send trans ok event func: %s speed [%f]", __func__, player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002269 }
2270 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002271 _dvr_playback_fffb_replay(handle);
2272
2273 pthread_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002274 DVR_DEBUG(1, "unlock func: %s", __func__);
2275
hualing chen5cbe1a62020-02-10 16:36:36 +08002276 return DVR_SUCCESS;
2277}
2278
hualing chen87072a82020-03-12 16:20:12 +08002279//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002280static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002281 //
2282 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002283
2284 if (player == NULL) {
2285 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2286 return DVR_FAILURE;
2287 }
2288
hualing chen5cbe1a62020-02-10 16:36:36 +08002289 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002290 if (player->has_video) {
2291 AmTsPlayer_stopVideoDecoding(player->handle);
2292 //playback_device_video_stop(player->handle);
2293 }
2294
2295 if (player->has_audio) {
2296 AmTsPlayer_stopAudioDecoding(player->handle);
2297 //playback_device_audio_stop(player->handle);
2298 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002299 //start video and audio
2300
hualing chen2aba4022020-03-02 13:49:55 +08002301 am_tsplayer_video_params vparams;
2302 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08002303 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002304
2305 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002306 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002307 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
2308 //start audio and video
2309 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002310 //audio and video pis is all invalid, return error.
hualing chen5cbe1a62020-02-10 16:36:36 +08002311 DVR_DEBUG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002312 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002313 return -1;
2314 }
2315
2316 if (VALID_PID(vparams.pid)) {
2317 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002318 if (trick == DVR_TRUE) {
2319 DVR_DEBUG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002320 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002321 }
hualing chen2aba4022020-03-02 13:49:55 +08002322 else
2323 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2324 AmTsPlayer_setVideoParams(player->handle, &vparams);
2325 AmTsPlayer_startVideoDecoding(player->handle);
2326 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002327 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002328 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002329 }
hualing chena540a7e2020-03-27 16:44:05 +08002330
2331 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002332 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002333 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002334 } else {
hualing chena540a7e2020-03-27 16:44:05 +08002335 if (VALID_PID(aparams.pid)) {
2336 player->has_audio = DVR_TRUE;
2337 DVR_DEBUG(1, " func: %s start audio", __func__);
2338 AmTsPlayer_startAudioDecoding(player->handle);
2339 AmTsPlayer_setAudioParams(player->handle, &aparams);
2340 //playback_device_audio_start(player->handle , &aparams);
2341 }
hualing chen31140872020-03-25 12:29:26 +08002342 AmTsPlayer_stopFast(player->handle);
2343 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2344 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2345 }
hualing chen2aba4022020-03-02 13:49:55 +08002346 player->cmd.last_cmd = player->cmd.cur_cmd;
2347 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002348 player->cmd.state = DVR_PLAYBACK_STATE_START;
2349 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08002350 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002351 return 0;
2352}
2353
2354
hualing chenb31a6c62020-01-13 17:27:00 +08002355/**\brief Set play speed
2356 * \param[in] handle playback handle
2357 * \param[in] speed playback speed
2358 * \retval DVR_SUCCESS On success
2359 * \return Error code
2360 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002361int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2362
2363 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002364
2365 if (player == NULL) {
2366 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2367 return DVR_FAILURE;
2368 }
2369
2370 DVR_DEBUG(1, "lock func: %s speed [%d]", __func__, speed.speed.speed);
2371 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
2372 DVR_DEBUG(1, " func: %s not support speed [%d]", __func__, speed.speed.speed);
2373 return DVR_FAILURE;
2374 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002375 pthread_mutex_lock(&player->lock);
2376 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2377 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2378 player->cmd.last_cmd = player->cmd.cur_cmd;
2379 }
hualing chen31140872020-03-25 12:29:26 +08002380 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002381 IS_KERNEL_SPEED(speed.speed.speed)) {
2382 //case 1. cur speed is 100,set 200 50 25 12 .
2383 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2384 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002385 //if last speed is x2 or s2, we need stop fast
hualing chena540a7e2020-03-27 16:44:05 +08002386 if (player->has_audio) {
2387 DVR_DEBUG(1, "fast play stop audio");
2388 AmTsPlayer_stopAudioDecoding(player->handle);
2389 }
hualing chen31140872020-03-25 12:29:26 +08002390 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002391 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002392 player->cmd.speed.speed = speed.speed;
2393 player->speed = (float)speed.speed.speed/(float)100;
2394 pthread_mutex_unlock(&player->lock);
2395 return DVR_SUCCESS;
2396 }
2397 //case 2. not start play
2398 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2399 //only set speed.and return;
hualing chena540a7e2020-03-27 16:44:05 +08002400 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002401 player->cmd.speed.speed = speed.speed;
2402 player->speed = (float)speed.speed.speed/(float)100;
2403 pthread_mutex_unlock(&player->lock);
2404 return DVR_SUCCESS;
hualing chen87072a82020-03-12 16:20:12 +08002405 }
hualing chen31140872020-03-25 12:29:26 +08002406 //case 3 fffb mode
2407 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2408 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2409 //restart play at normal speed exit ff fb
2410 DVR_DEBUG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002411 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002412 player->cmd.speed.speed = speed.speed;
2413 player->speed = (float)speed.speed.speed/(float)100;
2414 _dvr_playback_replay(handle, DVR_FALSE);
2415 pthread_mutex_unlock(&player->lock);
2416 return DVR_SUCCESS;
2417 }
2418 }
2419 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002420 IS_KERNEL_SPEED(speed.speed.speed)) {
2421 //case 1. cur speed is kernel support speed,set kernel speed.
2422 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002423 //if last speed is x2 or s2, we need stop fast
hualing chena540a7e2020-03-27 16:44:05 +08002424 if (player->has_audio) {
2425 DVR_DEBUG(1, "fast play stop audio when pause");
2426 AmTsPlayer_stopAudioDecoding(player->handle);
2427 }
hualing chen31140872020-03-25 12:29:26 +08002428 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002429 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002430 player->cmd.speed.speed = speed.speed;
2431 player->speed = (float)speed.speed.speed/(float)100;
2432 pthread_mutex_unlock(&player->lock);
2433 return DVR_SUCCESS;
2434 }
2435 //case 2 fffb mode
2436 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2437 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2438 //restart play at normal speed exit ff fb
2439 DVR_DEBUG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002440 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002441 player->cmd.speed.speed = speed.speed;
2442 player->speed = (float)speed.speed.speed/(float)100;
2443 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2444 pthread_mutex_unlock(&player->lock);
2445 return DVR_SUCCESS;
2446 }
hualing chen31140872020-03-25 12:29:26 +08002447 }
hualing chena540a7e2020-03-27 16:44:05 +08002448 if (IS_KERNEL_SPEED(speed.speed.speed)) {
2449 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chen87072a82020-03-12 16:20:12 +08002450 } else {
hualing chen31140872020-03-25 12:29:26 +08002451 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002452 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2453 else
2454 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
2455 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002456 player->cmd.speed.mode = speed.mode;
2457 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002458 player->speed = (float)speed.speed.speed/(float)100;
2459 //reset fffb time, if change speed value
2460 _dvr_init_fffb_time(handle);
hualing chen87072a82020-03-12 16:20:12 +08002461 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002462 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2463 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002464 //restart play at normal speed exit ff fb
2465 DVR_DEBUG(1, "set speed normal and replay playback");
2466 _dvr_playback_replay(handle, DVR_FALSE);
2467 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2468 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2469 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2470 DVR_DEBUG(1, "set speed normal at pause state ,set cur cmd");
2471 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002472 //need exit ff fb
hualing chen31140872020-03-25 12:29:26 +08002473 DVR_DEBUG(1, "unlock func: %s speed[%f]cmd[%d]", __func__, player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002474 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002475 return DVR_SUCCESS;
2476}
2477/**\brief Get playback status
2478 * \param[in] handle playback handle
2479 * \param[out] p_status playback status
2480 * \retval DVR_SUCCESS On success
2481 * \return Error code
2482 */
hualing chen040df222020-01-17 13:35:02 +08002483int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002484 DVR_PlaybackStatus_t *p_status) {
2485//
2486 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002487
2488 if (player == NULL) {
2489 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2490 return DVR_FAILURE;
2491 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002492
2493 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002494 //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 +08002495 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2496 player->state == DVR_PLAYBACK_STATE_START) {
2497 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2498 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002499 p_status->segment_id = player->cur_segment_id;
hualing chencc91e1c2020-02-28 13:26:17 +08002500 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002501 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002502
hualing chen5cbe1a62020-02-10 16:36:36 +08002503 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08002504 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08002505 p_status->flags = player->cur_segment.flags;
hualing chena540a7e2020-03-27 16:44:05 +08002506 DVR_DEBUG(1, "get stat end player state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]",
hualing chen6d24aa92020-03-23 18:43:47 +08002507 _dvr_playback_state_toString(player->state),
2508 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08002509 p_status->time_cur, p_status->time_end,
2510 p_status->segment_id,player->play_flag,
2511 player->speed);
hualing chenb31a6c62020-01-13 17:27:00 +08002512 return DVR_SUCCESS;
2513}
2514
hualing chen040df222020-01-17 13:35:02 +08002515void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
2516 if (segment != NULL) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002517 DVR_DEBUG(1, "segment id: %lld", segment->segment_id);
hualing chen040df222020-01-17 13:35:02 +08002518 DVR_DEBUG(1, "segment flag: %d", segment->flags);
2519 DVR_DEBUG(1, "segment location: [%s]", segment->location);
2520 DVR_DEBUG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
2521 DVR_DEBUG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
2522 DVR_DEBUG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
2523 DVR_DEBUG(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 +08002524 }
hualing chenb31a6c62020-01-13 17:27:00 +08002525}
2526
hualing chen5cbe1a62020-02-10 16:36:36 +08002527int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002528 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08002529
hualing chena540a7e2020-03-27 16:44:05 +08002530 if (player == NULL) {
2531 DVR_DEBUG(1, "func [%s] player is NULL", __func__);
2532 return DVR_FAILURE;
2533 }
2534
hualing chen040df222020-01-17 13:35:02 +08002535 DVR_PlaybackSegmentInfo_t *segment;
2536 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002537 {
hualing chen040df222020-01-17 13:35:02 +08002538 if (segment_id >= 0) {
2539 if (segment->segment_id == segment_id) {
2540 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002541 break;
2542 }
2543 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08002544 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08002545 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002546 }
2547 }
2548 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002549}