blob: 394d97cb0db52f7cbfb845010188c72d709ab687 [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 chen03fd4942021-07-15 15:56:41 +080015#include "dvr_utils.h"
16#include "dvr_types.h"
hualing chenb31a6c62020-01-13 17:27:00 +080017#include "dvr_playback.h"
Yahui Han1fbf3292021-11-08 18:17:19 +080018#include "am_crypt.h"
hualing chenb31a6c62020-01-13 17:27:00 +080019
Wentao MA96f68962022-06-15 19:45:35 +080020#define PB_LOG_TAG "libdvr-playback"
21#define DVR_PB_DEBUG(...) DVR_LOG_PRINT(LOG_LV_DEBUG, PB_LOG_TAG, __VA_ARGS__)
22#define DVR_PB_INFO(...) DVR_LOG_PRINT(LOG_LV_INFO, PB_LOG_TAG, __VA_ARGS__)
23#define DVR_PB_WARN(...) DVR_LOG_PRINT(LOG_LV_WARN, PB_LOG_TAG, __VA_ARGS__)
24#define DVR_PB_ERROR(...) DVR_LOG_PRINT(LOG_LV_ERROR, PB_LOG_TAG, __VA_ARGS__)
25#define DVR_PB_FATAL(...) DVR_LOG_PRINT(LOG_LV_FATAL, PB_LOG_TAG, __VA_ARGS__)
hualing chena540a7e2020-03-27 16:44:05 +080026
hualing chenb31a6c62020-01-13 17:27:00 +080027#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080028
hualing chend241c7a2021-06-22 13:34:27 +080029#define CONTROL_SPEED_ENABLE 0
hualing chena540a7e2020-03-27 16:44:05 +080030
31#define FF_SPEED (2.0f)
32#define FB_SPEED (-1.0f)
33#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080034#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080035
36#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))
37#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
38
Wentao MA907b6432022-08-01 06:23:08 +000039#define DVR_PLAYER_CHANGE_STATE(player,newstate)\
40 DVR_PB_INFO("%s:%d player %p changes state from %s to %s",__func__,__LINE__,\
41 player,_dvr_playback_state_toString(player->state),_dvr_playback_state_toString(newstate));\
42 player->state=newstate;
43
hualing chenb31a6c62020-01-13 17:27:00 +080044
hualing chenb5cd42e2020-04-15 17:03:34 +080045#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080046#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080047//if tsplayer delay time < 200 and no data can read, we will pause
48#define MIN_TSPLAYER_DELAY_TIME (200)
49
hualing chen041c4092020-04-05 15:11:50 +080050#define MAX_CACHE_TIME (30000)
hualing chen43a89bc2022-01-19 14:31:20 +080051//used pcr to control avsync,default not used
52//#define AVSYNC_USED_PCR 1
hualing chena540a7e2020-03-27 16:44:05 +080053static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080054//
55static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chen99508642021-10-18 15:41:17 +080056static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_PlaybackPids_t now_pids, DVR_PlaybackPids_t pids, int type);
hualing chencc91e1c2020-02-28 13:26:17 +080057static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
58static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080059static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080060static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080061static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
62 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080063static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen7ea70a72021-09-09 11:25:13 +080064static uint32_t dvr_playback_calculate_last_valid_segment(
65 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos);
hualing chen87072a82020-03-12 16:20:12 +080066
hualing chenbcada022020-04-22 14:27:01 +080067
hualing chena5f03222021-12-02 11:22:35 +080068
hualing chenbcada022020-04-22 14:27:01 +080069static char* _cmd_toString(int cmd)
70{
71
72 char *string[DVR_PLAYBACK_CMD_NONE+1]={
73 "start",
74 "stop",
Wentao MA270dc0f2022-08-23 13:17:26 +080075 "v_start",
76 "a_start",
77 "v_stop",
78 "a_stop",
79 "v_restart",
80 "a_restart",
81 "av_restart",
82 "v_stop_a_start",
83 "a_stop_v_start",
84 "v_stop_a_restart",
85 "a_stop_v_restart",
86 "v_start_a_restart",
87 "a_start_v_restart",
hualing chenbcada022020-04-22 14:27:01 +080088 "pause",
89 "resume",
90 "seek",
91 "ff",
92 "fb",
93 "NONE"
94 };
95
96 if (cmd > DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +080097 return "unknown";
hualing chenbcada022020-04-22 14:27:01 +080098 } else {
99 return string[cmd];
100 }
101}
102
103
Wentao MA907b6432022-08-01 06:23:08 +0000104static char* _dvr_playback_state_toString(int state)
hualing chen6d24aa92020-03-23 18:43:47 +0800105{
Wentao MA907b6432022-08-01 06:23:08 +0000106 char *strings[5]={
107 "START",
108 "STOP",
109 "PAUSE",
110 "FF",
111 "FB",
hualing chen6d24aa92020-03-23 18:43:47 +0800112 };
113
Wentao MA907b6432022-08-01 06:23:08 +0000114 if (state >= 5 || state < 0) {
115 return "UNKNOWN";
hualing chen6d24aa92020-03-23 18:43:47 +0800116 }
Wentao MA907b6432022-08-01 06:23:08 +0000117 return strings[state];
hualing chen6d24aa92020-03-23 18:43:47 +0800118}
hualing chena540a7e2020-03-27 16:44:05 +0800119
120static DVR_Bool_t _dvr_support_speed(int speed) {
121
122 DVR_Bool_t ret = DVR_FALSE;
123
124 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800125 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800126 case PLAYBACK_SPEED_FBX2:
127 case PLAYBACK_SPEED_FBX4:
128 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800129 case PLAYBACK_SPEED_FBX16:
130 case PLAYBACK_SPEED_FBX12:
131 case PLAYBACK_SPEED_FBX32:
132 case PLAYBACK_SPEED_FBX48:
133 case PLAYBACK_SPEED_FBX64:
134 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800135 case PLAYBACK_SPEED_S2:
136 case PLAYBACK_SPEED_S4:
137 case PLAYBACK_SPEED_S8:
138 case PLAYBACK_SPEED_X1:
139 case PLAYBACK_SPEED_X2:
140 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800141 case PLAYBACK_SPEED_X3:
142 case PLAYBACK_SPEED_X5:
143 case PLAYBACK_SPEED_X6:
144 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800145 case PLAYBACK_SPEED_X8:
146 case PLAYBACK_SPEED_X12:
147 case PLAYBACK_SPEED_X16:
148 case PLAYBACK_SPEED_X32:
149 case PLAYBACK_SPEED_X48:
150 case PLAYBACK_SPEED_X64:
151 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800152 ret = DVR_TRUE;
153 break;
154 default:
Wentao MA96f68962022-06-15 19:45:35 +0800155 DVR_PB_INFO("not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800156 break;
157 }
158 return ret;
159}
Wentao MA907b6432022-08-01 06:23:08 +0000160
hualing chen6e4bfa52020-03-13 14:37:11 +0800161void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
162{
Wentao MA96f68962022-06-15 19:45:35 +0800163 DVR_PB_INFO("in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800164 DVR_Playback_t *player = NULL;
165 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800166 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800167 DVR_PB_INFO("play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800168 }
169 switch (event->type) {
170 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
171 {
Wentao MA96f68962022-06-15 19:45:35 +0800172 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800173 event->event.video_format.frame_width,
174 event->event.video_format.frame_height,
175 event->event.video_format.frame_rate);
176 break;
177 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800178 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
179 {
Wentao MA16f870e2022-09-09 11:00:22 +0800180 if (player == NULL) {
181 DVR_PB_WARN("player is null at line %d",__LINE__);
182 break;
183 }
Wentao MA96f68962022-06-15 19:45:35 +0800184 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800185 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800186 break;
187 }
188 default:
189 break;
190 }
191}
hualing chen2aba4022020-03-02 13:49:55 +0800192void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
193{
hualing chen6e4bfa52020-03-13 14:37:11 +0800194 DVR_Playback_t *player = NULL;
195 if (user_data != NULL) {
196 player = (DVR_Playback_t *) user_data;
Wentao MA16f870e2022-09-09 11:00:22 +0800197 DVR_PB_INFO("playing speed is [%f] in callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800198 }
hualing chen2aba4022020-03-02 13:49:55 +0800199 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800200 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
201 {
Wentao MA96f68962022-06-15 19:45:35 +0800202 DVR_PB_INFO("[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800203 event->event.video_format.frame_width,
204 event->event.video_format.frame_height,
205 event->event.video_format.frame_rate);
206 break;
207 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800208 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
209 {
Wentao MA96f68962022-06-15 19:45:35 +0800210 DVR_PB_INFO("[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
Wentao MA16f870e2022-09-09 11:00:22 +0800211 if (player == NULL) {
212 DVR_PB_WARN("player is null at line %d",__LINE__);
213 break;
214 }
hualing chene41f4372020-06-06 16:29:17 +0800215 if (player->first_trans_ok == DVR_FALSE) {
216 player->first_trans_ok = DVR_TRUE;
217 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
218 }
hualing chen30423862021-04-16 14:39:12 +0800219 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800220 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800221 player->seek_pause = DVR_FALSE;
222 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800223 break;
224 }
hualing chen487ae6d2020-07-22 10:34:11 +0800225 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
Wentao MA96f68962022-06-15 19:45:35 +0800226 DVR_PB_INFO("[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
Wentao MA16f870e2022-09-09 11:00:22 +0800227 if (player == NULL) {
228 DVR_PB_WARN("player is null at line %d",__LINE__);
229 break;
230 }
hualing chen487ae6d2020-07-22 10:34:11 +0800231 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
232 player->first_trans_ok = DVR_TRUE;
233 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
234 }
235 if (player != NULL && player->has_video == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +0800236 DVR_PB_INFO("[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
hualing chen487ae6d2020-07-22 10:34:11 +0800237 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800238 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800239 }
240 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800241 default:
Wentao MA270dc0f2022-08-23 13:17:26 +0800242 DVR_PB_INFO("[evt]unknown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800243 break;
244 }
245 if (player&&player->player_callback_func) {
Wentao MA16f870e2022-09-09 11:00:22 +0800246 DVR_PB_INFO("calling callback");
hualing chen6e4bfa52020-03-13 14:37:11 +0800247 player->player_callback_func(player->player_callback_userdata, event);
248 } else if (player == NULL){
Wentao MA16f870e2022-09-09 11:00:22 +0800249 DVR_PB_WARN("player pointer %p is invalid",player);
hualing chen6e4bfa52020-03-13 14:37:11 +0800250 } else {
Wentao MA16f870e2022-09-09 11:00:22 +0800251 DVR_PB_WARN("player callback function %p is invalid",player->player_callback_func);
hualing chen2aba4022020-03-02 13:49:55 +0800252 }
253}
hualing chencc91e1c2020-02-28 13:26:17 +0800254
hualing chen5cbe1a62020-02-10 16:36:36 +0800255//convert video and audio fmt
256static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
257 int format = 0;
258 if (is_audio == DVR_FALSE) {
259 //for video fmt
260 switch (fmt)
261 {
262 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800263 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800264 break;
265 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800266 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800267 break;
268 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800269 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800270 break;
271 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800272 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800273 break;
hualing chena540a7e2020-03-27 16:44:05 +0800274 case DVR_VIDEO_FORMAT_VP9:
275 format = AV_VIDEO_CODEC_VP9;
276 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800277 }
278 } else {
279 //for audio fmt
280 switch (fmt)
281 {
282 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800283 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800284 break;
285 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800286 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800287 break;
288 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800289 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800290 break;
291 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800292 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800293 break;
hualing chena540a7e2020-03-27 16:44:05 +0800294 case DVR_AUDIO_FORMAT_AAC:
295 format = AV_AUDIO_CODEC_AAC;
296 break;
297 case DVR_AUDIO_FORMAT_LATM:
298 format = AV_AUDIO_CODEC_LATM;
299 break;
300 case DVR_AUDIO_FORMAT_PCM:
301 format = AV_AUDIO_CODEC_PCM;
302 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800303 case DVR_AUDIO_FORMAT_AC4:
304 format = AV_AUDIO_CODEC_AC4;
305 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800306 }
307 }
308 return format;
309}
hualing chen040df222020-01-17 13:35:02 +0800310static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800311{
hualing chen040df222020-01-17 13:35:02 +0800312 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800313
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800314 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800315 return -1;
316
hualing chena540a7e2020-03-27 16:44:05 +0800317 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800318}
hualing chena540a7e2020-03-27 16:44:05 +0800319
hualing chen7ea70a72021-09-09 11:25:13 +0800320
321//get sys time sec
322static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800323{
324 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800325 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800326 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800327 s = (uint32_t)(ts.tv_sec);
Wentao MA96f68962022-06-15 19:45:35 +0800328 DVR_PB_INFO("n:%u", s);
hualing chen7ea70a72021-09-09 11:25:13 +0800329 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800330}
hualing chen86e7d482020-01-16 15:13:33 +0800331
hualing chen7ea70a72021-09-09 11:25:13 +0800332//get sys time ms
333static uint32_t _dvr_time_getClock(void)
334{
335 struct timespec ts;
336 uint32_t ms;
337 clock_gettime(CLOCK_REALTIME, &ts);
338 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
339 return ms;
340}
hualing chenb31a6c62020-01-13 17:27:00 +0800341
Wentao MA270dc0f2022-08-23 13:17:26 +0800342//timeout wait signal
hualing chen040df222020-01-17 13:35:02 +0800343static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800344{
hualing chen040df222020-01-17 13:35:02 +0800345 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800346
hualing chena540a7e2020-03-27 16:44:05 +0800347
348 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800349 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800350 return DVR_FAILURE;
351 }
352
hualing chen86e7d482020-01-16 15:13:33 +0800353 struct timespec ts;
354 clock_gettime(CLOCK_MONOTONIC, &ts);
355 //ms为毫秒,换算成秒
356 ts.tv_sec += ms/1000;
357 //在outtime的基础上,增加ms毫秒
358 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
359 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
360 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
361 //us的值有可能超过1秒,
362 ts.tv_sec += us / 1000000;
363 us = us % 1000000;
364 ts.tv_nsec = us * 1000;//换算成纳秒
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800365
366 int val = dvr_mutex_save(&player->lock);
367 pthread_cond_timedwait(&player->cond, &player->lock.lock, &ts);
368 dvr_mutex_restore(&player->lock, val);
hualing chen86e7d482020-01-16 15:13:33 +0800369 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800370}
hualing chen31140872020-03-25 12:29:26 +0800371//get tsplay delay time ms
372static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
373 DVR_Playback_t *player = (DVR_Playback_t *) handle;
374 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800375 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800376 DVR_PB_INFO("tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800377 return 0;
378 }
379 AmTsPlayer_getDelayTime(player->handle, &cache);
Wentao MA96f68962022-06-15 19:45:35 +0800380 DVR_PB_INFO("tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800381 return cache;
382}
hualing chenb31a6c62020-01-13 17:27:00 +0800383//send signal
hualing chen040df222020-01-17 13:35:02 +0800384static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800385{
hualing chen87072a82020-03-12 16:20:12 +0800386 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800387
388 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800389 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800390 return DVR_FAILURE;
391 }
Wentao MA96f68962022-06-15 19:45:35 +0800392 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800393 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800394 pthread_cond_signal(&player->cond);
Wentao MA96f68962022-06-15 19:45:35 +0800395 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800396 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800397 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800398}
399
hualing chen2932d372020-04-29 13:44:00 +0800400//send playback event, need check is need lock first
401static 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 +0800402
403 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800404
405 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800406 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800407 return DVR_FAILURE;
408 }
409
hualing chencc91e1c2020-02-28 13:26:17 +0800410 switch (evt) {
411 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800412 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800413 break;
414 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
415 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800416 DVR_PB_INFO("trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800417 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800418 break;
419 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
420 break;
421 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
422 break;
423 case DVR_PLAYBACK_EVENT_NO_KEY:
424 break;
425 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800426 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800427 DVR_PB_INFO("reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800428 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800429 break;
430 case DVR_PLAYBACK_EVENT_REACHED_END:
431 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800432 DVR_PB_INFO("reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800433 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800434 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800435 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800436 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800437 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800438 default:
439 break;
440 }
441 if (player->openParams.event_fn != NULL)
442 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800443 return DVR_SUCCESS;
444}
hualing chen2932d372020-04-29 13:44:00 +0800445static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800446{
447 DVR_Play_Notify_t notify;
448 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
449 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
450 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800451 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800452 return DVR_SUCCESS;
453}
454
hualing chen2932d372020-04-29 13:44:00 +0800455static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800456{
457 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800458
Wentao MA16f870e2022-09-09 11:00:22 +0800459 if (player == NULL) {
460 DVR_PB_ERROR("player is NULL");
461 return DVR_FAILURE;
462 }
hualing chene3797f02021-01-13 14:53:28 +0800463 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800464 if (CONTROL_SPEED_ENABLE == 0)
465 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800466 }
hualing chena540a7e2020-03-27 16:44:05 +0800467
hualing chen03fd4942021-07-15 15:56:41 +0800468 if (player->send_time == 0) {
hualing chend241c7a2021-06-22 13:34:27 +0800469 if (CONTROL_SPEED_ENABLE == 0)
470 player->send_time = _dvr_time_getClock() + 500;
471 else
472 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800473 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen56c0a162022-01-27 17:01:50 +0800474 if ((player->send_time - _dvr_time_getClock()) > 1000) {
475 player->send_time = _dvr_time_getClock() + 500;
Wentao MA96f68962022-06-15 19:45:35 +0800476 DVR_PB_INFO("player send time occur system time changed!!!!!");
hualing chen56c0a162022-01-27 17:01:50 +0800477 } else {
478 return DVR_SUCCESS;
479 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800480 }
hualing chend241c7a2021-06-22 13:34:27 +0800481 if (CONTROL_SPEED_ENABLE == 0)
482 player->send_time = _dvr_time_getClock() + 500;
483 else
484 player->send_time = _dvr_time_getClock() + 20;
485
hualing chen6e4bfa52020-03-13 14:37:11 +0800486 DVR_Play_Notify_t notify;
487 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
488 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
489 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800490 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800491 return DVR_SUCCESS;
492}
493
hualing chencc91e1c2020-02-28 13:26:17 +0800494//check is ongoing segment
495static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
496
497 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800498
499 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800500 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800501 return DVR_FAILURE;
502 }
wentao.maa210e5e2022-10-12 16:10:03 +0800503 int ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800504 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800505 return DVR_FALSE;
506 }
hualing chencc91e1c2020-02-28 13:26:17 +0800507 return DVR_TRUE;
508}
hualing chen4b7c15d2020-04-07 16:13:48 +0800509
510
511static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
512 DVR_Playback_t *player = (DVR_Playback_t *) handle;
513 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800514 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800515 player->fffb_current = player->fffb_start;
516 //get segment current time pos
517 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800518 player->next_fffb_time = _dvr_time_getClock();
519
520 return DVR_SUCCESS;
521}
522
hualing chen2aba4022020-03-02 13:49:55 +0800523static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
524 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800525 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800526 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800527 player->fffb_current = player->fffb_start;
528 //get segment current time pos
529 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800530
hualing chen2aba4022020-03-02 13:49:55 +0800531 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800532 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800533 return DVR_SUCCESS;
534}
hualing chencc91e1c2020-02-28 13:26:17 +0800535//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800536static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
537
538 DVR_Playback_t *player = (DVR_Playback_t *) handle;
539 DVR_PlaybackSegmentInfo_t *segment;
540 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
541
hualing chena540a7e2020-03-27 16:44:05 +0800542 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800543 DVR_PB_INFO(" player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800544 return DVR_FAILURE;
545 }
546
hualing chen87072a82020-03-12 16:20:12 +0800547 int found = 0;
548 int found_eq_id = 0;
wentao.maa22bc852022-10-13 12:18:06 +0800549 // This error is surpressed as the macro code is picked from kernel.
550 // prefetch() here incurring self_assign is used to avoid some compiling
551 // warnings.
552 // coverity[self_assign]
hualing chen87072a82020-03-12 16:20:12 +0800553 list_for_each_entry(segment, &player->segment_list, head)
554 {
555 if (player->segment_is_open == DVR_FALSE) {
556 //get first segment from list, case segment is not open
557 if (!IS_FB(player->speed))
558 found = 1;
559 } else if (segment->segment_id == segmentid) {
560 //find cur segment, we need get next one
561 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.
Wentao MA96f68962022-06-15 19:45:35 +0800571 DVR_PB_INFO("not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800572 return DVR_FAILURE;
573 }
574 }
575 }
576 if (found == 1) {
577 found = 2;
578 break;
579 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800580 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800581 }
582 if (found != 2) {
583 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800584 DVR_PB_INFO("not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800585 return DVR_FAILURE;
586 }
Wentao MA96f68962022-06-15 19:45:35 +0800587 DVR_PB_INFO("found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800588 return DVR_SUCCESS;
589}
590
591//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800592static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800593
hualing chen040df222020-01-17 13:35:02 +0800594 DVR_Playback_t *player = (DVR_Playback_t *) handle;
595 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800596 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800597 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800598 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800599 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800600 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800601 return DVR_FAILURE;
602 }
603
hualing chen03fd4942021-07-15 15:56:41 +0800604 if (IS_FB(player->speed)
605 && dvr_playback_check_limit(handle)) {
606 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
607 //case cur id < segment id
608 if (player->cur_segment_id <= segmentid) {
609 //expired ts data is player,return error
Wentao MA96f68962022-06-15 19:45:35 +0800610 DVR_PB_INFO("reach start segment ,return error");
hualing chen03fd4942021-07-15 15:56:41 +0800611 return DVR_FAILURE;
612 }
Wentao MA96f68962022-06-15 19:45:35 +0800613 DVR_PB_INFO("has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800614 }
615
hualing chen86e7d482020-01-16 15:13:33 +0800616 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800617 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800618
wentao.maa22bc852022-10-13 12:18:06 +0800619 // This error is surpressed as the macro code is picked from kernel.
620 // prefetch() here incurring self_assign is used to avoid some compiling
621 // warnings.
622 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +0800623 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800624 {
hualing chencc91e1c2020-02-28 13:26:17 +0800625 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800626 //get first segment from list, case segment is not open
627 if (!IS_FB(player->speed))
628 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800629 } else if (segment->segment_id == player->cur_segment_id) {
630 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800631 found_eq_id = 1;
632 if (!IS_FB(player->speed)) {
633 found = 1;
634 continue;
635 } else {
636 //if is fb mode.we need used pre segment
637 if (pre_segment != NULL) {
638 found = 1;
639 } else {
640 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800641 DVR_PB_INFO("not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800642 return DVR_FAILURE;
643 }
644 }
hualing chen86e7d482020-01-16 15:13:33 +0800645 }
646 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800647 if (IS_FB(player->speed)) {
648 //used pre segment
649 segment = pre_segment;
650 }
hualing chencc91e1c2020-02-28 13:26:17 +0800651 //save segment info
652 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800653 if (player->r_handle)
Wentao MA270dc0f2022-08-23 13:17:26 +0800654 player->last_segment_total = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800655 player->last_segment.segment_id = player->cur_segment.segment_id;
656 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800657 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
658 //pids
659 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
660
hualing chen5cbe1a62020-02-10 16:36:36 +0800661 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800662 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800663 player->cur_segment_id = segment->segment_id;
664 player->cur_segment.segment_id = segment->segment_id;
665 player->cur_segment.flags = segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800666 DVR_PB_INFO("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 +0800667 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800668 //pids
hualing chen040df222020-01-17 13:35:02 +0800669 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800670 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800671 break;
hualing chen86e7d482020-01-16 15:13:33 +0800672 }
hualing chen2aba4022020-03-02 13:49:55 +0800673 pre_segment = segment;
674 }
675 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
676 //used the last one segment to open
677 //get segment info
678 player->segment_is_open = DVR_TRUE;
679 player->cur_segment_id = pre_segment->segment_id;
680 player->cur_segment.segment_id = pre_segment->segment_id;
681 player->cur_segment.flags = pre_segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800682 DVR_PB_INFO("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 +0800683 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
684 //pids
685 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
686 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800687 }
688 if (found != 2) {
689 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800690 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800691 }
692 return DVR_SUCCESS;
693}
hualing chen040df222020-01-17 13:35:02 +0800694//open next segment to play,if reach list end return errro.
695static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800696{
hualing chen040df222020-01-17 13:35:02 +0800697 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800698 Segment_OpenParams_t params;
699 int ret = DVR_SUCCESS;
700
hualing chena540a7e2020-03-27 16:44:05 +0800701 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800702 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800703 return DVR_FAILURE;
704 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800705 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800706retry:
hualing chena540a7e2020-03-27 16:44:05 +0800707 ret = _dvr_get_next_segmentId(handle);
708 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800709 DVR_PB_INFO("not found segment info");
hualing chen4b7c15d2020-04-07 16:13:48 +0800710 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800711 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800712 }
713
714 if (player->r_handle != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800715 DVR_PB_INFO("close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800716 segment_close(player->r_handle);
717 player->r_handle = NULL;
718 }
719
Wentao MA4d85ff32022-09-23 11:36:18 +0800720 memset((void*)&params,0,sizeof(params));
Wentao MA270dc0f2022-08-23 13:17:26 +0800721 //cp current segment path to location
hualing chen5cbe1a62020-02-10 16:36:36 +0800722 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800723 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800724 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800725 DVR_PB_INFO("open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen4b7c15d2020-04-07 16:13:48 +0800726
hualing chen86e7d482020-01-16 15:13:33 +0800727 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800728 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800729 DVR_PB_INFO("open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800730 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800731 }
Wentao MA01de0e62022-01-10 18:48:23 +0800732 // Keep the start segment_id when the first segment_open is called during a playback
733 if (player->first_start_id == UINT64_MAX) {
734 player->first_start_id = player->cur_segment.segment_id;
735 }
hualing chen87072a82020-03-12 16:20:12 +0800736 pthread_mutex_unlock(&player->segment_lock);
737 int total = _dvr_get_end_time( handle);
738 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800739 if (IS_FB(player->speed)) {
740 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800741 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800742 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +0800743 DVR_PB_INFO("seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800744 }
hualing chen87072a82020-03-12 16:20:12 +0800745 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800746 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +0800747 DVR_PB_INFO("next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800748 return ret;
749}
750
hualing chen5cbe1a62020-02-10 16:36:36 +0800751//open next segment to play,if reach list end return errro.
752static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
753{
754 DVR_Playback_t *player = (DVR_Playback_t *) handle;
755 Segment_OpenParams_t params;
756 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800757 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800758 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800759 return DVR_FAILURE;
760 }
hualing chencc91e1c2020-02-28 13:26:17 +0800761 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800762 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800763 }
hualing chencc91e1c2020-02-28 13:26:17 +0800764 uint64_t id = segment_id;
Wentao MA07d3d742022-09-06 09:58:05 +0800765 DVR_PB_INFO("start finding segment[%lld] info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800766 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800767
768 DVR_PlaybackSegmentInfo_t *segment;
769
770 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800771
wentao.maa22bc852022-10-13 12:18:06 +0800772 // This error is surpressed as the macro code is picked from kernel.
773 // prefetch() here incurring self_assign is used to avoid some compiling
774 // warnings.
775 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800776 list_for_each_entry(segment, &player->segment_list, head)
777 {
Wentao MA96f68962022-06-15 19:45:35 +0800778 DVR_PB_INFO("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 +0800779 if (segment->segment_id == segment_id) {
780 found = 1;
781 }
782 if (found == 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800783 DVR_PB_INFO("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 +0800784 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800785 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800786 player->cur_segment_id = segment->segment_id;
787 player->cur_segment.segment_id = segment->segment_id;
788 player->cur_segment.flags = segment->flags;
Wentao MAe88ad702022-09-02 10:35:00 +0800789 const int len = strlen(segment->location);
790 if (len >= DVR_MAX_LOCATION_SIZE || len <= 0) {
791 DVR_PB_ERROR("Invalid segment.location length %d",len);
792 pthread_mutex_unlock(&player->segment_lock);
793 return DVR_FAILURE;
794 }
795 strncpy(player->cur_segment.location, segment->location, len+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800796 //pids
797 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +0800798 DVR_PB_INFO("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 +0800799 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800800 }
801 }
hualing chencc91e1c2020-02-28 13:26:17 +0800802 if (found == 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800803 DVR_PB_INFO("not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800804 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800805 return DVR_FAILURE;
806 }
Wentao MA4d85ff32022-09-23 11:36:18 +0800807 memset((void*)&params,0,sizeof(params));
Wentao MAe88ad702022-09-02 10:35:00 +0800808
809 const int len2 = strlen(player->cur_segment.location);
810 if (len2 >= DVR_MAX_LOCATION_SIZE || len2 <= 0) {
811 DVR_PB_ERROR("Invalid cur_segment.location length %d",len2);
812 pthread_mutex_unlock(&player->segment_lock);
813 return DVR_FAILURE;
814 }
815 strncpy(params.location, player->cur_segment.location, len2+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800816 params.segment_id = (uint64_t)player->cur_segment.segment_id;
817 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800818 DVR_PB_INFO("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 +0800819 if (player->r_handle != NULL) {
820 segment_close(player->r_handle);
821 player->r_handle = NULL;
822 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800823 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800824 if (ret == DVR_FAILURE) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800825 DVR_PB_INFO("segment open error");
hualing chen4b7c15d2020-04-07 16:13:48 +0800826 }
Wentao MA01de0e62022-01-10 18:48:23 +0800827 // Keep the start segment_id when the first segment_open is called during a playback
828 if (player->first_start_id == UINT64_MAX) {
829 player->first_start_id = player->cur_segment.segment_id;
830 }
hualing chen2aba4022020-03-02 13:49:55 +0800831 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800832 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800833
Wentao MA96f68962022-06-15 19:45:35 +0800834 DVR_PB_INFO("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 +0800835 return ret;
836}
837
838
839//get play info by segment id
840static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
841 uint64_t segment_id,
Wentao MA270dc0f2022-08-23 13:17:26 +0800842 am_tsplayer_video_params *video_param,
843 am_tsplayer_audio_params *audio_param, am_tsplayer_audio_params *ad_param) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800844
845 DVR_Playback_t *player = (DVR_Playback_t *) handle;
846 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800847 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800848 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800849 return DVR_FAILURE;
850 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800851
852 int found = 0;
853
wentao.maa22bc852022-10-13 12:18:06 +0800854 // This error is surpressed as the macro code is picked from kernel.
855 // prefetch() here incurring self_assign is used to avoid some compiling
856 // warnings.
857 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800858 list_for_each_entry(segment, &player->segment_list, head)
859 {
hualing chen87072a82020-03-12 16:20:12 +0800860 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800861 //get first segment from list
862 found = 1;
863 }
864 if (segment->segment_id == segment_id) {
865 found = 1;
866 }
867 if (found == 1) {
868 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800869 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800870 player->cur_segment_id = segment->segment_id;
Wentao MA96f68962022-06-15 19:45:35 +0800871 DVR_PB_INFO("get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800872 player->cur_segment.segment_id = segment->segment_id;
873 player->cur_segment.flags = segment->flags;
874 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800875 player->cur_segment.pids.video.pid = segment->pids.video.pid;
876 player->cur_segment.pids.video.format = segment->pids.video.format;
877 player->cur_segment.pids.video.type = segment->pids.video.type;
878 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
879 player->cur_segment.pids.audio.format = segment->pids.audio.format;
880 player->cur_segment.pids.audio.type = segment->pids.audio.type;
881 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
882 player->cur_segment.pids.ad.format = segment->pids.ad.format;
883 player->cur_segment.pids.ad.type = segment->pids.ad.type;
884 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800885 //
Wentao MA270dc0f2022-08-23 13:17:26 +0800886 video_param->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
887 video_param->pid = segment->pids.video.pid;
888 audio_param->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
889 audio_param->pid = segment->pids.audio.pid;
890 ad_param->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
891 ad_param->pid =segment->pids.ad.pid;
892 DVR_PB_INFO("get play info success[0x%x]apid[0x%x]vfmt[%d]afmt[%d]", video_param->pid, audio_param->pid, video_param->codectype, audio_param->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800893 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800894 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800895 }
896 }
hualing chencc91e1c2020-02-28 13:26:17 +0800897 if (found != 2) {
898 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800899 DVR_PB_INFO("get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800900 return DVR_FAILURE;
901 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800902
903 return DVR_SUCCESS;
904}
hualing chencc91e1c2020-02-28 13:26:17 +0800905static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
906 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800907 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800908 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800909 return DVR_FAILURE;
910 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800911
hualing chencc91e1c2020-02-28 13:26:17 +0800912 //compare cur segment
913 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
914 {
915 //check video pids, stop or restart
hualing chen99508642021-10-18 15:41:17 +0800916 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800917 //check sub audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800918 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800919 //check audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800920 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 1);
Wentao MA96f68962022-06-15 19:45:35 +0800921 DVR_PB_INFO(":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 +0800922 //check pcr pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800923 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800924 }
hualing chena540a7e2020-03-27 16:44:05 +0800925 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800926}
hualing chen5cbe1a62020-02-10 16:36:36 +0800927
hualing chend241c7a2021-06-22 13:34:27 +0800928static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
929{
930 DVR_Playback_t *player = (DVR_Playback_t *) handle;
931 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800932 DVR_PB_INFO("player is NULL");
hualing chend241c7a2021-06-22 13:34:27 +0800933 return DVR_TRUE;
934 }
wentao.maa210e5e2022-10-12 16:10:03 +0800935 char buf[10] = {0};
hualing chend241c7a2021-06-22 13:34:27 +0800936 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800937 DVR_PB_INFO("player get prop[%d][%s]", atoi(buf), buf);
hualing chend241c7a2021-06-22 13:34:27 +0800938
939 if (atoi(buf) != 1) {
940 //return DVR_TRUE;
941 }
942
Wentao MA96f68962022-06-15 19:45:35 +0800943 DVR_PB_INFO(":play speed: %f ply dur: %u sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800944 player->speed,
945 player->con_spe.ply_dur,
946 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800947
948 if (player->speed != 1.0f)
949 return DVR_TRUE;
950
951 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800952 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800953 return DVR_FALSE;
954
955 return DVR_TRUE;
956}
957
hualing chencc91e1c2020-02-28 13:26:17 +0800958static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
959{
960 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800961 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800962 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800963 return DVR_FAILURE;
964 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800965 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
Wentao MA96f68962022-06-15 19:45:35 +0800966 DVR_PB_INFO("vendor is amlogic. no used segment flag to hide or show av");
hualing chenf43b8ba2020-07-28 13:11:42 +0800967 return DVR_SUCCESS;
968 }
Wentao MA96f68962022-06-15 19:45:35 +0800969 DVR_PB_INFO("flag[0x%x]id[%lld]last[0x%x][%llu]",
hualing chen03fd4942021-07-15 15:56:41 +0800970 player->cur_segment.flags,
971 player->cur_segment.segment_id,
972 player->last_segment.flags,
973 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800974 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
975 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800976 //enable display
Wentao MA96f68962022-06-15 19:45:35 +0800977 DVR_PB_INFO("unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800978 AmTsPlayer_showVideo(player->handle);
979 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800980 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
981 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800982 //disable display
Wentao MA96f68962022-06-15 19:45:35 +0800983 DVR_PB_INFO("mute");
hualing chen2aba4022020-03-02 13:49:55 +0800984 AmTsPlayer_hideVideo(player->handle);
985 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800986 }
987 return DVR_SUCCESS;
988}
hualing chene3797f02021-01-13 14:53:28 +0800989/*
Wentao MA270dc0f2022-08-23 13:17:26 +0800990if decode success first time.
991success: return true
hualing chene3797f02021-01-13 14:53:28 +0800992fail: return false
993*/
Wentao MA270dc0f2022-08-23 13:17:26 +0800994static DVR_Bool_t _dvr_pauselive_decode_success(DVR_PlaybackHandle_t handle) {
hualing chena540a7e2020-03-27 16:44:05 +0800995 DVR_Playback_t *player = (DVR_Playback_t *) handle;
996 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800997 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800998 return DVR_TRUE;
999 }
hualing chene3797f02021-01-13 14:53:28 +08001000 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +08001001 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +08001002 } else {
1003 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08001004 }
1005}
hualing chen86e7d482020-01-16 15:13:33 +08001006static void* _dvr_playback_thread(void *arg)
1007{
hualing chen040df222020-01-17 13:35:02 +08001008 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +08001009 //int need_open_segment = 1;
Wentao MA270dc0f2022-08-23 13:17:26 +08001010 am_tsplayer_input_buffer input_buffer;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001011 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +08001012 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +08001013
hualing chen39628212020-05-14 10:35:13 +08001014 #define MAX_REACHEND_TIMEOUT (3000)
1015 int reach_end_timeout = 0;//ms
1016 int cache_time = 0;
hualing chenb9a1a2c2021-12-31 11:27:59 +08001017 int timeout = 200;//ms
hualing chen40dd5462021-11-26 19:56:20 +08001018 int check_no_data_time = 4;
hualing chen2aba4022020-03-02 13:49:55 +08001019 uint64_t write_timeout_ms = 50;
hualing chen040df222020-01-17 13:35:02 +08001020 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +08001021 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +08001022 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001023 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +08001024 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001025 DVR_Bool_t goto_rewrite = DVR_FALSE;
yinming ding0ce94922021-09-08 15:09:15 +08001026 char prop_buf[10];
Wentao MA9628de82022-09-13 14:19:37 +08001027 int read = 0;
yinming ding0ce94922021-09-08 15:09:15 +08001028
1029 memset(prop_buf, 0 ,sizeof(prop_buf));
1030 dvr_prop_read("vendor.tv.libdvr.writetm", prop_buf, sizeof(prop_buf));
Wentao MA96f68962022-06-15 19:45:35 +08001031 DVR_PB_INFO("---vendor.tv.libdvr.writetm get prop[%d][%s]block_size[%d]", atoi(prop_buf), prop_buf, player->openParams.block_size);
yinming ding0ce94922021-09-08 15:09:15 +08001032 if (atoi(prop_buf) > 0)
1033 write_timeout_ms = atoi(prop_buf);
hualing chen03fd4942021-07-15 15:56:41 +08001034
hualing chen56c0a162022-01-27 17:01:50 +08001035
1036 memset(prop_buf, 0 ,sizeof(prop_buf));
1037 dvr_prop_read("vendor.tv.libdvr.waittm", prop_buf, sizeof(prop_buf));
Wentao MA96f68962022-06-15 19:45:35 +08001038 DVR_PB_INFO("---vendor.tv.libdvr.waittm get prop[%d][%s]block_size[%d]", atoi(prop_buf), prop_buf, player->openParams.block_size);
hualing chen56c0a162022-01-27 17:01:50 +08001039 if (atoi(prop_buf) > 0)
1040 timeout = atoi(prop_buf);
1041
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001042 if (player->is_secure_mode) {
1043 if (dec_buf_size > player->secure_buffer_size) {
Wentao MA96f68962022-06-15 19:45:35 +08001044 DVR_PB_INFO("playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001045 return NULL;
1046 }
1047 }
wentao.maa210e5e2022-10-12 16:10:03 +08001048
1049 uint8_t *buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001050 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +08001051 DVR_PB_INFO("Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001052 return NULL;
1053 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001054 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1055 input_buffer.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001056
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001057 dec_bufs.buf_data = malloc(dec_buf_size);
1058 if (!dec_bufs.buf_data) {
Wentao MA96f68962022-06-15 19:45:35 +08001059 DVR_PB_INFO("Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +08001060 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001061 return NULL;
1062 }
1063 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1064 dec_bufs.buf_size = dec_buf_size;
1065
hualing chencc91e1c2020-02-28 13:26:17 +08001066 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001067 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1068 }
hualing chen86e7d482020-01-16 15:13:33 +08001069
hualing chen86e7d482020-01-16 15:13:33 +08001070 if (ret != DVR_SUCCESS) {
1071 if (buf != NULL) {
1072 free(buf);
hualing chen86e7d482020-01-16 15:13:33 +08001073 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001074 free(dec_bufs.buf_data);
Wentao MA96f68962022-06-15 19:45:35 +08001075 DVR_PB_INFO("get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001076 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001077 }
Wentao MA96f68962022-06-15 19:45:35 +08001078 DVR_PB_INFO("--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001079 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001080 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1081 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1082 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1083 player->first_trans_ok = DVR_TRUE;
1084 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1085 }
hualing chencc91e1c2020-02-28 13:26:17 +08001086 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001087 //set video show
1088 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001089 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1090 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001091 int trick_stat = 0;
1092 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001093
hualing chen86e7d482020-01-16 15:13:33 +08001094 //check trick stat
Wentao MA96f68962022-06-15 19:45:35 +08001095 //DVR_PB_INFO("lock check_no_data_time:%d", check_no_data_time);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001096 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001097
Wentao MA907b6432022-08-01 06:23:08 +00001098 {
Wentao MA9a164002022-08-29 11:20:24 +08001099 static struct timespec _prev_ts={0,0};
Wentao MA907b6432022-08-01 06:23:08 +00001100 struct timespec _nowts,_diffts;
1101 clock_gettime(CLOCK_MONOTONIC, &_nowts);
Wentao MA9a164002022-08-29 11:20:24 +08001102 clock_timespec_subtract(&_nowts,&_prev_ts,&_diffts);
Wentao MA907b6432022-08-01 06:23:08 +00001103 if (_diffts.tv_sec>0) {
1104 char _logbuf[512]={0};
1105 char* _pbuf=_logbuf;
1106 int _nchar=0;
1107 DVR_PlaybackSegmentInfo_t* _segment;
wentao.maa22bc852022-10-13 12:18:06 +08001108 // This error is surpressed as the macro code is picked from kernel.
1109 // prefetch() here incurring self_assign is used to avoid some compiling
1110 // warnings.
1111 // coverity[self_assign]
Wentao MA907b6432022-08-01 06:23:08 +00001112 list_for_each_entry(_segment, &player->segment_list, head) {
1113 if (player->cur_segment_id == _segment->segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08001114 int seg_size = segment_get_cur_segment_size(player->r_handle);
1115 int read_ptr = segment_tell_position(player->r_handle);
Wentao MA907b6432022-08-01 06:23:08 +00001116 float progress = -1.0f;
Wentao MA9a164002022-08-29 11:20:24 +08001117 if (seg_size>0) {
1118 progress = (float)read_ptr*100/seg_size;
Wentao MA907b6432022-08-01 06:23:08 +00001119 }
Wentao MA4d85ff32022-09-23 11:36:18 +08001120 _nchar=sprintf(_pbuf,"%lld(%.1f%%), ",_segment->segment_id,progress);
Wentao MA907b6432022-08-01 06:23:08 +00001121 } else {
1122 _nchar=sprintf(_pbuf,"%lld, ",_segment->segment_id);
1123 }
1124 if (_nchar<0) {
1125 break;
1126 }
1127 _pbuf+=_nchar;
1128 if (_pbuf-_logbuf+10 >= sizeof(_logbuf)) {
1129 sprintf(_pbuf,"...");
1130 break;
1131 }
1132 }
Wentao MA9a164002022-08-29 11:20:24 +08001133 DVR_PB_INFO("clk: %08u, seg_list: %s",_nowts.tv_sec,_logbuf);
1134 _prev_ts=_nowts;
Wentao MA907b6432022-08-01 06:23:08 +00001135 }
1136 }
1137
hualing chen2aba4022020-03-02 13:49:55 +08001138 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1139 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001140 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001141 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001142 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001143 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001144 {
hualing chen2aba4022020-03-02 13:49:55 +08001145 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1146 if (trick_stat > 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001147 DVR_PB_INFO("trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001148 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001149 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 +08001150 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001151 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001152 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001153 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
Wentao MA270dc0f2022-08-23 13:17:26 +08001154 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_V_START
1155 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_A_START
hualing chen2aba4022020-03-02 13:49:55 +08001156 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
Wentao MA96f68962022-06-15 19:45:35 +08001157 DVR_PB_INFO("pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001158 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001159 //need change to pause state
1160 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1161 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00001162 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08001163 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001164 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001165 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001166 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001167 AmTsPlayer_pauseVideoDecoding(player->handle);
1168 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001169 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001170 DVR_PB_INFO("clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001171 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001172 }
1173 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1174 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001175 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001176 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001177 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001178 DVR_PB_INFO("fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001179 player->speed,
1180 player->fffb_current,
1181 _dvr_time_getClock(),
1182 _dvr_playback_state_toString(player->state),
1183 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001184 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001185 //dvr_mutex_unlock(&player->lock);
1186 //dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001187 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001188 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001189 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001190 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001191 } else if (_dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001192 DVR_PB_INFO("fffb timeout-to pause video---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001193 player->speed,
1194 player->fffb_current,
1195 _dvr_time_getClock(),
1196 _dvr_playback_state_toString(player->state),
1197 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001198 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001199 //dvr_mutex_unlock(&player->lock);
1200 //dvr_mutex_lock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001201 AmTsPlayer_pauseVideoDecoding(player->handle);
1202 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001203 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001204 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001205 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001206 }
Wentao MA96f68962022-06-15 19:45:35 +08001207 DVR_PB_INFO("fffb play-------speed[%f][%d][%d][%s][%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001208 player->speed,
1209 goto_rewrite,
1210 real_read,
1211 _dvr_playback_state_toString(player->state),
1212 player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001213 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001214 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001215 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1216 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001217 DVR_PB_INFO("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001218 dvr_mutex_unlock(&player->lock);
1219
hualing chen2aba4022020-03-02 13:49:55 +08001220 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001221 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001222 dvr_mutex_lock(&player->lock);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001223 player->fffb_play = DVR_FALSE;
hualing chen1ffd85b2021-08-16 15:18:43 +08001224 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1225 //on pause state,user seek to new pos,we need pause and wait
1226 //user to resume
Wentao MA96f68962022-06-15 19:45:35 +08001227 DVR_PB_INFO("pause, when got first frame event when user seek end");
hualing chen1ffd85b2021-08-16 15:18:43 +08001228 player->first_frame = 0;
1229 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1230 AmTsPlayer_pauseVideoDecoding(player->handle);
1231 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001232 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001233 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001234 //for first into fffb when reset speed
1235 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1236 _dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001237 DVR_PB_INFO("fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001238 player->speed,
1239 player->fffb_current,
1240 _dvr_time_getClock(),
1241 _dvr_playback_state_toString(player->state),
1242 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001243 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001244 //dvr_mutex_unlock(&player->lock);
1245 //dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001246 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001247 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001248 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001249 continue;
1250 }
Wentao MA96f68962022-06-15 19:45:35 +08001251 DVR_PB_INFO("fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001252 player->speed,
1253 goto_rewrite,
1254 real_read,
1255 _dvr_playback_state_toString(player->state),
1256 player->cmd.cur_cmd,
1257 player->fffb_play);
Wentao MA96f68962022-06-15 19:45:35 +08001258 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001259 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001260 goto_rewrite = DVR_FALSE;
1261 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001262 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001263 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001264 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1265 player->first_frame = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001266 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001267 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001268 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001269 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001270 }
hualing chenb31a6c62020-01-13 17:27:00 +08001271 }
hualing chen86e7d482020-01-16 15:13:33 +08001272
hualing chen30423862021-04-16 14:39:12 +08001273 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1274 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001275 //check is need send time send end
Wentao MA96f68962022-06-15 19:45:35 +08001276 DVR_PB_INFO("pause, continue");
1277 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001278 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001279 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001280 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001281 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001282 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001283 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001284 continue;
1285 }
hualing chen266b9502020-04-04 17:39:39 +08001286 //when seek action is done. we need drop write timeout data.
1287 if (player->drop_ts == DVR_TRUE) {
1288 goto_rewrite = DVR_FALSE;
1289 real_read = 0;
1290 player->drop_ts = DVR_FALSE;
1291 }
hualing chen2aba4022020-03-02 13:49:55 +08001292 if (goto_rewrite == DVR_TRUE) {
1293 goto_rewrite = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001294 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001295 dvr_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001296 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Wentao MA96f68962022-06-15 19:45:35 +08001297 //DVR_PB_INFO("rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001298 goto rewrite;
1299 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001300 //.check is need send time send end
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001301 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001302 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001303 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001304 pthread_mutex_lock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001305 //DVR_PB_INFO("start read");
Wentao MA9628de82022-09-13 14:19:37 +08001306 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001307 real_read = real_read + read;
1308 player->ts_cache_len = real_read;
Wentao MA96f68962022-06-15 19:45:35 +08001309 //DVR_PB_INFO("start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001310 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001311 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001312 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001313 if (read < 0 && errno == EIO) {
1314 //EIO ERROR, EXIT THRAD
Wentao MA96f68962022-06-15 19:45:35 +08001315 DVR_PB_INFO("read error.EIO error, exit thread");
hualing chenb5cd42e2020-04-15 17:03:34 +08001316 DVR_Play_Notify_t notify;
1317 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1318 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001319 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001320 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001321 goto end;
1322 } else if (read < 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001323 DVR_PB_INFO("read error.:%d EIO:%d", errno, EIO);
hualing chenb5cd42e2020-04-15 17:03:34 +08001324 }
hualing chen87072a82020-03-12 16:20:12 +08001325 //if on fb mode and read file end , we need calculate pos to retry read.
1326 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001327 DVR_PB_INFO("recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
hualing chen03fd4942021-07-15 15:56:41 +08001328 read,
1329 real_read,
1330 buf_len,
1331 player->speed,
1332 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001333 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001334 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001335 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001336 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001337 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001338 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001339 continue;
1340 }
Wentao MA96f68962022-06-15 19:45:35 +08001341 //DVR_PB_INFO("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 +08001342 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001343 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001344 #define MIN_CACHE_TIME (3000)
1345 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001346 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001347 if (_cache_time > MIN_CACHE_TIME) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001348 //dvr_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001349 /*if cache time > 20s , we think get time is error,*/
1350 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
Wentao MA907b6432022-08-01 06:23:08 +00001351 DVR_PB_WARN("read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
hualing chene3797f02021-01-13 14:53:28 +08001352 }
hualing chen1679f812021-11-08 15:17:46 +08001353 //_dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001354 //dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001355 // DVR_PB_INFO("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 +08001356 //continue;
1357 }
hualing chen969fe7b2021-05-26 15:13:17 +08001358
hualing chen040df222020-01-17 13:35:02 +08001359 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001360 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001361 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001362
1363 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen1679f812021-11-08 15:17:46 +08001364
1365 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1366 player->noData++;
Wentao MA96f68962022-06-15 19:45:35 +08001367 DVR_PB_INFO("playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001368 if (player->noData == check_no_data_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001369 DVR_PB_INFO("playback send nodata event nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001370 //send event here and pause
1371 DVR_Play_Notify_t notify;
1372 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1373 notify.event = DVR_PLAYBACK_EVENT_NODATA;
Wentao MA96f68962022-06-15 19:45:35 +08001374 DVR_PB_INFO("send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001375 //get play statue not here
1376 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1377 }
1378 }
1379 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001380 if ((ret != DVR_SUCCESS &&
hualing chen03fd4942021-07-15 15:56:41 +08001381 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001382 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001383 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
Wentao MA270dc0f2022-08-23 13:17:26 +08001384 _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player)) ||
hualing chen39628212020-05-14 10:35:13 +08001385 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001386 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001387 DVR_Play_Notify_t notify;
1388 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1389 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1390 //get play statue not here
1391 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001392 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001393 //continue,timeshift mode, when read end,need wait cur recording segment
Wentao MA96f68962022-06-15 19:45:35 +08001394 DVR_PB_INFO("playback is send end delay:[%d]reach_end_timeout[%d]ms", delay, reach_end_timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001395 dvr_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001396 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001397 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001398 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001399 } else if (ret != DVR_SUCCESS) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001400 DVR_PB_INFO("delay:%d pauselive:%d", delay, _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001401 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08001402 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001403 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08001404 delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chena540a7e2020-03-27 16:44:05 +08001405 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001406 if (delay < cache_time) {
1407 //delay time is changed and then has data to play, so not start timeout
hualing chen1679f812021-11-08 15:17:46 +08001408 reach_end_timeout = 0;
hualing chen39628212020-05-14 10:35:13 +08001409 } else {
1410 reach_end_timeout = reach_end_timeout + timeout;
1411 }
1412 cache_time = delay;
hualing chen31140872020-03-25 12:29:26 +08001413 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001414 }
hualing chen39628212020-05-14 10:35:13 +08001415 reach_end_timeout = 0;
1416 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001417 //change next segment success case
1418 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001419 dvr_mutex_lock(&player->lock);
hualing chen40dd5462021-11-26 19:56:20 +08001420 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001421 DVR_PB_INFO("_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001422 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1423 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001424 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001425 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001426 real_read = real_read + read;
1427 player->ts_cache_len = real_read;
1428 pthread_mutex_unlock(&player->segment_lock);
1429
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001430 dvr_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001431 }//read len 0 check end
hualing chen40dd5462021-11-26 19:56:20 +08001432 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001433 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001434 DVR_PB_INFO("playback send data event resume[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001435 //send event here and pause
1436 DVR_Play_Notify_t notify;
1437 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1438 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
Wentao MA96f68962022-06-15 19:45:35 +08001439 DVR_PB_INFO("----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001440 //get play statue not here
1441 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001442 }
hualing chen39628212020-05-14 10:35:13 +08001443 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001444 //real_read = real_read + read;
Wentao MA270dc0f2022-08-23 13:17:26 +08001445 input_buffer.buf_size = real_read;
1446 input_buffer.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001447
Wentao MA270dc0f2022-08-23 13:17:26 +08001448 //check read data len,if len < 0, we need continue
1449 if (input_buffer.buf_size <= 0 || input_buffer.buf_data == NULL) {
1450 DVR_PB_INFO("error occur read_read [%d],buf=[%p]",input_buffer.buf_size, input_buffer.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001451 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001452 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001453 player->ts_cache_len = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001454 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001455 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001456 }
hualing chen266b9502020-04-04 17:39:39 +08001457 //if need write whole block size, we need check read buf len is eq block size.
1458 if (b_writed_whole_block == DVR_TRUE) {
1459 //buf_len is block size value.
1460 if (real_read < buf_len) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001461 //continue to read data from file
Wentao MA96f68962022-06-15 19:45:35 +08001462 DVR_PB_INFO("read buf len[%d] is < block size [%d]", real_read, buf_len);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001463 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001464 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1465 dvr_mutex_unlock(&player->lock);
1466 DVR_PB_INFO("read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001467 continue;
1468 } else if (real_read > buf_len) {
Wentao MA96f68962022-06-15 19:45:35 +08001469 DVR_PB_INFO("read buf len[%d] is > block size [%d],this error occur", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001470 }
1471 }
1472
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001473 if (player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001474 DVR_CryptoParams_t crypto_params;
1475
1476 memset(&crypto_params, 0, sizeof(crypto_params));
1477 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1478 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1479 crypto_params.segment_id = player->cur_segment.segment_id;
Wentao MA270dc0f2022-08-23 13:17:26 +08001480 crypto_params.offset = segment_tell_position(player->r_handle) - input_buffer.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001481 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
Wentao MA96f68962022-06-15 19:45:35 +08001482 DVR_PB_INFO("offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001483 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1484 crypto_params.input_buffer.addr = (size_t)buf;
1485 crypto_params.input_buffer.size = real_read;
1486
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001487 if (player->is_secure_mode) {
1488 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1489 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1490 crypto_params.output_buffer.size = dec_buf_size;
1491 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001492 input_buffer.buf_data = player->secure_buffer;
1493 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001494 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001495 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001496 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001497 input_buffer.buf_size = crypto_params.output_size;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001498 } else { // only for NAGRA
1499 crypto_params.output_buffer.type = crypto_params.input_buffer.type;
1500 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1501 crypto_params.output_buffer.size = crypto_params.input_buffer.size;
1502 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001503 input_buffer.buf_data = (uint8_t*)crypto_params.output_buffer.addr;
1504 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001505 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001506 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001507 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001508 input_buffer.buf_size = crypto_params.output_buffer.size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001509 }
Yahui Han1fbf3292021-11-08 18:17:19 +08001510 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001511 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001512 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
Wentao MA270dc0f2022-08-23 13:17:26 +08001513 input_buffer.buf_data = dec_bufs.buf_data;
1514 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1515 input_buffer.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001516 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001517rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001518 if (player->drop_ts == DVR_TRUE) {
1519 //need drop ts data when seek occur.we need read next loop,drop this ts data
1520 goto_rewrite = DVR_FALSE;
1521 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001522 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001523 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001524 player->drop_ts = DVR_FALSE;
Wentao MA63c6cba2022-09-20 10:14:29 +08001525 pthread_mutex_unlock(&player->segment_lock);
1526 DVR_PB_INFO("----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001527 continue;
1528 }
hualing chen21a40372021-10-29 11:07:26 +08001529
1530 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001531 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001532 //used for printf first write data time.
1533 //to check change channel kpi.
1534 if (first_write == 0) {
1535 first_write++;
Wentao MA270dc0f2022-08-23 13:17:26 +08001536 DVR_PB_INFO("----first write ts data");
hualing chenb9a02922021-12-14 11:29:47 +08001537 }
1538
Wentao MA270dc0f2022-08-23 13:17:26 +08001539 ret = AmTsPlayer_writeData(player->handle, &input_buffer, write_timeout_ms);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001540 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001541 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001542 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001543 real_read = 0;
1544 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001545 if (CONTROL_SPEED_ENABLE == 1) {
1546check0:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001547 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001548 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001549 break;
1550 }
hualing chend241c7a2021-06-22 13:34:27 +08001551 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001552 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001553 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001554 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001555 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1556 goto check0;
1557 }
1558 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001559 //DVR_PB_INFO("write write_success:%d input_buffer.buf_size:%d", write_success, input_buffer.buf_size);
hualing chen87072a82020-03-12 16:20:12 +08001560 } else {
hualing chen21a40372021-10-29 11:07:26 +08001561 pthread_mutex_unlock(&player->segment_lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001562 DVR_PB_INFO("write time out write_success:%d input_buffer.buf_size:%d systime:%u",
hualing chen03fd4942021-07-15 15:56:41 +08001563 write_success,
Wentao MA270dc0f2022-08-23 13:17:26 +08001564 input_buffer.buf_size,
hualing chen03fd4942021-07-15 15:56:41 +08001565 _dvr_time_getClock());
1566
hualing chena540a7e2020-03-27 16:44:05 +08001567 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001568 if (CONTROL_SPEED_ENABLE == 1) {
1569check1:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001570 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001571 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001572 break;
1573 }
hualing chend241c7a2021-06-22 13:34:27 +08001574 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001575 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001576 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001577 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001578 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1579 goto check1;
1580 }
1581 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001582 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001583 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001584 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001585 if (!player->is_running) {
Wentao MA96f68962022-06-15 19:45:35 +08001586 DVR_PB_INFO("playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001587 break;
1588 }
hualing chen2aba4022020-03-02 13:49:55 +08001589 goto_rewrite = DVR_TRUE;
1590 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001591 }
1592 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001593end:
Wentao MA96f68962022-06-15 19:45:35 +08001594 DVR_PB_INFO("playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001595 free(buf);
1596 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001597 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001598}
1599
1600
hualing chen040df222020-01-17 13:35:02 +08001601static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001602{
hualing chen040df222020-01-17 13:35:02 +08001603 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001604
1605 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001606 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001607 return DVR_FAILURE;
1608 }
Wentao MA96f68962022-06-15 19:45:35 +08001609 DVR_PB_INFO("start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001610 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001611 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001612 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001613 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001614 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001615 if (rc < 0)
1616 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001617 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001618}
1619
1620
hualing chen040df222020-01-17 13:35:02 +08001621static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001622{
hualing chen040df222020-01-17 13:35:02 +08001623 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001624
1625 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001626 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001627 return DVR_FAILURE;
1628 }
1629
Wentao MA96f68962022-06-15 19:45:35 +08001630 DVR_PB_INFO("stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001631 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001632 {
1633 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001634 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001635 pthread_join(player->playback_thread, NULL);
1636 }
1637 if (player->r_handle) {
1638 segment_close(player->r_handle);
1639 player->r_handle = NULL;
1640 }
Wentao MA96f68962022-06-15 19:45:35 +08001641 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001642 return 0;
1643}
1644
hualing chen1679f812021-11-08 15:17:46 +08001645static int getFakePid()
1646{
1647 char fake_pid_prop[] = "vendor.tv.dtv.fake_pid";
wentao.maa210e5e2022-10-12 16:10:03 +08001648 char buf[32] = {0};
hualing chen1679f812021-11-08 15:17:46 +08001649 int pid = 0xffff;
1650
1651 dvr_prop_read(fake_pid_prop, buf, sizeof(buf));
1652
1653 if (sscanf(buf, "%i", &pid) != 1)
1654 {
Wentao MA96f68962022-06-15 19:45:35 +08001655 DVR_PB_INFO("get fake pid error");
hualing chen1679f812021-11-08 15:17:46 +08001656 pid = 0xffff;
1657 }
1658 return pid;
1659}
1660
1661void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1662
1663 DVR_ASSERT(handle);
1664 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1665 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001666 DVR_PB_INFO("player is NULL");
hualing chen1679f812021-11-08 15:17:46 +08001667 return ;
1668 }
1669 if (player->need_seek_start == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001670 DVR_PB_INFO("player need_seek_start is false");
hualing chen1679f812021-11-08 15:17:46 +08001671 return ;
1672 }
1673
hualing chena5f03222021-12-02 11:22:35 +08001674 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001675 player->need_seek_start = DVR_FALSE;
1676 }
Wentao MA96f68962022-06-15 19:45:35 +08001677 DVR_PB_INFO("player player->need_seek_start=%d", player->need_seek_start);
hualing chen1679f812021-11-08 15:17:46 +08001678}
1679
hualing chenb31a6c62020-01-13 17:27:00 +08001680/**\brief Open an dvr palyback
1681 * \param[out] p_handle dvr playback addr
1682 * \param[in] params dvr playback open parameters
1683 * \retval DVR_SUCCESS On success
1684 * \return Error code
1685 */
hualing chen040df222020-01-17 13:35:02 +08001686int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001687
hualing chen040df222020-01-17 13:35:02 +08001688 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001689 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001690
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001691 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
wentao.maa22bc852022-10-13 12:18:06 +08001692 DVR_RETURN_IF_FALSE(player);
hualing chenb31a6c62020-01-13 17:27:00 +08001693
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001694 dvr_mutex_init(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001695 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001696 pthread_condattr_init(&cattr);
1697 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1698 pthread_cond_init(&player->cond, &cattr);
1699 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001700
hualing chen5cbe1a62020-02-10 16:36:36 +08001701 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001702 INIT_LIST_HEAD(&player->segment_list);
1703 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1704 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001705 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001706 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00001707 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen86e7d482020-01-16 15:13:33 +08001708 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001709 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001710 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001711
hualing chen86e7d482020-01-16 15:13:33 +08001712 //store open params
hualing chen040df222020-01-17 13:35:02 +08001713 player->openParams.dmx_dev_id = params->dmx_dev_id;
1714 player->openParams.block_size = params->block_size;
Wentao MA96f68962022-06-15 19:45:35 +08001715 DVR_PB_INFO("playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001716 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001717 player->openParams.event_fn = params->event_fn;
1718 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001719 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001720 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001721
hualing chen5cbe1a62020-02-10 16:36:36 +08001722 player->has_pids = params->has_pids;
1723
hualing chen2aba4022020-03-02 13:49:55 +08001724 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001725
1726 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1727 //for test get callback
1728 if (0 && player->player_callback_func == NULL) {
1729 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1730 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
Wentao MA96f68962022-06-15 19:45:35 +08001731 DVR_PB_INFO("playback open get callback[%p][%p][%p][%p]",
hualing chen03fd4942021-07-15 15:56:41 +08001732 player->player_callback_func,
1733 player->player_callback_userdata,
1734 _dvr_tsplayer_callback_test,
1735 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001736 }
1737 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001738
hualing chen86e7d482020-01-16 15:13:33 +08001739 //init has audio and video
1740 player->has_video = DVR_FALSE;
1741 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001742 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001743 player->last_segment_id = 0LL;
1744 player->segment_is_open = DVR_FALSE;
Wentao MA5629ad82022-08-24 10:03:02 +08001745 player->audio_presentation_id = -1;
hualing chenb31a6c62020-01-13 17:27:00 +08001746
hualing chen5cbe1a62020-02-10 16:36:36 +08001747 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001748 player->fffb_current = 0;
1749 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001750 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001751 //seek time
1752 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001753 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001754
Yahui Han1fbf3292021-11-08 18:17:19 +08001755 //allocate cryptor if have clearkey
1756 if (params->keylen > 0) {
1757 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +08001758 (uint8_t *)params->cleariv,
1759 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +08001760 if (!player->cryptor) {
Wentao MA96f68962022-06-15 19:45:35 +08001761 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +08001762 }
1763 } else {
1764 player->cryptor = NULL;
1765 }
1766
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001767 //init secure stuff
1768 player->dec_func = NULL;
1769 player->dec_userdata = NULL;
1770 player->is_secure_mode = 0;
1771 player->secure_buffer = NULL;
1772 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001773 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001774
hualing chen4b7c15d2020-04-07 16:13:48 +08001775 player->fffb_play = DVR_FALSE;
1776
1777 player->last_send_time_id = UINT64_MAX;
1778 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001779 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001780
hualing chend241c7a2021-06-22 13:34:27 +08001781 //speed con init
1782 if (CONTROL_SPEED_ENABLE == 1) {
1783 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001784 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001785 player->con_spe.sys_dur = 0;
1786 player->con_spe.sys_sta = 0;
1787 }
1788
hualing chen03fd4942021-07-15 15:56:41 +08001789 //limit info
1790 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001791 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001792 //need seek to start pos
1793 player->first_start_time = 0;
Wentao MA01de0e62022-01-10 18:48:23 +08001794 player->first_start_id = UINT64_MAX;
1795 player->check_cache_flag = DVR_TRUE;
hualing chen8a657f32021-08-30 13:12:49 +08001796 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001797 //fake_pid init
1798 player->fake_pid = getFakePid();
hualing chen86e7d482020-01-16 15:13:33 +08001799 *p_handle = player;
1800 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001801}
1802
1803/**\brief Close an dvr palyback
1804 * \param[in] handle playback handle
1805 * \retval DVR_SUCCESS On success
1806 * \return Error code
1807 */
hualing chen040df222020-01-17 13:35:02 +08001808int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001809
hualing chen86e7d482020-01-16 15:13:33 +08001810 DVR_ASSERT(handle);
Wentao MA96f68962022-06-15 19:45:35 +08001811 DVR_PB_INFO(":into");
hualing chen040df222020-01-17 13:35:02 +08001812 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001813 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001814 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001815 return DVR_FAILURE;
1816 }
1817
hualing chencc91e1c2020-02-28 13:26:17 +08001818 if (player->state != DVR_PLAYBACK_STATE_STOP)
1819 {
Wentao MA96f68962022-06-15 19:45:35 +08001820 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001821 if (player->cryptor) {
1822 am_crypt_des_close(player->cryptor);
1823 player->cryptor = NULL;
1824 }
hualing chencc91e1c2020-02-28 13:26:17 +08001825 dvr_playback_stop(handle, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08001826 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
hualing chenb96aa2c2020-04-15 14:13:53 +08001827 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001828 DVR_PB_INFO(":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001829 }
Wentao MA96f68962022-06-15 19:45:35 +08001830 DVR_PB_INFO(":into");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001831 dvr_mutex_destroy(&player->lock);
Zhiqiang Hanc9513462022-06-21 09:55:23 +08001832 pthread_mutex_destroy(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001833 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001834
1835 if (player) {
1836 free(player);
hualing chen040df222020-01-17 13:35:02 +08001837 }
Wentao MA96f68962022-06-15 19:45:35 +08001838 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001839 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001840}
1841
Wentao MA270dc0f2022-08-23 13:17:26 +08001842/**\brief Start play audio and video, used start audio api and start video api
hualing chenb31a6c62020-01-13 17:27:00 +08001843 * \param[in] handle playback handle
1844 * \param[in] params audio playback params,contains fmt and pid...
1845 * \retval DVR_SUCCESS On success
1846 * \return Error code
1847 */
hualing chen040df222020-01-17 13:35:02 +08001848int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1849 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA270dc0f2022-08-23 13:17:26 +08001850 am_tsplayer_video_params video_params;
1851 am_tsplayer_audio_params audio_params;
1852 am_tsplayer_audio_params ad_params;
hualing chena540a7e2020-03-27 16:44:05 +08001853
Wentao MA270dc0f2022-08-23 13:17:26 +08001854 memset(&video_params, 0, sizeof(video_params));
1855 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001856
hualing chena540a7e2020-03-27 16:44:05 +08001857 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001858 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001859 return DVR_FAILURE;
1860 }
hualing chencc91e1c2020-02-28 13:26:17 +08001861 uint64_t segment_id = player->cur_segment_id;
Wentao MA96f68962022-06-15 19:45:35 +08001862 DVR_PB_INFO("[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001863
hualing chena540a7e2020-03-27 16:44:05 +08001864 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001865 //can used start api to resume playback
1866 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1867 return dvr_playback_resume(handle);
1868 }
hualing chen87072a82020-03-12 16:20:12 +08001869 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001870 //if flag is paused and not decode first frame. if user resume, we need
hualing chen9b434f02020-06-10 15:06:54 +08001871 //clear flag and set trickmode none
1872 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001873 DVR_PB_INFO("[%p]clear pause live flag and clear trick mode", handle);
hualing chen9b434f02020-06-10 15:06:54 +08001874 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1875 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1876 }
Wentao MA96f68962022-06-15 19:45:35 +08001877 DVR_PB_INFO("stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001878 return DVR_SUCCESS;
1879 }
hualing chen86e7d482020-01-16 15:13:33 +08001880 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001881 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001882 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08001883 DVR_PB_INFO("lock flag:0x%x", flag);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001884 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001885 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08001886 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08001887 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
1888 //audio and video pids are all invalid, return error.
1889 DVR_PB_ERROR("unlock dvr play back start error, not found audio and video info [0x%x]", video_params.pid);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001890 dvr_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001891 DVR_Play_Notify_t notify;
1892 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1893 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1894 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1895 notify.info.transition_failed_data.segment_id = segment_id;
1896 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001897 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001898 return -1;
1899 }
hualing chen31140872020-03-25 12:29:26 +08001900
hualing chencc91e1c2020-02-28 13:26:17 +08001901 {
Wentao MA270dc0f2022-08-23 13:17:26 +08001902 if (VALID_PID(video_params.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001903 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001904 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001905 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001906 DVR_PB_INFO("set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001907 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1908 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001909 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
Wentao MA96f68962022-06-15 19:45:35 +08001910 DVR_PB_INFO("set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001911 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001912 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001913 DVR_PB_INFO("set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001914 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001915 }
hualing chena93bbbc2020-12-22 17:23:42 +08001916 AmTsPlayer_showVideo(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08001917 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08001918 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001919 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001920 }
hualing chena540a7e2020-03-27 16:44:05 +08001921
Wentao MA270dc0f2022-08-23 13:17:26 +08001922 DVR_PB_INFO("player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, video_params.pid, audio_params.pid);
hualing chen4b7c15d2020-04-07 16:13:48 +08001923 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001924 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1925 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1926 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001927 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001928 } else {
1929 player->cmd.last_cmd = player->cmd.cur_cmd;
1930 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001931 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001932 //set fast play
Wentao MA96f68962022-06-15 19:45:35 +08001933 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08001934 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001935 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08001936 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08001937 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08001938 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08001939 dvr_playback_change_seek_state(handle, ad_params.pid);
1940 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08001941 AmTsPlayer_enableADMix(player->handle);
1942 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001943 if (VALID_PID(audio_params.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001944 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08001945 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08001946 dvr_playback_change_seek_state(handle, audio_params.pid);
1947 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08001948 if (player->audio_presentation_id > -1) {
1949 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
1950 }
hualing chen969fe7b2021-05-26 15:13:17 +08001951 AmTsPlayer_startAudioDecoding(player->handle);
1952 }
hualing chen31140872020-03-25 12:29:26 +08001953 }
hualing chencc91e1c2020-02-28 13:26:17 +08001954 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001955 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001956 }
hualing chen86e7d482020-01-16 15:13:33 +08001957 }
hualing chen43a89bc2022-01-19 14:31:20 +08001958#ifdef AVSYNC_USED_PCR
1959 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001960 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08001961 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
1962 }
1963#endif
Wentao MA96f68962022-06-15 19:45:35 +08001964 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001965 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001966 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001967 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001968}
hualing chen040df222020-01-17 13:35:02 +08001969/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001970 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001971 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001972 * \retval DVR_SUCCESS On success
1973 * \return Error code
1974 */
hualing chen040df222020-01-17 13:35:02 +08001975int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1976 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa22bc852022-10-13 12:18:06 +08001977 DVR_RETURN_IF_FALSE(player);
hualing chena540a7e2020-03-27 16:44:05 +08001978
Wentao MA96f68962022-06-15 19:45:35 +08001979 DVR_PB_INFO("add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001980 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001981
hualing chen040df222020-01-17 13:35:02 +08001982 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
wentao.maa22bc852022-10-13 12:18:06 +08001983 DVR_RETURN_IF_FALSE(segment);
hualing chen040df222020-01-17 13:35:02 +08001984 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001985
Wentao MA270dc0f2022-08-23 13:17:26 +08001986 //not memcpy chunk info.
hualing chen040df222020-01-17 13:35:02 +08001987 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001988 //cp location
hualing chen040df222020-01-17 13:35:02 +08001989 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001990
Wentao MA96f68962022-06-15 19:45:35 +08001991 DVR_PB_INFO("add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001992 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001993
1994 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001995 segment->pids.video.pid = info->pids.video.pid;
1996 segment->pids.video.format = info->pids.video.format;
1997 segment->pids.video.type = info->pids.video.type;
1998
hualing chen2aba4022020-03-02 13:49:55 +08001999 segment->pids.audio.pid = info->pids.audio.pid;
2000 segment->pids.audio.format = info->pids.audio.format;
2001 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08002002
hualing chen2aba4022020-03-02 13:49:55 +08002003 segment->pids.ad.pid = info->pids.ad.pid;
2004 segment->pids.ad.format = info->pids.ad.format;
2005 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08002006
2007 segment->pids.pcr.pid = info->pids.pcr.pid;
2008
Wentao MA96f68962022-06-15 19:45:35 +08002009 DVR_PB_INFO("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);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002010 dvr_mutex_lock(&player->lock);
wentao.maa22bc852022-10-13 12:18:06 +08002011 list_add_tail(segment, &player->segment_list);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002012 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002013 DVR_PB_DEBUG("unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08002014
hualing chen5cbe1a62020-02-10 16:36:36 +08002015 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002016}
hualing chen040df222020-01-17 13:35:02 +08002017/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08002018 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08002019 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002020 * \retval DVR_SUCCESS On success
2021 * \return Error code
2022 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002023int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002024 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08002025 DVR_PB_INFO("remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08002026 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002027 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002028 return DVR_FAILURE;
2029 }
2030
hualing chencc91e1c2020-02-28 13:26:17 +08002031 if (segment_id == player->cur_segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08002032 DVR_PB_INFO("not support remove current segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08002033 return DVR_FAILURE;
2034 }
Wentao MA96f68962022-06-15 19:45:35 +08002035 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002036 dvr_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08002037 DVR_PlaybackSegmentInfo_t *segment = NULL;
2038 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
2039 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002040 {
hualing chen040df222020-01-17 13:35:02 +08002041 if (segment->segment_id == segment_id) {
2042 list_del(&segment->head);
2043 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002044 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002045 }
hualing chen86e7d482020-01-16 15:13:33 +08002046 }
Wentao MA96f68962022-06-15 19:45:35 +08002047 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002048 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002049
2050 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002051}
hualing chen040df222020-01-17 13:35:02 +08002052/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08002053 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08002054 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08002055 * \retval DVR_SUCCESS On success
2056 * \return Error code
2057 */
hualing chen040df222020-01-17 13:35:02 +08002058int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002059 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08002060 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08002061 DVR_PB_INFO("update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08002062 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002063 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002064 return DVR_FAILURE;
2065 }
hualing chenf43b8ba2020-07-28 13:11:42 +08002066 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
Wentao MA96f68962022-06-15 19:45:35 +08002067 DVR_PB_INFO("vendor is amlogic. not hide or show av and update segment");
hualing chenf43b8ba2020-07-28 13:11:42 +08002068 return DVR_SUCCESS;
2069 }
hualing chena540a7e2020-03-27 16:44:05 +08002070
hualing chen040df222020-01-17 13:35:02 +08002071 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002072 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002073 dvr_mutex_lock(&player->lock);
wentao.maa22bc852022-10-13 12:18:06 +08002074 // This error is surpressed as the macro code is picked from kernel.
2075 // prefetch() here incurring self_assign is used to avoid some compiling
2076 // warnings.
2077 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002078 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002079 {
hualing chen040df222020-01-17 13:35:02 +08002080 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08002081 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08002082 }
hualing chen86e7d482020-01-16 15:13:33 +08002083 // if encramble to free, only set flag and return;
2084
2085 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08002086 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002087 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
2088 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08002089 //disable display, mute
Wentao MA96f68962022-06-15 19:45:35 +08002090 DVR_PB_INFO("mute av");
hualing chen2aba4022020-03-02 13:49:55 +08002091 AmTsPlayer_hideVideo(player->handle);
2092 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002093 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
2094 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002095 //enable display, unmute
Wentao MA96f68962022-06-15 19:45:35 +08002096 DVR_PB_INFO("unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08002097 AmTsPlayer_showVideo(player->handle);
2098 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002099 } else {
2100 //do nothing
2101 }
2102 } else {
2103 //do nothing
2104 }
2105 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08002106 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08002107 }
Wentao MA96f68962022-06-15 19:45:35 +08002108 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002109 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002110 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002111}
2112
2113
hualing chen99508642021-10-18 15:41:17 +08002114static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_PlaybackPids_t now_pids, DVR_PlaybackPids_t set_pids, int type) {
hualing chen040df222020-01-17 13:35:02 +08002115 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08002116 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08002117 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08002118
2119 if (type == 0) {
2120 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08002121 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08002122 } else if (type == 1) {
2123 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08002124 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08002125 } else if (type == 2) {
2126 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08002127 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08002128 } else {
2129 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08002130 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08002131 }
2132
hualing chena540a7e2020-03-27 16:44:05 +08002133 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002134 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002135 return DVR_FAILURE;
2136 }
Wentao MA96f68962022-06-15 19:45:35 +08002137 DVR_PB_INFO(" do check");
hualing chen86e7d482020-01-16 15:13:33 +08002138 if (now_pid.pid == set_pid.pid) {
2139 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08002140 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08002141 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08002142 if (VALID_PID(now_pid.pid)) {
2143 //stop now stream
2144 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002145 //stop video
hualing chenc70a8df2020-05-12 19:23:11 +08002146 if (player->has_video == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002147 DVR_PB_INFO("stop video");
hualing chenc70a8df2020-05-12 19:23:11 +08002148 AmTsPlayer_stopVideoDecoding(player->handle);
2149 player->has_video = DVR_FALSE;
2150 }
hualing chen86e7d482020-01-16 15:13:33 +08002151 } else if (type == 1) {
2152 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002153 if (player->has_audio == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002154 DVR_PB_INFO("stop audio");
hualing chenc70a8df2020-05-12 19:23:11 +08002155 AmTsPlayer_stopAudioDecoding(player->handle);
2156 player->has_audio = DVR_FALSE;
2157 }
hualing chen86e7d482020-01-16 15:13:33 +08002158 } else if (type == 2) {
2159 //stop sub audio
Wentao MA96f68962022-06-15 19:45:35 +08002160 DVR_PB_INFO("stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002161 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002162 } else if (type == 3) {
2163 //pcr
2164 }
2165 }
2166 if (VALID_PID(set_pid.pid)) {
2167 //start
2168 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002169 //start video
2170 am_tsplayer_video_params video_params;
2171 video_params.pid = set_pid.pid;
2172 video_params.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002173 player->has_video = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002174 DVR_PB_INFO("start video pid[%d]fmt[%d]",video_params.pid, video_params.codectype);
2175 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen2aba4022020-03-02 13:49:55 +08002176 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002177 //playback_device_video_start(player->handle,&video_params);
hualing chen86e7d482020-01-16 15:13:33 +08002178 } else if (type == 1) {
2179 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002180 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002181 if (VALID_PID(set_pids.ad.pid)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002182 am_tsplayer_audio_params ad_params;
2183 ad_params.pid = set_pids.ad.pid;
2184 ad_params.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2185 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",ad_params.pid, ad_params.codectype);
2186 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen275379e2021-06-15 17:57:21 +08002187 AmTsPlayer_enableADMix(player->handle);
2188 }
2189
Wentao MA270dc0f2022-08-23 13:17:26 +08002190 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002191
Wentao MA270dc0f2022-08-23 13:17:26 +08002192 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002193
Wentao MA270dc0f2022-08-23 13:17:26 +08002194 audio_params.pid = set_pid.pid;
2195 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002196 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002197 DVR_PB_INFO("start audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2198 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002199 if (player->audio_presentation_id > -1) {
2200 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2201 }
hualing chenc70a8df2020-05-12 19:23:11 +08002202 AmTsPlayer_startAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002203 //playback_device_audio_start(player->handle,&audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002204 }
hualing chen86e7d482020-01-16 15:13:33 +08002205 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002206 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002207 if (set_pids.audio.pid == now_pids.audio.pid) {
2208 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002209 DVR_PB_INFO("stop audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002210 AmTsPlayer_stopAudioDecoding(player->handle);
2211 }
Wentao MA270dc0f2022-08-23 13:17:26 +08002212 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002213
Wentao MA270dc0f2022-08-23 13:17:26 +08002214 memset(&audio_params, 0, sizeof(audio_params));
2215 audio_params.pid = set_pid.pid;
2216 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002217 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002218 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2219 AmTsPlayer_setADParams(player->handle, &audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002220 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002221
2222 if (set_pids.audio.pid == now_pids.audio.pid) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002223 am_tsplayer_audio_params audio_params;
hualing chen99508642021-10-18 15:41:17 +08002224
Wentao MA270dc0f2022-08-23 13:17:26 +08002225 memset(&audio_params, 0, sizeof(audio_params));
hualing chen99508642021-10-18 15:41:17 +08002226
Wentao MA270dc0f2022-08-23 13:17:26 +08002227 audio_params.pid = set_pids.audio.pid;
2228 audio_params.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
hualing chen99508642021-10-18 15:41:17 +08002229 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002230 DVR_PB_INFO("restart audio when start ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002231 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002232 if (player->audio_presentation_id > -1) {
2233 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2234 }
hualing chen99508642021-10-18 15:41:17 +08002235 AmTsPlayer_startAudioDecoding(player->handle);
2236 }
hualing chenc70a8df2020-05-12 19:23:11 +08002237 }
hualing chen86e7d482020-01-16 15:13:33 +08002238 } else if (type == 3) {
2239 //pcr
Wentao MA96f68962022-06-15 19:45:35 +08002240 DVR_PB_INFO("start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002241 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002242 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002243 //audio and video all close
2244 if (!player->has_audio && !player->has_video) {
Wentao MA907b6432022-08-01 06:23:08 +00002245 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen5cbe1a62020-02-10 16:36:36 +08002246 }
hualing chen43a89bc2022-01-19 14:31:20 +08002247 } else if (type == 2) {
2248 //case disable ad
Wentao MA96f68962022-06-15 19:45:35 +08002249 DVR_PB_INFO("restart audio when stop ad");
hualing chen43a89bc2022-01-19 14:31:20 +08002250 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
Wentao MA6d045b32022-02-18 18:47:25 +08002251 if (VALID_PID(now_pids.audio.pid)) {
2252 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002253 DVR_PB_INFO("stop audio when stop ad pid [0x%x]", now_pids.audio.pid);
Wentao MA6d045b32022-02-18 18:47:25 +08002254 AmTsPlayer_stopAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002255 am_tsplayer_audio_params audio_params;
hualing chen43a89bc2022-01-19 14:31:20 +08002256
Wentao MA270dc0f2022-08-23 13:17:26 +08002257 memset(&audio_params, 0, sizeof(audio_params));
hualing chen43a89bc2022-01-19 14:31:20 +08002258
Wentao MA270dc0f2022-08-23 13:17:26 +08002259 audio_params.pid = now_pids.audio.pid;
2260 audio_params.codectype= _dvr_convert_stream_fmt(now_pids.audio.format, DVR_TRUE);
Wentao MA6d045b32022-02-18 18:47:25 +08002261 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002262 DVR_PB_INFO("restart audio when stop ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002263 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002264 if (player->audio_presentation_id > -1) {
2265 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2266 }
Wentao MA6d045b32022-02-18 18:47:25 +08002267 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen43a89bc2022-01-19 14:31:20 +08002268 }
Wentao MA6d045b32022-02-18 18:47:25 +08002269 }
hualing chen86e7d482020-01-16 15:13:33 +08002270 }
2271 }
2272 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002273}
hualing chena5f03222021-12-02 11:22:35 +08002274/**\brief dvr play back only update segment pids info
2275 * only update pid info not to start stop codec.
2276 * \param[in] handle playback handle
2277 * \param[in] segment_id need updated pids segment id
2278 * \param[in] p_pids need updated pids
2279 * \retval DVR_SUCCESS On success
2280 * \return Error code
2281 */
2282int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2283 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2284 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002285 DVR_PB_INFO("player is NULL");
hualing chena5f03222021-12-02 11:22:35 +08002286 return DVR_FAILURE;
2287 }
2288
2289 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002290 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002291 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002292 DVR_PB_INFO("get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
wentao.maa22bc852022-10-13 12:18:06 +08002293 // This error is surpressed as the macro code is picked from kernel.
2294 // prefetch() here incurring self_assign is used to avoid some compiling
2295 // warnings.
2296 // coverity[self_assign]
hualing chena5f03222021-12-02 11:22:35 +08002297 list_for_each_entry(segment, &player->segment_list, head)
2298 {
2299 if (segment->segment_id == segment_id) {
2300 if (player->cur_segment_id == segment_id) {
2301 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002302 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chena5f03222021-12-02 11:22:35 +08002303 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002304 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002305 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002306 return 0;
2307 }
2308 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2309 }
2310 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002311 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002312 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002313 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002314 break;
2315 }
2316 }
Wentao MA96f68962022-06-15 19:45:35 +08002317 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002318 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002319 return DVR_SUCCESS;
2320}
2321
hualing chen5cbe1a62020-02-10 16:36:36 +08002322/**\brief dvr play back update segment pids
2323 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002324 * add pid stream and stop remove pid stream.
2325 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002326 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002327 * \retval DVR_SUCCESS On success
2328 * \return Error code
2329 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002330int 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 +08002331 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002332 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002333 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002334 return DVR_FAILURE;
2335 }
2336
hualing chen040df222020-01-17 13:35:02 +08002337 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002338 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002339 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002340 DVR_PB_INFO("get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08002341
wentao.maa22bc852022-10-13 12:18:06 +08002342 // This error is surpressed as the macro code is picked from kernel.
2343 // prefetch() here incurring self_assign is used to avoid some compiling
2344 // warnings.
2345 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002346 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002347 {
hualing chen040df222020-01-17 13:35:02 +08002348 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002349
2350 if (player->cur_segment_id == segment_id) {
2351 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002352 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002353 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002354 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002355 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002356 return 0;
2357 }
2358
2359 //if segment is on going segment,we need stop start stream
2360 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA96f68962022-06-15 19:45:35 +08002361 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002362 dvr_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002363 if (segment->pids.audio.pid != p_pids->audio.pid &&
2364 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002365 //not used this to seek to start pos.we will
Wentao MA9a164002022-08-29 11:20:24 +08002366 //add update only api. if need seek to start
hualing chena5f03222021-12-02 11:22:35 +08002367 //pos, we will call only update api and used seek api
2368 //to start and stop av codec
2369 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002370 player->need_seek_start = DVR_FALSE;
2371 pthread_mutex_lock(&player->segment_lock);
2372 player->drop_ts = DVR_TRUE;
2373 player->ts_cache_len = 0;
2374 if (player->first_start_time > 0)
2375 player->first_start_time = player->first_start_time - 1;
2376 segment_seek(player->r_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002377 DVR_PB_ERROR("unlock segment update need seek time_offset %llu [0x%x][0x%x]", player->first_start_time, segment->pids.audio.pid, segment->pids.ad.pid);
hualing chen8a657f32021-08-30 13:12:49 +08002378 pthread_mutex_unlock(&player->segment_lock);
2379 }
2380 }
hualing chen1679f812021-11-08 15:17:46 +08002381 //check video pids, stop or restart
2382 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
2383 //check sub audio pids stop or restart
2384 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
2385 //check audio pids stop or restart
2386 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
2387 //check pcr pids stop or restart
2388 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
2389
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002390 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002391 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2392 //if state is pause, we need process at resume api. we only record change info
2393 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2394 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2395 if (VALID_PID(segment->pids.video.pid)
2396 && VALID_PID(p_pids->video.pid)
2397 && segment->pids.video.pid != p_pids->video.pid) {
2398 //restart video
Wentao MA270dc0f2022-08-23 13:17:26 +08002399 v_cmd = DVR_PLAYBACK_CMD_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002400 }
2401 if (!VALID_PID(segment->pids.video.pid)
2402 && VALID_PID(p_pids->video.pid)
2403 && segment->pids.video.pid != p_pids->video.pid) {
2404 //start video
Wentao MA270dc0f2022-08-23 13:17:26 +08002405 v_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002406 }
2407 if (VALID_PID(segment->pids.video.pid)
2408 && !VALID_PID(p_pids->video.pid)
2409 && segment->pids.video.pid != p_pids->video.pid) {
2410 //stop video
Wentao MA270dc0f2022-08-23 13:17:26 +08002411 v_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002412 }
2413 if (VALID_PID(segment->pids.audio.pid)
2414 && VALID_PID(p_pids->audio.pid)
2415 && segment->pids.audio.pid != p_pids->audio.pid) {
2416 //restart audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002417 a_cmd = DVR_PLAYBACK_CMD_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002418 }
2419 if (!VALID_PID(segment->pids.audio.pid)
2420 && VALID_PID(p_pids->audio.pid)
2421 && segment->pids.audio.pid != p_pids->audio.pid) {
2422 //start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002423 a_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002424 }
2425 if (VALID_PID(segment->pids.audio.pid)
2426 && !VALID_PID(p_pids->audio.pid)
2427 && segment->pids.audio.pid != p_pids->audio.pid) {
2428 //stop audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002429 a_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002430 }
2431 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2432 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2433 //do nothing
2434 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2435 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2436 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2437 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2438 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2439 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002440 if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2441 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002442 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002443 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
2444 }else if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2445 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002446 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002447 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002448 } else {
2449 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002450 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002451 }
2452
Wentao MA270dc0f2022-08-23 13:17:26 +08002453 if (v_cmd == DVR_PLAYBACK_CMD_V_START
2454 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002455 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002456 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START_A_RESTART;
2457 } else if (v_cmd == DVR_PLAYBACK_CMD_V_START
2458 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002459 //not occur this case
2460 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2461 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2462 } else {
2463 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002464 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002465 }
2466
Wentao MA270dc0f2022-08-23 13:17:26 +08002467 if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2468 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002469 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002470 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_START;
2471 } else if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2472 && a_cmd == DVR_PLAYBACK_CMD_A_RESTART) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002473 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002474 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002475 } else {
2476 //not occur this case
2477 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2478 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2479 }
2480 }
2481 }
hualing chene10666f2020-04-14 13:58:37 +08002482 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002483 }
hualing chen86e7d482020-01-16 15:13:33 +08002484 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002485 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002486 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002487 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002488 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002489 }
hualing chen86e7d482020-01-16 15:13:33 +08002490 }
Wentao MA96f68962022-06-15 19:45:35 +08002491 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002492 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002493 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002494}
2495/**\brief Stop play, will stop video and audio
2496 * \param[in] handle playback handle
2497 * \param[in] clear is clear last frame
2498 * \retval DVR_SUCCESS On success
2499 * \return Error code
2500 */
hualing chen040df222020-01-17 13:35:02 +08002501int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2502 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002503 DVR_UNUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002504 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002505 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002506 return DVR_FAILURE;
2507 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002508 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002509 DVR_PB_INFO(":playback is stoped");
hualing chenb96aa2c2020-04-15 14:13:53 +08002510 return DVR_SUCCESS;
2511 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002512 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002513 DVR_PB_INFO(":playback is stoped");
Ke Gong3c0caba2020-04-21 22:58:18 -07002514 return DVR_SUCCESS;
2515 }
hualing chen87072a82020-03-12 16:20:12 +08002516 _stop_playback_thread(handle);
Wentao MA96f68962022-06-15 19:45:35 +08002517 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002518 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002519 DVR_PB_INFO(":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002520 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002521 if (player->has_video) {
2522 AmTsPlayer_resumeVideoDecoding(player->handle);
2523 }
2524 if (player->has_audio) {
2525 AmTsPlayer_resumeAudioDecoding(player->handle);
2526 }
2527 if (player->has_video) {
2528 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002529 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002530 AmTsPlayer_stopVideoDecoding(player->handle);
2531 }
2532 if (player->has_audio) {
2533 player->has_audio = DVR_FALSE;
2534 AmTsPlayer_stopAudioDecoding(player->handle);
2535 }
hualing chendf118dd2020-05-21 15:49:11 +08002536 if (player->has_ad_audio) {
2537 player->has_ad_audio =DVR_FALSE;
2538 AmTsPlayer_disableADMix(player->handle);
2539 }
hualing chen266b9502020-04-04 17:39:39 +08002540
hualing chen86e7d482020-01-16 15:13:33 +08002541 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002542 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2543 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002544 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen87072a82020-03-12 16:20:12 +08002545 player->cur_segment_id = UINT64_MAX;
2546 player->segment_is_open = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08002547 DVR_PB_DEBUG("unlock");
2548 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002549 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002550 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002551}
2552/**\brief Start play audio
2553 * \param[in] handle playback handle
2554 * \param[in] params audio playback params,contains fmt and pid...
2555 * \retval DVR_SUCCESS On success
2556 * \return Error code
2557 */
hualing chen2aba4022020-03-02 13:49:55 +08002558
Wentao MA270dc0f2022-08-23 13:17:26 +08002559int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param, am_tsplayer_audio_params *ad_param) {
hualing chen040df222020-01-17 13:35:02 +08002560 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002561
2562 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002563 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002564 return DVR_FAILURE;
2565 }
hualing chen86e7d482020-01-16 15:13:33 +08002566 _start_playback_thread(handle);
2567 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002568 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002569 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002570
Wentao MA270dc0f2022-08-23 13:17:26 +08002571 if (VALID_PID(ad_param->pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08002572 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002573 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002574 AmTsPlayer_setADParams(player->handle, ad_param);
hualing chendf118dd2020-05-21 15:49:11 +08002575 AmTsPlayer_enableADMix(player->handle);
2576 }
hualing chen969fe7b2021-05-26 15:13:17 +08002577 if (VALID_PID(param->pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08002578 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08002579 player->has_audio = DVR_TRUE;
2580 AmTsPlayer_setAudioParams(player->handle, param);
Wentao MA5629ad82022-08-24 10:03:02 +08002581 if (player->audio_presentation_id > -1) {
2582 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2583 }
hualing chen969fe7b2021-05-26 15:13:17 +08002584 AmTsPlayer_startAudioDecoding(player->handle);
2585 }
hualing chendf118dd2020-05-21 15:49:11 +08002586
hualing chen86e7d482020-01-16 15:13:33 +08002587 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002588 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen040df222020-01-17 13:35:02 +08002589 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002590 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002591 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002592 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002593 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002594}
2595/**\brief Stop play audio
2596 * \param[in] handle playback handle
2597 * \retval DVR_SUCCESS On success
2598 * \return Error code
2599 */
hualing chen040df222020-01-17 13:35:02 +08002600int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2601 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002602
2603 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002604 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002605 return DVR_FAILURE;
2606 }
2607
hualing chen2aba4022020-03-02 13:49:55 +08002608 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002609 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002610 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002611 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002612 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002613 _stop_playback_thread(handle);
2614 } else {
2615 //do nothing.video is playing
2616 }
Wentao MA96f68962022-06-15 19:45:35 +08002617 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002618 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002619
hualing chenf00cdc82020-06-10 14:23:35 +08002620 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002621 player->has_audio = DVR_FALSE;
2622 AmTsPlayer_stopAudioDecoding(player->handle);
2623 }
hualing chen87072a82020-03-12 16:20:12 +08002624
hualing chendf118dd2020-05-21 15:49:11 +08002625 if (player->has_ad_audio) {
2626 player->has_ad_audio =DVR_FALSE;
2627 AmTsPlayer_disableADMix(player->handle);
2628 }
2629
hualing chen87072a82020-03-12 16:20:12 +08002630 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002631 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002632
Wentao MA96f68962022-06-15 19:45:35 +08002633 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002634 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002635 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002636}
2637/**\brief Start play video
2638 * \param[in] handle playback handle
2639 * \param[in] params video playback params,contains fmt and pid...
2640 * \retval DVR_SUCCESS On success
2641 * \return Error code
2642 */
hualing chen2aba4022020-03-02 13:49:55 +08002643int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002644 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002645
2646 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002647 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002648 return DVR_FAILURE;
2649 }
2650
hualing chen86e7d482020-01-16 15:13:33 +08002651 _start_playback_thread(handle);
2652 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002653 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002654 dvr_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002655 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002656 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002657 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002658 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002659
2660 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002661 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002662 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08002663 DVR_PB_INFO("settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002664 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2665 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002666 }
2667 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002668 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen040df222020-01-17 13:35:02 +08002669 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002670 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002671 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002672 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002673 return DVR_SUCCESS;
2674}
2675/**\brief Stop play video
2676 * \param[in] handle playback handle
2677 * \retval DVR_SUCCESS On success
2678 * \return Error code
2679 */
hualing chen040df222020-01-17 13:35:02 +08002680int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2681 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002682
2683 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002684 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002685 return DVR_FAILURE;
2686 }
2687
hualing chen86e7d482020-01-16 15:13:33 +08002688 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002689 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002690 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002691 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002692 _stop_playback_thread(handle);
2693 } else {
2694 //do nothing.audio is playing
2695 }
hualing chen7a56cba2020-04-14 14:09:27 +08002696
Wentao MA96f68962022-06-15 19:45:35 +08002697 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002698 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002699
hualing chen87072a82020-03-12 16:20:12 +08002700 player->has_video = DVR_FALSE;
2701
2702 AmTsPlayer_stopVideoDecoding(player->handle);
2703 //playback_device_video_stop(player->handle);
2704
2705 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002706 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002707
Wentao MA96f68962022-06-15 19:45:35 +08002708 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002709 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002710 return DVR_SUCCESS;
2711}
2712/**\brief Pause play
2713 * \param[in] handle playback handle
2714 * \param[in] flush whether its internal buffers should be flushed
2715 * \retval DVR_SUCCESS On success
2716 * \return Error code
2717 */
hualing chen040df222020-01-17 13:35:02 +08002718int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2719 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002720 DVR_UNUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002721 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002722 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002723 return DVR_FAILURE;
2724 }
hualing chenf00cdc82020-06-10 14:23:35 +08002725 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
Wentao MA96f68962022-06-15 19:45:35 +08002726 DVR_PB_INFO("player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002727 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002728 }
Wentao MA96f68962022-06-15 19:45:35 +08002729 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002730 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002731 DVR_PB_DEBUG("get lock");
hualing chen266b9502020-04-04 17:39:39 +08002732 if (player->has_video)
2733 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002734 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002735 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002736
2737 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002738 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2739 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2740 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002741 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002742 } else {
2743 player->cmd.last_cmd = player->cmd.cur_cmd;
2744 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2745 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002746 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002747 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002748 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002749 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002750
hualing chen86e7d482020-01-16 15:13:33 +08002751 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002752}
2753
hualing chen5cbe1a62020-02-10 16:36:36 +08002754//not add lock
2755static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2756{
2757 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2758
hualing chena540a7e2020-03-27 16:44:05 +08002759 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002760 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002761 return DVR_FAILURE;
2762 }
2763
hualing chen5cbe1a62020-02-10 16:36:36 +08002764 //get video params and audio params
Wentao MA96f68962022-06-15 19:45:35 +08002765 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002766 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08002767 am_tsplayer_video_params video_params;
2768 am_tsplayer_audio_params audio_params;
2769 am_tsplayer_audio_params ad_params;
hualing chencc91e1c2020-02-28 13:26:17 +08002770 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002771
Wentao MA270dc0f2022-08-23 13:17:26 +08002772 memset(&video_params, 0, sizeof(video_params));
2773 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002774
Wentao MA270dc0f2022-08-23 13:17:26 +08002775 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
Wentao MA96f68962022-06-15 19:45:35 +08002776 DVR_PB_INFO("unlock cmd: %d", cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002777 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002778
2779 switch (cmd) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002780 case DVR_PLAYBACK_CMD_AV_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002781 //av restart
Wentao MA270dc0f2022-08-23 13:17:26 +08002782 DVR_PB_INFO("do_cmd av_restart");
hualing chen87072a82020-03-12 16:20:12 +08002783 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002784 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002785 case DVR_PLAYBACK_CMD_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002786 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002787 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002788 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002789 case DVR_PLAYBACK_CMD_V_START:
2790 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002791 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002792 case DVR_PLAYBACK_CMD_V_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002793 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002794 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002795 case DVR_PLAYBACK_CMD_A_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002796 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002797 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002798 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002799 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002800 case DVR_PLAYBACK_CMD_A_START:
2801 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002802 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002803 case DVR_PLAYBACK_CMD_A_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002804 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002805 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002806 case DVR_PLAYBACK_CMD_A_STOP_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002807 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2808 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002809 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002810 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002811 case DVR_PLAYBACK_CMD_A_STOP_V_START:
hualing chen2aba4022020-03-02 13:49:55 +08002812 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002813 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002814 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002815 case DVR_PLAYBACK_CMD_V_STOP_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002816 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2817 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002818 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002819 break;
2820 case DVR_PLAYBACK_CMD_STOP:
2821 break;
2822 case DVR_PLAYBACK_CMD_START:
2823 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002824 case DVR_PLAYBACK_CMD_A_START_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002825 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002826 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2827 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002828 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002829 case DVR_PLAYBACK_CMD_V_START_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002830 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002831 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2832 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002833 break;
2834 case DVR_PLAYBACK_CMD_FF:
2835 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002836 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002837 break;
2838 default:
2839 break;
2840 }
2841 return DVR_SUCCESS;
2842}
2843
2844/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002845 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002846 * \retval DVR_SUCCESS On success
2847 * \return Error code
2848 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002849int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2850 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002851 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002852 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002853 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002854 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002855 return DVR_FAILURE;
2856 }
2857
hualing chena991aa82021-08-16 10:21:15 +08002858 if (dvr_playback_check_limit(handle)) {
2859 //get id and pos to check if we can seek to this pos
Wentao MA96f68962022-06-15 19:45:35 +08002860 DVR_PB_INFO("player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002861 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2862 if (segmentid != player->cur_segment_id ||
2863 (segmentid == player->cur_segment_id &&
2864 pos > _dvr_get_cur_time(handle))) {
2865 //first to seek new pos and to resume
Wentao MA96f68962022-06-15 19:45:35 +08002866 DVR_PB_INFO("seek new pos and to resume");
hualing chena991aa82021-08-16 10:21:15 +08002867 dvr_playback_seek(handle, segmentid, pos);
2868 }
hualing chen7ea70a72021-09-09 11:25:13 +08002869 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002870 DVR_PB_INFO("player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002871 }
hualing chena991aa82021-08-16 10:21:15 +08002872
hualing chen5cbe1a62020-02-10 16:36:36 +08002873 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08002874 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002875 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002876 player->first_frame = 0;
2877 if (player->has_video)
2878 AmTsPlayer_pauseVideoDecoding(player->handle);
2879 if (player->has_audio)
2880 AmTsPlayer_pauseAudioDecoding(player->handle);
2881
hualing chen266b9502020-04-04 17:39:39 +08002882 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002883 DVR_PB_INFO("dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002884 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2885 AmTsPlayer_resumeVideoDecoding(player->handle);
2886 }
2887 if (player->has_audio) {
2888 AmTsPlayer_resumeAudioDecoding(player->handle);
2889 }
2890 //check is has audio param,if has audio .we need start audio,
2891 //we will stop audio when ff fb, if reach end, we will pause.so we need
2892 //start audio when resume play
2893
Wentao MA270dc0f2022-08-23 13:17:26 +08002894 am_tsplayer_video_params video_params;
2895 am_tsplayer_audio_params audio_params;
2896 am_tsplayer_audio_params ad_params;
hualing chen266b9502020-04-04 17:39:39 +08002897 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002898
Wentao MA270dc0f2022-08-23 13:17:26 +08002899 memset(&video_params, 0, sizeof(video_params));
2900 memset(&audio_params, 0, sizeof(audio_params));
2901 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
hualing chen266b9502020-04-04 17:39:39 +08002902 //valid audio pid, start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002903 if (player->has_ad_audio == DVR_FALSE && VALID_PID(ad_params.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chen969fe7b2021-05-26 15:13:17 +08002904 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002905 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002906 dvr_playback_change_seek_state(handle, ad_params.pid);
2907 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen969fe7b2021-05-26 15:13:17 +08002908 AmTsPlayer_enableADMix(player->handle);
2909 }
2910
Wentao MA270dc0f2022-08-23 13:17:26 +08002911 if (player->has_audio == DVR_FALSE && VALID_PID(audio_params.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chen266b9502020-04-04 17:39:39 +08002912 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002913 dvr_playback_change_seek_state(handle, audio_params.pid);
2914 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002915 if (player->audio_presentation_id > -1) {
2916 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2917 }
hualing chen266b9502020-04-04 17:39:39 +08002918 AmTsPlayer_startAudioDecoding(player->handle);
2919 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08002920 DVR_PB_INFO("audio_params.pid:%d player->has_audio:%d speed:%d", audio_params.pid, player->has_audio, player->cmd.speed.speed.speed);
hualing chen266b9502020-04-04 17:39:39 +08002921 }
hualing chendf118dd2020-05-21 15:49:11 +08002922
hualing chen87072a82020-03-12 16:20:12 +08002923 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2924 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2925 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002926 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002927 } else {
2928 player->cmd.last_cmd = player->cmd.cur_cmd;
2929 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2930 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002931 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002932 }
Wentao MA96f68962022-06-15 19:45:35 +08002933 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002934 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002935 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
Wentao MA96f68962022-06-15 19:45:35 +08002936 DVR_PB_INFO("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002937 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002938 player->first_frame = 0;
2939 if (player->has_video)
2940 AmTsPlayer_pauseVideoDecoding(player->handle);
2941 if (player->has_audio)
2942 AmTsPlayer_pauseAudioDecoding(player->handle);
2943
hualing chene41f4372020-06-06 16:29:17 +08002944 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002945 DVR_PB_INFO("dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002946 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002947 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002948 }
hualing chen041c4092020-04-05 15:11:50 +08002949 if (player->has_audio)
2950 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002951 DVR_PB_INFO("set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen9811b212020-10-29 11:21:44 +08002952 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2953 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chend1686e52022-01-05 17:10:42 +08002954 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002955 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002956 DVR_PB_INFO("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002957 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002958 } else {
2959 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2960 {
Wentao MA96f68962022-06-15 19:45:35 +08002961 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002962 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002963 player->first_frame = 0;
2964 if (player->has_video)
2965 AmTsPlayer_pauseVideoDecoding(player->handle);
2966 if (player->has_audio)
2967 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002968 //clear flag
Wentao MA96f68962022-06-15 19:45:35 +08002969 DVR_PB_INFO("clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002970 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2971 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002972 if (player->has_video) {
2973 AmTsPlayer_resumeVideoDecoding(player->handle);
2974 }
2975 if (player->has_audio)
2976 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002977 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002978 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002979 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002980 }
2981 return DVR_SUCCESS;
2982}
2983
hualing chena540a7e2020-03-27 16:44:05 +08002984static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2985
2986 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2987 DVR_PlaybackSegmentInfo_t *segment = NULL;
2988 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2989 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2990
wentao.maa22bc852022-10-13 12:18:06 +08002991 // This error is surpressed as the macro code is picked from kernel.
2992 // prefetch() here incurring self_assign is used to avoid some compiling
2993 // warnings.
2994 // coverity[self_assign]
hualing chena540a7e2020-03-27 16:44:05 +08002995 list_for_each_entry(segment, &player->segment_list, head)
2996 {
2997 if (segment->segment_id == segment_id) {
2998 cur_segment = segment;
2999 }
3000 if (segment->segment_id == set_seg_id) {
3001 set_segment = segment;
3002 }
3003 if (cur_segment != NULL && set_segment != NULL) {
3004 break;
3005 }
3006 }
3007 if (cur_segment == NULL || set_segment == NULL) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003008 DVR_PB_INFO("set segment or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08003009 return DVR_TRUE;
3010 }
3011 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
3012 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
3013 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
3014 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
Wentao MA96f68962022-06-15 19:45:35 +08003015 DVR_PB_INFO("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 +08003016 return DVR_TRUE;
3017 }
Wentao MA96f68962022-06-15 19:45:35 +08003018 DVR_PB_INFO("play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08003019 return DVR_FALSE;
3020}
3021
hualing chen03fd4942021-07-15 15:56:41 +08003022/**\brief set limit
3023 * \param[in] handle playback handle
3024 * \param[in] rec start time ms
3025 * \param[in] rec limit time ms
3026 * \retval DVR_SUCCESS On success
3027 * \return Error code
3028 */
hualing chen7ea70a72021-09-09 11:25:13 +08003029int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08003030{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
3031
3032 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003033 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003034 return DVR_FAILURE;
3035 }
hualing chen7ea70a72021-09-09 11:25:13 +08003036 _dvr_getClock_sec();
Wentao MA96f68962022-06-15 19:45:35 +08003037 DVR_PB_INFO("lock time %lu limit: %u player->state:%d", time, limit, player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003038 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003039 player->rec_start = time;
3040 player->limit = limit;
Wentao MA96f68962022-06-15 19:45:35 +08003041 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003042 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003043 return DVR_SUCCESS;
3044}
3045
hualing chen5cbe1a62020-02-10 16:36:36 +08003046/**\brief seek
3047 * \param[in] handle playback handle
3048 * \param[in] time_offset time offset base cur segment
3049 * \retval DVR_SUCCESS On success
3050 * \return Error code
3051 */
hualing chencc91e1c2020-02-28 13:26:17 +08003052int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08003053 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08003054 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08003055 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003056 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003057 return DVR_FAILURE;
3058 }
3059
Wentao MA96f68962022-06-15 19:45:35 +08003060 DVR_PB_INFO("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);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003061 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003062
hualing chena540a7e2020-03-27 16:44:05 +08003063 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
Wentao MA96f68962022-06-15 19:45:35 +08003064 DVR_PB_INFO("player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08003065
hualing chen5cbe1a62020-02-10 16:36:36 +08003066 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08003067 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08003068 if (ret ==DVR_FAILURE) {
wentao.maa210e5e2022-10-12 16:10:03 +08003069 DVR_PB_ERROR("unlock seek error at open segment");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003070 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003071 return DVR_FAILURE;
3072 }
3073 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
3074 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08003075 DVR_PB_INFO("is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08003076 time_offset = _dvr_get_end_time(handle);
3077 } else {
wentao.maa210e5e2022-10-12 16:10:03 +08003078 DVR_PB_ERROR("is not ongoing segment when seek end, return failure");
3079 return DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08003080 }
3081 }
3082
Wentao MA96f68962022-06-15 19:45:35 +08003083 DVR_PB_INFO("seek open id[%lld]flag[0x%x] time_offset %u",
hualing chen03fd4942021-07-15 15:56:41 +08003084 player->cur_segment.segment_id,
3085 player->cur_segment.flags,
3086 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08003087 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08003088 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3089 //forward playback.not seek end of file
3090 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
3091 //default -2000ms
3092 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
3093 }
hualing chen86e7d482020-01-16 15:13:33 +08003094 }
Wentao MA01de0e62022-01-10 18:48:23 +08003095 // Seek can be regarded as a new playback, so keep the start segment_id for it also
hualing chen8a657f32021-08-30 13:12:49 +08003096 if (player->need_seek_start == DVR_TRUE) {
3097 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
Wentao MA01de0e62022-01-10 18:48:23 +08003098 player->first_start_id = player->cur_segment.segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003099 }
hualing chen2aba4022020-03-02 13:49:55 +08003100 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08003101 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08003102 player->ts_cache_len = 0;
wentao.maa210e5e2022-10-12 16:10:03 +08003103 int offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08003104 DVR_PB_ERROR("seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08003105 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08003106 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08003107
hualing chen2aba4022020-03-02 13:49:55 +08003108 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08003109
3110 player->last_send_time_id = UINT64_MAX;
Wentao MA270dc0f2022-08-23 13:17:26 +08003111 player->last_segment_total = 0LL;
hualing chen03fd4942021-07-15 15:56:41 +08003112 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08003113 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08003114 player->fffb_current = _dvr_time_getClock();
3115 player->fffb_start = player->fffb_current;
3116 player->fffb_start_pcr = _dvr_get_cur_time(handle);
3117 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08003118 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08003119 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003120 //only seek file,not start
Wentao MA96f68962022-06-15 19:45:35 +08003121 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003122 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003123 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08003124 }
hualing chen86e7d482020-01-16 15:13:33 +08003125 //stop play
Wentao MA96f68962022-06-15 19:45:35 +08003126 DVR_PB_ERROR("seek stop play, not inject data has video[%d]audio[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003127 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08003128
hualing chen266b9502020-04-04 17:39:39 +08003129 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08003130 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003131 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003132 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003133 }
3134
hualing chen40dd5462021-11-26 19:56:20 +08003135
hualing chen266b9502020-04-04 17:39:39 +08003136 if (player->has_audio) {
3137 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003138 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003139 }
hualing chendf118dd2020-05-21 15:49:11 +08003140 if (player->has_ad_audio) {
3141 player->has_ad_audio =DVR_FALSE;
3142 AmTsPlayer_disableADMix(player->handle);
3143 }
3144
hualing chen86e7d482020-01-16 15:13:33 +08003145 //start play
Wentao MA270dc0f2022-08-23 13:17:26 +08003146 am_tsplayer_video_params video_params;
3147 am_tsplayer_audio_params audio_params;
3148 am_tsplayer_audio_params ad_params;
hualing chenb31a6c62020-01-13 17:27:00 +08003149
Wentao MA270dc0f2022-08-23 13:17:26 +08003150 memset(&video_params, 0, sizeof(video_params));
3151 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003152
hualing chen040df222020-01-17 13:35:02 +08003153 player->cur_segment_id = segment_id;
3154
3155 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08003156 //get segment info and audio video pid fmt ;
Wentao MA270dc0f2022-08-23 13:17:26 +08003157 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08003158 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003159 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chena5f03222021-12-02 11:22:35 +08003160 //audio and video pid is all invalid, return error.
Wentao MA270dc0f2022-08-23 13:17:26 +08003161 DVR_PB_ERROR("unlock seek start dvr play back start error, not found audio and video info [0x%x]", video_params.pid);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003162 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08003163 return -1;
3164 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003165 DVR_PB_ERROR("seek start[0x%x]", video_params.pid);
hualing chen86e7d482020-01-16 15:13:33 +08003166 //add
hualing chen040df222020-01-17 13:35:02 +08003167 if (sync == DVR_PLAYBACK_SYNC) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003168 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003169 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08003170 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08003171 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08003172 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08003173 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003174 //if is pause state. we need set trick mode.
Wentao MA96f68962022-06-15 19:45:35 +08003175 DVR_PB_INFO("seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003176 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08003177 }
Wentao MA96f68962022-06-15 19:45:35 +08003178 DVR_PB_INFO("start video");
Wentao MA270dc0f2022-08-23 13:17:26 +08003179 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003180 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003181 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08003182 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
3183 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
3184 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
3185 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
3186 AmTsPlayer_stopFast(player->handle);
3187 }
hualing chen266b9502020-04-04 17:39:39 +08003188 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08003189 } else {
3190 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08003191 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003192 if (VALID_PID(ad_params.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08003193 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003194 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003195 dvr_playback_change_seek_state(handle, ad_params.pid);
3196 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003197 AmTsPlayer_enableADMix(player->handle);
3198 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003199 if (VALID_PID(audio_params.pid) && player->speed == 1.0) {
Wentao MA96f68962022-06-15 19:45:35 +08003200 DVR_PB_INFO("start audio seek");
Wentao MA270dc0f2022-08-23 13:17:26 +08003201 dvr_playback_change_seek_state(handle, audio_params.pid);
3202 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003203 if (player->audio_presentation_id > -1) {
3204 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3205 }
hualing chen969fe7b2021-05-26 15:13:17 +08003206 AmTsPlayer_startAudioDecoding(player->handle);
3207 player->has_audio = DVR_TRUE;
3208 }
hualing chen43a89bc2022-01-19 14:31:20 +08003209#ifdef AVSYNC_USED_PCR
3210 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003211 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003212 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3213 }
3214#endif
hualing chen86e7d482020-01-16 15:13:33 +08003215 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003216 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen2aba4022020-03-02 13:49:55 +08003217 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00003218 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
Wentao MA270dc0f2022-08-23 13:17:26 +08003219 if (VALID_PID(audio_params.pid) || VALID_PID(video_params.pid))
hualing chena5f03222021-12-02 11:22:35 +08003220 player->seek_pause = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08003221 DVR_PB_INFO("set state pause in seek vpid[0x%x]apid[0x%x]",video_params.pid, audio_params.pid);
hualing chen87072a82020-03-12 16:20:12 +08003222 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
Wentao MA16f870e2022-09-09 11:00:22 +08003223 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chen31140872020-03-25 12:29:26 +08003224 player->speed > 1.0f||
3225 player->speed <= -1.0f) {
Wentao MA96f68962022-06-15 19:45:35 +08003226 DVR_PB_INFO("not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003227 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003228 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003229 DVR_PB_INFO("set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003230 player->cmd.last_cmd = player->cmd.cur_cmd;
3231 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3232 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003233 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen2aba4022020-03-02 13:49:55 +08003234 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003235 player->last_send_time_id = UINT64_MAX;
Wentao MA96f68962022-06-15 19:45:35 +08003236 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003237 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003238
3239 return DVR_SUCCESS;
3240}
hualing chen5cbe1a62020-02-10 16:36:36 +08003241
Wentao MAac5ea062022-08-11 11:44:27 +08003242// Get current playback time position of the ongoing segment.
3243// Notice the return value may be negative. This is because previous segment's
3244// data cached in demux buffer need to be considered.
hualing chen5cbe1a62020-02-10 16:36:36 +08003245static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3246 //get cur time of segment
3247 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003248
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003249 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003250 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003251 return DVR_FAILURE;
3252 }
3253
Wentao MA270dc0f2022-08-23 13:17:26 +08003254 int64_t cache = 0;//default es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003255 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003256 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003257 uint64_t cur = 0;
3258 if (player->ts_cache_len > 0 && pos < 0) {
3259 //this case is open new segment end,but cache data is last segment.
3260 //we need used last segment len to send play time.
3261 cur = 0;
3262 } else {
3263 cur = segment_tell_position_time(player->r_handle, pos);
3264 }
hualing chen21a40372021-10-29 11:07:26 +08003265 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003266 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08003267 DVR_PB_INFO("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 +08003268 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3269 cache = 0;
3270 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003271 int cur_time = (int)(cur > cache ? cur - cache : 0);
3272 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003273}
3274
Wentao MAac5ea062022-08-11 11:44:27 +08003275// Get current playback time position of the ongoing segment.
3276// Notice the return value may be negative. This is because previous segment's
3277// data cached in demux buffer need to be considered.
hualing chen969fe7b2021-05-26 15:13:17 +08003278static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3279 //get cur time of segment
3280 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3281
hualing chen03fd4942021-07-15 15:56:41 +08003282 if (player == NULL || player->handle == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003283 DVR_PB_INFO("player is NULL");
hualing chen969fe7b2021-05-26 15:13:17 +08003284 return DVR_FAILURE;
3285 }
3286
Wentao MA270dc0f2022-08-23 13:17:26 +08003287 int64_t cache = 0;//default es buf cache 500ms
hualing chen969fe7b2021-05-26 15:13:17 +08003288 int cur_time = 0;
hualing chen969fe7b2021-05-26 15:13:17 +08003289 pthread_mutex_lock(&player->segment_lock);
hualing chena5f03222021-12-02 11:22:35 +08003290 loff_t tmp_pos = segment_tell_position(player->r_handle);
3291 loff_t pos = tmp_pos - player->ts_cache_len;
3292 uint64_t cur = 0;
3293 if (player->ts_cache_len > 0 && (tmp_pos < player->ts_cache_len)) {
3294 //this case is open new segment end,but cache data is last segment.
3295 //we need used last segment len to send play time.
3296 cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003297 DVR_PB_INFO("change segment [%lld][%lld]",
hualing chen926a8ec2021-12-20 20:38:24 +08003298 player->last_segment_id, player->cur_segment_id);
hualing chena5f03222021-12-02 11:22:35 +08003299 } else {
3300 cur = segment_tell_position_time(player->r_handle, pos);
3301 }
hualing chen21a40372021-10-29 11:07:26 +08003302 AmTsPlayer_getDelayTime(player->handle, &cache);
Wentao MAaf716972021-12-28 13:28:52 +08003303
hualing chen969fe7b2021-05-26 15:13:17 +08003304 pthread_mutex_unlock(&player->segment_lock);
Wentao MA01de0e62022-01-10 18:48:23 +08003305
3306 // The idea here is to work around a weakness of AmTsPlayer_getDelayTime at
3307 // starting phase of a playback in a short period of 20ms or less. During the
3308 // said period, getDelayTime does NOT work as expect to return real cache
3309 // length because demux isn't actually running to provide valid pts to
3310 // TsPlayer. "cache==0" implies the situation that playback is NOT actually
3311 // started. Under such conditions a '0' cache size may NOT reflect actual data
3312 // length remaining in TsPlayer cache, therefore corresponding libdvr 'cur' is
3313 // useless if data in TsPlayer cache is not considered, so it needs to be
Wentao MA270dc0f2022-08-23 13:17:26 +08003314 // reset to a previous valid state. To make the reset operation stricter, extra
Wentao MA01de0e62022-01-10 18:48:23 +08003315 // AmTsPlayer_getPts invocations on both video/audio are introduced to test if
3316 // TsPlayer can get valid pts which indicates the actual running status of
3317 // demux. (JIRA issue: SWPL-68740)
3318 if (player->first_start_id != UINT64_MAX && cache == 0
3319 && player->check_cache_flag == DVR_TRUE ) {
3320 uint64_t pts_a=0;
3321 uint64_t pts_v=0;
3322 AmTsPlayer_getPts(player->handle, TS_STREAM_AUDIO, &pts_a);
3323 AmTsPlayer_getPts(player->handle, TS_STREAM_VIDEO, &pts_v);
3324 if ((int64_t)pts_a <= 0 && (int64_t)pts_v <= 0) {
3325 // Identified the wired situation and just return previous valid state
3326 cur = player->first_start_time;
3327 *id = player->first_start_id;
3328 return cur;
3329 }
3330 }
3331 if (cache != 0) {
3332 // Do NOT permit to enter 'if' code block above any more
3333 player->check_cache_flag=DVR_FALSE;
3334 }
3335
Wentao MA96f68962022-06-15 19:45:35 +08003336 DVR_PB_INFO("***get play cur time [%lld] cache:%lld cur id [%lld]"
3337 " last id [%lld] pb cache len [%d] pos [%lld][%lld]",
hualing chen926a8ec2021-12-20 20:38:24 +08003338 cur,
3339 cache,
3340 player->cur_segment_id,
3341 player->last_send_time_id,
3342 player->ts_cache_len,
3343 pos,
3344 tmp_pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003345 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3346 cache = 0;
3347 }
3348 if (cur > cache) {
3349 cur_time = (int)(cur - cache);
3350 *id = player->cur_segment_id;
Wentao MA270dc0f2022-08-23 13:17:26 +08003351 } else if (player->last_segment_total > 0) {
hualing chend1686e52022-01-05 17:10:42 +08003352 //if at fb mode,we not used last id to replace cur id if cache > cur time.
3353 //this case only used for normal speed or ff speed
3354 if (!IS_FB(player->speed) && player->last_segment_id <= player->cur_segment_id) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003355 if (player->last_segment_total > (cache - cur))
3356 cur_time = (int)(player->last_segment_total - (cache - cur));
hualing chend1686e52022-01-05 17:10:42 +08003357 else
Wentao MA270dc0f2022-08-23 13:17:26 +08003358 cur_time = (int)(player->last_segment_total - cur);
hualing chen8a657f32021-08-30 13:12:49 +08003359
hualing chend1686e52022-01-05 17:10:42 +08003360 *id = player->last_segment_id;
3361 } else {//fb mode
3362 cur_time = (int)(cur);
3363 *id = player->cur_segment_id;
3364 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003365 DVR_PB_INFO("get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_total);
hualing chen969fe7b2021-05-26 15:13:17 +08003366 } else {
3367 cur_time = 0;
3368 *id = player->cur_segment_id;
3369 }
hualing chen969fe7b2021-05-26 15:13:17 +08003370 return cur_time;
3371}
3372
hualing chencc91e1c2020-02-28 13:26:17 +08003373//get current segment current pcr time of read pos
3374static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3375 //get cur time of segment
3376 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003377
3378 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003379 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003380 return DVR_FAILURE;
3381 }
3382
hualing chen2aba4022020-03-02 13:49:55 +08003383 pthread_mutex_lock(&player->segment_lock);
3384 uint64_t end = segment_tell_total_time(player->r_handle);
Wentao MA96f68962022-06-15 19:45:35 +08003385 DVR_PB_INFO("get total time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08003386 pthread_mutex_unlock(&player->segment_lock);
3387 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003388}
3389
hualing chen03fd4942021-07-15 15:56:41 +08003390DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3391{
3392 //check is set limit info
3393 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3394
3395 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003396 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003397 return DVR_FALSE;
3398 }
3399 if (player->rec_start > 0 || player->limit > 0) {
3400 return DVR_TRUE;
3401 }
3402 return DVR_FALSE;
3403}
3404
3405/**\brief set DVR playback calculate expired time len
3406 * \param[in] handle, DVR playback session handle
3407 * \return DVR_SUCCESS on success
3408 * \return error code on failure
3409 */
hualing chen7ea70a72021-09-09 11:25:13 +08003410uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003411{
3412 //calculate expired time to play
3413 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003414 uint32_t cur_time;
3415 uint32_t tmp_time;
3416 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003417 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003418 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003419 return expired;
3420 }
hualing chen7ea70a72021-09-09 11:25:13 +08003421 if (player->rec_start == 0 || player->limit == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003422 DVR_PB_INFO("rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003423 return expired;
3424 }
3425 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003426 cur_time = _dvr_getClock_sec();
3427 if ((cur_time - player->rec_start) > player->limit) {
3428 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3429 expired = *(int*)&tmp_time;
Wentao MA96f68962022-06-15 19:45:35 +08003430 DVR_PB_INFO("cur_time:%u, rec start:%u limit:%d c_r_diff:%u expired:%u tmp_time:%u",
hualing chen03fd4942021-07-15 15:56:41 +08003431 cur_time,
3432 player->rec_start,
3433 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003434 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3435 }
hualing chen03fd4942021-07-15 15:56:41 +08003436 return expired;
3437}
3438
3439/**\brief set DVR playback obsolete time
3440 * \param[in] handle, DVR playback session handle
3441 * \param[in] obsolete, obsolete len
3442 * \return DVR_SUCCESS on success
3443 * \return error code on failure
3444 */
3445int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3446{
3447 int expired = 0;
3448 //calculate expired time to play
3449 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3450
3451 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003452 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003453 return DVR_FALSE;
3454 }
3455 //get system time
Wentao MA96f68962022-06-15 19:45:35 +08003456 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003457 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003458 player->obsolete = obsolete;
Wentao MA96f68962022-06-15 19:45:35 +08003459 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003460 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003461 return expired;
3462}
3463
3464/**\brief update DVR playback newest segment duration
3465 * \param[in] handle, DVR playback session handle
3466 * \param[in] segmentid, newest segment id
3467 * \param[in] dur dur time ms
3468 * \return DVR_SUCCESS on success
3469 * \return error code on failure
3470 */
3471int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3472uint64_t segmentid, int dur)
3473{
3474 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3475 DVR_PlaybackSegmentInfo_t *segment;
3476 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3477
3478 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003479 DVR_PB_INFO(" player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003480 return DVR_FAILURE;
3481 }
3482 //update the newest segment duration on timeshift mode
wentao.maa22bc852022-10-13 12:18:06 +08003483 // This error is surpressed as the macro code is picked from kernel.
3484 // prefetch() here incurring self_assign is used to avoid some compiling
3485 // warnings.
3486 // coverity[self_assign]
hualing chen03fd4942021-07-15 15:56:41 +08003487 list_for_each_entry(segment, &player->segment_list, head)
3488 {
3489 if (segment->segment_id == segmentid) {
3490 segment->duration = dur;
3491 break;
3492 }
3493 pre_segment = segment;
3494 }
3495
3496 return DVR_SUCCESS;
3497}
3498
hualing chen7ea70a72021-09-09 11:25:13 +08003499static uint32_t dvr_playback_calculate_last_valid_segment(
3500 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003501{
hualing chen7ea70a72021-09-09 11:25:13 +08003502 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003503 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003504 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003505 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003506 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003507 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3508
3509 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003510 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003511 return DVR_FAILURE;
3512 }
3513 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003514 if (expired == 0) {
3515 *segmentid = player->cur_segment_id;
3516 *pos = 0;
3517 return DVR_SUCCESS;
3518 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003519 DVR_PlaybackSegmentInfo_t *p_seg;
wentao.maa22bc852022-10-13 12:18:06 +08003520 // This error is surpressed as the macro code is picked from kernel.
3521 // prefetch() here incurring self_assign is used to avoid some compiling
3522 // warnings.
3523 // coverity[self_assign]
Wentao MA270dc0f2022-08-23 13:17:26 +08003524 list_for_each_entry_reverse(p_seg, &player->segment_list, head) {
3525 segment_id = p_seg->segment_id;
hualing chen03fd4942021-07-15 15:56:41 +08003526
Wentao MA270dc0f2022-08-23 13:17:26 +08003527 if ((player->obsolete + pre_off + p_seg->duration) > expired)
hualing chen03fd4942021-07-15 15:56:41 +08003528 break;
3529
Wentao MA270dc0f2022-08-23 13:17:26 +08003530 last_segment_id = p_seg->segment_id;
3531 pre_off += p_seg->duration;
hualing chen03fd4942021-07-15 15:56:41 +08003532 }
3533
3534 if (last_segment_id == segment_id) {
3535 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3536 off = expired;
3537 } else if (player->obsolete >= expired) {
3538 off = 0;
3539 } else {
3540 off = expired - pre_off - player->obsolete;
3541 }
3542 *segmentid = segment_id;
3543 *pos = off;
3544 return DVR_SUCCESS;
3545}
3546
hualing chen4b7c15d2020-04-07 16:13:48 +08003547#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003548//start replay
3549static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3550
3551 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3552 //calculate pcr seek time
3553 int t_diff = 0;
3554 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003555 uint64_t segmentid = 0;
3556 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003557 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003558 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003559 return DVR_FAILURE;
3560 }
3561
hualing chen5cbe1a62020-02-10 16:36:36 +08003562 if (player->fffb_start == -1) {
3563 //set fffb start time ms
3564 player->fffb_start = _dvr_time_getClock();
3565 player->fffb_current = player->fffb_start;
3566 //get segment current time pos
3567 player->fffb_start_pcr = _dvr_get_cur_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003568 DVR_PB_INFO("calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
hualing chen03fd4942021-07-15 15:56:41 +08003569 player->fffb_start_pcr, player->speed);
hualing chene41f4372020-06-06 16:29:17 +08003570 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003571 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003572 } else {
3573 player->fffb_current = _dvr_time_getClock();
3574 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003575 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003576 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003577 if (seek_time <= 0) {
3578 //need seek to pre one segment
3579 seek_time = 0;
3580 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003581 //seek segment pos
3582 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003583 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003584 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003585 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3586 //set seek time to 0;
Wentao MA96f68962022-06-15 19:45:35 +08003587 DVR_PB_INFO("segment seek to 0 at fb mode [%d]id[%lld]",
hualing chen03fd4942021-07-15 15:56:41 +08003588 seek_time,
3589 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003590 seek_time = 0;
3591 }
hualing chen03fd4942021-07-15 15:56:41 +08003592 if (IS_FB(player->speed)
3593 && dvr_playback_check_limit(handle)) {
3594 //fb case.check expired time
3595 //get id and pos to check if we can seek to this pos
3596 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3597 //case cur id < segment id
3598 if (player->cur_segment_id < segmentid) {
3599 //expired ts data is player,return error
3600 //
3601 pthread_mutex_unlock(&player->segment_lock);
3602 return 0;
3603 } else if (player->cur_segment_id == segmentid) {
3604 //id is same,compare seek pos
3605 if (seek_time < pos) {
3606 //expired ts data is player,return error
3607 //
3608 pthread_mutex_unlock(&player->segment_lock);
3609 return 0;
3610 }
3611 }
3612 //case can play
3613 }
hualing chen041c4092020-04-05 15:11:50 +08003614 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
3615 seek_time = 0;
3616 }
hualing chen2aba4022020-03-02 13:49:55 +08003617 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003618 } else {
3619 //
Wentao MA96f68962022-06-15 19:45:35 +08003620 DVR_PB_INFO("segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003621 }
Wentao MA96f68962022-06-15 19:45:35 +08003622 DVR_PB_INFO("calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003623 seek_time,
3624 player->speed,
3625 player->cur_segment_id,
3626 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003627 }
hualing chen2aba4022020-03-02 13:49:55 +08003628 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003629}
3630
3631
3632//start replay
3633static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3634 //
3635 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003636
3637 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003638 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003639 return DVR_FAILURE;
3640 }
3641
hualing chen5cbe1a62020-02-10 16:36:36 +08003642 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003643 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08003644 DVR_PB_INFO("fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003645 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003646 AmTsPlayer_stopVideoDecoding(player->handle);
3647 }
3648 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003649 DVR_PB_INFO("fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003650 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003651 AmTsPlayer_stopAudioDecoding(player->handle);
3652 }
hualing chendf118dd2020-05-21 15:49:11 +08003653 if (player->has_ad_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003654 DVR_PB_INFO("fffb stop audio");
hualing chendf118dd2020-05-21 15:49:11 +08003655 player->has_ad_audio =DVR_FALSE;
3656 AmTsPlayer_disableADMix(player->handle);
3657 }
hualing chen2aba4022020-03-02 13:49:55 +08003658
hualing chen5cbe1a62020-02-10 16:36:36 +08003659 //start video and audio
3660
Wentao MA270dc0f2022-08-23 13:17:26 +08003661 am_tsplayer_video_params video_params;
3662 am_tsplayer_audio_params audio_params;
3663 am_tsplayer_audio_params ad_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003664
Wentao MA270dc0f2022-08-23 13:17:26 +08003665 memset(&video_params, 0, sizeof(video_params));
3666 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003667
hualing chen87072a82020-03-12 16:20:12 +08003668 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003669
3670 //get segment info and audio video pid fmt ;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003671 //dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08003672 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003673 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003674 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
3675 //audio and video pids are all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003676 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003677 return -1;
3678 }
3679
Wentao MA270dc0f2022-08-23 13:17:26 +08003680 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003681 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003682 DVR_PB_INFO("fffb start video");
3683 //DVR_PB_INFO("fffb start video and save last frame");
hualing chen0888c032020-12-18 17:54:57 +08003684 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003685 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003686 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
Wentao MA270dc0f2022-08-23 13:17:26 +08003687 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003688 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003689 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003690 //playback_device_video_start(player->handle , &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003691 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003692 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003693 }
hualing chen31140872020-03-25 12:29:26 +08003694 //fffb mode need stop fast;
Wentao MA96f68962022-06-15 19:45:35 +08003695 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003696 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003697 return 0;
3698}
3699
3700static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3701 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003702 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003703 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003704 return DVR_FAILURE;
3705 }
3706
3707 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003708 DVR_PB_INFO("lock speed [%f]", player->speed);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003709 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003710
hualing chen2aba4022020-03-02 13:49:55 +08003711 int seek_time = _dvr_playback_calculate_seekpos(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003712 DVR_PB_INFO("get lock speed [%f]id [%lld]seek_time[%d]", player->speed, player->cur_segment_id, seek_time);
hualing chen041c4092020-04-05 15:11:50 +08003713
hualing chen87072a82020-03-12 16:20:12 +08003714 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3715 //seek time set 0
3716 seek_time = 0;
3717 }
hualing chen041c4092020-04-05 15:11:50 +08003718 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003719 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3720 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003721 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003722 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003723 DVR_PB_DEBUG("unlock");
hualing chen87072a82020-03-12 16:20:12 +08003724 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003725 //send event here and pause
3726 DVR_Play_Notify_t notify;
3727 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003728 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003729 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003730 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08003731 DVR_PB_INFO("*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08003732 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003733 return DVR_SUCCESS;
3734 }
hualing chen2932d372020-04-29 13:44:00 +08003735 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003736 _dvr_init_fffb_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003737 DVR_PB_INFO("*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003738 }
3739 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003740 _dvr_playback_fffb_replay(handle);
3741
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003742 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003743 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003744
hualing chen5cbe1a62020-02-10 16:36:36 +08003745 return DVR_SUCCESS;
3746}
3747
hualing chen87072a82020-03-12 16:20:12 +08003748//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003749static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003750 //
3751 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003752
3753 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003754 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003755 return DVR_FAILURE;
3756 }
3757
hualing chen5cbe1a62020-02-10 16:36:36 +08003758 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003759 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003760 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003761 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003762 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003763 }
3764
3765 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003766 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003767 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003768 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003769 //start video and audio
3770
Wentao MA270dc0f2022-08-23 13:17:26 +08003771 am_tsplayer_video_params video_params;
3772 am_tsplayer_audio_params audio_params;
3773 am_tsplayer_audio_params ad_params;
hualing chen87072a82020-03-12 16:20:12 +08003774 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003775
Wentao MA270dc0f2022-08-23 13:17:26 +08003776 memset(&video_params, 0, sizeof(video_params));
3777 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003778
hualing chen5cbe1a62020-02-10 16:36:36 +08003779 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08003780 DVR_PB_INFO("into");
Wentao MA270dc0f2022-08-23 13:17:26 +08003781 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003782 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003783 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003784 //audio and video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003785 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003786 return -1;
3787 }
3788
Wentao MA270dc0f2022-08-23 13:17:26 +08003789 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003790 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003791 if (trick == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003792 DVR_PB_INFO("settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003793 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003794 }
hualing chen266b9502020-04-04 17:39:39 +08003795 else {
hualing chen2aba4022020-03-02 13:49:55 +08003796 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003797 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003798 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003799 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003800 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003801 }
hualing chena540a7e2020-03-27 16:44:05 +08003802
3803 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
Wentao MA96f68962022-06-15 19:45:35 +08003804 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08003805 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003806 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003807 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08003808 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08003809 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003810 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003811 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003812 AmTsPlayer_enableADMix(player->handle);
3813 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003814 if (VALID_PID(audio_params.pid)) {
hualing chen969fe7b2021-05-26 15:13:17 +08003815 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003816 DVR_PB_INFO("start audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003817 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003818 if (player->audio_presentation_id > -1) {
3819 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3820 }
hualing chen969fe7b2021-05-26 15:13:17 +08003821 AmTsPlayer_startAudioDecoding(player->handle);
3822 }
hualing chendf118dd2020-05-21 15:49:11 +08003823
Wentao MA96f68962022-06-15 19:45:35 +08003824 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003825 AmTsPlayer_stopFast(player->handle);
3826 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3827 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3828 }
hualing chen43a89bc2022-01-19 14:31:20 +08003829#ifdef AVSYNC_USED_PCR
3830 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003831 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003832 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3833 }
3834#endif
hualing chen2aba4022020-03-02 13:49:55 +08003835 player->cmd.last_cmd = player->cmd.cur_cmd;
3836 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003837 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003838 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen5cbe1a62020-02-10 16:36:36 +08003839 return 0;
3840}
3841
3842
hualing chenb31a6c62020-01-13 17:27:00 +08003843/**\brief Set play speed
3844 * \param[in] handle playback handle
3845 * \param[in] speed playback speed
3846 * \retval DVR_SUCCESS On success
3847 * \return Error code
3848 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003849int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3850
3851 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003852
3853 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003854 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003855 return DVR_FAILURE;
3856 }
3857
hualing chena540a7e2020-03-27 16:44:05 +08003858 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08003859 DVR_PB_INFO(" func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003860 return DVR_FAILURE;
3861 }
hualing chenf00cdc82020-06-10 14:23:35 +08003862 if (speed.speed.speed == player->cmd.speed.speed.speed) {
Wentao MA96f68962022-06-15 19:45:35 +08003863 DVR_PB_INFO(" func: eq speed [%d]", speed.speed.speed);
hualing chenf00cdc82020-06-10 14:23:35 +08003864 return DVR_SUCCESS;
3865 }
Wentao MA96f68962022-06-15 19:45:35 +08003866 DVR_PB_INFO("lock func: speed [%d]", speed.speed.speed);
hualing chen1679f812021-11-08 15:17:46 +08003867
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003868 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003869 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3870 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3871 player->cmd.last_cmd = player->cmd.cur_cmd;
3872 }
hualing chene41f4372020-06-06 16:29:17 +08003873
hualing chen31140872020-03-25 12:29:26 +08003874 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003875 IS_KERNEL_SPEED(speed.speed.speed) ) {
3876 //case 1. not start play.only set speed
3877 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3878 //only set speed.and return;
3879 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3880 player->cmd.speed.speed = speed.speed;
3881 player->speed = (float)speed.speed.speed/(float)100;
3882 player->fffb_play = DVR_FALSE;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003883 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003884 DVR_PB_DEBUG("unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003885 return DVR_SUCCESS;
3886 }
3887 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003888 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3889 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003890 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003891 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3892 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003893 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003894 AmTsPlayer_stopFast(player->handle);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003895 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003896 DVR_PB_DEBUG("unlock ---\r\n");
Wentao MA270dc0f2022-08-23 13:17:26 +08003897 _dvr_cmd(handle, DVR_PLAYBACK_CMD_A_START);
Wentao MA96f68962022-06-15 19:45:35 +08003898 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003899 dvr_mutex_lock(&player->lock);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003900 } else {
3901 //set play speed and if audio is start, stop audio.
3902 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003903 DVR_PB_INFO("fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003904 AmTsPlayer_stopAudioDecoding(player->handle);
3905 player->has_audio = DVR_FALSE;
3906 }
Wentao MA96f68962022-06-15 19:45:35 +08003907 DVR_PB_INFO("start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003908 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003909 }
hualing chenbcada022020-04-22 14:27:01 +08003910 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003911 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003912 player->cmd.speed.speed = speed.speed;
3913 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA96f68962022-06-15 19:45:35 +08003914 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003915 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003916 return DVR_SUCCESS;
3917 }
hualing chen31140872020-03-25 12:29:26 +08003918 //case 3 fffb mode
3919 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3920 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3921 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003922 DVR_PB_INFO("set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003923 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003924 player->cmd.speed.speed = speed.speed;
3925 player->speed = (float)speed.speed.speed/(float)100;
3926 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003927 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003928 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003929 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003930 return DVR_SUCCESS;
3931 }
3932 }
3933 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003934 IS_KERNEL_SPEED(speed.speed.speed)) {
3935 //case 1. cur speed is kernel support speed,set kernel speed.
3936 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003937 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003938 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3939 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003940 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003941 AmTsPlayer_stopFast(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003942 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003943 } else {
3944 //set play speed and if audio is start, stop audio.
3945 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003946 DVR_PB_INFO("fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003947 AmTsPlayer_stopAudioDecoding(player->handle);
3948 player->has_audio = DVR_FALSE;
3949 }
Wentao MA96f68962022-06-15 19:45:35 +08003950 DVR_PB_INFO("start fast");
hualing chenf00cdc82020-06-10 14:23:35 +08003951 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003952 }
hualing chena540a7e2020-03-27 16:44:05 +08003953 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003954 player->cmd.speed.speed = speed.speed;
3955 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003956 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003957 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003958 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003959 return DVR_SUCCESS;
3960 }
3961 //case 2 fffb mode
3962 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3963 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3964 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003965 DVR_PB_INFO("set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003966 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003967 player->cmd.speed.speed = speed.speed;
3968 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA270dc0f2022-08-23 13:17:26 +08003969 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
hualing chenbcada022020-04-22 14:27:01 +08003970 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003971 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003972 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003973 return DVR_SUCCESS;
3974 }
hualing chen31140872020-03-25 12:29:26 +08003975 }
hualing chena540a7e2020-03-27 16:44:05 +08003976 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3977 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003978 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003979 } else {
hualing chen31140872020-03-25 12:29:26 +08003980 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003981 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3982 else
3983 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003984 player->fffb_play = DVR_TRUE;
3985 }
3986 DVR_Bool_t init_last_time = DVR_FALSE;
3987 if (player->speed > 0.0f && speed.speed.speed < 0) {
3988 init_last_time = DVR_TRUE;
3989 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3990 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003991 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003992 player->cmd.speed.mode = speed.mode;
3993 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003994 player->speed = (float)speed.speed.speed/(float)100;
3995 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003996 _dvr_init_fffb_t(handle);
3997 if (init_last_time == DVR_TRUE)
3998 player->last_send_time_id = UINT64_MAX;
3999
hualing chen87072a82020-03-12 16:20:12 +08004000 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08004001 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
4002 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08004003 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08004004 DVR_PB_INFO("set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08004005 _dvr_playback_replay(handle, DVR_FALSE);
4006 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
4007 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08004008 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
Wentao MA96f68962022-06-15 19:45:35 +08004009 DVR_PB_INFO("set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08004010 }
Wentao MA96f68962022-06-15 19:45:35 +08004011 DVR_PB_INFO("unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004012 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08004013 return DVR_SUCCESS;
4014}
hualing chen2932d372020-04-29 13:44:00 +08004015
hualing chenb31a6c62020-01-13 17:27:00 +08004016/**\brief Get playback status
4017 * \param[in] handle playback handle
4018 * \param[out] p_status playback status
4019 * \retval DVR_SUCCESS On success
4020 * \return Error code
4021 */
hualing chen2932d372020-04-29 13:44:00 +08004022static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
4023 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08004024//
4025 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08004026 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08004027 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004028 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004029 return DVR_FAILURE;
4030 }
hualing chen1679f812021-11-08 15:17:46 +08004031 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08004032 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004033 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08004034 }
4035
hualing chen5cbe1a62020-02-10 16:36:36 +08004036 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08004037 //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 +08004038 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
4039 player->state == DVR_PLAYBACK_STATE_START) {
4040 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
4041 }
hualing chen041c4092020-04-05 15:11:50 +08004042
hualing chencc91e1c2020-02-28 13:26:17 +08004043 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08004044 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08004045
4046 if (CONTROL_SPEED_ENABLE == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08004047 if (player->con_spe.ply_sta == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08004048 DVR_PB_INFO("player dur[%u] sta[%u] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08004049 player->con_spe.ply_dur,
4050 player->con_spe.ply_sta,
4051 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08004052 player->con_spe.ply_sta = p_status->time_cur;
4053 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
4054 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
Wentao MA96f68962022-06-15 19:45:35 +08004055 DVR_PB_INFO("player dur[%u] sta[%u] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004056 player->con_spe.ply_dur,
4057 player->con_spe.ply_sta,
4058 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08004059 player->con_spe.ply_sta = p_status->time_cur;
4060 }
4061
4062 if (player->con_spe.sys_sta == 0) {
4063 player->con_spe.sys_sta = _dvr_time_getClock();
4064 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
4065 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
4066 player->con_spe.sys_sta = _dvr_time_getClock();
4067 }
4068 }
4069
hualing chen4b7c15d2020-04-07 16:13:48 +08004070 if (player->last_send_time_id == UINT64_MAX) {
4071 player->last_send_time_id = player->cur_segment_id;
4072 player->last_cur_time = p_status->time_cur;
4073 }
4074 if (player->last_send_time_id == player->cur_segment_id) {
4075 if (player->speed > 0.0f ) {
4076 //ff
4077 if (p_status->time_cur < player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004078 DVR_PB_INFO("get ff time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004079 player->last_cur_time,
4080 p_status->time_cur,
4081 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08004082 p_status->time_cur = player->last_cur_time;
4083 } else {
4084 player->last_cur_time = p_status->time_cur;
4085 }
hualing chene41f4372020-06-06 16:29:17 +08004086 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08004087 //fb
4088 if (p_status->time_cur > player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004089 DVR_PB_INFO("get fb time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004090 player->last_cur_time,
4091 p_status->time_cur,
4092 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08004093 p_status->time_cur = player->last_cur_time;
4094 } else {
4095 player->last_cur_time = p_status->time_cur;
4096 }
4097 }
hualing chend241c7a2021-06-22 13:34:27 +08004098 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08004099 player->last_cur_time = p_status->time_cur;
4100 }
hualing chen969fe7b2021-05-26 15:13:17 +08004101 player->last_send_time_id = segment_id;
4102 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08004103
hualing chen5cbe1a62020-02-10 16:36:36 +08004104 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08004105 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08004106 p_status->flags = player->cur_segment.flags;
Wentao MA96f68962022-06-15 19:45:35 +08004107 DVR_PB_INFO("player real state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]is_lock[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004108 _dvr_playback_state_toString(player->state),
4109 _dvr_playback_state_toString(p_status->state),
4110 p_status->time_cur, p_status->time_end,
4111 p_status->segment_id,player->play_flag,
4112 player->speed,
4113 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08004114 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08004115 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004116 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08004117 }
hualing chen2932d372020-04-29 13:44:00 +08004118 return DVR_SUCCESS;
4119}
4120
4121
4122/**\brief Get playback status
4123 * \param[in] handle playback handle
4124 * \param[out] p_status playback status
4125 * \retval DVR_SUCCESS On success
4126 * \return Error code
4127 */
4128int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
4129 DVR_PlaybackStatus_t *p_status) {
4130//
4131 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4132
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004133 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
4134
hualing chen2932d372020-04-29 13:44:00 +08004135 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004136 DVR_PB_INFO("player is NULL");
hualing chen2932d372020-04-29 13:44:00 +08004137 return DVR_FAILURE;
4138 }
Wentao MA96f68962022-06-15 19:45:35 +08004139 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004140 dvr_mutex_lock(&player->lock);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004141 if (!player->has_video && !player->has_audio)
4142 p_status->time_cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08004143 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004144 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08004145
hualing chenb31a6c62020-01-13 17:27:00 +08004146 return DVR_SUCCESS;
4147}
4148
hualing chen040df222020-01-17 13:35:02 +08004149void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
4150 if (segment != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004151 DVR_PB_INFO("segment id: %lld", segment->segment_id);
4152 DVR_PB_INFO("segment flag: %d", segment->flags);
4153 DVR_PB_INFO("segment location: [%s]", segment->location);
4154 DVR_PB_INFO("segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
4155 DVR_PB_INFO("segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
4156 DVR_PB_INFO("segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
4157 DVR_PB_INFO("segment sub apid: 0x%x sub afmt:0x%x", segment->pids.ad.pid,segment->pids.ad.format);
hualing chen86e7d482020-01-16 15:13:33 +08004158 }
hualing chenb31a6c62020-01-13 17:27:00 +08004159}
4160
hualing chen5cbe1a62020-02-10 16:36:36 +08004161int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004162 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08004163
hualing chena540a7e2020-03-27 16:44:05 +08004164 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004165 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004166 return DVR_FAILURE;
4167 }
4168
hualing chen040df222020-01-17 13:35:02 +08004169 DVR_PlaybackSegmentInfo_t *segment;
wentao.maa22bc852022-10-13 12:18:06 +08004170 // This error is surpressed as the macro code is picked from kernel.
4171 // prefetch() here incurring self_assign is used to avoid some compiling
4172 // warnings.
4173 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08004174 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08004175 {
Wentao MA07d3d742022-09-06 09:58:05 +08004176 if (segment->segment_id == segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004177 _dvr_dump_segment(segment);
Wentao MA07d3d742022-09-06 09:58:05 +08004178 break;
hualing chen86e7d482020-01-16 15:13:33 +08004179 }
4180 }
4181 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08004182}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004183
pengfei.liu27cc4ec2020-04-03 16:28:16 +08004184int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004185{
4186 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4187 DVR_RETURN_IF_FALSE(player);
4188 DVR_RETURN_IF_FALSE(func);
4189
Wentao MA96f68962022-06-15 19:45:35 +08004190 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004191 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004192
4193 player->dec_func = func;
4194 player->dec_userdata = userdata;
4195
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004196 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004197 DVR_PB_INFO("out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004198 return DVR_SUCCESS;
4199}
4200
4201int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
4202{
4203 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4204 DVR_RETURN_IF_FALSE(player);
4205 DVR_RETURN_IF_FALSE(p_secure_buf);
4206 DVR_RETURN_IF_FALSE(len);
4207
Wentao MA96f68962022-06-15 19:45:35 +08004208 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004209 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004210
4211 player->is_secure_mode = 1;
4212 player->secure_buffer = p_secure_buf;
4213 player->secure_buffer_size = len;
4214
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004215 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004216 DVR_PB_INFO("out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004217 return DVR_SUCCESS;
4218}
Wentao MA5629ad82022-08-24 10:03:02 +08004219
4220int dvr_playback_set_ac4_preselection_id(DVR_PlaybackHandle_t handle, int presel_id)
4221{
4222 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa210e5e2022-10-12 16:10:03 +08004223 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MA5629ad82022-08-24 10:03:02 +08004224
4225 player->audio_presentation_id = presel_id;
4226 am_tsplayer_result ret = AmTsPlayer_setParams(player->handle,
4227 AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &presel_id);
4228 DVR_RETURN_IF_FALSE(ret == AM_TSPLAYER_OK);
4229
4230 return DVR_SUCCESS;
4231}