blob: 6f45315e845cc51b3eb1a500a11dea487b21ccf7 [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
17#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chen31140872020-03-25 12:29:26 +080018#define IS_FFFB(_SPEED_) ((_SPEED_) > 1.0f && (_SPEED_) < -1.0f)
19#define IS_FB(_SPEED_) ((_SPEED_) < 0.0f)
hualing chenb31a6c62020-01-13 17:27:00 +080020
hualing chen2aba4022020-03-02 13:49:55 +080021#define FFFB_SLEEP_TIME 1000
hualing chen2aba4022020-03-02 13:49:55 +080022#define FB_DEFAULT_LEFT_TIME (2000)
hualing chen31140872020-03-25 12:29:26 +080023//if tsplayer delay time < 200 and no data can read, we will pause
24#define MIN_TSPLAYER_DELAY_TIME (200)
25
hualing chen5cbe1a62020-02-10 16:36:36 +080026//
27static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chencc91e1c2020-02-28 13:26:17 +080028static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type);
29static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
30static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080031static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080032static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
33
hualing chen2aba4022020-03-02 13:49:55 +080034static int first_frame = 0;
35
hualing chen6d24aa92020-03-23 18:43:47 +080036static char* _dvr_playback_state_toString(int stat)
37{
38 char *string[DVR_PLAYBACK_STATE_FB+1]={
39 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080040 "stop",
hualing chen31140872020-03-25 12:29:26 +080041 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080042 "ff",
43 "fb"
44 };
45
46 if (stat > DVR_PLAYBACK_STATE_FB) {
47 return "unkown";
48 } else {
49 return string[stat];
50 }
51}
hualing chen6e4bfa52020-03-13 14:37:11 +080052void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
53{
54 DVR_DEBUG(1, "in callback test ");
55 DVR_Playback_t *player = NULL;
56 if (user_data != NULL) {
57 DVR_Playback_t *player = (DVR_Playback_t *) user_data;
58 DVR_DEBUG(1, "play speed [%d] in callback test ", player->speed);
59 }
60 switch (event->type) {
61 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
62 {
63 DVR_DEBUG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
64 event->event.video_format.frame_width,
65 event->event.video_format.frame_height,
66 event->event.video_format.frame_rate);
67 break;
68 }
hualing chen6e4bfa52020-03-13 14:37:11 +080069 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
70 {
71 DVR_DEBUG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
72 first_frame = 1;
73 break;
74 }
75 default:
76 break;
77 }
78}
hualing chen2aba4022020-03-02 13:49:55 +080079void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
80{
hualing chen6e4bfa52020-03-13 14:37:11 +080081 DVR_Playback_t *player = NULL;
82 if (user_data != NULL) {
83 player = (DVR_Playback_t *) user_data;
hualing chen31140872020-03-25 12:29:26 +080084 DVR_DEBUG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +080085 }
hualing chen2aba4022020-03-02 13:49:55 +080086 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +080087 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
88 {
89 DVR_DEBUG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
90 event->event.video_format.frame_width,
91 event->event.video_format.frame_height,
92 event->event.video_format.frame_rate);
93 break;
94 }
hualing chen6e4bfa52020-03-13 14:37:11 +080095 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
96 {
97 DVR_DEBUG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
98 first_frame = 1;
99 break;
100 }
101 default:
hualing chen6d24aa92020-03-23 18:43:47 +0800102 DVR_DEBUG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800103 break;
104 }
105 if (player&&player->player_callback_func) {
hualing chen6d24aa92020-03-23 18:43:47 +0800106 DVR_DEBUG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800107 player->player_callback_func(player->player_callback_userdata, event);
108 } else if (player == NULL){
109 DVR_DEBUG(1, "player is null, get userdata error\n");
110 } else {
111 DVR_DEBUG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800112 }
113}
hualing chencc91e1c2020-02-28 13:26:17 +0800114
hualing chen5cbe1a62020-02-10 16:36:36 +0800115//convert video and audio fmt
116static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
117 int format = 0;
118 if (is_audio == DVR_FALSE) {
119 //for video fmt
120 switch (fmt)
121 {
122 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800123 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800124 break;
125 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800126 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800127 break;
128 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800129 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800130 break;
131 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800132 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800133 break;
134 }
135 } else {
136 //for audio fmt
137 switch (fmt)
138 {
139 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800140 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800141 break;
142 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800143 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800144 break;
145 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800146 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800147 break;
148 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800149 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800150 break;
151 }
152 }
153 return format;
154}
hualing chen040df222020-01-17 13:35:02 +0800155static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800156{
hualing chen2aba4022020-03-02 13:49:55 +0800157 int state = 0;
hualing chen040df222020-01-17 13:35:02 +0800158 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800159
hualing chen5cbe1a62020-02-10 16:36:36 +0800160 if (player->handle == NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800161 return -1;
162
hualing chen2aba4022020-03-02 13:49:55 +0800163 return first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800164}
hualing chen5cbe1a62020-02-10 16:36:36 +0800165//get sys time ms
166static int _dvr_time_getClock(void)
167{
168 struct timespec ts;
169 int ms;
170
171 clock_gettime(CLOCK_MONOTONIC, &ts);
172 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
173
174 return ms;
175}
hualing chen86e7d482020-01-16 15:13:33 +0800176
hualing chenb31a6c62020-01-13 17:27:00 +0800177
178//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800179static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800180{
hualing chen040df222020-01-17 13:35:02 +0800181 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800182
hualing chen86e7d482020-01-16 15:13:33 +0800183 struct timespec ts;
184 clock_gettime(CLOCK_MONOTONIC, &ts);
185 //ms为毫秒,换算成秒
186 ts.tv_sec += ms/1000;
187 //在outtime的基础上,增加ms毫秒
188 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
189 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
190 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
191 //us的值有可能超过1秒,
192 ts.tv_sec += us / 1000000;
193 us = us % 1000000;
194 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800195 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
196 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800197}
hualing chen31140872020-03-25 12:29:26 +0800198//get tsplay delay time ms
199static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
200 DVR_Playback_t *player = (DVR_Playback_t *) handle;
201 int64_t cache = 0;
202 if (player == NULL || player->handle == NULL) {
203 DVR_DEBUG(1, "tsplayer delay time error, handle is NULL");
204 return 0;
205 }
206 AmTsPlayer_getDelayTime(player->handle, &cache);
207 DVR_DEBUG(1, "tsplayer cache time [%d]ms", cache);
208 return cache;
209}
hualing chenb31a6c62020-01-13 17:27:00 +0800210//send signal
hualing chen040df222020-01-17 13:35:02 +0800211static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800212{
hualing chen87072a82020-03-12 16:20:12 +0800213 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
214 DVR_DEBUG(1, "send signal lock");
215 pthread_mutex_lock(&player->lock);
216 DVR_DEBUG(1, "send signal got lock");
217 pthread_cond_signal(&player->cond);
218 DVR_DEBUG(1, "send signal unlock");
219 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800220 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800221}
222
hualing chencc91e1c2020-02-28 13:26:17 +0800223//send playback event
224static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify) {
225
226 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +0800227 switch (evt) {
228 case DVR_PLAYBACK_EVENT_ERROR:
229 break;
230 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
231 //GET STATE
232 DVR_DEBUG(1, "trans ok----");
233 dvr_playback_get_status(handle, &(notify->play_status));
234 break;
235 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
236 break;
237 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
238 break;
239 case DVR_PLAYBACK_EVENT_NO_KEY:
240 break;
241 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800242 //GET STATE
243 DVR_DEBUG(1, "reached begin---");
244 dvr_playback_get_status(handle, &(notify->play_status));
hualing chencc91e1c2020-02-28 13:26:17 +0800245 break;
246 case DVR_PLAYBACK_EVENT_REACHED_END:
247 //GET STATE
248 DVR_DEBUG(1, "reached end---");
249 dvr_playback_get_status(handle, &(notify->play_status));
250 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800251 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
252 //DVR_DEBUG(1, "send playtime---");
253 dvr_playback_get_status(handle, &(notify->play_status));
254 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800255 default:
256 break;
257 }
258 if (player->openParams.event_fn != NULL)
259 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800260 return DVR_SUCCESS;
261}
262static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle)
263{
264 DVR_Play_Notify_t notify;
265 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
266 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
267 //get play statue not here
268 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify);
269 return DVR_SUCCESS;
270}
271
hualing chen6e4bfa52020-03-13 14:37:11 +0800272static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle)
273{
274 DVR_Playback_t *player = (DVR_Playback_t *) handle;
275 if (player->send_time ==0) {
276 player->send_time = _dvr_time_getClock() + 1000;
277 } else if (player->send_time > _dvr_time_getClock()) {
278 return DVR_SUCCESS;
279 }
280 player->send_time = _dvr_time_getClock() + 1000;
281 DVR_Play_Notify_t notify;
282 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
283 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
284 //get play statue not here
285 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify);
286 return DVR_SUCCESS;
287}
288
289
hualing chencc91e1c2020-02-28 13:26:17 +0800290//check is ongoing segment
291static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
292
293 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800294 int ret = DVR_FAILURE;
295 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800296 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800297 return DVR_FALSE;
298 }
hualing chencc91e1c2020-02-28 13:26:17 +0800299 return DVR_TRUE;
300}
hualing chen2aba4022020-03-02 13:49:55 +0800301static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
302 DVR_Playback_t *player = (DVR_Playback_t *) handle;
303 player->fffb_current = -1;
304 player->fffb_start = -1;
305 player->fffb_start_pcr = -1;
306 player->next_fffb_time = _dvr_time_getClock();
307 return DVR_SUCCESS;
308}
hualing chencc91e1c2020-02-28 13:26:17 +0800309//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800310static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
311
312 DVR_Playback_t *player = (DVR_Playback_t *) handle;
313 DVR_PlaybackSegmentInfo_t *segment;
314 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
315
316 int found = 0;
317 int found_eq_id = 0;
318 list_for_each_entry(segment, &player->segment_list, head)
319 {
320 if (player->segment_is_open == DVR_FALSE) {
321 //get first segment from list, case segment is not open
322 if (!IS_FB(player->speed))
323 found = 1;
324 } else if (segment->segment_id == segmentid) {
325 //find cur segment, we need get next one
326 found_eq_id = 1;
327 if (!IS_FB(player->speed)) {
328 found = 1;
329 continue;
330 } else {
331 //if is fb mode.we need used pre segment
332 if (pre_segment != NULL) {
333 found = 1;
334 } else {
335 //not find next id.
336 DVR_DEBUG(1, "not has find next segment on fb mode");
337 return DVR_FAILURE;
338 }
339 }
340 }
341 if (found == 1) {
342 found = 2;
343 break;
344 }
345 }
346 if (found != 2) {
347 //list is null or reache list end
348 DVR_DEBUG(1, "not found next segment return failure");
349 return DVR_FAILURE;
350 }
351 DVR_DEBUG(1, "found next segment return success");
352 return DVR_SUCCESS;
353}
354
355//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800356static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800357
hualing chen040df222020-01-17 13:35:02 +0800358 DVR_Playback_t *player = (DVR_Playback_t *) handle;
359 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800360 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800361
362 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800363 int found_eq_id = 0;
hualing chen040df222020-01-17 13:35:02 +0800364 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800365 {
hualing chencc91e1c2020-02-28 13:26:17 +0800366 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800367 //get first segment from list, case segment is not open
368 if (!IS_FB(player->speed))
369 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800370 } else if (segment->segment_id == player->cur_segment_id) {
371 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800372 found_eq_id = 1;
373 if (!IS_FB(player->speed)) {
374 found = 1;
375 continue;
376 } else {
377 //if is fb mode.we need used pre segment
378 if (pre_segment != NULL) {
379 found = 1;
380 } else {
381 //not find next id.
382 DVR_DEBUG(1, "not find next segment on fb mode");
383 return DVR_FAILURE;
384 }
385 }
hualing chen86e7d482020-01-16 15:13:33 +0800386 }
387 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800388 if (IS_FB(player->speed)) {
389 //used pre segment
390 segment = pre_segment;
391 }
hualing chencc91e1c2020-02-28 13:26:17 +0800392 //save segment info
393 player->last_segment_id = player->cur_segment_id;
hualing chen87072a82020-03-12 16:20:12 +0800394 player->last_segment.segment_id = player->cur_segment.segment_id;
395 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800396 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
397 //pids
398 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
399
hualing chen5cbe1a62020-02-10 16:36:36 +0800400 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800401 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800402 player->cur_segment_id = segment->segment_id;
403 player->cur_segment.segment_id = segment->segment_id;
404 player->cur_segment.flags = segment->flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800405 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 +0800406 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800407 //pids
hualing chen040df222020-01-17 13:35:02 +0800408 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800409 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800410 break;
hualing chen86e7d482020-01-16 15:13:33 +0800411 }
hualing chen2aba4022020-03-02 13:49:55 +0800412 pre_segment = segment;
413 }
414 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
415 //used the last one segment to open
416 //get segment info
417 player->segment_is_open = DVR_TRUE;
418 player->cur_segment_id = pre_segment->segment_id;
419 player->cur_segment.segment_id = pre_segment->segment_id;
420 player->cur_segment.flags = pre_segment->flags;
421 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);
422 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
423 //pids
424 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
425 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800426 }
427 if (found != 2) {
428 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800429 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800430 }
431 return DVR_SUCCESS;
432}
hualing chen040df222020-01-17 13:35:02 +0800433//open next segment to play,if reach list end return errro.
434static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800435{
hualing chen040df222020-01-17 13:35:02 +0800436 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800437 Segment_OpenParams_t params;
438 int ret = DVR_SUCCESS;
439
hualing chen040df222020-01-17 13:35:02 +0800440 int id = _dvr_get_next_segmentId(handle);
hualing chen86e7d482020-01-16 15:13:33 +0800441 if (id < 0) {
hualing chen040df222020-01-17 13:35:02 +0800442 DVR_DEBUG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800443 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800444 }
445
446 if (player->r_handle != NULL) {
447 segment_close(player->r_handle);
448 player->r_handle = NULL;
449 }
450
451 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800452 //cp chur segment path to location
453 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800454 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800455 params.mode = SEGMENT_MODE_READ;
hualing chencc91e1c2020-02-28 13:26:17 +0800456 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 +0800457 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +0800458 ret = segment_open(&params, &(player->r_handle));
hualing chen87072a82020-03-12 16:20:12 +0800459 pthread_mutex_unlock(&player->segment_lock);
460 int total = _dvr_get_end_time( handle);
461 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800462 if (IS_FB(player->speed)) {
463 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen87072a82020-03-12 16:20:12 +0800464 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800465 }
hualing chen87072a82020-03-12 16:20:12 +0800466 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800467 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800468 DVR_DEBUG(1, "next player->dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800469 return ret;
470}
471
hualing chen5cbe1a62020-02-10 16:36:36 +0800472//open next segment to play,if reach list end return errro.
473static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
474{
475 DVR_Playback_t *player = (DVR_Playback_t *) handle;
476 Segment_OpenParams_t params;
477 int ret = DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800478 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800479 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800480 }
hualing chencc91e1c2020-02-28 13:26:17 +0800481 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800482 if (id < 0) {
483 DVR_DEBUG(1, "not found segment info");
484 return DVR_FAILURE;
485 }
hualing chencc91e1c2020-02-28 13:26:17 +0800486 DVR_DEBUG(1, "start found segment[%lld][%lld] info", id,segment_id);
hualing chen2aba4022020-03-02 13:49:55 +0800487 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800488
489 DVR_PlaybackSegmentInfo_t *segment;
490
491 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800492
hualing chen5cbe1a62020-02-10 16:36:36 +0800493 list_for_each_entry(segment, &player->segment_list, head)
494 {
hualing chencc91e1c2020-02-28 13:26:17 +0800495 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 +0800496 if (segment->segment_id == segment_id) {
497 found = 1;
498 }
499 if (found == 1) {
hualing chencc91e1c2020-02-28 13:26:17 +0800500 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 +0800501 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800502 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800503 player->cur_segment_id = segment->segment_id;
504 player->cur_segment.segment_id = segment->segment_id;
505 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800506 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800507 //pids
508 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +0800509 DVR_DEBUG(1, "cur found location [%s]id[%lld]flag[%x]", player->cur_segment.location, player->cur_segment.segment_id,player->cur_segment.flags);
510 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800511 }
512 }
hualing chencc91e1c2020-02-28 13:26:17 +0800513 if (found == 0) {
514 DVR_DEBUG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800515 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800516 return DVR_FAILURE;
517 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800518 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800519 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800520 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800521 params.segment_id = (uint64_t)player->cur_segment.segment_id;
522 params.mode = SEGMENT_MODE_READ;
hualing chencc91e1c2020-02-28 13:26:17 +0800523 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 +0800524 if (player->r_handle != NULL) {
525 segment_close(player->r_handle);
526 player->r_handle = NULL;
527 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800528 ret = segment_open(&params, &(player->r_handle));
hualing chen2aba4022020-03-02 13:49:55 +0800529 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800530 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800531
532 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 +0800533 return ret;
534}
535
536
537//get play info by segment id
538static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
539 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800540 am_tsplayer_video_params *vparam,
541 am_tsplayer_audio_params *aparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800542
543 DVR_Playback_t *player = (DVR_Playback_t *) handle;
544 DVR_PlaybackSegmentInfo_t *segment;
545
546 int found = 0;
547
548 list_for_each_entry(segment, &player->segment_list, head)
549 {
hualing chen87072a82020-03-12 16:20:12 +0800550 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800551 //get first segment from list
552 found = 1;
553 }
554 if (segment->segment_id == segment_id) {
555 found = 1;
556 }
557 if (found == 1) {
558 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800559 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800560 player->cur_segment_id = segment->segment_id;
561 DVR_DEBUG(1, "get play info id [%lld]", player->cur_segment_id);
562 player->cur_segment.segment_id = segment->segment_id;
563 player->cur_segment.flags = segment->flags;
564 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800565 player->cur_segment.pids.video.pid = segment->pids.video.pid;
566 player->cur_segment.pids.video.format = segment->pids.video.format;
567 player->cur_segment.pids.video.type = segment->pids.video.type;
568 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
569 player->cur_segment.pids.audio.format = segment->pids.audio.format;
570 player->cur_segment.pids.audio.type = segment->pids.audio.type;
571 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
572 player->cur_segment.pids.ad.format = segment->pids.ad.format;
573 player->cur_segment.pids.ad.type = segment->pids.ad.type;
574 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800575 //
hualing chen2aba4022020-03-02 13:49:55 +0800576 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800577 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800578 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800579 aparam->pid = segment->pids.audio.pid;
hualing chencc91e1c2020-02-28 13:26:17 +0800580 DVR_DEBUG(1, "get play info sucess[0x%x]apid[0x%x]", vparam->pid, aparam->pid);
hualing chen5cbe1a62020-02-10 16:36:36 +0800581 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800582 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800583 }
584 }
hualing chencc91e1c2020-02-28 13:26:17 +0800585 if (found != 2) {
586 //list is null or reache list end
587 DVR_DEBUG(1, "get play info fail");
588 return DVR_FAILURE;
589 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800590
591 return DVR_SUCCESS;
592}
hualing chencc91e1c2020-02-28 13:26:17 +0800593static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
594 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen5cbe1a62020-02-10 16:36:36 +0800595
hualing chencc91e1c2020-02-28 13:26:17 +0800596 //compare cur segment
597 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
598 {
599 //check video pids, stop or restart
600 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
601 //check audio pids stop or restart
602 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
603 //check sub audio pids stop or restart
604 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
605 //check pcr pids stop or restart
606 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
607 }
608 return 0;
609}
hualing chen5cbe1a62020-02-10 16:36:36 +0800610
hualing chencc91e1c2020-02-28 13:26:17 +0800611static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
612{
613 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800614 DVR_DEBUG(1, "call %s flag[0x%x]id[%lld]last[0x%x][%d]", __func__, player->cur_segment.flags, player->cur_segment.segment_id, player->last_segment.flags, player->last_segment.segment_id);
615 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
616 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800617 //enable display
hualing chen2aba4022020-03-02 13:49:55 +0800618 DVR_DEBUG(1, "call %s unmute", __func__);
619 AmTsPlayer_showVideo(player->handle);
620 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800621 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
622 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800623 //disable display
hualing chencc91e1c2020-02-28 13:26:17 +0800624 DVR_DEBUG(1, "call %s mute", __func__);
hualing chen2aba4022020-03-02 13:49:55 +0800625 AmTsPlayer_hideVideo(player->handle);
626 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800627 }
628 return DVR_SUCCESS;
629}
hualing chen86e7d482020-01-16 15:13:33 +0800630static void* _dvr_playback_thread(void *arg)
631{
hualing chen040df222020-01-17 13:35:02 +0800632 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800633 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800634 am_tsplayer_input_buffer wbufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800635 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800636
hualing chen6d24aa92020-03-23 18:43:47 +0800637 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800638 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800639 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800640 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen86e7d482020-01-16 15:13:33 +0800641 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800642 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800643
hualing chen86e7d482020-01-16 15:13:33 +0800644 buf = malloc(buf_len);
hualing chen2aba4022020-03-02 13:49:55 +0800645 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
646 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800647
648 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800649 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
650 }
hualing chen86e7d482020-01-16 15:13:33 +0800651
hualing chen86e7d482020-01-16 15:13:33 +0800652 if (ret != DVR_SUCCESS) {
653 if (buf != NULL) {
654 free(buf);
655 buf = NULL;
656 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800657 DVR_DEBUG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800658 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800659 }
hualing chencc91e1c2020-02-28 13:26:17 +0800660 //get play statue not here
661 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
662 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800663 //set video show
664 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800665
hualing chen86e7d482020-01-16 15:13:33 +0800666 int trick_stat = 0;
667 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800668
hualing chen86e7d482020-01-16 15:13:33 +0800669 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800670 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800671
hualing chen2aba4022020-03-02 13:49:55 +0800672 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
673 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800674 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
675 player->speed > 1.0f ||player->speed <= -1.0f ||
676 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800677 {
hualing chen2aba4022020-03-02 13:49:55 +0800678 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
679 if (trick_stat > 0) {
680 DVR_DEBUG(1, "trick stat[%d] is > 0", trick_stat);
hualing chen87072a82020-03-12 16:20:12 +0800681 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 +0800682 //check last cmd
683 if(player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800684 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800685 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
686 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800687 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
688 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
689 DVR_DEBUG(1, "pause play-------");
690 //need change to pause state
691 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
692 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800693 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800694 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800695 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chen2aba4022020-03-02 13:49:55 +0800696 first_frame = 0;
697 AmTsPlayer_pauseVideoDecoding(player->handle);
698 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +0800699 }
700 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
701 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen31140872020-03-25 12:29:26 +0800702 ||player->speed > 1.0f ||player->speed < -1.0f) {
hualing chen2aba4022020-03-02 13:49:55 +0800703 //restart play stream if speed > 2
704 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
705 _dvr_time_getClock() < player->next_fffb_time) {
hualing chen31140872020-03-25 12:29:26 +0800706 DVR_DEBUG(1, "fffb timeout----speed[%f] fffb cur[%d] cur sys[%d]", player->speed, player->fffb_current,_dvr_time_getClock());
hualing chen2aba4022020-03-02 13:49:55 +0800707 //used timeout wait need lock first,so we unlock and lock
708 //pthread_mutex_unlock(&player->lock);
709 //pthread_mutex_lock(&player->lock);
710 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
711 pthread_mutex_unlock(&player->lock);
712 continue;
713 }
hualing chen31140872020-03-25 12:29:26 +0800714 DVR_DEBUG(1, "fffb play-------speed[%f][%d][%d]", player->speed, goto_rewrite, real_read);
hualing chen2aba4022020-03-02 13:49:55 +0800715 pthread_mutex_unlock(&player->lock);
716 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800717 real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800718 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
719 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800720 }
hualing chen2aba4022020-03-02 13:49:55 +0800721 }
hualing chenb31a6c62020-01-13 17:27:00 +0800722 }
hualing chen86e7d482020-01-16 15:13:33 +0800723
hualing chen87072a82020-03-12 16:20:12 +0800724 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800725 //check is need send time send end
726 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800727 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
728 pthread_mutex_unlock(&player->lock);
729 continue;
730 }
hualing chen2aba4022020-03-02 13:49:55 +0800731 if (goto_rewrite == DVR_TRUE) {
732 goto_rewrite = DVR_FALSE;
733 pthread_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +0800734 //DVR_DEBUG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +0800735 goto rewrite;
736 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800737 //.check is need send time send end
738 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player);
hualing chen87072a82020-03-12 16:20:12 +0800739
740 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
741 pthread_mutex_unlock(&player->lock);
742 //if on fb mode and read file end , we need calculate pos to retry read.
743 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen31140872020-03-25 12:29:26 +0800744 DVR_DEBUG(1, "recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%d]", read,real_read, buf_len, player->speed,player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800745 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
746 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +0800747 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
748 pthread_mutex_unlock(&player->lock);
749 continue;
750 }
hualing chen31140872020-03-25 12:29:26 +0800751 //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 +0800752 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +0800753 //file end.need to play next segment
hualing chen040df222020-01-17 13:35:02 +0800754 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +0800755 //init fffb time if change segment
756 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +0800757
758 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
759 if (ret != DVR_SUCCESS && delay <= MIN_TSPLAYER_DELAY_TIME) {
760 //send end event to hal
761 DVR_Play_Notify_t notify;
762 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
763 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
764 //get play statue not here
765 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
766 player->auto_pause = DVR_TRUE;
767 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify);
768 //continue,timeshift mode, when read end,need wait cur recording segment
769 DVR_DEBUG(1, "playback is send end");
770 pthread_mutex_lock(&player->lock);
771 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
772 pthread_mutex_unlock(&player->lock);
773 continue;
774 } else if (ret != DVR_SUCCESS && delay > MIN_TSPLAYER_DELAY_TIME) {
775 //not send event and pause,sleep and go to next time to recheck
776 pthread_mutex_lock(&player->lock);
777 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
778 pthread_mutex_unlock(&player->lock);
779 continue;
hualing chen86e7d482020-01-16 15:13:33 +0800780 }
hualing chen31140872020-03-25 12:29:26 +0800781 //change next segment success case
hualing chencc91e1c2020-02-28 13:26:17 +0800782 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player);
783 pthread_mutex_lock(&player->lock);
784 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
785 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +0800786 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +0800787 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800788 }
789 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +0800790 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +0800791 wbufs.buf_data = buf;
hualing chen31140872020-03-25 12:29:26 +0800792rewrite:
hualing chen86e7d482020-01-16 15:13:33 +0800793 //read data
794 //descramble data
795 //read data to inject
hualing chen2aba4022020-03-02 13:49:55 +0800796 if ( AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms) == AM_TSPLAYER_OK) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800797 real_read = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +0800798 continue;
hualing chen87072a82020-03-12 16:20:12 +0800799 } else {
hualing chen6d24aa92020-03-23 18:43:47 +0800800 DVR_DEBUG(1, "write time out");
hualing chencc91e1c2020-02-28 13:26:17 +0800801 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +0800802 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +0800803 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800804 if (!player->is_running) {
hualing chen2aba4022020-03-02 13:49:55 +0800805 DVR_DEBUG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +0800806 break;
807 }
hualing chen2aba4022020-03-02 13:49:55 +0800808 goto_rewrite = DVR_TRUE;
809 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +0800810 }
811 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800812 DVR_DEBUG(1, "playback thread is end");
hualing chen86e7d482020-01-16 15:13:33 +0800813 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +0800814}
815
816
hualing chen040df222020-01-17 13:35:02 +0800817static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800818{
hualing chen040df222020-01-17 13:35:02 +0800819 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +0800820 DVR_DEBUG(1, "start thread------[%d]", player->is_running);
821 if (player->is_running == DVR_TRUE) {
hualing chen86e7d482020-01-16 15:13:33 +0800822 return 0;
823 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800824 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +0800825 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +0800826 if (rc < 0)
827 player->is_running = DVR_FALSE;
hualing chencc91e1c2020-02-28 13:26:17 +0800828 DVR_DEBUG(1, "start thread------[%d] end", player->is_running);
hualing chen86e7d482020-01-16 15:13:33 +0800829 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800830}
831
832
hualing chen040df222020-01-17 13:35:02 +0800833static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800834{
hualing chen040df222020-01-17 13:35:02 +0800835 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +0800836 DVR_DEBUG(1, "stopthread------[%d]", player->is_running);
837 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +0800838 {
839 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800840 _dvr_playback_sendSignal(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800841 //pthread_cond_signal(&player->cond);
hualing chen86e7d482020-01-16 15:13:33 +0800842 pthread_join(player->playback_thread, NULL);
843 }
844 if (player->r_handle) {
845 segment_close(player->r_handle);
846 player->r_handle = NULL;
847 }
hualing chen87072a82020-03-12 16:20:12 +0800848 DVR_DEBUG(1, "stopthread------[%d]", player->is_running);
hualing chen86e7d482020-01-16 15:13:33 +0800849 return 0;
850}
851
hualing chenb31a6c62020-01-13 17:27:00 +0800852/**\brief Open an dvr palyback
853 * \param[out] p_handle dvr playback addr
854 * \param[in] params dvr playback open parameters
855 * \retval DVR_SUCCESS On success
856 * \return Error code
857 */
hualing chen040df222020-01-17 13:35:02 +0800858int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +0800859
hualing chen040df222020-01-17 13:35:02 +0800860 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +0800861 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +0800862
hualing chen040df222020-01-17 13:35:02 +0800863 player = (DVR_Playback_t*)malloc(sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +0800864
hualing chen86e7d482020-01-16 15:13:33 +0800865 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +0800866 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +0800867 pthread_condattr_init(&cattr);
868 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
869 pthread_cond_init(&player->cond, &cattr);
870 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +0800871
hualing chen5cbe1a62020-02-10 16:36:36 +0800872 //init segment list head
hualing chen040df222020-01-17 13:35:02 +0800873 INIT_LIST_HEAD(&player->segment_list);
874 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
875 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +0800876 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +0800877 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +0800878 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +0800879 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +0800880 player->speed = 1.0f;
hualing chen2aba4022020-03-02 13:49:55 +0800881
hualing chen86e7d482020-01-16 15:13:33 +0800882 //store open params
hualing chen040df222020-01-17 13:35:02 +0800883 player->openParams.dmx_dev_id = params->dmx_dev_id;
884 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +0800885 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +0800886 player->openParams.event_fn = params->event_fn;
887 player->openParams.event_userdata = params->event_userdata;
888
hualing chen5cbe1a62020-02-10 16:36:36 +0800889 player->has_pids = params->has_pids;
890
hualing chen2aba4022020-03-02 13:49:55 +0800891 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +0800892
893 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
894 //for test get callback
895 if (0 && player->player_callback_func == NULL) {
896 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
897 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
898 DVR_DEBUG(1, "playback open get callback[%p][%p][%p][%p]",player->player_callback_func, player->player_callback_userdata, _dvr_tsplayer_callback_test,player);
899 }
900 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +0800901
hualing chen86e7d482020-01-16 15:13:33 +0800902 //init has audio and video
903 player->has_video = DVR_FALSE;
904 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +0800905 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +0800906 player->last_segment_id = 0LL;
907 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +0800908
hualing chen5cbe1a62020-02-10 16:36:36 +0800909 //init ff fb time
910 player->fffb_current = -1;
911 player->fffb_start =-1;
912 player->fffb_start_pcr = -1;
913 //seek time
914 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +0800915 player->send_time = 0;
hualing chen87072a82020-03-12 16:20:12 +0800916 //auto pause init
917 player->auto_pause = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +0800918 *p_handle = player;
919 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +0800920}
921
922/**\brief Close an dvr palyback
923 * \param[in] handle playback handle
924 * \retval DVR_SUCCESS On success
925 * \return Error code
926 */
hualing chen040df222020-01-17 13:35:02 +0800927int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800928
hualing chen86e7d482020-01-16 15:13:33 +0800929 DVR_ASSERT(handle);
hualing chenb31a6c62020-01-13 17:27:00 +0800930
hualing chen040df222020-01-17 13:35:02 +0800931 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800932 DVR_DEBUG(1, "func: %s, will resume", __func__);
hualing chencc91e1c2020-02-28 13:26:17 +0800933 if (player->state != DVR_PLAYBACK_STATE_STOP)
934 {
935 dvr_playback_stop(handle, DVR_TRUE);
936 }
hualing chen87072a82020-03-12 16:20:12 +0800937 AmTsPlayer_resumeVideoDecoding(player->handle);
938 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +0800939 pthread_mutex_destroy(&player->lock);
940 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +0800941
942 if (player) {
943 free(player);
944 player = NULL;
945 }
hualing chen86e7d482020-01-16 15:13:33 +0800946 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +0800947}
948
hualing chenb31a6c62020-01-13 17:27:00 +0800949/**\brief Start play audio and video, used start auido api and start video api
950 * \param[in] handle playback handle
951 * \param[in] params audio playback params,contains fmt and pid...
952 * \retval DVR_SUCCESS On success
953 * \return Error code
954 */
hualing chen040df222020-01-17 13:35:02 +0800955int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
956 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +0800957 am_tsplayer_video_params vparams;
958 am_tsplayer_audio_params aparams;
hualing chencc91e1c2020-02-28 13:26:17 +0800959 uint64_t segment_id = player->cur_segment_id;
960 DVR_DEBUG(1, "[%s][%p]segment_id:[%lld]",__func__, handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +0800961
hualing chen040df222020-01-17 13:35:02 +0800962 int sync = DVR_PLAYBACK_SYNC;
hualing chen87072a82020-03-12 16:20:12 +0800963 player->auto_pause = DVR_FALSE;
hualing chencc91e1c2020-02-28 13:26:17 +0800964 //can used start api to resume playback
965 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
966 return dvr_playback_resume(handle);
967 }
hualing chen87072a82020-03-12 16:20:12 +0800968 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
969 DVR_DEBUG(1, "stat is start, not need into start play");
970 return DVR_SUCCESS;
971 }
hualing chen86e7d482020-01-16 15:13:33 +0800972 player->play_flag = flag;
hualing chen5cbe1a62020-02-10 16:36:36 +0800973 //get segment info and audio video pid fmt ;
hualing chen31140872020-03-25 12:29:26 +0800974 DVR_DEBUG(1, "lock func: %s %p flag:0x%x", __func__, handle, flag);
hualing chen86e7d482020-01-16 15:13:33 +0800975 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800976 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +0800977 //start audio and video
978 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
979 //audio abnd video pis is all invalid, return error.
980 DVR_DEBUG(0, "dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +0800981 DVR_DEBUG(1, "unlock func: %s", __func__);
982 pthread_mutex_unlock(&player->lock);
983 DVR_Play_Notify_t notify;
984 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
985 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
986 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
987 notify.info.transition_failed_data.segment_id = segment_id;
988 //get play statue not here
989 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify);
hualing chen86e7d482020-01-16 15:13:33 +0800990 return -1;
991 }
hualing chen31140872020-03-25 12:29:26 +0800992
hualing chencc91e1c2020-02-28 13:26:17 +0800993 {
hualing chen86e7d482020-01-16 15:13:33 +0800994 if (VALID_PID(vparams.pid)) {
995 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +0800996 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +0800997 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
998 DVR_DEBUG(1, "set trick mode -pauselive flag--");
999 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1000 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001001 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen31140872020-03-25 12:29:26 +08001002 DVR_DEBUG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001003 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001004 } else {
1005 DVR_DEBUG(1, "set trick mode ---none");
1006 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001007 }
1008 AmTsPlayer_setVideoParams(player->handle, &vparams);
1009 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001010 }
hualing chen86e7d482020-01-16 15:13:33 +08001011 if (VALID_PID(aparams.pid)) {
1012 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001013 AmTsPlayer_setAudioParams(player->handle, &aparams);
1014 AmTsPlayer_startAudioDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001015 }
hualing chen6d24aa92020-03-23 18:43:47 +08001016 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 +08001017 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1018 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1019 player->cmd.state = DVR_PLAYBACK_STATE_START;
1020 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001021 } else {
1022 player->cmd.last_cmd = player->cmd.cur_cmd;
1023 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen31140872020-03-25 12:29:26 +08001024 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_S2) {
1025 //set fast play
1026 DVR_DEBUG(1, "dvr start fast mode");
1027 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
1028 }
hualing chencc91e1c2020-02-28 13:26:17 +08001029 player->cmd.state = DVR_PLAYBACK_STATE_START;
1030 player->state = DVR_PLAYBACK_STATE_START;
1031 }
hualing chen86e7d482020-01-16 15:13:33 +08001032 }
hualing chencc91e1c2020-02-28 13:26:17 +08001033 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001034 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001035 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001036 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001037}
hualing chen040df222020-01-17 13:35:02 +08001038/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001039 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001040 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001041 * \retval DVR_SUCCESS On success
1042 * \return Error code
1043 */
hualing chen040df222020-01-17 13:35:02 +08001044int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1045 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001046 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001047
hualing chencc91e1c2020-02-28 13:26:17 +08001048 DVR_DEBUG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001049 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001050
hualing chen040df222020-01-17 13:35:02 +08001051 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1052 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001053
hualing chen86e7d482020-01-16 15:13:33 +08001054 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001055 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001056 //cp location
hualing chen040df222020-01-17 13:35:02 +08001057 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001058
1059 DVR_DEBUG(1, "add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001060 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001061
1062 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001063 segment->pids.video.pid = info->pids.video.pid;
1064 segment->pids.video.format = info->pids.video.format;
1065 segment->pids.video.type = info->pids.video.type;
1066
hualing chen2aba4022020-03-02 13:49:55 +08001067 segment->pids.audio.pid = info->pids.audio.pid;
1068 segment->pids.audio.format = info->pids.audio.format;
1069 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001070
hualing chen2aba4022020-03-02 13:49:55 +08001071 segment->pids.ad.pid = info->pids.ad.pid;
1072 segment->pids.ad.format = info->pids.ad.format;
1073 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001074
1075 segment->pids.pcr.pid = info->pids.pcr.pid;
1076
1077 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 +08001078 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001079 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001080 pthread_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001081 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chenb31a6c62020-01-13 17:27:00 +08001082
hualing chen5cbe1a62020-02-10 16:36:36 +08001083 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001084}
hualing chen040df222020-01-17 13:35:02 +08001085/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001086 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001087 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001088 * \retval DVR_SUCCESS On success
1089 * \return Error code
1090 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001091int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001092 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen5cbe1a62020-02-10 16:36:36 +08001093 DVR_DEBUG(1, "remove segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001094 if (segment_id == player->cur_segment_id) {
1095 DVR_DEBUG(1, "not suport remove curren segment id: %lld", segment_id);
1096 return DVR_FAILURE;
1097 }
1098 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001099 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001100 DVR_PlaybackSegmentInfo_t *segment;
1101 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001102 {
hualing chen040df222020-01-17 13:35:02 +08001103 if (segment->segment_id == segment_id) {
1104 list_del(&segment->head);
1105 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001106 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001107 }
hualing chen86e7d482020-01-16 15:13:33 +08001108 }
hualing chencc91e1c2020-02-28 13:26:17 +08001109 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001110 pthread_mutex_unlock(&player->lock);
1111
1112 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001113}
hualing chen040df222020-01-17 13:35:02 +08001114/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001115 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001116 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001117 * \retval DVR_SUCCESS On success
1118 * \return Error code
1119 */
hualing chen040df222020-01-17 13:35:02 +08001120int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001121 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001122 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen5cbe1a62020-02-10 16:36:36 +08001123 DVR_DEBUG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chenb31a6c62020-01-13 17:27:00 +08001124
hualing chen040df222020-01-17 13:35:02 +08001125 DVR_PlaybackSegmentInfo_t *segment;
hualing chencc91e1c2020-02-28 13:26:17 +08001126 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001127 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001128 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001129 {
hualing chen040df222020-01-17 13:35:02 +08001130 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001131 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001132 }
hualing chen86e7d482020-01-16 15:13:33 +08001133 // if encramble to free, only set flag and return;
1134
1135 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001136 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001137 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1138 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001139 //disable display, mute
hualing chen2aba4022020-03-02 13:49:55 +08001140 AmTsPlayer_hideVideo(player->handle);
1141 AmTsPlayer_setAudioMute(player->handle, 1, 1);
1142 //playback_device_mute_audio(player->handle, 1);
1143 //playback_device_mute_video(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001144 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1145 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001146 //enable display, unmute
hualing chen2aba4022020-03-02 13:49:55 +08001147 AmTsPlayer_showVideo(player->handle);
1148 AmTsPlayer_setAudioMute(player->handle, 0, 0);
1149 //playback_device_mute_audio(player->handle, 0);
1150 //playback_device_mute_video(player->handle, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001151 } else {
1152 //do nothing
1153 }
1154 } else {
1155 //do nothing
1156 }
1157 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001158 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001159 }
hualing chencc91e1c2020-02-28 13:26:17 +08001160 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001161 pthread_mutex_unlock(&player->lock);
1162 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001163}
1164
1165
hualing chen5cbe1a62020-02-10 16:36:36 +08001166static 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 +08001167 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001168 DVR_DEBUG(1, "do check pid %p", handle);
1169 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001170
hualing chen86e7d482020-01-16 15:13:33 +08001171 if (now_pid.pid == set_pid.pid) {
1172 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001173 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001174 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001175 if (VALID_PID(now_pid.pid)) {
1176 //stop now stream
1177 if (type == 0) {
1178 //stop vieo
hualing chen2aba4022020-03-02 13:49:55 +08001179 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001180 player->has_video = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001181 } else if (type == 1) {
1182 //stop audio
hualing chen2aba4022020-03-02 13:49:55 +08001183 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001184 player->has_audio = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001185 } else if (type == 2) {
1186 //stop sub audio
hualing chen86e7d482020-01-16 15:13:33 +08001187 } else if (type == 3) {
1188 //pcr
1189 }
1190 }
1191 if (VALID_PID(set_pid.pid)) {
1192 //start
1193 if (type == 0) {
1194 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001195 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001196 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001197 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001198 player->has_video = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001199 AmTsPlayer_setVideoParams(player->handle, &vparams);
1200 AmTsPlayer_startVideoDecoding(player->handle);
1201 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001202 } else if (type == 1) {
1203 //start audio
hualing chen2aba4022020-03-02 13:49:55 +08001204 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001205 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001206 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001207 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001208 AmTsPlayer_setAudioParams(player->handle, &aparams);
1209 AmTsPlayer_startAudioDecoding(player->handle);
1210 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001211 } else if (type == 2) {
hualing chen2aba4022020-03-02 13:49:55 +08001212 am_tsplayer_audio_params aparams;
hualing chen86e7d482020-01-16 15:13:33 +08001213 aparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001214 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001215 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001216 AmTsPlayer_setAudioParams(player->handle, &aparams);
1217 AmTsPlayer_startAudioDecoding(player->handle);
1218 //playback_device_audio_start(player->handle,&aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001219 } else if (type == 3) {
1220 //pcr
hualing chen2aba4022020-03-02 13:49:55 +08001221 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001222 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001223 //audio and video all close
1224 if (!player->has_audio && !player->has_video) {
1225 player->state = DVR_PLAYBACK_STATE_STOP;
1226 }
hualing chen86e7d482020-01-16 15:13:33 +08001227 }
1228 }
1229 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001230}
hualing chen5cbe1a62020-02-10 16:36:36 +08001231/**\brief dvr play back update segment pids
1232 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001233 * add pid stream and stop remove pid stream.
1234 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001235 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001236 * \retval DVR_SUCCESS On success
1237 * \return Error code
1238 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001239int 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 +08001240 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001241 DVR_DEBUG(1, "update segment id: %lld", segment_id);
1242 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001243
hualing chen040df222020-01-17 13:35:02 +08001244 DVR_PlaybackSegmentInfo_t *segment;
hualing chencc91e1c2020-02-28 13:26:17 +08001245 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001246 pthread_mutex_lock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001247 DVR_DEBUG(1, "get lock [%p] update segment id: %lld cur id %lld",handle, segment_id, player->cur_segment_id);
1248
hualing chen040df222020-01-17 13:35:02 +08001249 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001250 {
hualing chen040df222020-01-17 13:35:02 +08001251 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001252
1253 if (player->cur_segment_id == segment_id) {
1254 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1255 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1256 //do nothing when ff fb
1257 DVR_DEBUG(1, "now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001258 DVR_DEBUG(1, "unlock func: %s", __func__);
1259 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001260 return 0;
1261 }
1262
1263 //if segment is on going segment,we need stop start stream
1264 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001265 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001266 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001267 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001268 //check audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001269 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001270 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001271 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
hualing chen5cbe1a62020-02-10 16:36:36 +08001272 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001273 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1274 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001275 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1276 //if state is pause, we need process at resume api. we only record change info
1277 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1278 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1279 if (VALID_PID(segment->pids.video.pid)
1280 && VALID_PID(p_pids->video.pid)
1281 && segment->pids.video.pid != p_pids->video.pid) {
1282 //restart video
1283 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1284 }
1285 if (!VALID_PID(segment->pids.video.pid)
1286 && VALID_PID(p_pids->video.pid)
1287 && segment->pids.video.pid != p_pids->video.pid) {
1288 //start video
1289 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1290 }
1291 if (VALID_PID(segment->pids.video.pid)
1292 && !VALID_PID(p_pids->video.pid)
1293 && segment->pids.video.pid != p_pids->video.pid) {
1294 //stop video
1295 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1296 }
1297 if (VALID_PID(segment->pids.audio.pid)
1298 && VALID_PID(p_pids->audio.pid)
1299 && segment->pids.audio.pid != p_pids->audio.pid) {
1300 //restart audio
1301 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1302 }
1303 if (!VALID_PID(segment->pids.audio.pid)
1304 && VALID_PID(p_pids->audio.pid)
1305 && segment->pids.audio.pid != p_pids->audio.pid) {
1306 //start audio
1307 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1308 }
1309 if (VALID_PID(segment->pids.audio.pid)
1310 && !VALID_PID(p_pids->audio.pid)
1311 && segment->pids.audio.pid != p_pids->audio.pid) {
1312 //stop audio
1313 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1314 }
1315 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1316 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1317 //do nothing
1318 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1319 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1320 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1321 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1322 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1323 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1324 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1325 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1326 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1327 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1328 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1329 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1330 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1331 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1332 } else {
1333 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1334 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1335 }
1336
1337 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1338 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1339 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1340 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1341 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1342 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1343 //not occur this case
1344 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1345 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1346 } else {
1347 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1348 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1349 }
1350
1351 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1352 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1353 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1354 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1355 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1356 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1357 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1358 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1359 } else {
1360 //not occur this case
1361 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1362 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1363 }
1364 }
1365 }
1366 }
hualing chen86e7d482020-01-16 15:13:33 +08001367 //save pids info
hualing chen040df222020-01-17 13:35:02 +08001368 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +08001369 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001370 }
hualing chen86e7d482020-01-16 15:13:33 +08001371 }
hualing chencc91e1c2020-02-28 13:26:17 +08001372 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001373 pthread_mutex_unlock(&player->lock);
1374 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001375}
1376/**\brief Stop play, will stop video and audio
1377 * \param[in] handle playback handle
1378 * \param[in] clear is clear last frame
1379 * \retval DVR_SUCCESS On success
1380 * \return Error code
1381 */
hualing chen040df222020-01-17 13:35:02 +08001382int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1383 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001384 DVR_DEBUG(1, "---into-stop-----");
1385 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen87072a82020-03-12 16:20:12 +08001386 _stop_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001387 pthread_mutex_lock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001388 DVR_DEBUG(1, "---into-stop---1--");
hualing chen31140872020-03-25 12:29:26 +08001389 AmTsPlayer_stopFast(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001390 AmTsPlayer_resumeVideoDecoding(player->handle);
1391 AmTsPlayer_resumeAudioDecoding(player->handle);
1392 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001393 AmTsPlayer_stopVideoDecoding(player->handle);
1394 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001395 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001396 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1397 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1398 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001399 player->cur_segment_id = UINT64_MAX;
1400 player->segment_is_open = DVR_FALSE;
hualing chencc91e1c2020-02-28 13:26:17 +08001401 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001402 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001403 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001404}
1405/**\brief Start play audio
1406 * \param[in] handle playback handle
1407 * \param[in] params audio playback params,contains fmt and pid...
1408 * \retval DVR_SUCCESS On success
1409 * \return Error code
1410 */
hualing chen2aba4022020-03-02 13:49:55 +08001411
1412int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001413 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001414 DVR_DEBUG(1, "into func: %s", __func__);
1415 DVR_DEBUG(1, "[%s][%p]",__func__, handle);
hualing chen86e7d482020-01-16 15:13:33 +08001416 _start_playback_thread(handle);
1417 //start audio and video
hualing chencc91e1c2020-02-28 13:26:17 +08001418 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001419 pthread_mutex_lock(&player->lock);
1420 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001421 AmTsPlayer_setAudioParams(player->handle, param);
1422 AmTsPlayer_startAudioDecoding(player->handle);
1423 //playback_device_audio_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001424 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001425 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
1426 player->cmd.state = DVR_PLAYBACK_STATE_START;
1427 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001428 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001429 pthread_mutex_unlock(&player->lock);
1430 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001431}
1432/**\brief Stop play audio
1433 * \param[in] handle playback handle
1434 * \retval DVR_SUCCESS On success
1435 * \return Error code
1436 */
hualing chen040df222020-01-17 13:35:02 +08001437int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
1438 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001439 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001440 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001441
hualing chen2aba4022020-03-02 13:49:55 +08001442 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001443 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001444 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1445 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001446 //destory thread
1447 _stop_playback_thread(handle);
1448 } else {
1449 //do nothing.video is playing
1450 }
hualing chen87072a82020-03-12 16:20:12 +08001451 player->has_audio = DVR_FALSE;
1452
1453 AmTsPlayer_stopAudioDecoding(player->handle);
1454 player->cmd.last_cmd = player->cmd.cur_cmd;
1455 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
1456
hualing chencc91e1c2020-02-28 13:26:17 +08001457 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001458 pthread_mutex_unlock(&player->lock);
1459 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001460}
1461/**\brief Start play video
1462 * \param[in] handle playback handle
1463 * \param[in] params video playback params,contains fmt and pid...
1464 * \retval DVR_SUCCESS On success
1465 * \return Error code
1466 */
hualing chen2aba4022020-03-02 13:49:55 +08001467int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08001468 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +08001469 _start_playback_thread(handle);
1470 //start audio and video
hualing chencc91e1c2020-02-28 13:26:17 +08001471 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001472 pthread_mutex_lock(&player->lock);
1473 player->has_video = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001474 AmTsPlayer_setAudioParams(player->handle, param);
1475 AmTsPlayer_startAudioDecoding(player->handle);
1476
1477 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08001478 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08001479 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen87072a82020-03-12 16:20:12 +08001480 DVR_DEBUG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08001481 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1482 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08001483 }
1484 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001485 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
1486 player->cmd.state = DVR_PLAYBACK_STATE_START;
1487 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001488 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001489 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001490 return DVR_SUCCESS;
1491}
1492/**\brief Stop play video
1493 * \param[in] handle playback handle
1494 * \retval DVR_SUCCESS On success
1495 * \return Error code
1496 */
hualing chen040df222020-01-17 13:35:02 +08001497int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
1498 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001499 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001500 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001501
1502 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08001503 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1504 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001505 //destory thread
1506 _stop_playback_thread(handle);
1507 } else {
1508 //do nothing.audio is playing
1509 }
hualing chen87072a82020-03-12 16:20:12 +08001510 player->has_video = DVR_FALSE;
1511
1512 AmTsPlayer_stopVideoDecoding(player->handle);
1513 //playback_device_video_stop(player->handle);
1514
1515 player->cmd.last_cmd = player->cmd.cur_cmd;
1516 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
1517
hualing chencc91e1c2020-02-28 13:26:17 +08001518 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001519 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001520 return DVR_SUCCESS;
1521}
1522/**\brief Pause play
1523 * \param[in] handle playback handle
1524 * \param[in] flush whether its internal buffers should be flushed
1525 * \retval DVR_SUCCESS On success
1526 * \return Error code
1527 */
hualing chen040df222020-01-17 13:35:02 +08001528int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
1529 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08001530 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001531 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001532 DVR_DEBUG(1, "get lock func: %s", __func__);
1533 AmTsPlayer_pauseVideoDecoding(player->handle);
1534 AmTsPlayer_pauseAudioDecoding(player->handle);
1535
1536 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001537 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1538 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1539 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1540 player->state = DVR_PLAYBACK_STATE_PAUSE;
1541 player->auto_pause = DVR_FALSE;
1542 } else {
1543 player->cmd.last_cmd = player->cmd.cur_cmd;
1544 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1545 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1546 player->state = DVR_PLAYBACK_STATE_PAUSE;
1547 player->auto_pause = DVR_FALSE;
1548 }
hualing chen86e7d482020-01-16 15:13:33 +08001549 pthread_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001550 DVR_DEBUG(1, "unlock func: %s", __func__);
1551
hualing chen86e7d482020-01-16 15:13:33 +08001552 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001553}
1554
hualing chen5cbe1a62020-02-10 16:36:36 +08001555//not add lock
1556static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
1557{
1558 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1559
1560 //get video params and audio params
hualing chencc91e1c2020-02-28 13:26:17 +08001561 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08001562 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001563 am_tsplayer_video_params vparams;
1564 am_tsplayer_audio_params aparams;
hualing chencc91e1c2020-02-28 13:26:17 +08001565 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08001566
1567 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams);
hualing chen87072a82020-03-12 16:20:12 +08001568 DVR_DEBUG(1, "unlock func: %s cmd: %d", __func__, cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08001569 pthread_mutex_unlock(&player->lock);
1570
1571 switch (cmd) {
1572 case DVR_PLAYBACK_CMD_AVRESTART:
1573 //av restart
hualing chen87072a82020-03-12 16:20:12 +08001574 DVR_DEBUG(1, "do_cmd avrestart");
1575 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001576 break;
1577 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001578 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1579 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001580 break;
1581 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001582 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001583 break;
1584 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001585 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001586 break;
1587 case DVR_PLAYBACK_CMD_ARESTART:
1588 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08001589 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1590 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001591 break;
1592 case DVR_PLAYBACK_CMD_ASTART:
hualing chen2aba4022020-03-02 13:49:55 +08001593 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001594 break;
1595 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08001596 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001597 break;
1598 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001599 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1600 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1601 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001602 break;
1603 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08001604 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1605 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001606 break;
1607 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001608 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1609 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1610 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001611 break;
1612 case DVR_PLAYBACK_CMD_STOP:
1613 break;
1614 case DVR_PLAYBACK_CMD_START:
1615 break;
1616 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001617 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
1618 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
1619 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001620 break;
1621 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08001622 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
1623 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
1624 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001625 break;
1626 case DVR_PLAYBACK_CMD_FF:
1627 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08001628 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001629 break;
1630 default:
1631 break;
1632 }
1633 return DVR_SUCCESS;
1634}
1635
1636/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08001637 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08001638 * \retval DVR_SUCCESS On success
1639 * \return Error code
1640 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001641int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
1642 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1643
1644 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001645 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08001646 pthread_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001647 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001648 AmTsPlayer_resumeVideoDecoding(player->handle);
1649 AmTsPlayer_resumeAudioDecoding(player->handle);
1650 //playback_device_resume(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08001651 player->auto_pause = DVR_FALSE;
1652 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1653 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1654 player->cmd.state = DVR_PLAYBACK_STATE_START;
1655 player->state = DVR_PLAYBACK_STATE_START;
1656 } else {
1657 player->cmd.last_cmd = player->cmd.cur_cmd;
1658 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
1659 player->cmd.state = DVR_PLAYBACK_STATE_START;
1660 player->state = DVR_PLAYBACK_STATE_START;
1661 }
hualing chencc91e1c2020-02-28 13:26:17 +08001662 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08001663 pthread_mutex_unlock(&player->lock);
1664 } else {
hualing chen31140872020-03-25 12:29:26 +08001665 player->auto_pause = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001666 AmTsPlayer_resumeVideoDecoding(player->handle);
1667 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001668 DVR_DEBUG(1, "func: %s, set start state", __func__);
1669 player->cmd.state = DVR_PLAYBACK_STATE_START;
1670 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08001671 _dvr_cmd(handle, player->cmd.cur_cmd);
1672 }
1673 return DVR_SUCCESS;
1674}
1675
hualing chen5cbe1a62020-02-10 16:36:36 +08001676/**\brief seek
1677 * \param[in] handle playback handle
1678 * \param[in] time_offset time offset base cur segment
1679 * \retval DVR_SUCCESS On success
1680 * \return Error code
1681 */
hualing chencc91e1c2020-02-28 13:26:17 +08001682int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08001683 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +08001684 DVR_DEBUG(1, "lock func: %s segment_id %llu cur id %d 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 +08001685 DVR_DEBUG(1, "[%s][%p]---player->state[%d]----",__func__, handle, player->state);
hualing chen86e7d482020-01-16 15:13:33 +08001686 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001687 DVR_DEBUG(1, "[%s][%p]---player->state[%d]---get lock-",__func__, handle, player->state);
1688
hualing chen86e7d482020-01-16 15:13:33 +08001689 int offset = -1;
hualing chen5cbe1a62020-02-10 16:36:36 +08001690 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08001691 int ret = _dvr_open_segment(handle, segment_id);
1692 if (ret ==DVR_FAILURE) {
1693 DVR_DEBUG(1, "seek error at open segment");
1694 pthread_mutex_unlock(&player->lock);
1695 return DVR_FAILURE;
1696 }
1697 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
1698 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
1699 DVR_DEBUG(1, "is ongoing segment when seek end, need return success");
1700 //pthread_mutex_unlock(&player->lock);
1701 //return DVR_SUCCESS;
1702 time_offset = _dvr_get_end_time(handle);
1703 } else {
1704 DVR_DEBUG(1, "is not ongoing segment when seek end, return failure");
1705 pthread_mutex_unlock(&player->lock);
1706 return DVR_FAILURE;
1707 }
1708 }
1709
hualing chencc91e1c2020-02-28 13:26:17 +08001710 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 +08001711 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08001712 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
1713 //forward playback.not seek end of file
1714 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
1715 //default -2000ms
1716 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
1717 }
hualing chen86e7d482020-01-16 15:13:33 +08001718 }
hualing chen2aba4022020-03-02 13:49:55 +08001719 pthread_mutex_lock(&player->segment_lock);
1720 offset = segment_seek(player->r_handle, (uint64_t)time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08001721 DVR_DEBUG(0, "---seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
1722 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001723 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08001724
hualing chen2aba4022020-03-02 13:49:55 +08001725 _dvr_get_end_time(handle);
1726 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08001727 player->fffb_current = _dvr_time_getClock();
1728 player->fffb_start = player->fffb_current;
1729 player->fffb_start_pcr = _dvr_get_cur_time(handle);
1730 player->next_fffb_time = player->fffb_current;
hualing chen2aba4022020-03-02 13:49:55 +08001731
1732 if (player->state == DVR_PLAYBACK_STATE_STOP || player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001733 //only seek file,not start
hualing chencc91e1c2020-02-28 13:26:17 +08001734 DVR_DEBUG(1, "unlock func: %s", __func__);
1735 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001736 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08001737 }
hualing chen86e7d482020-01-16 15:13:33 +08001738 //stop play
hualing chen2aba4022020-03-02 13:49:55 +08001739 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 +08001740 if (player->has_video)
hualing chen2aba4022020-03-02 13:49:55 +08001741 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08001742 if (player->has_audio)
hualing chen2aba4022020-03-02 13:49:55 +08001743 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001744 //start play
hualing chen2aba4022020-03-02 13:49:55 +08001745 am_tsplayer_video_params vparams;
1746 am_tsplayer_audio_params aparams;
hualing chenb31a6c62020-01-13 17:27:00 +08001747
hualing chen040df222020-01-17 13:35:02 +08001748 player->cur_segment_id = segment_id;
1749
1750 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08001751 //get segment info and audio video pid fmt ;
1752 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
hualing chen86e7d482020-01-16 15:13:33 +08001753 //start audio and video
1754 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1755 //audio abnd video pis is all invalid, return error.
1756 DVR_DEBUG(0, "seek start dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001757 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001758 pthread_mutex_unlock(&player->lock);
1759 return -1;
1760 }
1761 //add
hualing chen040df222020-01-17 13:35:02 +08001762 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08001763 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001764 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08001765 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chen31140872020-03-25 12:29:26 +08001766 player->speed > 1.0f||
1767 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001768 //if is pause state. we need set trick mode.
hualing chen31140872020-03-25 12:29:26 +08001769 DVR_DEBUG(1, "[%s]seek set trick mode player->speed [%f]", __func__, player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001770 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08001771 }
hualing chen2aba4022020-03-02 13:49:55 +08001772 AmTsPlayer_setVideoParams(player->handle, &vparams);
1773 AmTsPlayer_startVideoDecoding(player->handle);
1774 //playback_device_video_start(player->handle , &vparams);
hualing chenb31a6c62020-01-13 17:27:00 +08001775 }
hualing chen86e7d482020-01-16 15:13:33 +08001776 if (VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08001777 AmTsPlayer_setAudioParams(player->handle, &aparams);
1778 AmTsPlayer_startAudioDecoding(player->handle);
1779 //playback_device_audio_start(player->handle , &aparams);
hualing chenb31a6c62020-01-13 17:27:00 +08001780 }
hualing chen86e7d482020-01-16 15:13:33 +08001781 }
hualing chen2aba4022020-03-02 13:49:55 +08001782 if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
1783 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1784 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
1785 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
1786 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))) {
1787 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
1788 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001789 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
1790 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001791 player->speed > 1.0f||
1792 player->speed <= -1.0f) {
hualing chen87072a82020-03-12 16:20:12 +08001793 DVR_DEBUG(1, "not set cmd to seek");
1794 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08001795 } else {
hualing chen87072a82020-03-12 16:20:12 +08001796 DVR_DEBUG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08001797 player->cmd.last_cmd = player->cmd.cur_cmd;
1798 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
1799 player->cmd.state = DVR_PLAYBACK_STATE_START;
1800 player->state = DVR_PLAYBACK_STATE_START;
1801 }
hualing chencc91e1c2020-02-28 13:26:17 +08001802 DVR_DEBUG(1, "unlock func: %s ---", __func__);
hualing chen86e7d482020-01-16 15:13:33 +08001803 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08001804
1805 return DVR_SUCCESS;
1806}
hualing chen5cbe1a62020-02-10 16:36:36 +08001807
1808//get current segment current pcr time of read pos
1809static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
1810 //get cur time of segment
1811 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen31140872020-03-25 12:29:26 +08001812 int64_t cache = 0;//defalut es buf cache 500ms
1813 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08001814 pthread_mutex_lock(&player->segment_lock);
1815 uint64_t cur = segment_tell_current_time(player->r_handle);
1816 pthread_mutex_unlock(&player->segment_lock);
1817 DVR_DEBUG(1, "get cur time [%lld]", cur);
hualing chen87072a82020-03-12 16:20:12 +08001818 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1819 cache = 0;
1820 }
hualing chen31140872020-03-25 12:29:26 +08001821 return (int)(cur > cache ? cur - cache : 0);
hualing chencc91e1c2020-02-28 13:26:17 +08001822}
1823
1824//get current segment current pcr time of read pos
1825static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
1826 //get cur time of segment
1827 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001828 pthread_mutex_lock(&player->segment_lock);
1829 uint64_t end = segment_tell_total_time(player->r_handle);
1830 DVR_DEBUG(1, "get tatal time [%lld]", end);
1831 pthread_mutex_unlock(&player->segment_lock);
1832 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08001833}
1834
hualing chen87072a82020-03-12 16:20:12 +08001835#define FB_MIX_SEEK_TIME 1000
hualing chen5cbe1a62020-02-10 16:36:36 +08001836//start replay
1837static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
1838
1839 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1840 //calculate pcr seek time
1841 int t_diff = 0;
1842 int seek_time = 0;
1843 if (player->fffb_start == -1) {
1844 //set fffb start time ms
1845 player->fffb_start = _dvr_time_getClock();
1846 player->fffb_current = player->fffb_start;
1847 //get segment current time pos
1848 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen31140872020-03-25 12:29:26 +08001849 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 +08001850 t_diff = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001851 //default first time 1ms seek
hualing chen87072a82020-03-12 16:20:12 +08001852 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08001853 } else {
1854 player->fffb_current = _dvr_time_getClock();
1855 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08001856 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08001857 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08001858 if (seek_time <= 0) {
1859 //need seek to pre one segment
1860 seek_time = 0;
1861 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001862 //seek segment pos
1863 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08001864 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001865 segment_seek(player->r_handle, seek_time);
hualing chen2aba4022020-03-02 13:49:55 +08001866 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001867 } else {
1868 //
1869 DVR_DEBUG(1, "segment not open,can not seek");
1870 }
hualing chen31140872020-03-25 12:29:26 +08001871 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 +08001872 }
hualing chen2aba4022020-03-02 13:49:55 +08001873 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08001874}
1875
1876
1877//start replay
1878static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
1879 //
1880 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1881 //stop
hualing chen2aba4022020-03-02 13:49:55 +08001882 if (player->has_video) {
1883 DVR_DEBUG(1, "fffb stop video");
1884 AmTsPlayer_stopVideoDecoding(player->handle);
1885 }
1886 if (player->has_audio) {
1887 DVR_DEBUG(1, "fffb stop audio");
1888 AmTsPlayer_stopAudioDecoding(player->handle);
1889 }
1890
hualing chen5cbe1a62020-02-10 16:36:36 +08001891 //start video and audio
1892
hualing chen2aba4022020-03-02 13:49:55 +08001893 am_tsplayer_video_params vparams;
1894 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08001895 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08001896
1897 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08001898 //pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001899 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
1900 //start audio and video
1901 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
1902 //audio abnd video pis is all invalid, return error.
1903 DVR_DEBUG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001904 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001905 return -1;
1906 }
1907
1908 if (VALID_PID(vparams.pid)) {
1909 player->has_video = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001910 DVR_DEBUG(1, "fffb start video");
hualing chen31140872020-03-25 12:29:26 +08001911 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001912 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1913 AmTsPlayer_setVideoParams(player->handle, &vparams);
1914 AmTsPlayer_startVideoDecoding(player->handle);
1915 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001916 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08001917 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001918 }
1919 if (VALID_PID(aparams.pid)) {
1920 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08001921 DVR_DEBUG(1, "fffb start audio");
1922 AmTsPlayer_setAudioParams(player->handle, &aparams);
1923 AmTsPlayer_startAudioDecoding(player->handle);
1924 //playback_device_audio_start(player->handle , &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08001925 }
hualing chen31140872020-03-25 12:29:26 +08001926 //fffb mode need stop fast;
1927 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001928
hualing chencc91e1c2020-02-28 13:26:17 +08001929 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001930 return 0;
1931}
1932
1933static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
1934 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001935 first_frame = 0;
hualing chen31140872020-03-25 12:29:26 +08001936 DVR_DEBUG(1, "lock func: %s speed [%f]", __func__, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08001937 pthread_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001938 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 +08001939
hualing chen2aba4022020-03-02 13:49:55 +08001940 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen87072a82020-03-12 16:20:12 +08001941 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
1942 //seek time set 0
1943 seek_time = 0;
1944 }
hualing chen2aba4022020-03-02 13:49:55 +08001945 if (seek_time == 0 && IS_FB(player->speed)) {
1946 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
1947 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1948 if (ret != DVR_SUCCESS) {
hualing chen87072a82020-03-12 16:20:12 +08001949 pthread_mutex_unlock(&player->lock);
1950 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08001951 //send event here and pause
1952 DVR_Play_Notify_t notify;
1953 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08001954 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08001955 //get play statue not here
1956 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify);
hualing chen31140872020-03-25 12:29:26 +08001957 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 +08001958 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08001959 return DVR_SUCCESS;
1960 }
hualing chen87072a82020-03-12 16:20:12 +08001961 _dvr_playback_sent_transition_ok(handle);
hualing chen2aba4022020-03-02 13:49:55 +08001962 _dvr_init_fffb_time(handle);
hualing chen31140872020-03-25 12:29:26 +08001963 DVR_DEBUG(1, "*******************send trans ok event func: %s speed [%f]", __func__, player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001964 }
1965 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08001966 _dvr_playback_fffb_replay(handle);
1967
1968 pthread_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001969 DVR_DEBUG(1, "unlock func: %s", __func__);
1970
hualing chen5cbe1a62020-02-10 16:36:36 +08001971 return DVR_SUCCESS;
1972}
1973
hualing chen87072a82020-03-12 16:20:12 +08001974//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08001975static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001976 //
1977 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1978 //stop
hualing chen2aba4022020-03-02 13:49:55 +08001979 if (player->has_video) {
1980 AmTsPlayer_stopVideoDecoding(player->handle);
1981 //playback_device_video_stop(player->handle);
1982 }
1983
1984 if (player->has_audio) {
1985 AmTsPlayer_stopAudioDecoding(player->handle);
1986 //playback_device_audio_stop(player->handle);
1987 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001988 //start video and audio
1989
hualing chen2aba4022020-03-02 13:49:55 +08001990 am_tsplayer_video_params vparams;
1991 am_tsplayer_audio_params aparams;
hualing chen87072a82020-03-12 16:20:12 +08001992 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08001993
1994 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08001995 DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08001996 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams);
1997 //start audio and video
1998 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08001999 //audio and video pis is all invalid, return error.
hualing chen5cbe1a62020-02-10 16:36:36 +08002000 DVR_DEBUG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002001 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002002 return -1;
2003 }
2004
2005 if (VALID_PID(vparams.pid)) {
2006 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002007 if (trick == DVR_TRUE) {
2008 DVR_DEBUG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002009 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002010 }
hualing chen2aba4022020-03-02 13:49:55 +08002011 else
2012 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2013 AmTsPlayer_setVideoParams(player->handle, &vparams);
2014 AmTsPlayer_startVideoDecoding(player->handle);
2015 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002016 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002017 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002018 }
2019 if (VALID_PID(aparams.pid)) {
2020 player->has_audio = DVR_TRUE;
hualing chen2aba4022020-03-02 13:49:55 +08002021 AmTsPlayer_startAudioDecoding(player->handle);
2022 AmTsPlayer_setAudioParams(player->handle, &aparams);
2023 //playback_device_audio_start(player->handle , &aparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002024 }
hualing chen31140872020-03-25 12:29:26 +08002025 if (player->cmd.speed.speed.speed = PLAYBACK_SPEED_S2) {
2026 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2027 } else {
2028 AmTsPlayer_stopFast(player->handle);
2029 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2030 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2031 }
hualing chen2aba4022020-03-02 13:49:55 +08002032 player->cmd.last_cmd = player->cmd.cur_cmd;
2033 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002034 player->cmd.state = DVR_PLAYBACK_STATE_START;
2035 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08002036 DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen5cbe1a62020-02-10 16:36:36 +08002037 return 0;
2038}
2039
2040
hualing chenb31a6c62020-01-13 17:27:00 +08002041/**\brief Set play speed
2042 * \param[in] handle playback handle
2043 * \param[in] speed playback speed
2044 * \retval DVR_SUCCESS On success
2045 * \return Error code
2046 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002047int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2048
2049 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +08002050 DVR_DEBUG(1, "lock func: %s speed [%d]", __func__, speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002051 pthread_mutex_lock(&player->lock);
2052 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2053 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2054 player->cmd.last_cmd = player->cmd.cur_cmd;
2055 }
hualing chen31140872020-03-25 12:29:26 +08002056 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
2057 speed.speed.speed == PLAYBACK_SPEED_S2) {
2058 //case 1. cur speed is 100,set 50.
2059 //we think x1 and s2 is normal speed. is not ff fb.
2060 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen87072a82020-03-12 16:20:12 +08002061 //if last speed is x2 or s2, we need stop fast
hualing chen31140872020-03-25 12:29:26 +08002062 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
2063 player->cmd.speed.mode = speed.mode;
2064 player->cmd.speed.speed = speed.speed;
2065 player->speed = (float)speed.speed.speed/(float)100;
2066 pthread_mutex_unlock(&player->lock);
2067 return DVR_SUCCESS;
2068 }
2069 //case 2. not start play
2070 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2071 //only set speed.and return;
2072 player->cmd.speed.mode = speed.mode;
2073 player->cmd.speed.speed = speed.speed;
2074 player->speed = (float)speed.speed.speed/(float)100;
2075 pthread_mutex_unlock(&player->lock);
2076 return DVR_SUCCESS;
hualing chen87072a82020-03-12 16:20:12 +08002077 }
hualing chen31140872020-03-25 12:29:26 +08002078 //case 3 fffb mode
2079 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2080 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2081 //restart play at normal speed exit ff fb
2082 DVR_DEBUG(1, "set speed normal and replay playback");
2083 player->cmd.speed.mode = speed.mode;
2084 player->cmd.speed.speed = speed.speed;
2085 player->speed = (float)speed.speed.speed/(float)100;
2086 _dvr_playback_replay(handle, DVR_FALSE);
2087 pthread_mutex_unlock(&player->lock);
2088 return DVR_SUCCESS;
2089 }
2090 }
2091 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
2092 speed.speed.speed == PLAYBACK_SPEED_S2) {
2093 //case 1. cur speed is 100,set 50.
2094 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2095 //if last speed is x2 or s2, we need stop fast
2096 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
2097 player->cmd.speed.mode = speed.mode;
2098 player->cmd.speed.speed = speed.speed;
2099 player->speed = (float)speed.speed.speed/(float)100;
2100 pthread_mutex_unlock(&player->lock);
2101 return DVR_SUCCESS;
2102 }
2103 //case 2 fffb mode
2104 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2105 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2106 //restart play at normal speed exit ff fb
2107 DVR_DEBUG(1, "set speed x1 s2 and replay playback");
2108 player->cmd.speed.mode = speed.mode;
2109 player->cmd.speed.speed = speed.speed;
2110 player->speed = (float)speed.speed.speed/(float)100;
2111 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2112 pthread_mutex_unlock(&player->lock);
2113 return DVR_SUCCESS;
2114 }
2115 //case 3 x2 to s2 or s2 to x2 not support this case, x2 is fffb
2116 /*if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X2 ||
2117 player->cmd.speed.speed.speed == PLAYBACK_SPEED_S2) {
2118 player->cmd.speed.mode = speed.mode;
2119 player->cmd.speed.speed = speed.speed;
2120 player->speed = (float)speed.speed.speed/(float)100;
2121 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
2122 pthread_mutex_unlock(&player->lock);
2123 return DVR_SUCCESS;
2124 }*/
2125 }
2126 if ((speed.speed.speed == PLAYBACK_SPEED_X1) ||
2127 (speed.speed.speed == PLAYBACK_SPEED_S2)) {
2128 //we think x1 and s2 is normal speed. is not ff fb.
hualing chen87072a82020-03-12 16:20:12 +08002129 } else {
hualing chen31140872020-03-25 12:29:26 +08002130 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08002131 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
2132 else
2133 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
2134 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002135 player->cmd.speed.mode = speed.mode;
2136 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08002137 player->speed = (float)speed.speed.speed/(float)100;
2138 //reset fffb time, if change speed value
2139 _dvr_init_fffb_time(handle);
hualing chen87072a82020-03-12 16:20:12 +08002140 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08002141 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2142 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08002143 //restart play at normal speed exit ff fb
2144 DVR_DEBUG(1, "set speed normal and replay playback");
2145 _dvr_playback_replay(handle, DVR_FALSE);
2146 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
2147 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
2148 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2149 DVR_DEBUG(1, "set speed normal at pause state ,set cur cmd");
2150 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002151 //need exit ff fb
hualing chen31140872020-03-25 12:29:26 +08002152 DVR_DEBUG(1, "unlock func: %s speed[%f]cmd[%d]", __func__, player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002153 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002154 return DVR_SUCCESS;
2155}
2156/**\brief Get playback status
2157 * \param[in] handle playback handle
2158 * \param[out] p_status playback status
2159 * \retval DVR_SUCCESS On success
2160 * \return Error code
2161 */
hualing chen040df222020-01-17 13:35:02 +08002162int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002163 DVR_PlaybackStatus_t *p_status) {
2164//
2165 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chencc91e1c2020-02-28 13:26:17 +08002166 //pthread_mutex_lock(&player->lock);
2167 //DVR_DEBUG(1, "lock func: %s", __func__);
hualing chen6d24aa92020-03-23 18:43:47 +08002168 //DVR_DEBUG(1, "get stat start id[%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +08002169
2170 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08002171 //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 +08002172 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
2173 player->state == DVR_PLAYBACK_STATE_START) {
2174 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
2175 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002176 p_status->segment_id = player->cur_segment_id;
hualing chencc91e1c2020-02-28 13:26:17 +08002177 p_status->time_end = _dvr_get_end_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002178 p_status->time_cur = _dvr_get_cur_time(handle);
hualing chen2aba4022020-03-02 13:49:55 +08002179
hualing chen5cbe1a62020-02-10 16:36:36 +08002180 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08002181 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08002182 p_status->flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +08002183 //pthread_mutex_unlock(&player->lock);
2184 //DVR_DEBUG(1, "unlock func: %s", __func__);
hualing chen6d24aa92020-03-23 18:43:47 +08002185 DVR_DEBUG(1, "get stat end player state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]",
2186 _dvr_playback_state_toString(player->state),
2187 _dvr_playback_state_toString(p_status->state),
2188 p_status->time_cur, p_status->time_end, p_status->segment_id,player->play_flag);
hualing chenb31a6c62020-01-13 17:27:00 +08002189 return DVR_SUCCESS;
2190}
2191
hualing chen040df222020-01-17 13:35:02 +08002192void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
2193 if (segment != NULL) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002194 DVR_DEBUG(1, "segment id: %lld", segment->segment_id);
hualing chen040df222020-01-17 13:35:02 +08002195 DVR_DEBUG(1, "segment flag: %d", segment->flags);
2196 DVR_DEBUG(1, "segment location: [%s]", segment->location);
2197 DVR_DEBUG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
2198 DVR_DEBUG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
2199 DVR_DEBUG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
2200 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 +08002201 }
hualing chenb31a6c62020-01-13 17:27:00 +08002202}
2203
hualing chen5cbe1a62020-02-10 16:36:36 +08002204int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002205 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08002206
hualing chen040df222020-01-17 13:35:02 +08002207 DVR_PlaybackSegmentInfo_t *segment;
2208 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002209 {
hualing chen040df222020-01-17 13:35:02 +08002210 if (segment_id >= 0) {
2211 if (segment->segment_id == segment_id) {
2212 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002213 break;
2214 }
2215 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08002216 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08002217 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002218 }
2219 }
2220 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002221}