blob: 92e0fc42695b556d6a4ec3f9a4b98d4975ca5dae [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <poll.h>
11#include <errno.h>
12#include <signal.h>
13#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080014#include <errno.h>
hualing chenb31a6c62020-01-13 17:27:00 +080015
hualing chenb31a6c62020-01-13 17:27:00 +080016#include "dvr_playback.h"
17
Gong Ke2a0ebbe2021-05-25 15:22:50 +080018#define DVR_PB_DG(_level, _fmt...) \
19 DVR_DEBUG_FL(_level, "playback", _fmt)
hualing chena540a7e2020-03-27 16:44:05 +080020
hualing chenb31a6c62020-01-13 17:27:00 +080021#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080022
23
24#define FF_SPEED (2.0f)
25#define FB_SPEED (-1.0f)
26#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080027#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080028
29#define IS_KERNEL_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_X1) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
30#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
31
hualing chenb31a6c62020-01-13 17:27:00 +080032
hualing chenb5cd42e2020-04-15 17:03:34 +080033#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080034#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080035//if tsplayer delay time < 200 and no data can read, we will pause
36#define MIN_TSPLAYER_DELAY_TIME (200)
37
hualing chen041c4092020-04-05 15:11:50 +080038#define MAX_CACHE_TIME (30000)
39
hualing chena540a7e2020-03-27 16:44:05 +080040static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080041//
42static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chencc91e1c2020-02-28 13:26:17 +080043static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_StreamInfo_t set_pid, int type);
44static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
45static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080046static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080047static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080048static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
49 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080050static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen87072a82020-03-12 16:20:12 +080051
hualing chenbcada022020-04-22 14:27:01 +080052
53static char* _cmd_toString(int cmd)
54{
55
56 char *string[DVR_PLAYBACK_CMD_NONE+1]={
57 "start",
58 "stop",
59 "vstart",
60 "astart",
61 "vstop",
62 "astop",
63 "vrestart",
64 "arestart",
65 "avrestart",
66 "vstopastart",
67 "astopvstart",
68 "vstoparestart",
69 "astopvrestart",
70 "vstartarestart",
71 "astartvrestart",
72 "pause",
73 "resume",
74 "seek",
75 "ff",
76 "fb",
77 "NONE"
78 };
79
80 if (cmd > DVR_PLAYBACK_CMD_NONE) {
81 return "unkown";
82 } else {
83 return string[cmd];
84 }
85}
86
87
hualing chen6d24aa92020-03-23 18:43:47 +080088static char* _dvr_playback_state_toString(int stat)
89{
90 char *string[DVR_PLAYBACK_STATE_FB+1]={
91 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080092 "stop",
hualing chen31140872020-03-25 12:29:26 +080093 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080094 "ff",
95 "fb"
96 };
97
98 if (stat > DVR_PLAYBACK_STATE_FB) {
99 return "unkown";
100 } else {
101 return string[stat];
102 }
103}
hualing chena540a7e2020-03-27 16:44:05 +0800104
105static DVR_Bool_t _dvr_support_speed(int speed) {
106
107 DVR_Bool_t ret = DVR_FALSE;
108
109 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800110 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800111 case PLAYBACK_SPEED_FBX2:
112 case PLAYBACK_SPEED_FBX4:
113 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800114 case PLAYBACK_SPEED_FBX16:
115 case PLAYBACK_SPEED_FBX12:
116 case PLAYBACK_SPEED_FBX32:
117 case PLAYBACK_SPEED_FBX48:
118 case PLAYBACK_SPEED_FBX64:
119 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800120 case PLAYBACK_SPEED_S2:
121 case PLAYBACK_SPEED_S4:
122 case PLAYBACK_SPEED_S8:
123 case PLAYBACK_SPEED_X1:
124 case PLAYBACK_SPEED_X2:
125 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800126 case PLAYBACK_SPEED_X3:
127 case PLAYBACK_SPEED_X5:
128 case PLAYBACK_SPEED_X6:
129 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800130 case PLAYBACK_SPEED_X8:
131 case PLAYBACK_SPEED_X12:
132 case PLAYBACK_SPEED_X16:
133 case PLAYBACK_SPEED_X32:
134 case PLAYBACK_SPEED_X48:
135 case PLAYBACK_SPEED_X64:
136 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800137 ret = DVR_TRUE;
138 break;
139 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800140 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800141 break;
142 }
143 return ret;
144}
hualing chen6e4bfa52020-03-13 14:37:11 +0800145void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
146{
hualing chen4b7c15d2020-04-07 16:13:48 +0800147 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800148 DVR_Playback_t *player = NULL;
149 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800150 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800151 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800152 }
153 switch (event->type) {
154 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
155 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800156 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800157 event->event.video_format.frame_width,
158 event->event.video_format.frame_height,
159 event->event.video_format.frame_rate);
160 break;
161 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800162 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
163 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800164 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800165 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800166 break;
167 }
168 default:
169 break;
170 }
171}
hualing chen2aba4022020-03-02 13:49:55 +0800172void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
173{
hualing chen6e4bfa52020-03-13 14:37:11 +0800174 DVR_Playback_t *player = NULL;
175 if (user_data != NULL) {
176 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800177 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800178 }
hualing chen2aba4022020-03-02 13:49:55 +0800179 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800180 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
181 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800182 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800183 event->event.video_format.frame_width,
184 event->event.video_format.frame_height,
185 event->event.video_format.frame_rate);
186 break;
187 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800188 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
189 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800190 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chene41f4372020-06-06 16:29:17 +0800191 if (player->first_trans_ok == DVR_FALSE) {
192 player->first_trans_ok = DVR_TRUE;
193 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
194 }
hualing chen30423862021-04-16 14:39:12 +0800195 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800196 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800197 player->seek_pause = DVR_FALSE;
198 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800199 break;
200 }
hualing chen487ae6d2020-07-22 10:34:11 +0800201 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
202 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
203 player->first_trans_ok = DVR_TRUE;
204 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
205 }
206 if (player != NULL && player->has_video == DVR_FALSE) {
207 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
208 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800209 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800210 }
211 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800212 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800213 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800214 break;
215 }
216 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800217 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800218 player->player_callback_func(player->player_callback_userdata, event);
219 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800220 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800221 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800222 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800223 }
224}
hualing chencc91e1c2020-02-28 13:26:17 +0800225
hualing chen5cbe1a62020-02-10 16:36:36 +0800226//convert video and audio fmt
227static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
228 int format = 0;
229 if (is_audio == DVR_FALSE) {
230 //for video fmt
231 switch (fmt)
232 {
233 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800234 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800235 break;
236 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800237 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800238 break;
239 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800240 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800241 break;
242 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800243 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800244 break;
hualing chena540a7e2020-03-27 16:44:05 +0800245 case DVR_VIDEO_FORMAT_VP9:
246 format = AV_VIDEO_CODEC_VP9;
247 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800248 }
249 } else {
250 //for audio fmt
251 switch (fmt)
252 {
253 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800254 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800255 break;
256 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800257 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800258 break;
259 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800260 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800261 break;
262 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800263 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800264 break;
hualing chena540a7e2020-03-27 16:44:05 +0800265 case DVR_AUDIO_FORMAT_AAC:
266 format = AV_AUDIO_CODEC_AAC;
267 break;
268 case DVR_AUDIO_FORMAT_LATM:
269 format = AV_AUDIO_CODEC_LATM;
270 break;
271 case DVR_AUDIO_FORMAT_PCM:
272 format = AV_AUDIO_CODEC_PCM;
273 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800274 case DVR_AUDIO_FORMAT_AC4:
275 format = AV_AUDIO_CODEC_AC4;
276 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800277 }
278 }
279 return format;
280}
hualing chen040df222020-01-17 13:35:02 +0800281static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800282{
hualing chen040df222020-01-17 13:35:02 +0800283 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800284
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800285 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800286 return -1;
287
hualing chena540a7e2020-03-27 16:44:05 +0800288 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800289}
hualing chena540a7e2020-03-27 16:44:05 +0800290
hualing chen5cbe1a62020-02-10 16:36:36 +0800291//get sys time ms
292static int _dvr_time_getClock(void)
293{
294 struct timespec ts;
295 int ms;
296
297 clock_gettime(CLOCK_MONOTONIC, &ts);
298 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
299
300 return ms;
301}
hualing chen86e7d482020-01-16 15:13:33 +0800302
hualing chenb31a6c62020-01-13 17:27:00 +0800303
304//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800305static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800306{
hualing chen040df222020-01-17 13:35:02 +0800307 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800308
hualing chena540a7e2020-03-27 16:44:05 +0800309
310 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800311 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800312 return DVR_FAILURE;
313 }
314
hualing chen86e7d482020-01-16 15:13:33 +0800315 struct timespec ts;
316 clock_gettime(CLOCK_MONOTONIC, &ts);
317 //ms为毫秒,换算成秒
318 ts.tv_sec += ms/1000;
319 //在outtime的基础上,增加ms毫秒
320 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
321 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
322 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
323 //us的值有可能超过1秒,
324 ts.tv_sec += us / 1000000;
325 us = us % 1000000;
326 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800327 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
328 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800329}
hualing chen31140872020-03-25 12:29:26 +0800330//get tsplay delay time ms
331static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
332 DVR_Playback_t *player = (DVR_Playback_t *) handle;
333 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800334 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800335 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800336 return 0;
337 }
338 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800339 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800340 return cache;
341}
hualing chenb31a6c62020-01-13 17:27:00 +0800342//send signal
hualing chen040df222020-01-17 13:35:02 +0800343static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800344{
hualing chen87072a82020-03-12 16:20:12 +0800345 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800346
347 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800348 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800349 return DVR_FAILURE;
350 }
351
hualing chen87072a82020-03-12 16:20:12 +0800352 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800353 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800354 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800355 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800356}
357
hualing chen2932d372020-04-29 13:44:00 +0800358//send playback event, need check is need lock first
359static int _dvr_playback_sent_event(DVR_PlaybackHandle_t handle, DVR_PlaybackEvent_t evt, DVR_Play_Notify_t *notify, DVR_Bool_t is_lock) {
hualing chencc91e1c2020-02-28 13:26:17 +0800360
361 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800362
363 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800364 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800365 return DVR_FAILURE;
366 }
367
hualing chencc91e1c2020-02-28 13:26:17 +0800368 switch (evt) {
369 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800370 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800371 break;
372 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
373 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800374 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800375 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800376 break;
377 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
378 break;
379 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
380 break;
381 case DVR_PLAYBACK_EVENT_NO_KEY:
382 break;
383 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800384 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800385 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800386 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800387 break;
388 case DVR_PLAYBACK_EVENT_REACHED_END:
389 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800390 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800391 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800392 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800393 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800394 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800395 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800396 default:
397 break;
398 }
399 if (player->openParams.event_fn != NULL)
400 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800401 return DVR_SUCCESS;
402}
hualing chen2932d372020-04-29 13:44:00 +0800403static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800404{
405 DVR_Play_Notify_t notify;
406 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
407 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
408 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800409 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800410 return DVR_SUCCESS;
411}
412
hualing chen2932d372020-04-29 13:44:00 +0800413static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800414{
415 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800416
hualing chene3797f02021-01-13 14:53:28 +0800417 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800418 return DVR_SUCCESS;
419 }
hualing chena540a7e2020-03-27 16:44:05 +0800420 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800421 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800422 return DVR_FAILURE;
423 }
424
hualing chen6e4bfa52020-03-13 14:37:11 +0800425 if (player->send_time ==0) {
hualing chen0888c032020-12-18 17:54:57 +0800426 player->send_time = _dvr_time_getClock() + 500;
427 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800428 return DVR_SUCCESS;
429 }
hualing chen0888c032020-12-18 17:54:57 +0800430 player->send_time = _dvr_time_getClock() + 500;
hualing chen6e4bfa52020-03-13 14:37:11 +0800431 DVR_Play_Notify_t notify;
432 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
433 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
434 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800435 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800436 return DVR_SUCCESS;
437}
438
hualing chencc91e1c2020-02-28 13:26:17 +0800439//check is ongoing segment
440static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
441
442 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800443 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800444
445 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800446 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800447 return DVR_FAILURE;
448 }
hualing chen87072a82020-03-12 16:20:12 +0800449 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800450 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800451 return DVR_FALSE;
452 }
hualing chencc91e1c2020-02-28 13:26:17 +0800453 return DVR_TRUE;
454}
hualing chen4b7c15d2020-04-07 16:13:48 +0800455
456
457static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
458 DVR_Playback_t *player = (DVR_Playback_t *) handle;
459 player->fffb_start = _dvr_time_getClock();
460 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
461 player->fffb_current = player->fffb_start;
462 //get segment current time pos
463 player->fffb_start_pcr = _dvr_get_cur_time(handle);
464 //player->fffb_current = -1;
465 //player->fffb_start = -1;
466 //player->fffb_start_pcr = -1;
467 player->next_fffb_time = _dvr_time_getClock();
468
469 return DVR_SUCCESS;
470}
471
hualing chen2aba4022020-03-02 13:49:55 +0800472static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
473 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800474 player->fffb_start = _dvr_time_getClock();
475 DVR_PB_DG(1, " player->fffb_start:%d", player->fffb_start);
476 player->fffb_current = player->fffb_start;
477 //get segment current time pos
478 player->fffb_start_pcr = _dvr_get_cur_time(handle);
479 //player->fffb_current = -1;
480 //player->fffb_start = -1;
481 //player->fffb_start_pcr = -1;
hualing chen2aba4022020-03-02 13:49:55 +0800482 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800483 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800484 return DVR_SUCCESS;
485}
hualing chencc91e1c2020-02-28 13:26:17 +0800486//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800487static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
488
489 DVR_Playback_t *player = (DVR_Playback_t *) handle;
490 DVR_PlaybackSegmentInfo_t *segment;
491 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
492
hualing chena540a7e2020-03-27 16:44:05 +0800493 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800494 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800495 return DVR_FAILURE;
496 }
497
hualing chen87072a82020-03-12 16:20:12 +0800498 int found = 0;
499 int found_eq_id = 0;
500 list_for_each_entry(segment, &player->segment_list, head)
501 {
502 if (player->segment_is_open == DVR_FALSE) {
503 //get first segment from list, case segment is not open
504 if (!IS_FB(player->speed))
505 found = 1;
506 } else if (segment->segment_id == segmentid) {
507 //find cur segment, we need get next one
508 found_eq_id = 1;
509 if (!IS_FB(player->speed)) {
510 found = 1;
511 continue;
512 } else {
513 //if is fb mode.we need used pre segment
514 if (pre_segment != NULL) {
515 found = 1;
516 } else {
517 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800518 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800519 return DVR_FAILURE;
520 }
521 }
522 }
523 if (found == 1) {
524 found = 2;
525 break;
526 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800527 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800528 }
529 if (found != 2) {
530 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800531 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800532 return DVR_FAILURE;
533 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800534 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800535 return DVR_SUCCESS;
536}
537
538//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800539static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800540
hualing chen040df222020-01-17 13:35:02 +0800541 DVR_Playback_t *player = (DVR_Playback_t *) handle;
542 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800543 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen969fe7b2021-05-26 15:13:17 +0800544
hualing chena540a7e2020-03-27 16:44:05 +0800545 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800546 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800547 return DVR_FAILURE;
548 }
549
hualing chen86e7d482020-01-16 15:13:33 +0800550 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800551 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800552
hualing chen040df222020-01-17 13:35:02 +0800553 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800554 {
hualing chencc91e1c2020-02-28 13:26:17 +0800555 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800556 //get first segment from list, case segment is not open
557 if (!IS_FB(player->speed))
558 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800559 } else if (segment->segment_id == player->cur_segment_id) {
560 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800561 found_eq_id = 1;
562 if (!IS_FB(player->speed)) {
563 found = 1;
564 continue;
565 } else {
566 //if is fb mode.we need used pre segment
567 if (pre_segment != NULL) {
568 found = 1;
569 } else {
570 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800571 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800572 return DVR_FAILURE;
573 }
574 }
hualing chen86e7d482020-01-16 15:13:33 +0800575 }
576 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800577 if (IS_FB(player->speed)) {
578 //used pre segment
579 segment = pre_segment;
580 }
hualing chencc91e1c2020-02-28 13:26:17 +0800581 //save segment info
582 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800583 if (player->r_handle)
584 player->last_segment_tatol = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800585 player->last_segment.segment_id = player->cur_segment.segment_id;
586 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800587 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
588 //pids
589 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
590
hualing chen5cbe1a62020-02-10 16:36:36 +0800591 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800592 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800593 player->cur_segment_id = segment->segment_id;
594 player->cur_segment.segment_id = segment->segment_id;
595 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800596 DVR_PB_DG(1, "set cur id cur flag[0x%x]segment->flags flag[0x%x] id [%lld]", player->cur_segment.flags, segment->flags, segment->segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800597 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800598 //pids
hualing chen040df222020-01-17 13:35:02 +0800599 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800600 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800601 break;
hualing chen86e7d482020-01-16 15:13:33 +0800602 }
hualing chen2aba4022020-03-02 13:49:55 +0800603 pre_segment = segment;
604 }
605 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
606 //used the last one segment to open
607 //get segment info
608 player->segment_is_open = DVR_TRUE;
609 player->cur_segment_id = pre_segment->segment_id;
610 player->cur_segment.segment_id = pre_segment->segment_id;
611 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800612 DVR_PB_DG(1, "set cur id fb last one cur flag[0x%x]segment->flags flag[0x%x] id [%lld]", player->cur_segment.flags, pre_segment->flags, pre_segment->segment_id);
hualing chen2aba4022020-03-02 13:49:55 +0800613 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
614 //pids
615 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
616 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800617 }
618 if (found != 2) {
619 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800620 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800621 }
622 return DVR_SUCCESS;
623}
hualing chen040df222020-01-17 13:35:02 +0800624//open next segment to play,if reach list end return errro.
625static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800626{
hualing chen040df222020-01-17 13:35:02 +0800627 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800628 Segment_OpenParams_t params;
629 int ret = DVR_SUCCESS;
630
hualing chena540a7e2020-03-27 16:44:05 +0800631 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800632 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800633 return DVR_FAILURE;
634 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800635 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800636
637 ret = _dvr_get_next_segmentId(handle);
638 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800639 DVR_PB_DG(1, "not found segment info");
640 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800641 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800642 }
643
644 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800645 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800646 segment_close(player->r_handle);
647 player->r_handle = NULL;
648 }
649
650 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800651 //cp chur segment path to location
652 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800653 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800654 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800655 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
656
hualing chen86e7d482020-01-16 15:13:33 +0800657 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800658 if (ret == DVR_FAILURE) {
659 DVR_PB_DG(1, "open segment error");
660 }
hualing chen87072a82020-03-12 16:20:12 +0800661 pthread_mutex_unlock(&player->segment_lock);
662 int total = _dvr_get_end_time( handle);
663 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800664 if (IS_FB(player->speed)) {
665 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800666 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800667 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800668 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800669 }
hualing chen87072a82020-03-12 16:20:12 +0800670 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800671 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800672 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800673 return ret;
674}
675
hualing chen5cbe1a62020-02-10 16:36:36 +0800676//open next segment to play,if reach list end return errro.
677static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
678{
679 DVR_Playback_t *player = (DVR_Playback_t *) handle;
680 Segment_OpenParams_t params;
681 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800682 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800683 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800684 return DVR_FAILURE;
685 }
hualing chencc91e1c2020-02-28 13:26:17 +0800686 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800687 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800688 }
hualing chencc91e1c2020-02-28 13:26:17 +0800689 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800690 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800691 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800692 return DVR_FAILURE;
693 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800694 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800695 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800696
697 DVR_PlaybackSegmentInfo_t *segment;
698
699 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800700
hualing chen5cbe1a62020-02-10 16:36:36 +0800701 list_for_each_entry(segment, &player->segment_list, head)
702 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800703 DVR_PB_DG(1, "see 1 location [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800704 if (segment->segment_id == segment_id) {
705 found = 1;
706 }
707 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800708 DVR_PB_DG(1, "found [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800709 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800710 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800711 player->cur_segment_id = segment->segment_id;
712 player->cur_segment.segment_id = segment->segment_id;
713 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800714 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800715 //pids
716 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800717 DVR_PB_DG(1, "cur found location [%s]id[%lld]flag[%x]", player->cur_segment.location, player->cur_segment.segment_id,player->cur_segment.flags);
hualing chencc91e1c2020-02-28 13:26:17 +0800718 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800719 }
720 }
hualing chencc91e1c2020-02-28 13:26:17 +0800721 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800722 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800723 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800724 return DVR_FAILURE;
725 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800726 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800727 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800728 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800729 params.segment_id = (uint64_t)player->cur_segment.segment_id;
730 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800731 DVR_PB_DG(1, "open segment location[%s][%lld]cur flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen2aba4022020-03-02 13:49:55 +0800732 if (player->r_handle != NULL) {
733 segment_close(player->r_handle);
734 player->r_handle = NULL;
735 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800736 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800737 if (ret == DVR_FAILURE) {
738 DVR_PB_DG(1, "segment opne error");
739 }
hualing chen2aba4022020-03-02 13:49:55 +0800740 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800741 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800742
hualing chen4b7c15d2020-04-07 16:13:48 +0800743 DVR_PB_DG(1, "player->dur [%d]cur id [%lld]cur flag [0x%x]\r\n", player->dur,player->cur_segment.segment_id, player->cur_segment.flags);
hualing chen5cbe1a62020-02-10 16:36:36 +0800744 return ret;
745}
746
747
748//get play info by segment id
749static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
750 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800751 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800752 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800753
754 DVR_Playback_t *player = (DVR_Playback_t *) handle;
755 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800756 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800757 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800758 return DVR_FAILURE;
759 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800760
761 int found = 0;
762
763 list_for_each_entry(segment, &player->segment_list, head)
764 {
hualing chen87072a82020-03-12 16:20:12 +0800765 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800766 //get first segment from list
767 found = 1;
768 }
769 if (segment->segment_id == segment_id) {
770 found = 1;
771 }
772 if (found == 1) {
773 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800774 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800775 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800776 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800777 player->cur_segment.segment_id = segment->segment_id;
778 player->cur_segment.flags = segment->flags;
779 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800780 player->cur_segment.pids.video.pid = segment->pids.video.pid;
781 player->cur_segment.pids.video.format = segment->pids.video.format;
782 player->cur_segment.pids.video.type = segment->pids.video.type;
783 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
784 player->cur_segment.pids.audio.format = segment->pids.audio.format;
785 player->cur_segment.pids.audio.type = segment->pids.audio.type;
786 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
787 player->cur_segment.pids.ad.format = segment->pids.ad.format;
788 player->cur_segment.pids.ad.type = segment->pids.ad.type;
789 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800790 //
hualing chen2aba4022020-03-02 13:49:55 +0800791 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800792 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800793 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800794 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800795 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
796 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800797 DVR_PB_DG(1, "get play info sucess[0x%x]apid[0x%x]vfmt[%d]afmt[%d]", vparam->pid, aparam->pid, vparam->codectype, aparam->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800798 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800799 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800800 }
801 }
hualing chencc91e1c2020-02-28 13:26:17 +0800802 if (found != 2) {
803 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800804 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800805 return DVR_FAILURE;
806 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800807
808 return DVR_SUCCESS;
809}
hualing chencc91e1c2020-02-28 13:26:17 +0800810static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
811 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800812 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800813 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800814 return DVR_FAILURE;
815 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800816
hualing chencc91e1c2020-02-28 13:26:17 +0800817 //compare cur segment
818 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
819 {
820 //check video pids, stop or restart
821 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids.video, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800822 //check sub audio pids stop or restart
823 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids.ad, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800824 //check audio pids stop or restart
825 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids.audio, 1);
hualing chene3797f02021-01-13 14:53:28 +0800826 DVR_PB_DG(1, ":last apid: %d set apid: %d", player->last_segment.pids.audio.pid,player->cur_segment.pids.audio.pid);
hualing chencc91e1c2020-02-28 13:26:17 +0800827 //check pcr pids stop or restart
828 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids.pcr, 3);
829 }
hualing chena540a7e2020-03-27 16:44:05 +0800830 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800831}
hualing chen5cbe1a62020-02-10 16:36:36 +0800832
hualing chencc91e1c2020-02-28 13:26:17 +0800833static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
834{
835 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800836 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800837 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800838 return DVR_FAILURE;
839 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800840 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
841 DVR_PB_DG(1, "vendor is amlogic. no used segment flag to hide or show av");
842 return DVR_SUCCESS;
843 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800844 DVR_PB_DG(1, "flag[0x%x]id[%lld]last[0x%x][%llu]", player->cur_segment.flags, player->cur_segment.segment_id, player->last_segment.flags, player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800845 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
846 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800847 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800848 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800849 AmTsPlayer_showVideo(player->handle);
850 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800851 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
852 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800853 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800854 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800855 AmTsPlayer_hideVideo(player->handle);
856 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800857 }
858 return DVR_SUCCESS;
859}
hualing chene3797f02021-01-13 14:53:28 +0800860/*
861if decodec sucess first time.
862sucess: return true
863fail: return false
864*/
hualing chena540a7e2020-03-27 16:44:05 +0800865static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
866 DVR_Playback_t *player = (DVR_Playback_t *) handle;
867 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800868 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800869 return DVR_TRUE;
870 }
hualing chene3797f02021-01-13 14:53:28 +0800871 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800872 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800873 } else {
874 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800875 }
876}
hualing chen86e7d482020-01-16 15:13:33 +0800877static void* _dvr_playback_thread(void *arg)
878{
hualing chen040df222020-01-17 13:35:02 +0800879 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800880 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800881 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800882 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800883 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800884
hualing chen39628212020-05-14 10:35:13 +0800885 #define MAX_REACHEND_TIMEOUT (3000)
886 int reach_end_timeout = 0;//ms
887 int cache_time = 0;
hualing chen6d24aa92020-03-23 18:43:47 +0800888 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800889 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800890 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800891 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800892 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
893
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800894 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800895 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800896 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chene41f4372020-06-06 16:29:17 +0800897 int retry_open_seg = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800898 if (player->is_secure_mode) {
899 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800900 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800901 return NULL;
902 }
903 }
hualing chen86e7d482020-01-16 15:13:33 +0800904 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800905 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800906 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800907 return NULL;
908 }
hualing chen2aba4022020-03-02 13:49:55 +0800909 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
910 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800911
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800912 dec_bufs.buf_data = malloc(dec_buf_size);
913 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800914 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800915 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800916 return NULL;
917 }
918 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
919 dec_bufs.buf_size = dec_buf_size;
920
hualing chencc91e1c2020-02-28 13:26:17 +0800921 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800922 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
923 }
hualing chen86e7d482020-01-16 15:13:33 +0800924
hualing chen86e7d482020-01-16 15:13:33 +0800925 if (ret != DVR_SUCCESS) {
926 if (buf != NULL) {
927 free(buf);
928 buf = NULL;
929 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800930 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800931 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800932 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800933 }
hualing chen4fe3bee2020-10-23 13:58:52 +0800934 DVR_PB_DG(1, "player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
935 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +0800936 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
937 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
938 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
939 player->first_trans_ok = DVR_TRUE;
940 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
941 }
hualing chencc91e1c2020-02-28 13:26:17 +0800942 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800943 //set video show
944 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800945
hualing chen86e7d482020-01-16 15:13:33 +0800946 int trick_stat = 0;
947 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +0800948
hualing chen86e7d482020-01-16 15:13:33 +0800949 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +0800950 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800951
hualing chen2aba4022020-03-02 13:49:55 +0800952 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
953 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +0800954 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +0800955 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +0800956 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +0800957 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +0800958 {
hualing chen2aba4022020-03-02 13:49:55 +0800959 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
960 if (trick_stat > 0) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800961 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]", trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +0800962 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 +0800963 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +0800964 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +0800965 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +0800966 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
967 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +0800968 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
969 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chenbcada022020-04-22 14:27:01 +0800970 DVR_PB_DG(1, "pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]", player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +0800971 //need change to pause state
972 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
973 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +0800974 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +0800975 //clear flag
hualing chen31140872020-03-25 12:29:26 +0800976 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +0800977 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +0800978 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +0800979 AmTsPlayer_pauseVideoDecoding(player->handle);
980 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +0800981 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800982 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +0800983 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800984 }
985 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
986 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +0800987 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +0800988 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +0800989 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
990 DVR_PB_DG(1, "fffb pause state----speed[%f] fffb cur[%d] cur sys[%d] [%s] [%d]", player->speed, player->fffb_current,_dvr_time_getClock(),_dvr_playback_state_toString(player->state), player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +0800991 //used timeout wait need lock first,so we unlock and lock
992 //pthread_mutex_unlock(&player->lock);
993 //pthread_mutex_lock(&player->lock);
994 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
995 pthread_mutex_unlock(&player->lock);
996 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +0800997 } else if (_dvr_time_getClock() < player->next_fffb_time) {
998 DVR_PB_DG(1, "fffb timeout-to pause video---speed[%f] fffb cur[%d] cur sys[%d] [%s] [%d]", player->speed, player->fffb_current,_dvr_time_getClock(),_dvr_playback_state_toString(player->state), player->next_fffb_time);
999 //used timeout wait need lock first,so we unlock and lock
1000 //pthread_mutex_unlock(&player->lock);
1001 //pthread_mutex_lock(&player->lock);
1002 AmTsPlayer_pauseVideoDecoding(player->handle);
1003 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1004 pthread_mutex_unlock(&player->lock);
1005 continue;
1006
hualing chen2aba4022020-03-02 13:49:55 +08001007 }
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001008 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d][%s][%d]", player->speed, goto_rewrite, real_read, _dvr_playback_state_toString(player->state), player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001009 pthread_mutex_unlock(&player->lock);
1010 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001011 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001012 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1013 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001014 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001015 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001016 pthread_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001017 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001018 }else if (player->fffb_play == DVR_TRUE){
1019 //for first into fffb when reset speed
1020 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1021 _dvr_time_getClock() < player->next_fffb_time) {
1022 DVR_PB_DG(1, "fffb timeout-fffb play---speed[%f] fffb cur[%d] cur sys[%d] [%s] [%d]", player->speed, player->fffb_current,_dvr_time_getClock(),_dvr_playback_state_toString(player->state), player->next_fffb_time);
1023 //used timeout wait need lock first,so we unlock and lock
1024 //pthread_mutex_unlock(&player->lock);
1025 //pthread_mutex_lock(&player->lock);
1026 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1027 pthread_mutex_unlock(&player->lock);
1028 continue;
1029 }
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001030 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]", player->speed, goto_rewrite, real_read, _dvr_playback_state_toString(player->state), player->cmd.cur_cmd, player->fffb_play);
hualing chen4b7c15d2020-04-07 16:13:48 +08001031 pthread_mutex_unlock(&player->lock);
1032 goto_rewrite = DVR_FALSE;
1033 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001034 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001035 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1036 player->first_frame = 0;
1037 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1038 pthread_mutex_lock(&player->lock);
1039 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001040 }
hualing chenb31a6c62020-01-13 17:27:00 +08001041 }
hualing chen86e7d482020-01-16 15:13:33 +08001042
hualing chen30423862021-04-16 14:39:12 +08001043 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1044 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001045 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001046 DVR_PB_DG(1, "pause, continue");
hualing chen2932d372020-04-29 13:44:00 +08001047 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen87072a82020-03-12 16:20:12 +08001048 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1049 pthread_mutex_unlock(&player->lock);
1050 continue;
1051 }
hualing chen266b9502020-04-04 17:39:39 +08001052 //when seek action is done. we need drop write timeout data.
1053 if (player->drop_ts == DVR_TRUE) {
1054 goto_rewrite = DVR_FALSE;
1055 real_read = 0;
1056 player->drop_ts = DVR_FALSE;
1057 }
hualing chen2aba4022020-03-02 13:49:55 +08001058 if (goto_rewrite == DVR_TRUE) {
1059 goto_rewrite = DVR_FALSE;
1060 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001061 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001062 goto rewrite;
1063 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001064 //.check is need send time send end
hualing chen2932d372020-04-29 13:44:00 +08001065 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001066 pthread_mutex_lock(&player->segment_lock);
hualing chene41f4372020-06-06 16:29:17 +08001067 //DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001068 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chenfbf8e022020-06-15 13:43:11 +08001069 //DVR_PB_DG(1, "start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001070 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001071 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001072 if (read < 0 && errno == EIO) {
1073 //EIO ERROR, EXIT THRAD
1074 DVR_PB_DG(1, "read error.EIO error, exit thread");
1075 DVR_Play_Notify_t notify;
1076 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1077 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001078 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001079 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001080 goto end;
1081 } else if (read < 0) {
1082 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1083 }
hualing chen87072a82020-03-12 16:20:12 +08001084 //if on fb mode and read file end , we need calculate pos to retry read.
1085 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001086 DVR_PB_DG(1, "recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]", read,real_read, buf_len, player->speed,player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001087 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
1088 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001089 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1090 pthread_mutex_unlock(&player->lock);
1091 continue;
1092 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001093 //DVR_PB_DG(1, "read ts [%d]buf_len[%d]speed[%f]real_read:%d", read, buf_len, player->speed, real_read);
hualing chen86e7d482020-01-16 15:13:33 +08001094 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001095 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001096 #define MIN_CACHE_TIME (3000)
1097 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001098 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001099 if (_cache_time > MIN_CACHE_TIME) {
hualing chene41f4372020-06-06 16:29:17 +08001100 pthread_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001101 /*if cache time > 20s , we think get time is error,*/
1102 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
1103 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1104 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1105 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1106 }
1107 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
hualing chene41f4372020-06-06 16:29:17 +08001108 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001109 DVR_PB_DG(1, "read end but cache time is %d > %d, to sleep end and continue", _cache_time, MIN_CACHE_TIME);
hualing chene41f4372020-06-06 16:29:17 +08001110 //continue;
1111 }
hualing chen969fe7b2021-05-26 15:13:17 +08001112
hualing chen040df222020-01-17 13:35:02 +08001113 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001114 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001115 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001116
1117 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chene3797f02021-01-13 14:53:28 +08001118 if (ret != DVR_SUCCESS) {
1119 player->noData++;
1120 DVR_PB_DG(1, "playback is sleep:[%d]ms nodata[%d]", timeout, player->noData);
1121 if (player->noData == 4) {
1122 DVR_PB_DG(1, "playback send nodata event nodata[%d]", player->noData);
1123 //send event here and pause
1124 DVR_Play_Notify_t notify;
1125 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1126 notify.event = DVR_PLAYBACK_EVENT_NODATA;
1127 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_NODATA");
1128 //get play statue not here
1129 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1130 }
1131 }
1132 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001133 if ((ret != DVR_SUCCESS &&
hualing chen90b3ae62021-03-30 10:49:28 +08001134 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001135 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001136 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001137 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1138 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001139 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001140 DVR_Play_Notify_t notify;
1141 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1142 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1143 //get play statue not here
1144 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001145 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001146 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001147 DVR_PB_DG(1, "playback is send end delay:[%d]reach_end_timeout[%d]ms", delay, reach_end_timeout);
hualing chen31140872020-03-25 12:29:26 +08001148 pthread_mutex_lock(&player->lock);
1149 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1150 pthread_mutex_unlock(&player->lock);
1151 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001152 } else if (ret != DVR_SUCCESS) {
1153 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001154 if (delay < cache_time) {
1155 //delay time is changed and then has data to play, so not start timeout
1156 } else {
1157 reach_end_timeout = reach_end_timeout + timeout;
1158 }
1159 cache_time = delay;
hualing chen4b7c15d2020-04-07 16:13:48 +08001160 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001161 pthread_mutex_lock(&player->lock);
1162 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1163 pthread_mutex_unlock(&player->lock);
1164 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001165 }
hualing chen39628212020-05-14 10:35:13 +08001166 reach_end_timeout = 0;
1167 cache_time = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001168 pthread_mutex_lock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001169 //change next segment success case
1170 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001171 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001172 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1173 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001174 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001175 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001176 }//read len 0 check end
1177 if (player->noData > 0) {
1178 player->noData = 0;
1179 DVR_PB_DG(1, "playback send data event resume[%d]", player->noData);
1180 //send event here and pause
1181 DVR_Play_Notify_t notify;
1182 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1183 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
1184 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_DATARESUME");
1185 //get play statue not here
1186 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001187 }
hualing chen39628212020-05-14 10:35:13 +08001188 reach_end_timeout = 0;
hualing chen86e7d482020-01-16 15:13:33 +08001189 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001190 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001191 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001192
hualing chena540a7e2020-03-27 16:44:05 +08001193 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001194 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001195 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001196 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001197 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001198 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001199 }
hualing chen266b9502020-04-04 17:39:39 +08001200 //if need write whole block size, we need check read buf len is eq block size.
1201 if (b_writed_whole_block == DVR_TRUE) {
1202 //buf_len is block size value.
1203 if (real_read < buf_len) {
1204 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001205 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001206 pthread_mutex_lock(&player->lock);
1207 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1208 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001209 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001210 continue;
1211 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001212 DVR_PB_DG(1, "read buf len[%d] is > block size [%d],this error occur", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001213 }
1214 }
1215
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001216 if (player->dec_func) {
1217 DVR_CryptoParams_t crypto_params;
1218
1219 memset(&crypto_params, 0, sizeof(crypto_params));
1220 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1221 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1222 crypto_params.segment_id = player->cur_segment.segment_id;
hualing chen1f26ffa2020-11-03 10:39:20 +08001223 crypto_params.offset = segment_tell_position(player->r_handle) - wbufs.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001224 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
1225 DVR_PB_DG(1, "offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001226 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1227 crypto_params.input_buffer.addr = (size_t)buf;
1228 crypto_params.input_buffer.size = real_read;
1229
1230 if (player->is_secure_mode) {
1231 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1232 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1233 crypto_params.output_buffer.size = dec_buf_size;
1234 ret = player->dec_func(&crypto_params, player->dec_userdata);
1235 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001236 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001237 } else {
1238 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1239 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1240 crypto_params.output_buffer.size = dec_buf_size;
1241 ret = player->dec_func(&crypto_params, player->dec_userdata);
1242 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001243 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001244 }
1245 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001246 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001247 }
pengfei.liufda2a972020-04-09 14:47:15 +08001248 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001249 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001250rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001251 if (player->drop_ts == DVR_TRUE) {
1252 //need drop ts data when seek occur.we need read next loop,drop this ts data
1253 goto_rewrite = DVR_FALSE;
1254 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001255 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001256 player->drop_ts = DVR_FALSE;
1257 continue;
1258 }
hualing chen5605eed2020-05-26 18:18:06 +08001259 player->ts_cache_len = real_read;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001260 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1261 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001262 player->ts_cache_len = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001263 real_read = 0;
1264 write_success++;
hualing chen5605eed2020-05-26 18:18:06 +08001265 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001266 continue;
hualing chen87072a82020-03-12 16:20:12 +08001267 } else {
hualing chen2932d372020-04-29 13:44:00 +08001268 DVR_PB_DG(1, "write time out write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001269 write_success = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001270 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001271 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001272 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001273 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001274 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001275 break;
1276 }
hualing chen2aba4022020-03-02 13:49:55 +08001277 goto_rewrite = DVR_TRUE;
1278 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001279 }
1280 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001281end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001282 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001283 free(buf);
1284 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001285 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001286}
1287
1288
hualing chen040df222020-01-17 13:35:02 +08001289static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001290{
hualing chen040df222020-01-17 13:35:02 +08001291 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001292
1293 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001294 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001295 return DVR_FAILURE;
1296 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001297 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001298 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001299 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001300 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001301 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001302 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001303 if (rc < 0)
1304 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001305 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001306}
1307
1308
hualing chen040df222020-01-17 13:35:02 +08001309static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001310{
hualing chen040df222020-01-17 13:35:02 +08001311 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001312
1313 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001314 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001315 return DVR_FAILURE;
1316 }
1317
hualing chen4b7c15d2020-04-07 16:13:48 +08001318 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001319 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001320 {
1321 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001322 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001323 pthread_join(player->playback_thread, NULL);
1324 }
1325 if (player->r_handle) {
1326 segment_close(player->r_handle);
1327 player->r_handle = NULL;
1328 }
hualing chen7a56cba2020-04-14 14:09:27 +08001329 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001330 return 0;
1331}
1332
hualing chenb31a6c62020-01-13 17:27:00 +08001333/**\brief Open an dvr palyback
1334 * \param[out] p_handle dvr playback addr
1335 * \param[in] params dvr playback open parameters
1336 * \retval DVR_SUCCESS On success
1337 * \return Error code
1338 */
hualing chen040df222020-01-17 13:35:02 +08001339int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001340
hualing chen040df222020-01-17 13:35:02 +08001341 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001342 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001343
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001344 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001345
hualing chen86e7d482020-01-16 15:13:33 +08001346 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001347 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001348 pthread_condattr_init(&cattr);
1349 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1350 pthread_cond_init(&player->cond, &cattr);
1351 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001352
hualing chen5cbe1a62020-02-10 16:36:36 +08001353 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001354 INIT_LIST_HEAD(&player->segment_list);
1355 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1356 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001357 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001358 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001359 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001360 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001361 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001362 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001363
hualing chen86e7d482020-01-16 15:13:33 +08001364 //store open params
hualing chen040df222020-01-17 13:35:02 +08001365 player->openParams.dmx_dev_id = params->dmx_dev_id;
1366 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001367 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001368 player->openParams.event_fn = params->event_fn;
1369 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001370 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001371 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001372
hualing chen5cbe1a62020-02-10 16:36:36 +08001373 player->has_pids = params->has_pids;
1374
hualing chen2aba4022020-03-02 13:49:55 +08001375 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001376
1377 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1378 //for test get callback
1379 if (0 && player->player_callback_func == NULL) {
1380 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1381 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen4b7c15d2020-04-07 16:13:48 +08001382 DVR_PB_DG(1, "playback open get callback[%p][%p][%p][%p]",player->player_callback_func, player->player_callback_userdata, _dvr_tsplayer_callback_test,player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001383 }
1384 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001385
hualing chen86e7d482020-01-16 15:13:33 +08001386 //init has audio and video
1387 player->has_video = DVR_FALSE;
1388 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001389 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001390 player->last_segment_id = 0LL;
1391 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001392
hualing chen5cbe1a62020-02-10 16:36:36 +08001393 //init ff fb time
1394 player->fffb_current = -1;
1395 player->fffb_start =-1;
1396 player->fffb_start_pcr = -1;
1397 //seek time
1398 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001399 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001400
1401 //init secure stuff
1402 player->dec_func = NULL;
1403 player->dec_userdata = NULL;
1404 player->is_secure_mode = 0;
1405 player->secure_buffer = NULL;
1406 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001407 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001408
hualing chen4b7c15d2020-04-07 16:13:48 +08001409 player->fffb_play = DVR_FALSE;
1410
1411 player->last_send_time_id = UINT64_MAX;
1412 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001413 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001414
hualing chen86e7d482020-01-16 15:13:33 +08001415 *p_handle = player;
1416 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001417}
1418
1419/**\brief Close an dvr palyback
1420 * \param[in] handle playback handle
1421 * \retval DVR_SUCCESS On success
1422 * \return Error code
1423 */
hualing chen040df222020-01-17 13:35:02 +08001424int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001425
hualing chen86e7d482020-01-16 15:13:33 +08001426 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001427 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001428 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001429 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001430 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001431 return DVR_FAILURE;
1432 }
1433
hualing chencc91e1c2020-02-28 13:26:17 +08001434 if (player->state != DVR_PLAYBACK_STATE_STOP)
1435 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001436 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001437 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001438 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1439 } else {
1440 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001441 }
hualing chen7a56cba2020-04-14 14:09:27 +08001442 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001443 pthread_mutex_destroy(&player->lock);
1444 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001445
1446 if (player) {
1447 free(player);
1448 player = NULL;
1449 }
hualing chen7a56cba2020-04-14 14:09:27 +08001450 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001451 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001452}
1453
hualing chenb31a6c62020-01-13 17:27:00 +08001454/**\brief Start play audio and video, used start auido api and start video api
1455 * \param[in] handle playback handle
1456 * \param[in] params audio playback params,contains fmt and pid...
1457 * \retval DVR_SUCCESS On success
1458 * \return Error code
1459 */
hualing chen040df222020-01-17 13:35:02 +08001460int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1461 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001462 am_tsplayer_video_params vparams;
1463 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001464 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001465
1466 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001467 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001468 return DVR_FAILURE;
1469 }
hualing chencc91e1c2020-02-28 13:26:17 +08001470 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001471 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001472
hualing chena540a7e2020-03-27 16:44:05 +08001473 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001474 //can used start api to resume playback
1475 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1476 return dvr_playback_resume(handle);
1477 }
hualing chen87072a82020-03-12 16:20:12 +08001478 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001479 //if flag is puased and not decodec first frame. if user resume, we need
1480 //clear flag and set trickmode none
1481 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1482 DVR_PB_DG(1, "[%p]clear pause live flag and clear trick mode", handle);
1483 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1484 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1485 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001486 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001487 return DVR_SUCCESS;
1488 }
hualing chen86e7d482020-01-16 15:13:33 +08001489 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001490 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001491 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001492 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001493 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001494 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001495 //start audio and video
Zhiqiang Hana9d261b2020-11-11 18:38:10 +08001496 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001497 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001498 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001499 pthread_mutex_unlock(&player->lock);
1500 DVR_Play_Notify_t notify;
1501 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1502 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1503 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1504 notify.info.transition_failed_data.segment_id = segment_id;
1505 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001506 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001507 return -1;
1508 }
hualing chen31140872020-03-25 12:29:26 +08001509
hualing chencc91e1c2020-02-28 13:26:17 +08001510 {
hualing chen86e7d482020-01-16 15:13:33 +08001511 if (VALID_PID(vparams.pid)) {
1512 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001513 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001514 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001515 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001516 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1517 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001518 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001519 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001520 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001521 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001522 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001523 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001524 }
hualing chena93bbbc2020-12-22 17:23:42 +08001525 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001526 AmTsPlayer_setVideoParams(player->handle, &vparams);
1527 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001528 }
hualing chena540a7e2020-03-27 16:44:05 +08001529
hualing chen4b7c15d2020-04-07 16:13:48 +08001530 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1531 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001532 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1533 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1534 player->cmd.state = DVR_PLAYBACK_STATE_START;
1535 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001536 } else {
1537 player->cmd.last_cmd = player->cmd.cur_cmd;
1538 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001539 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001540 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001541 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001542 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001543 } else {
hualing chendf118dd2020-05-21 15:49:11 +08001544 if (VALID_PID(adparams.pid)) {
1545 player->has_ad_audio = DVR_TRUE;
1546 DVR_PB_DG(1, "start ad audio");
1547 AmTsPlayer_setADParams(player->handle, &adparams);
1548 AmTsPlayer_enableADMix(player->handle);
1549 }
hualing chen969fe7b2021-05-26 15:13:17 +08001550 if (VALID_PID(aparams.pid)) {
1551 DVR_PB_DG(1, "start audio");
1552 player->has_audio = DVR_TRUE;
1553 AmTsPlayer_setAudioParams(player->handle, &aparams);
1554 AmTsPlayer_startAudioDecoding(player->handle);
1555 }
hualing chen31140872020-03-25 12:29:26 +08001556 }
hualing chencc91e1c2020-02-28 13:26:17 +08001557 player->cmd.state = DVR_PLAYBACK_STATE_START;
1558 player->state = DVR_PLAYBACK_STATE_START;
1559 }
hualing chen86e7d482020-01-16 15:13:33 +08001560 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001561 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001562 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001563 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001564 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001565}
hualing chen040df222020-01-17 13:35:02 +08001566/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001567 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001568 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001569 * \retval DVR_SUCCESS On success
1570 * \return Error code
1571 */
hualing chen040df222020-01-17 13:35:02 +08001572int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1573 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001574
hualing chena540a7e2020-03-27 16:44:05 +08001575 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001576 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001577 return DVR_FAILURE;
1578 }
1579
hualing chen4b7c15d2020-04-07 16:13:48 +08001580 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001581 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001582
hualing chen040df222020-01-17 13:35:02 +08001583 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1584 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001585
hualing chen86e7d482020-01-16 15:13:33 +08001586 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001587 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001588 //cp location
hualing chen040df222020-01-17 13:35:02 +08001589 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001590
hualing chen4b7c15d2020-04-07 16:13:48 +08001591 DVR_PB_DG(1, "add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001592 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001593
1594 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001595 segment->pids.video.pid = info->pids.video.pid;
1596 segment->pids.video.format = info->pids.video.format;
1597 segment->pids.video.type = info->pids.video.type;
1598
hualing chen2aba4022020-03-02 13:49:55 +08001599 segment->pids.audio.pid = info->pids.audio.pid;
1600 segment->pids.audio.format = info->pids.audio.format;
1601 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001602
hualing chen2aba4022020-03-02 13:49:55 +08001603 segment->pids.ad.pid = info->pids.ad.pid;
1604 segment->pids.ad.format = info->pids.ad.format;
1605 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001606
1607 segment->pids.pcr.pid = info->pids.pcr.pid;
1608
hualing chen4b7c15d2020-04-07 16:13:48 +08001609 DVR_PB_DG(1, "lock pid [0x%x][0x%x][0x%x][0x%x]", segment->pids.video.pid,segment->pids.audio.pid, info->pids.video.pid,info->pids.audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001610 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001611 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001612 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001613 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001614
hualing chen5cbe1a62020-02-10 16:36:36 +08001615 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001616}
hualing chen040df222020-01-17 13:35:02 +08001617/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001618 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001619 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001620 * \retval DVR_SUCCESS On success
1621 * \return Error code
1622 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001623int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001624 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001625 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001626 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001627 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001628 return DVR_FAILURE;
1629 }
1630
hualing chencc91e1c2020-02-28 13:26:17 +08001631 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001632 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001633 return DVR_FAILURE;
1634 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001635 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001636 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001637 DVR_PlaybackSegmentInfo_t *segment = NULL;
1638 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1639 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001640 {
hualing chen040df222020-01-17 13:35:02 +08001641 if (segment->segment_id == segment_id) {
1642 list_del(&segment->head);
1643 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001644 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001645 }
hualing chen86e7d482020-01-16 15:13:33 +08001646 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001647 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001648 pthread_mutex_unlock(&player->lock);
1649
1650 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001651}
hualing chen040df222020-01-17 13:35:02 +08001652/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001653 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001654 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001655 * \retval DVR_SUCCESS On success
1656 * \return Error code
1657 */
hualing chen040df222020-01-17 13:35:02 +08001658int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001659 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001660 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001661 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001662 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001663 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001664 return DVR_FAILURE;
1665 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001666 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
1667 DVR_PB_DG(1, "vendor is amlogic. not hide or show av and update segment");
1668 return DVR_SUCCESS;
1669 }
hualing chena540a7e2020-03-27 16:44:05 +08001670
hualing chen040df222020-01-17 13:35:02 +08001671 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001672 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001673 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001674 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001675 {
hualing chen040df222020-01-17 13:35:02 +08001676 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001677 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001678 }
hualing chen86e7d482020-01-16 15:13:33 +08001679 // if encramble to free, only set flag and return;
1680
1681 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001682 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001683 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1684 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001685 //disable display, mute
hualing chen703f3572021-01-06 12:51:34 +08001686 DVR_PB_DG(1, "mute av");
hualing chen2aba4022020-03-02 13:49:55 +08001687 AmTsPlayer_hideVideo(player->handle);
1688 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001689 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1690 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001691 //enable display, unmute
hualing chen703f3572021-01-06 12:51:34 +08001692 DVR_PB_DG(1, "unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08001693 AmTsPlayer_showVideo(player->handle);
1694 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001695 } else {
1696 //do nothing
1697 }
1698 } else {
1699 //do nothing
1700 }
1701 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001702 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001703 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001704 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001705 pthread_mutex_unlock(&player->lock);
1706 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001707}
1708
1709
hualing chen5cbe1a62020-02-10 16:36:36 +08001710static 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 +08001711 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001712 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001713 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001714 return DVR_FAILURE;
1715 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001716 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001717 if (now_pid.pid == set_pid.pid) {
1718 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001719 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001720 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001721 if (VALID_PID(now_pid.pid)) {
1722 //stop now stream
1723 if (type == 0) {
1724 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001725 if (player->has_video == DVR_TRUE) {
1726 DVR_PB_DG(1, "stop video");
1727 AmTsPlayer_stopVideoDecoding(player->handle);
1728 player->has_video = DVR_FALSE;
1729 }
hualing chen86e7d482020-01-16 15:13:33 +08001730 } else if (type == 1) {
1731 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08001732 if (player->has_audio == DVR_TRUE) {
1733 DVR_PB_DG(1, "stop audio");
1734 AmTsPlayer_stopAudioDecoding(player->handle);
1735 player->has_audio = DVR_FALSE;
1736 }
hualing chen86e7d482020-01-16 15:13:33 +08001737 } else if (type == 2) {
1738 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001739 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001740 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001741 } else if (type == 3) {
1742 //pcr
1743 }
1744 }
1745 if (VALID_PID(set_pid.pid)) {
1746 //start
1747 if (type == 0) {
1748 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001749 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001750 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001751 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001752 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001753 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001754 AmTsPlayer_setVideoParams(player->handle, &vparams);
1755 AmTsPlayer_startVideoDecoding(player->handle);
1756 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001757 } else if (type == 1) {
1758 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001759 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chenc70a8df2020-05-12 19:23:11 +08001760 am_tsplayer_audio_params aparams;
1761 aparams.pid = set_pid.pid;
1762 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1763 player->has_audio = DVR_TRUE;
1764 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1765 AmTsPlayer_setAudioParams(player->handle, &aparams);
1766 AmTsPlayer_startAudioDecoding(player->handle);
1767 //playback_device_audio_start(player->handle,&aparams);
1768 }
hualing chen86e7d482020-01-16 15:13:33 +08001769 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001770 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chenc70a8df2020-05-12 19:23:11 +08001771 am_tsplayer_audio_params aparams;
1772 aparams.pid = set_pid.pid;
1773 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1774 player->has_audio = DVR_TRUE;
1775 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1776 AmTsPlayer_setADParams(player->handle, &aparams);
1777 AmTsPlayer_enableADMix(player->handle);
1778 //playback_device_audio_start(player->handle,&aparams);
1779 }
hualing chen86e7d482020-01-16 15:13:33 +08001780 } else if (type == 3) {
1781 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001782 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001783 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001784 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001785 //audio and video all close
1786 if (!player->has_audio && !player->has_video) {
1787 player->state = DVR_PLAYBACK_STATE_STOP;
1788 }
hualing chen86e7d482020-01-16 15:13:33 +08001789 }
1790 }
1791 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001792}
hualing chen5cbe1a62020-02-10 16:36:36 +08001793/**\brief dvr play back update segment pids
1794 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001795 * add pid stream and stop remove pid stream.
1796 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001797 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001798 * \retval DVR_SUCCESS On success
1799 * \return Error code
1800 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001801int 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 +08001802 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001803 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001804 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001805 return DVR_FAILURE;
1806 }
1807
hualing chen040df222020-01-17 13:35:02 +08001808 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001809 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001810 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001811 DVR_PB_DG(1, "get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001812
hualing chen040df222020-01-17 13:35:02 +08001813 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001814 {
hualing chen040df222020-01-17 13:35:02 +08001815 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001816
1817 if (player->cur_segment_id == segment_id) {
1818 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1819 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1820 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001821 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001822 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001823 return 0;
1824 }
1825
1826 //if segment is on going segment,we need stop start stream
1827 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001828 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001829 //check video pids, stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001830 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, p_pids->video, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001831 //check sub audio pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001832 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, p_pids->ad, 2);
jianchuan.pinge5f8c5a2021-02-03 19:11:05 +08001833 //check audio pids stop or restart
1834 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, p_pids->audio, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001835 //check pcr pids stop or restart
hualing chencc91e1c2020-02-28 13:26:17 +08001836 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, p_pids->pcr, 3);
1837 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001838 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1839 //if state is pause, we need process at resume api. we only record change info
1840 int v_cmd = DVR_PLAYBACK_CMD_NONE;
1841 int a_cmd = DVR_PLAYBACK_CMD_NONE;
1842 if (VALID_PID(segment->pids.video.pid)
1843 && VALID_PID(p_pids->video.pid)
1844 && segment->pids.video.pid != p_pids->video.pid) {
1845 //restart video
1846 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
1847 }
1848 if (!VALID_PID(segment->pids.video.pid)
1849 && VALID_PID(p_pids->video.pid)
1850 && segment->pids.video.pid != p_pids->video.pid) {
1851 //start video
1852 v_cmd = DVR_PLAYBACK_CMD_VSTART;
1853 }
1854 if (VALID_PID(segment->pids.video.pid)
1855 && !VALID_PID(p_pids->video.pid)
1856 && segment->pids.video.pid != p_pids->video.pid) {
1857 //stop video
1858 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
1859 }
1860 if (VALID_PID(segment->pids.audio.pid)
1861 && VALID_PID(p_pids->audio.pid)
1862 && segment->pids.audio.pid != p_pids->audio.pid) {
1863 //restart audio
1864 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
1865 }
1866 if (!VALID_PID(segment->pids.audio.pid)
1867 && VALID_PID(p_pids->audio.pid)
1868 && segment->pids.audio.pid != p_pids->audio.pid) {
1869 //start audio
1870 a_cmd = DVR_PLAYBACK_CMD_ASTART;
1871 }
1872 if (VALID_PID(segment->pids.audio.pid)
1873 && !VALID_PID(p_pids->audio.pid)
1874 && segment->pids.audio.pid != p_pids->audio.pid) {
1875 //stop audio
1876 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
1877 }
1878 if (a_cmd == DVR_PLAYBACK_CMD_NONE
1879 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
1880 //do nothing
1881 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
1882 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
1883 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1884 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
1885 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
1886 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
1887 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1888 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1889 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1890 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
1891 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
1892 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1893 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1894 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
1895 } else {
1896 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1897 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
1898 }
1899
1900 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1901 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
1902 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1903 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
1904 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
1905 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1906 //not occur this case
1907 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1908 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
1909 } else {
1910 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1911 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
1912 }
1913
1914 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1915 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
1916 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1917 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
1918 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
1919 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
1920 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1921 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
1922 } else {
1923 //not occur this case
1924 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
1925 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1926 }
1927 }
1928 }
hualing chene10666f2020-04-14 13:58:37 +08001929 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08001930 }
hualing chen86e7d482020-01-16 15:13:33 +08001931 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08001932 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08001933 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08001934 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001935 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001936 }
hualing chen86e7d482020-01-16 15:13:33 +08001937 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001938 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001939 pthread_mutex_unlock(&player->lock);
1940 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001941}
1942/**\brief Stop play, will stop video and audio
1943 * \param[in] handle playback handle
1944 * \param[in] clear is clear last frame
1945 * \retval DVR_SUCCESS On success
1946 * \return Error code
1947 */
hualing chen040df222020-01-17 13:35:02 +08001948int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
1949 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001950
1951 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001952 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001953 return DVR_FAILURE;
1954 }
hualing chenb96aa2c2020-04-15 14:13:53 +08001955 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1956 DVR_PB_DG(1, ":playback is stoped");
1957 return DVR_SUCCESS;
1958 }
Ke Gong3c0caba2020-04-21 22:58:18 -07001959 if (player->state == DVR_PLAYBACK_STATE_STOP) {
1960 DVR_PB_DG(1, ":playback is stoped");
1961 return DVR_SUCCESS;
1962 }
hualing chen87072a82020-03-12 16:20:12 +08001963 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001964 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001965 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08001966 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08001967 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001968 if (player->has_video) {
1969 AmTsPlayer_resumeVideoDecoding(player->handle);
1970 }
1971 if (player->has_audio) {
1972 AmTsPlayer_resumeAudioDecoding(player->handle);
1973 }
1974 if (player->has_video) {
1975 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08001976 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08001977 AmTsPlayer_stopVideoDecoding(player->handle);
1978 }
1979 if (player->has_audio) {
1980 player->has_audio = DVR_FALSE;
1981 AmTsPlayer_stopAudioDecoding(player->handle);
1982 }
hualing chendf118dd2020-05-21 15:49:11 +08001983 if (player->has_ad_audio) {
1984 player->has_ad_audio =DVR_FALSE;
1985 AmTsPlayer_disableADMix(player->handle);
1986 }
hualing chen266b9502020-04-04 17:39:39 +08001987
hualing chen86e7d482020-01-16 15:13:33 +08001988 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08001989 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
1990 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
1991 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08001992 player->cur_segment_id = UINT64_MAX;
1993 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001994 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08001995 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08001996 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001997 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001998}
1999/**\brief Start play audio
2000 * \param[in] handle playback handle
2001 * \param[in] params audio playback params,contains fmt and pid...
2002 * \retval DVR_SUCCESS On success
2003 * \return Error code
2004 */
hualing chen2aba4022020-03-02 13:49:55 +08002005
hualing chendf118dd2020-05-21 15:49:11 +08002006int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param, am_tsplayer_audio_params *adparam) {
hualing chen040df222020-01-17 13:35:02 +08002007 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002008
2009 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002010 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002011 return DVR_FAILURE;
2012 }
hualing chen86e7d482020-01-16 15:13:33 +08002013 _start_playback_thread(handle);
2014 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002015 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002016 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002017
hualing chendf118dd2020-05-21 15:49:11 +08002018 if (VALID_PID(adparam->pid)) {
2019 player->has_ad_audio = DVR_TRUE;
2020 DVR_PB_DG(1, "start ad audio");
2021 AmTsPlayer_setADParams(player->handle, adparam);
2022 AmTsPlayer_enableADMix(player->handle);
2023 }
hualing chen969fe7b2021-05-26 15:13:17 +08002024 if (VALID_PID(param->pid)) {
2025 DVR_PB_DG(1, "start audio");
2026 player->has_audio = DVR_TRUE;
2027 AmTsPlayer_setAudioParams(player->handle, param);
2028 AmTsPlayer_startAudioDecoding(player->handle);
2029 }
hualing chendf118dd2020-05-21 15:49:11 +08002030
hualing chen86e7d482020-01-16 15:13:33 +08002031 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002032 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
2033 player->cmd.state = DVR_PLAYBACK_STATE_START;
2034 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002035 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002036 pthread_mutex_unlock(&player->lock);
2037 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002038}
2039/**\brief Stop play audio
2040 * \param[in] handle playback handle
2041 * \retval DVR_SUCCESS On success
2042 * \return Error code
2043 */
hualing chen040df222020-01-17 13:35:02 +08002044int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2045 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002046
2047 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002048 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002049 return DVR_FAILURE;
2050 }
2051
hualing chen2aba4022020-03-02 13:49:55 +08002052 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002053 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002054 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2055 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002056 //destory thread
2057 _stop_playback_thread(handle);
2058 } else {
2059 //do nothing.video is playing
2060 }
hualing chen7a56cba2020-04-14 14:09:27 +08002061 DVR_PB_DG(1, "lock");
2062 pthread_mutex_lock(&player->lock);
2063
hualing chenf00cdc82020-06-10 14:23:35 +08002064 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002065 player->has_audio = DVR_FALSE;
2066 AmTsPlayer_stopAudioDecoding(player->handle);
2067 }
hualing chen87072a82020-03-12 16:20:12 +08002068
hualing chendf118dd2020-05-21 15:49:11 +08002069 if (player->has_ad_audio) {
2070 player->has_ad_audio =DVR_FALSE;
2071 AmTsPlayer_disableADMix(player->handle);
2072 }
2073
hualing chen87072a82020-03-12 16:20:12 +08002074 player->cmd.last_cmd = player->cmd.cur_cmd;
2075 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2076
hualing chen4b7c15d2020-04-07 16:13:48 +08002077 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002078 pthread_mutex_unlock(&player->lock);
2079 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002080}
2081/**\brief Start play video
2082 * \param[in] handle playback handle
2083 * \param[in] params video playback params,contains fmt and pid...
2084 * \retval DVR_SUCCESS On success
2085 * \return Error code
2086 */
hualing chen2aba4022020-03-02 13:49:55 +08002087int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002088 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002089
2090 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002091 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002092 return DVR_FAILURE;
2093 }
2094
hualing chen86e7d482020-01-16 15:13:33 +08002095 _start_playback_thread(handle);
2096 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002097 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002098 pthread_mutex_lock(&player->lock);
2099 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002100 AmTsPlayer_setVideoParams(player->handle, param);
2101 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002102
2103 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002104 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002105 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002106 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002107 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2108 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002109 }
2110 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002111 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2112 player->cmd.state = DVR_PLAYBACK_STATE_START;
2113 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002114 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002115 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002116 return DVR_SUCCESS;
2117}
2118/**\brief Stop play video
2119 * \param[in] handle playback handle
2120 * \retval DVR_SUCCESS On success
2121 * \return Error code
2122 */
hualing chen040df222020-01-17 13:35:02 +08002123int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2124 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002125
2126 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002127 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002128 return DVR_FAILURE;
2129 }
2130
hualing chen86e7d482020-01-16 15:13:33 +08002131 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002132 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2133 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002134 //destory thread
2135 _stop_playback_thread(handle);
2136 } else {
2137 //do nothing.audio is playing
2138 }
hualing chen7a56cba2020-04-14 14:09:27 +08002139
2140 DVR_PB_DG(1, "lock");
2141 pthread_mutex_lock(&player->lock);
2142
hualing chen87072a82020-03-12 16:20:12 +08002143 player->has_video = DVR_FALSE;
2144
2145 AmTsPlayer_stopVideoDecoding(player->handle);
2146 //playback_device_video_stop(player->handle);
2147
2148 player->cmd.last_cmd = player->cmd.cur_cmd;
2149 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2150
hualing chen4b7c15d2020-04-07 16:13:48 +08002151 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002152 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002153 return DVR_SUCCESS;
2154}
2155/**\brief Pause play
2156 * \param[in] handle playback handle
2157 * \param[in] flush whether its internal buffers should be flushed
2158 * \retval DVR_SUCCESS On success
2159 * \return Error code
2160 */
hualing chen040df222020-01-17 13:35:02 +08002161int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2162 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002163
2164 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002165 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002166 return DVR_FAILURE;
2167 }
hualing chenf00cdc82020-06-10 14:23:35 +08002168 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
2169 DVR_PB_DG(1, "player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002170 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002171 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002172 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002173 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002174 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002175 if (player->has_video)
2176 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002177 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002178 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002179
2180 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002181 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2182 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2183 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2184 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002185 } else {
2186 player->cmd.last_cmd = player->cmd.cur_cmd;
2187 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2188 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2189 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002190 }
hualing chen86e7d482020-01-16 15:13:33 +08002191 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002192 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002193
hualing chen86e7d482020-01-16 15:13:33 +08002194 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002195}
2196
hualing chen5cbe1a62020-02-10 16:36:36 +08002197//not add lock
2198static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2199{
2200 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2201
hualing chena540a7e2020-03-27 16:44:05 +08002202 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002203 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002204 return DVR_FAILURE;
2205 }
2206
hualing chen5cbe1a62020-02-10 16:36:36 +08002207 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002208 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002209 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002210 am_tsplayer_video_params vparams;
2211 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002212 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002213 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002214
hualing chendf118dd2020-05-21 15:49:11 +08002215 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002216 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002217 pthread_mutex_unlock(&player->lock);
2218
2219 switch (cmd) {
2220 case DVR_PLAYBACK_CMD_AVRESTART:
2221 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002222 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002223 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002224 break;
2225 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002226 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2227 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002228 break;
2229 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002230 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002231 break;
2232 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002233 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002234 break;
2235 case DVR_PLAYBACK_CMD_ARESTART:
2236 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002237 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002238 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002239 break;
2240 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002241 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002242 break;
2243 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002244 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002245 break;
2246 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002247 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2248 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2249 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002250 break;
2251 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002252 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2253 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002254 break;
2255 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002256 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2257 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002258 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002259 break;
2260 case DVR_PLAYBACK_CMD_STOP:
2261 break;
2262 case DVR_PLAYBACK_CMD_START:
2263 break;
2264 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002265 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2266 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002267 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002268 break;
2269 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002270 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2271 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002272 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002273 break;
2274 case DVR_PLAYBACK_CMD_FF:
2275 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002276 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002277 break;
2278 default:
2279 break;
2280 }
2281 return DVR_SUCCESS;
2282}
2283
2284/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002285 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002286 * \retval DVR_SUCCESS On success
2287 * \return Error code
2288 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002289int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2290 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2291
hualing chena540a7e2020-03-27 16:44:05 +08002292 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002293 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002294 return DVR_FAILURE;
2295 }
2296
hualing chen5cbe1a62020-02-10 16:36:36 +08002297 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002298 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002299 pthread_mutex_lock(&player->lock);
hualing chen266b9502020-04-04 17:39:39 +08002300 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002301 DVR_PB_DG(1, "dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002302 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2303 AmTsPlayer_resumeVideoDecoding(player->handle);
2304 }
2305 if (player->has_audio) {
2306 AmTsPlayer_resumeAudioDecoding(player->handle);
2307 }
2308 //check is has audio param,if has audio .we need start audio,
2309 //we will stop audio when ff fb, if reach end, we will pause.so we need
2310 //start audio when resume play
2311
2312 am_tsplayer_video_params vparams;
2313 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002314 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002315 uint64_t segmentid = player->cur_segment_id;
hualing chendf118dd2020-05-21 15:49:11 +08002316 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002317 //valid audio pid, start audio
hualing chen969fe7b2021-05-26 15:13:17 +08002318 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2319 player->has_ad_audio = DVR_TRUE;
2320 DVR_PB_DG(1, "start ad audio");
2321 AmTsPlayer_setADParams(player->handle, &adparams);
2322 AmTsPlayer_enableADMix(player->handle);
2323 }
2324
hualing chenc70a8df2020-05-12 19:23:11 +08002325 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chen266b9502020-04-04 17:39:39 +08002326 player->has_audio = DVR_TRUE;
2327 AmTsPlayer_setAudioParams(player->handle, &aparams);
2328 AmTsPlayer_startAudioDecoding(player->handle);
2329 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002330 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d speed:%d", aparams.pid, player->has_audio, player->cmd.speed.speed.speed);
hualing chen266b9502020-04-04 17:39:39 +08002331 }
hualing chendf118dd2020-05-21 15:49:11 +08002332
hualing chen87072a82020-03-12 16:20:12 +08002333 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2334 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2335 player->cmd.state = DVR_PLAYBACK_STATE_START;
2336 player->state = DVR_PLAYBACK_STATE_START;
2337 } else {
2338 player->cmd.last_cmd = player->cmd.cur_cmd;
2339 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2340 player->cmd.state = DVR_PLAYBACK_STATE_START;
2341 player->state = DVR_PLAYBACK_STATE_START;
2342 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002343 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002344 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002345 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
hualing chene41f4372020-06-06 16:29:17 +08002346 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002347 DVR_PB_DG(1, "dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002348 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002349 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002350 }
hualing chen041c4092020-04-05 15:11:50 +08002351 if (player->has_audio)
2352 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002353 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002354 player->cmd.state = DVR_PLAYBACK_STATE_START;
2355 player->state = DVR_PLAYBACK_STATE_START;
hualing chen9811b212020-10-29 11:21:44 +08002356 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2357 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002358 } else {
2359 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2360 {
2361 pthread_mutex_lock(&player->lock);
2362 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002363 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002364 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2365 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002366 if (player->has_video) {
2367 AmTsPlayer_resumeVideoDecoding(player->handle);
2368 }
2369 if (player->has_audio)
2370 AmTsPlayer_resumeAudioDecoding(player->handle);
2371
hualing chen041c4092020-04-05 15:11:50 +08002372 pthread_mutex_unlock(&player->lock);
2373 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002374 }
2375 return DVR_SUCCESS;
2376}
2377
hualing chena540a7e2020-03-27 16:44:05 +08002378static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2379
2380 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2381 DVR_PlaybackSegmentInfo_t *segment = NULL;
2382 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2383 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2384
2385 list_for_each_entry(segment, &player->segment_list, head)
2386 {
2387 if (segment->segment_id == segment_id) {
2388 cur_segment = segment;
2389 }
2390 if (segment->segment_id == set_seg_id) {
2391 set_segment = segment;
2392 }
2393 if (cur_segment != NULL && set_segment != NULL) {
2394 break;
2395 }
2396 }
2397 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002398 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002399 return DVR_TRUE;
2400 }
2401 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2402 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2403 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2404 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002405 DVR_PB_DG(1, "cur v[%d]a[%d] set v[%d]a[%d]",cur_segment->pids.video.pid,cur_segment->pids.audio.pid,set_segment->pids.video.pid,set_segment->pids.audio.pid);
hualing chena540a7e2020-03-27 16:44:05 +08002406 return DVR_TRUE;
2407 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002408 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002409 return DVR_FALSE;
2410}
2411
hualing chen5cbe1a62020-02-10 16:36:36 +08002412/**\brief seek
2413 * \param[in] handle playback handle
2414 * \param[in] time_offset time offset base cur segment
2415 * \retval DVR_SUCCESS On success
2416 * \return Error code
2417 */
hualing chencc91e1c2020-02-28 13:26:17 +08002418int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002419 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002420
2421 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002422 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002423 return DVR_FAILURE;
2424 }
2425
hualing chen4b7c15d2020-04-07 16:13:48 +08002426 DVR_PB_DG(1, "lock segment_id %llu cur id %llu time_offset %u cur end: %d player->state:%d", segment_id,player->cur_segment_id, (uint32_t)time_offset, _dvr_get_end_time(handle), player->state);
hualing chen86e7d482020-01-16 15:13:33 +08002427 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002428
hualing chen86e7d482020-01-16 15:13:33 +08002429 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002430 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002431 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002432
hualing chen5cbe1a62020-02-10 16:36:36 +08002433 //open segment if id is not current segment
hualing chen87072a82020-03-12 16:20:12 +08002434 int ret = _dvr_open_segment(handle, segment_id);
2435 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002436 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002437 pthread_mutex_unlock(&player->lock);
2438 return DVR_FAILURE;
2439 }
2440 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2441 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002442 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002443 //pthread_mutex_unlock(&player->lock);
2444 //return DVR_SUCCESS;
2445 time_offset = _dvr_get_end_time(handle);
2446 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002447 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002448 time_offset = _dvr_get_end_time(handle);
hualing chen87072a82020-03-12 16:20:12 +08002449 pthread_mutex_unlock(&player->lock);
2450 return DVR_FAILURE;
2451 }
2452 }
2453
hualing chen4b7c15d2020-04-07 16:13:48 +08002454 DVR_PB_DG(1, "seek open id[%lld]flag[0x%x] time_offset %u", player->cur_segment.segment_id, player->cur_segment.flags, time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08002455 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002456 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2457 //forward playback.not seek end of file
2458 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2459 //default -2000ms
2460 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2461 }
hualing chen86e7d482020-01-16 15:13:33 +08002462 }
hualing chen2aba4022020-03-02 13:49:55 +08002463 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002464 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002465 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002466 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002467 DVR_PB_DG(0, "seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08002468 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002469 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002470
hualing chen2aba4022020-03-02 13:49:55 +08002471 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002472
2473 player->last_send_time_id = UINT64_MAX;
2474
hualing chen2aba4022020-03-02 13:49:55 +08002475 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002476 player->fffb_current = _dvr_time_getClock();
2477 player->fffb_start = player->fffb_current;
2478 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2479 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002480 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002481 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002482 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002483 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002484 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002485 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002486 }
hualing chen86e7d482020-01-16 15:13:33 +08002487 //stop play
hualing chen4b7c15d2020-04-07 16:13:48 +08002488 DVR_PB_DG(0, "seek stop play, not inject data has video[%d]audio[%d]", player->has_video, player->has_audio);
hualing chen266b9502020-04-04 17:39:39 +08002489 if (player->has_video) {
2490 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002491 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002492 }
2493
2494 if (player->has_audio) {
2495 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002496 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002497 }
hualing chendf118dd2020-05-21 15:49:11 +08002498 if (player->has_ad_audio) {
2499 player->has_ad_audio =DVR_FALSE;
2500 AmTsPlayer_disableADMix(player->handle);
2501 }
2502
hualing chen86e7d482020-01-16 15:13:33 +08002503 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002504 am_tsplayer_video_params vparams;
2505 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002506 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002507
hualing chen040df222020-01-17 13:35:02 +08002508 player->cur_segment_id = segment_id;
2509
2510 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002511 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002512 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002513 //start audio and video
Zhiqiang Han9adc9722020-11-11 18:38:10 +08002514 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08002515 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002516 DVR_PB_DG(0, "unlock seek start dvr play back start error, not found audio and video info");
hualing chen86e7d482020-01-16 15:13:33 +08002517 pthread_mutex_unlock(&player->lock);
2518 return -1;
2519 }
2520 //add
hualing chen040df222020-01-17 13:35:02 +08002521 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002522 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002523 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002524 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08002525 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002526 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002527 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002528 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002529 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002530 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002531 }
hualing chen2aba4022020-03-02 13:49:55 +08002532 AmTsPlayer_setVideoParams(player->handle, &vparams);
2533 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002534 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
2535 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
2536 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2537 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2538 AmTsPlayer_stopFast(player->handle);
2539 }
hualing chen266b9502020-04-04 17:39:39 +08002540 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002541 }
hualing chene41f4372020-06-06 16:29:17 +08002542 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08002543 player->has_ad_audio = DVR_TRUE;
2544 DVR_PB_DG(1, "start ad audio");
2545 AmTsPlayer_setADParams(player->handle, &adparams);
2546 AmTsPlayer_enableADMix(player->handle);
2547 }
hualing chen969fe7b2021-05-26 15:13:17 +08002548 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
2549 DVR_PB_DG(1, "start audio seek");
2550 AmTsPlayer_setAudioParams(player->handle, &aparams);
2551 AmTsPlayer_startAudioDecoding(player->handle);
2552 player->has_audio = DVR_TRUE;
2553 }
hualing chen86e7d482020-01-16 15:13:33 +08002554 }
hualing chene41f4372020-06-06 16:29:17 +08002555 if (player->state == DVR_PLAYBACK_STATE_PAUSE /*&&
hualing chen2aba4022020-03-02 13:49:55 +08002556 ((player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2557 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) ||
2558 (player->cmd.last_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chene41f4372020-06-06 16:29:17 +08002559 player->cmd.last_cmd == DVR_PLAYBACK_CMD_FB))*/) {
hualing chen2aba4022020-03-02 13:49:55 +08002560 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2561 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen30423862021-04-16 14:39:12 +08002562 player->seek_pause = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002563 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002564 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2565 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002566 player->speed > 1.0f||
2567 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002568 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002569 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002570 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002571 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002572 player->cmd.last_cmd = player->cmd.cur_cmd;
2573 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2574 player->cmd.state = DVR_PLAYBACK_STATE_START;
2575 player->state = DVR_PLAYBACK_STATE_START;
2576 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002577 player->last_send_time_id = UINT64_MAX;
2578 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002579 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002580
2581 return DVR_SUCCESS;
2582}
hualing chen5cbe1a62020-02-10 16:36:36 +08002583
hualing chen5cbe1a62020-02-10 16:36:36 +08002584static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2585 //get cur time of segment
2586 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002587
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002588 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002589 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002590 return DVR_FAILURE;
2591 }
2592
hualing chen31140872020-03-25 12:29:26 +08002593 int64_t cache = 0;//defalut es buf cache 500ms
2594 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002595 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002596 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2597 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen2aba4022020-03-02 13:49:55 +08002598 pthread_mutex_unlock(&player->segment_lock);
hualing chenfbf8e022020-06-15 13:43:11 +08002599 DVR_PB_DG(1, "get cur time [%lld] cache:%lld cur id [%lld]last id [%lld] pb cache len [%d] [%lld]", cur, cache, player->cur_segment_id,player->last_send_time_id, player->ts_cache_len, pos);
hualing chen87072a82020-03-12 16:20:12 +08002600 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2601 cache = 0;
2602 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002603 int cur_time = (int)(cur > cache ? cur - cache : 0);
2604 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002605}
2606
hualing chen969fe7b2021-05-26 15:13:17 +08002607static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
2608 //get cur time of segment
2609 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2610
2611 if (player == NULL || player->handle == NULL) {
2612 DVR_PB_DG(1, "player is NULL");
2613 return DVR_FAILURE;
2614 }
2615
2616 int64_t cache = 0;//defalut es buf cache 500ms
2617 int cur_time = 0;
2618 AmTsPlayer_getDelayTime(player->handle, &cache);
2619 pthread_mutex_lock(&player->segment_lock);
2620 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2621 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
2622 pthread_mutex_unlock(&player->segment_lock);
2623 DVR_PB_DG(1, "get play cur time [%lld] cache:%lld cur id [%lld]last id [%lld] pb cache len [%d] [%lld]", cur, cache, player->cur_segment_id,player->last_send_time_id, player->ts_cache_len, pos);
2624 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2625 cache = 0;
2626 }
2627 if (cur > cache) {
2628 cur_time = (int)(cur - cache);
2629 *id = player->cur_segment_id;
2630 } else if (player->last_segment_tatol > 0) {
2631
2632 cur_time = (int)(player->last_segment_tatol - (cache - cur));
2633 *id = player->last_segment_id;
2634 DVR_PB_DG(1, "get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_tatol);
2635 } else {
2636 cur_time = 0;
2637 *id = player->cur_segment_id;
2638 }
2639
2640 return cur_time;
2641}
2642
hualing chencc91e1c2020-02-28 13:26:17 +08002643//get current segment current pcr time of read pos
2644static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2645 //get cur time of segment
2646 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002647
2648 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002649 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002650 return DVR_FAILURE;
2651 }
2652
hualing chen2aba4022020-03-02 13:49:55 +08002653 pthread_mutex_lock(&player->segment_lock);
2654 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002655 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002656 pthread_mutex_unlock(&player->segment_lock);
2657 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002658}
2659
hualing chen4b7c15d2020-04-07 16:13:48 +08002660#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08002661//start replay
2662static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
2663
2664 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2665 //calculate pcr seek time
2666 int t_diff = 0;
2667 int seek_time = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002668
2669 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002670 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002671 return DVR_FAILURE;
2672 }
2673
hualing chen5cbe1a62020-02-10 16:36:36 +08002674 if (player->fffb_start == -1) {
2675 //set fffb start time ms
2676 player->fffb_start = _dvr_time_getClock();
2677 player->fffb_current = player->fffb_start;
2678 //get segment current time pos
2679 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002680 DVR_PB_DG(1, "calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]", player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002681 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08002682 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08002683 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002684 } else {
2685 player->fffb_current = _dvr_time_getClock();
2686 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08002687 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08002688 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08002689 if (seek_time <= 0) {
2690 //need seek to pre one segment
2691 seek_time = 0;
2692 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002693 //seek segment pos
2694 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08002695 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002696 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08002697 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2698 //set seek time to 0;
2699 DVR_PB_DG(1, "segment seek to 0 at fb mode [%d]id[%lld]", seek_time, player->cur_segment_id);
2700 seek_time = 0;
2701 }
hualing chen041c4092020-04-05 15:11:50 +08002702 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
2703 seek_time = 0;
2704 }
hualing chen2aba4022020-03-02 13:49:55 +08002705 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002706 } else {
2707 //
hualing chen4b7c15d2020-04-07 16:13:48 +08002708 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08002709 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002710 DVR_PB_DG(1, "calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]", seek_time, player->speed,player->cur_segment_id, _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08002711 }
hualing chen2aba4022020-03-02 13:49:55 +08002712 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08002713}
2714
2715
2716//start replay
2717static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
2718 //
2719 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002720
2721 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002722 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002723 return DVR_FAILURE;
2724 }
2725
hualing chen5cbe1a62020-02-10 16:36:36 +08002726 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002727 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002728 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08002729 AmTsPlayer_stopVideoDecoding(player->handle);
2730 }
2731 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002732 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08002733 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002734 AmTsPlayer_stopAudioDecoding(player->handle);
2735 }
hualing chendf118dd2020-05-21 15:49:11 +08002736 if (player->has_ad_audio) {
2737 DVR_PB_DG(1, "fffb stop audio");
2738 player->has_ad_audio =DVR_FALSE;
2739 AmTsPlayer_disableADMix(player->handle);
2740 }
hualing chen2aba4022020-03-02 13:49:55 +08002741
hualing chen5cbe1a62020-02-10 16:36:36 +08002742 //start video and audio
2743
hualing chen2aba4022020-03-02 13:49:55 +08002744 am_tsplayer_video_params vparams;
2745 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002746 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002747 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002748
2749 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08002750 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002751 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002752 //start audio and video
2753 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2754 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002755 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08002756 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002757 return -1;
2758 }
2759
2760 if (VALID_PID(vparams.pid)) {
2761 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002762 DVR_PB_DG(1, "fffb start video");
hualing chen0888c032020-12-18 17:54:57 +08002763 //DVR_PB_DG(1, "fffb start video and save last frame");
2764 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08002765 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08002766 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2767 AmTsPlayer_setVideoParams(player->handle, &vparams);
2768 AmTsPlayer_startVideoDecoding(player->handle);
2769 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002770 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08002771 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002772 }
hualing chen31140872020-03-25 12:29:26 +08002773 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08002774 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002775 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08002776 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002777 return 0;
2778}
2779
2780static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
2781 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002782 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002783 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002784 return DVR_FAILURE;
2785 }
2786
2787 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08002788 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08002789 pthread_mutex_lock(&player->lock);
2790
hualing chen2aba4022020-03-02 13:49:55 +08002791 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002792 DVR_PB_DG(1, "get lock speed [%f]id [%lld]seek_time[%d]", player->speed, player->cur_segment_id, seek_time);
hualing chen041c4092020-04-05 15:11:50 +08002793
hualing chen87072a82020-03-12 16:20:12 +08002794 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
2795 //seek time set 0
2796 seek_time = 0;
2797 }
hualing chen041c4092020-04-05 15:11:50 +08002798 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08002799 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
2800 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08002801 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002802 pthread_mutex_unlock(&player->lock);
2803 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002804 //send event here and pause
2805 DVR_Play_Notify_t notify;
2806 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08002807 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08002808 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08002809 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08002810 DVR_PB_DG(1, "*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08002811 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08002812 return DVR_SUCCESS;
2813 }
hualing chen2932d372020-04-29 13:44:00 +08002814 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08002815 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002816 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002817 }
2818 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08002819 _dvr_playback_fffb_replay(handle);
2820
2821 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002822 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002823
hualing chen5cbe1a62020-02-10 16:36:36 +08002824 return DVR_SUCCESS;
2825}
2826
hualing chen87072a82020-03-12 16:20:12 +08002827//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08002828static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002829 //
2830 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002831
2832 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002833 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002834 return DVR_FAILURE;
2835 }
2836
hualing chen5cbe1a62020-02-10 16:36:36 +08002837 //stop
hualing chen2aba4022020-03-02 13:49:55 +08002838 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08002839 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002840 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002841 }
2842
2843 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08002844 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002845 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002846 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002847 //start video and audio
2848
hualing chen2aba4022020-03-02 13:49:55 +08002849 am_tsplayer_video_params vparams;
2850 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002851 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08002852 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002853
2854 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08002855 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08002856 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002857 //start audio and video
2858 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08002859 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002860 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08002861 return -1;
2862 }
2863
2864 if (VALID_PID(vparams.pid)) {
2865 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08002866 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002867 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08002868 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08002869 }
hualing chen266b9502020-04-04 17:39:39 +08002870 else {
hualing chen2aba4022020-03-02 13:49:55 +08002871 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08002872 }
hualing chen2aba4022020-03-02 13:49:55 +08002873 AmTsPlayer_setVideoParams(player->handle, &vparams);
2874 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08002875 }
hualing chena540a7e2020-03-27 16:44:05 +08002876
2877 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08002878 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08002879 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002880 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08002881 } else {
hualing chendf118dd2020-05-21 15:49:11 +08002882 if (VALID_PID(adparams.pid)) {
2883 player->has_ad_audio = DVR_TRUE;
2884 DVR_PB_DG(1, "start ad audio");
2885 AmTsPlayer_setADParams(player->handle, &adparams);
2886 AmTsPlayer_enableADMix(player->handle);
2887 }
hualing chen969fe7b2021-05-26 15:13:17 +08002888 if (VALID_PID(aparams.pid)) {
2889 player->has_audio = DVR_TRUE;
2890 DVR_PB_DG(1, "start audio");
2891 AmTsPlayer_setAudioParams(player->handle, &aparams);
2892 AmTsPlayer_startAudioDecoding(player->handle);
2893 }
hualing chendf118dd2020-05-21 15:49:11 +08002894
hualing chen7a56cba2020-04-14 14:09:27 +08002895 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08002896 AmTsPlayer_stopFast(player->handle);
2897 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
2898 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
2899 }
hualing chen2aba4022020-03-02 13:49:55 +08002900 player->cmd.last_cmd = player->cmd.cur_cmd;
2901 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08002902 player->cmd.state = DVR_PLAYBACK_STATE_START;
2903 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002904 return 0;
2905}
2906
2907
hualing chenb31a6c62020-01-13 17:27:00 +08002908/**\brief Set play speed
2909 * \param[in] handle playback handle
2910 * \param[in] speed playback speed
2911 * \retval DVR_SUCCESS On success
2912 * \return Error code
2913 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002914int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
2915
2916 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002917
2918 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002919 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002920 return DVR_FAILURE;
2921 }
2922
hualing chen4b7c15d2020-04-07 16:13:48 +08002923 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002924 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002925 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08002926 return DVR_FAILURE;
2927 }
hualing chenf00cdc82020-06-10 14:23:35 +08002928 if (speed.speed.speed == player->cmd.speed.speed.speed) {
2929 DVR_PB_DG(1, " func: eq speed [%d]", speed.speed.speed);
2930 return DVR_SUCCESS;
2931 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002932 pthread_mutex_lock(&player->lock);
2933 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
2934 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
2935 player->cmd.last_cmd = player->cmd.cur_cmd;
2936 }
hualing chene41f4372020-06-06 16:29:17 +08002937
hualing chen31140872020-03-25 12:29:26 +08002938 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08002939 IS_KERNEL_SPEED(speed.speed.speed) ) {
2940 //case 1. not start play.only set speed
2941 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2942 //only set speed.and return;
2943 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
2944 player->cmd.speed.speed = speed.speed;
2945 player->speed = (float)speed.speed.speed/(float)100;
2946 player->fffb_play = DVR_FALSE;
2947 pthread_mutex_unlock(&player->lock);
2948 return DVR_SUCCESS;
2949 }
2950 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08002951 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
2952 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08002953 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002954 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2955 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002956 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002957 AmTsPlayer_stopFast(player->handle);
2958 pthread_mutex_unlock(&player->lock);
2959 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
2960 pthread_mutex_lock(&player->lock);
2961 } else {
2962 //set play speed and if audio is start, stop audio.
2963 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002964 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002965 AmTsPlayer_stopAudioDecoding(player->handle);
2966 player->has_audio = DVR_FALSE;
2967 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002968 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08002969 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08002970 }
hualing chenbcada022020-04-22 14:27:01 +08002971 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08002972 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002973 player->cmd.speed.speed = speed.speed;
2974 player->speed = (float)speed.speed.speed/(float)100;
2975 pthread_mutex_unlock(&player->lock);
2976 return DVR_SUCCESS;
2977 }
hualing chen31140872020-03-25 12:29:26 +08002978 //case 3 fffb mode
2979 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2980 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2981 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002982 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08002983 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08002984 player->cmd.speed.speed = speed.speed;
2985 player->speed = (float)speed.speed.speed/(float)100;
2986 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08002987 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08002988 pthread_mutex_unlock(&player->lock);
2989 return DVR_SUCCESS;
2990 }
2991 }
2992 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08002993 IS_KERNEL_SPEED(speed.speed.speed)) {
2994 //case 1. cur speed is kernel support speed,set kernel speed.
2995 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08002996 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08002997 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
2998 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08002999 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003000 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08003001 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003002 } else {
3003 //set play speed and if audio is start, stop audio.
3004 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003005 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003006 AmTsPlayer_stopAudioDecoding(player->handle);
3007 player->has_audio = DVR_FALSE;
3008 }
hualing chenf00cdc82020-06-10 14:23:35 +08003009 DVR_PB_DG(1, "start fast");
3010 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003011 }
hualing chena540a7e2020-03-27 16:44:05 +08003012 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003013 player->cmd.speed.speed = speed.speed;
3014 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003015 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003016 pthread_mutex_unlock(&player->lock);
3017 return DVR_SUCCESS;
3018 }
3019 //case 2 fffb mode
3020 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3021 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3022 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003023 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003024 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003025 player->cmd.speed.speed = speed.speed;
3026 player->speed = (float)speed.speed.speed/(float)100;
3027 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08003028 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003029 pthread_mutex_unlock(&player->lock);
3030 return DVR_SUCCESS;
3031 }
hualing chen31140872020-03-25 12:29:26 +08003032 }
hualing chena540a7e2020-03-27 16:44:05 +08003033 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3034 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003035 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003036 } else {
hualing chen31140872020-03-25 12:29:26 +08003037 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003038 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3039 else
3040 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003041 player->fffb_play = DVR_TRUE;
3042 }
3043 DVR_Bool_t init_last_time = DVR_FALSE;
3044 if (player->speed > 0.0f && speed.speed.speed < 0) {
3045 init_last_time = DVR_TRUE;
3046 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3047 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003048 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003049 player->cmd.speed.mode = speed.mode;
3050 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003051 player->speed = (float)speed.speed.speed/(float)100;
3052 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003053 _dvr_init_fffb_t(handle);
3054 if (init_last_time == DVR_TRUE)
3055 player->last_send_time_id = UINT64_MAX;
3056
hualing chen87072a82020-03-12 16:20:12 +08003057 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003058 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3059 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003060 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003061 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003062 _dvr_playback_replay(handle, DVR_FALSE);
3063 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3064 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
3065 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08003066 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003067 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003068 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08003069 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003070 return DVR_SUCCESS;
3071}
hualing chen2932d372020-04-29 13:44:00 +08003072
hualing chenb31a6c62020-01-13 17:27:00 +08003073/**\brief Get playback status
3074 * \param[in] handle playback handle
3075 * \param[out] p_status playback status
3076 * \retval DVR_SUCCESS On success
3077 * \return Error code
3078 */
hualing chen2932d372020-04-29 13:44:00 +08003079static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3080 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003081//
3082 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003083 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003084 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003085 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003086 return DVR_FAILURE;
3087 }
hualing chen2932d372020-04-29 13:44:00 +08003088 if (is_lock ==DVR_TRUE)
3089 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003090 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003091 //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 +08003092 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3093 player->state == DVR_PLAYBACK_STATE_START) {
3094 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3095 }
hualing chen041c4092020-04-05 15:11:50 +08003096
hualing chencc91e1c2020-02-28 13:26:17 +08003097 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003098
3099 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08003100 if (player->last_send_time_id == UINT64_MAX) {
3101 player->last_send_time_id = player->cur_segment_id;
3102 player->last_cur_time = p_status->time_cur;
3103 }
3104 if (player->last_send_time_id == player->cur_segment_id) {
3105 if (player->speed > 0.0f ) {
3106 //ff
3107 if (p_status->time_cur < player->last_cur_time ) {
3108 DVR_PB_DG(1, "get ff time error last[%d]cur[%d]diff[%d]", player->last_cur_time, p_status->time_cur, player->last_cur_time - p_status->time_cur);
3109 p_status->time_cur = player->last_cur_time;
3110 } else {
3111 player->last_cur_time = p_status->time_cur;
3112 }
hualing chene41f4372020-06-06 16:29:17 +08003113 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003114 //fb
3115 if (p_status->time_cur > player->last_cur_time ) {
3116 DVR_PB_DG(1, "get fb time error last[%d]cur[%d]diff[%d]", player->last_cur_time, p_status->time_cur, p_status->time_cur - player->last_cur_time );
3117 p_status->time_cur = player->last_cur_time;
3118 } else {
3119 player->last_cur_time = p_status->time_cur;
3120 }
3121 }
hualing chen969fe7b2021-05-26 15:13:17 +08003122 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003123 player->last_cur_time = p_status->time_cur;
3124 }
hualing chen969fe7b2021-05-26 15:13:17 +08003125 player->last_send_time_id = segment_id;
3126 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003127
hualing chen5cbe1a62020-02-10 16:36:36 +08003128 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003129 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003130 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08003131 DVR_PB_DG(1, "player real state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]is_lock[%d]",
hualing chen6d24aa92020-03-23 18:43:47 +08003132 _dvr_playback_state_toString(player->state),
3133 _dvr_playback_state_toString(p_status->state),
hualing chena540a7e2020-03-27 16:44:05 +08003134 p_status->time_cur, p_status->time_end,
3135 p_status->segment_id,player->play_flag,
hualing chen2932d372020-04-29 13:44:00 +08003136 player->speed,
3137 is_lock);
3138 if (is_lock ==DVR_TRUE)
3139 pthread_mutex_unlock(&player->lock);
3140 return DVR_SUCCESS;
3141}
3142
3143
3144/**\brief Get playback status
3145 * \param[in] handle playback handle
3146 * \param[out] p_status playback status
3147 * \retval DVR_SUCCESS On success
3148 * \return Error code
3149 */
3150int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3151 DVR_PlaybackStatus_t *p_status) {
3152//
3153 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3154
hualing chen969fe7b2021-05-26 15:13:17 +08003155
3156 char buf[10];
3157 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
3158 if (atoi(buf) != 1) {
3159
3160 }
3161 DVR_PB_DG(1, "player get prop[%d][%s]", atoi(buf), buf);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003162 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3163
hualing chen2932d372020-04-29 13:44:00 +08003164 if (player == NULL) {
3165 DVR_PB_DG(1, "player is NULL");
3166 return DVR_FAILURE;
3167 }
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003168 pthread_mutex_lock(&player->lock);
3169 if (!player->has_video && !player->has_audio)
3170 p_status->time_cur = 0;
3171 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08003172
hualing chenb31a6c62020-01-13 17:27:00 +08003173 return DVR_SUCCESS;
3174}
3175
hualing chen040df222020-01-17 13:35:02 +08003176void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
3177 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003178 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
3179 DVR_PB_DG(1, "segment flag: %d", segment->flags);
3180 DVR_PB_DG(1, "segment location: [%s]", segment->location);
3181 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
3182 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
3183 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3184 DVR_PB_DG(1, "segment sub apid: 0x%x sub afmt:0x%x", segment->pids.ad.pid,segment->pids.ad.format);
hualing chen86e7d482020-01-16 15:13:33 +08003185 }
hualing chenb31a6c62020-01-13 17:27:00 +08003186}
3187
hualing chen5cbe1a62020-02-10 16:36:36 +08003188int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003189 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003190
hualing chena540a7e2020-03-27 16:44:05 +08003191 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003192 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003193 return DVR_FAILURE;
3194 }
3195
hualing chen040df222020-01-17 13:35:02 +08003196 DVR_PlaybackSegmentInfo_t *segment;
3197 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003198 {
hualing chen040df222020-01-17 13:35:02 +08003199 if (segment_id >= 0) {
3200 if (segment->segment_id == segment_id) {
3201 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003202 break;
3203 }
3204 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003205 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003206 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003207 }
3208 }
3209 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003210}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003211
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003212int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003213{
3214 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3215 DVR_RETURN_IF_FALSE(player);
3216 DVR_RETURN_IF_FALSE(func);
3217
hualing chen4b7c15d2020-04-07 16:13:48 +08003218 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003219 pthread_mutex_lock(&player->lock);
3220
3221 player->dec_func = func;
3222 player->dec_userdata = userdata;
3223
3224 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003225 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003226 return DVR_SUCCESS;
3227}
3228
3229int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3230{
3231 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3232 DVR_RETURN_IF_FALSE(player);
3233 DVR_RETURN_IF_FALSE(p_secure_buf);
3234 DVR_RETURN_IF_FALSE(len);
3235
hualing chen4b7c15d2020-04-07 16:13:48 +08003236 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003237 pthread_mutex_lock(&player->lock);
3238
3239 player->is_secure_mode = 1;
3240 player->secure_buffer = p_secure_buf;
3241 player->secure_buffer_size = len;
3242
3243 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003244 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003245 return DVR_SUCCESS;
3246}