blob: 4eede63b6143d045c8a127724f055151a676e12c [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>
Wentao MA361eaac2023-03-21 13:12:28 +08008#include <sys/prctl.h>
hualing chenb31a6c62020-01-13 17:27:00 +08009#include <fcntl.h>
10#include <unistd.h>
11#include <poll.h>
12#include <errno.h>
13#include <signal.h>
14#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080015#include <errno.h>
hualing chen03fd4942021-07-15 15:56:41 +080016#include "dvr_utils.h"
17#include "dvr_types.h"
hualing chenb31a6c62020-01-13 17:27:00 +080018#include "dvr_playback.h"
Yahui Han1fbf3292021-11-08 18:17:19 +080019#include "am_crypt.h"
hualing chenb31a6c62020-01-13 17:27:00 +080020
Wentao MA96f68962022-06-15 19:45:35 +080021#define PB_LOG_TAG "libdvr-playback"
22#define DVR_PB_DEBUG(...) DVR_LOG_PRINT(LOG_LV_DEBUG, PB_LOG_TAG, __VA_ARGS__)
23#define DVR_PB_INFO(...) DVR_LOG_PRINT(LOG_LV_INFO, PB_LOG_TAG, __VA_ARGS__)
24#define DVR_PB_WARN(...) DVR_LOG_PRINT(LOG_LV_WARN, PB_LOG_TAG, __VA_ARGS__)
25#define DVR_PB_ERROR(...) DVR_LOG_PRINT(LOG_LV_ERROR, PB_LOG_TAG, __VA_ARGS__)
26#define DVR_PB_FATAL(...) DVR_LOG_PRINT(LOG_LV_FATAL, PB_LOG_TAG, __VA_ARGS__)
hualing chena540a7e2020-03-27 16:44:05 +080027
hualing chenb31a6c62020-01-13 17:27:00 +080028#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080029
hualing chena540a7e2020-03-27 16:44:05 +080030#define FF_SPEED (2.0f)
31#define FB_SPEED (-1.0f)
32#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080033#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080034
35#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))
36#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
37
Wentao MA907b6432022-08-01 06:23:08 +000038#define DVR_PLAYER_CHANGE_STATE(player,newstate)\
39 DVR_PB_INFO("%s:%d player %p changes state from %s to %s",__func__,__LINE__,\
40 player,_dvr_playback_state_toString(player->state),_dvr_playback_state_toString(newstate));\
41 player->state=newstate;
42
Wentao MAfae6ce82023-12-29 17:55:55 +080043//#define FOR_OTT_49490
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);
Wentao MA6dcdc342023-01-30 17:03:19 +080056static int _do_handle_pid_update(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);
Wentao MA804bab12022-11-29 10:01:26 +080066static int get_effective_tsplayer_delay_time(DVR_Playback_t* playback, int *time);
Wentao MA92a14892023-09-12 18:54:47 +080067static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id);
hualing chen87072a82020-03-12 16:20:12 +080068
hualing chenbcada022020-04-22 14:27:01 +080069
hualing chena5f03222021-12-02 11:22:35 +080070
hualing chenbcada022020-04-22 14:27:01 +080071static char* _cmd_toString(int cmd)
72{
73
74 char *string[DVR_PLAYBACK_CMD_NONE+1]={
75 "start",
76 "stop",
Wentao MA270dc0f2022-08-23 13:17:26 +080077 "v_start",
78 "a_start",
79 "v_stop",
80 "a_stop",
81 "v_restart",
82 "a_restart",
83 "av_restart",
84 "v_stop_a_start",
85 "a_stop_v_start",
86 "v_stop_a_restart",
87 "a_stop_v_restart",
88 "v_start_a_restart",
89 "a_start_v_restart",
hualing chenbcada022020-04-22 14:27:01 +080090 "pause",
91 "resume",
92 "seek",
93 "ff",
94 "fb",
95 "NONE"
96 };
97
98 if (cmd > DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +080099 return "unknown";
hualing chenbcada022020-04-22 14:27:01 +0800100 } else {
101 return string[cmd];
102 }
103}
104
105
Wentao MA907b6432022-08-01 06:23:08 +0000106static char* _dvr_playback_state_toString(int state)
hualing chen6d24aa92020-03-23 18:43:47 +0800107{
Wentao MA907b6432022-08-01 06:23:08 +0000108 char *strings[5]={
109 "START",
110 "STOP",
111 "PAUSE",
112 "FF",
113 "FB",
hualing chen6d24aa92020-03-23 18:43:47 +0800114 };
115
Wentao MA907b6432022-08-01 06:23:08 +0000116 if (state >= 5 || state < 0) {
117 return "UNKNOWN";
hualing chen6d24aa92020-03-23 18:43:47 +0800118 }
Wentao MA907b6432022-08-01 06:23:08 +0000119 return strings[state];
hualing chen6d24aa92020-03-23 18:43:47 +0800120}
hualing chena540a7e2020-03-27 16:44:05 +0800121
122static DVR_Bool_t _dvr_support_speed(int speed) {
123
124 DVR_Bool_t ret = DVR_FALSE;
125
126 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800127 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800128 case PLAYBACK_SPEED_FBX2:
129 case PLAYBACK_SPEED_FBX4:
130 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800131 case PLAYBACK_SPEED_FBX16:
132 case PLAYBACK_SPEED_FBX12:
133 case PLAYBACK_SPEED_FBX32:
134 case PLAYBACK_SPEED_FBX48:
135 case PLAYBACK_SPEED_FBX64:
136 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800137 case PLAYBACK_SPEED_S2:
138 case PLAYBACK_SPEED_S4:
139 case PLAYBACK_SPEED_S8:
140 case PLAYBACK_SPEED_X1:
141 case PLAYBACK_SPEED_X2:
142 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800143 case PLAYBACK_SPEED_X3:
144 case PLAYBACK_SPEED_X5:
145 case PLAYBACK_SPEED_X6:
146 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800147 case PLAYBACK_SPEED_X8:
148 case PLAYBACK_SPEED_X12:
149 case PLAYBACK_SPEED_X16:
150 case PLAYBACK_SPEED_X32:
151 case PLAYBACK_SPEED_X48:
152 case PLAYBACK_SPEED_X64:
153 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800154 ret = DVR_TRUE;
155 break;
156 default:
Wentao MA96f68962022-06-15 19:45:35 +0800157 DVR_PB_INFO("not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800158 break;
159 }
160 return ret;
161}
Wentao MA907b6432022-08-01 06:23:08 +0000162
Zhiqiang Hand5c1c042024-09-14 14:32:28 +0800163//get sys time sec
164static uint32_t _dvr_getClock_sec(void)
165{
166 struct timespec ts;
167 uint32_t s;
168 clock_gettime(CLOCK_REALTIME, &ts);
169 s = (uint32_t)(ts.tv_sec);
170 DVR_PB_INFO("n:%u", s);
171 return s;
172}
173
174//get sys time ms
175static uint32_t _dvr_time_getClock(void)
176{
177 struct timespec ts;
178 uint32_t ms;
179 clock_gettime(CLOCK_MONOTONIC, &ts);
180 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
181 return ms;
182}
183
184static void calc_speed_control(DVR_Playback_t *player, int32_t play_cur)
185{
186 if (player->con_spe.ply_sta == 0) {
187 DVR_PB_INFO("player dur[%d] sta[%d] cur[%d] -----reinit",
188 player->con_spe.ply_dur,
189 player->con_spe.ply_sta,
190 play_cur);
191 player->con_spe.ply_sta = play_cur;
192 } else if (player->speed == 1.0f && player->con_spe.ply_sta < play_cur) {
193 player->con_spe.ply_dur += (play_cur - player->con_spe.ply_sta);
194 DVR_PB_INFO("player dur[%d] sta[%d] cur[%d]",
195 player->con_spe.ply_dur,
196 player->con_spe.ply_sta,
197 play_cur);
198 player->con_spe.ply_sta = play_cur;
199 }
200
201 if (player->con_spe.sys_sta == 0) {
202 player->con_spe.sys_sta = _dvr_time_getClock();
203 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
204 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
205 player->con_spe.sys_sta = _dvr_time_getClock();
206 }
207}
208
209
hualing chen6e4bfa52020-03-13 14:37:11 +0800210void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
211{
Wentao MA96f68962022-06-15 19:45:35 +0800212 DVR_PB_INFO("in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800213 DVR_Playback_t *player = NULL;
214 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800215 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800216 DVR_PB_INFO("play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800217 }
218 switch (event->type) {
219 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
220 {
Wentao MA96f68962022-06-15 19:45:35 +0800221 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800222 event->event.video_format.frame_width,
223 event->event.video_format.frame_height,
224 event->event.video_format.frame_rate);
225 break;
226 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800227 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
228 {
Wentao MA16f870e2022-09-09 11:00:22 +0800229 if (player == NULL) {
230 DVR_PB_WARN("player is null at line %d",__LINE__);
231 break;
232 }
Wentao MA96f68962022-06-15 19:45:35 +0800233 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800234 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800235 break;
236 }
237 default:
238 break;
239 }
240}
Wentao MA804bab12022-11-29 10:01:26 +0800241
hualing chen2aba4022020-03-02 13:49:55 +0800242void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
243{
Wentao MA804bab12022-11-29 10:01:26 +0800244 DVR_Playback_t *play = (DVR_Playback_t*)user_data;
245 if (play == NULL) {
246 DVR_PB_WARN("play is invalid in %s",__func__);
247 return;
hualing chen6e4bfa52020-03-13 14:37:11 +0800248 }
hualing chen2aba4022020-03-02 13:49:55 +0800249 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800250 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
Wentao MA804bab12022-11-29 10:01:26 +0800251 DVR_PB_INFO("Received AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME");
252 if (play->first_trans_ok == DVR_FALSE) {
253 play->first_trans_ok = DVR_TRUE;
254 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)play, DVR_FALSE);
255 }
256 play->first_frame = 1;
257 play->seek_pause = DVR_FALSE;
258 break;
hualing chen487ae6d2020-07-22 10:34:11 +0800259 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
Wentao MA804bab12022-11-29 10:01:26 +0800260 DVR_PB_INFO("Received AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO");
261 if (play->first_trans_ok == DVR_FALSE && play->has_video == DVR_FALSE) {
262 play->first_trans_ok = DVR_TRUE;
263 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)play, DVR_FALSE);
264 }
265 if (play->has_video == DVR_FALSE) {
266 play->first_frame = 1;
267 play->seek_pause = DVR_FALSE;
268 }
hualing chen487ae6d2020-07-22 10:34:11 +0800269 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800270 default:
271 break;
272 }
Wentao MA804bab12022-11-29 10:01:26 +0800273 if (play->player_callback_func == NULL) {
274 DVR_PB_WARN("play callback function %p is invalid",play->player_callback_func);
275 return;
hualing chen2aba4022020-03-02 13:49:55 +0800276 }
Wentao MA804bab12022-11-29 10:01:26 +0800277 play->player_callback_func(play->player_callback_userdata, event);
hualing chen2aba4022020-03-02 13:49:55 +0800278}
hualing chencc91e1c2020-02-28 13:26:17 +0800279
hualing chen5cbe1a62020-02-10 16:36:36 +0800280//convert video and audio fmt
281static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
282 int format = 0;
283 if (is_audio == DVR_FALSE) {
284 //for video fmt
285 switch (fmt)
286 {
287 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800288 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800289 break;
290 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800291 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800292 break;
293 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800294 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800295 break;
296 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800297 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800298 break;
hualing chena540a7e2020-03-27 16:44:05 +0800299 case DVR_VIDEO_FORMAT_VP9:
300 format = AV_VIDEO_CODEC_VP9;
301 break;
Zhiqiang Han95255412024-04-23 17:36:19 +0800302 case DVR_VIDEO_FORMAT_DVES_AVC:
303 format = AV_VIDEO_CODEC_DVES_AVC;
304 break;
305 case DVR_VIDEO_FORMAT_DVES_HEVC:
306 format = AV_VIDEO_CODEC_DVES_HEVC;
307 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800308 }
309 } else {
310 //for audio fmt
311 switch (fmt)
312 {
313 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800314 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800315 break;
316 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800317 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800318 break;
319 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800320 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800321 break;
322 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800323 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800324 break;
hualing chena540a7e2020-03-27 16:44:05 +0800325 case DVR_AUDIO_FORMAT_AAC:
326 format = AV_AUDIO_CODEC_AAC;
327 break;
328 case DVR_AUDIO_FORMAT_LATM:
329 format = AV_AUDIO_CODEC_LATM;
330 break;
331 case DVR_AUDIO_FORMAT_PCM:
332 format = AV_AUDIO_CODEC_PCM;
333 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800334 case DVR_AUDIO_FORMAT_AC4:
335 format = AV_AUDIO_CODEC_AC4;
336 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800337 }
338 }
339 return format;
340}
hualing chen040df222020-01-17 13:35:02 +0800341static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800342{
hualing chen040df222020-01-17 13:35:02 +0800343 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800344
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800345 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800346 return -1;
347
hualing chena540a7e2020-03-27 16:44:05 +0800348 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800349}
hualing chena540a7e2020-03-27 16:44:05 +0800350
hualing chen7ea70a72021-09-09 11:25:13 +0800351
Wentao MA270dc0f2022-08-23 13:17:26 +0800352//timeout wait signal
hualing chen040df222020-01-17 13:35:02 +0800353static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800354{
hualing chen040df222020-01-17 13:35:02 +0800355 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800356
hualing chena540a7e2020-03-27 16:44:05 +0800357 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800358 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800359 return DVR_FAILURE;
360 }
361
hualing chen86e7d482020-01-16 15:13:33 +0800362 struct timespec ts;
363 clock_gettime(CLOCK_MONOTONIC, &ts);
hualing chen86e7d482020-01-16 15:13:33 +0800364 ts.tv_sec += ms/1000;
wentao.ma54e6aa32023-12-13 18:07:04 +0800365 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000);
hualing chen86e7d482020-01-16 15:13:33 +0800366 ts.tv_sec += us / 1000000;
367 us = us % 1000000;
wentao.ma54e6aa32023-12-13 18:07:04 +0800368 ts.tv_nsec = us * 1000;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800369
370 int val = dvr_mutex_save(&player->lock);
371 pthread_cond_timedwait(&player->cond, &player->lock.lock, &ts);
372 dvr_mutex_restore(&player->lock, val);
hualing chen86e7d482020-01-16 15:13:33 +0800373 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800374}
Wentao MA804bab12022-11-29 10:01:26 +0800375
hualing chenb31a6c62020-01-13 17:27:00 +0800376//send signal
hualing chen040df222020-01-17 13:35:02 +0800377static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800378{
hualing chen87072a82020-03-12 16:20:12 +0800379 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800380
381 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800382 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800383 return DVR_FAILURE;
384 }
Wentao MA96f68962022-06-15 19:45:35 +0800385 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800386 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800387 pthread_cond_signal(&player->cond);
Wentao MA96f68962022-06-15 19:45:35 +0800388 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800389 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800390 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800391}
392
hualing chen2932d372020-04-29 13:44:00 +0800393//send playback event, need check is need lock first
394static 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 +0800395
396 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800397
398 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800399 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800400 return DVR_FAILURE;
401 }
402
hualing chencc91e1c2020-02-28 13:26:17 +0800403 switch (evt) {
404 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800405 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800406 break;
407 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
408 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800409 DVR_PB_INFO("trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800410 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800411 break;
412 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
413 break;
414 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
415 break;
416 case DVR_PLAYBACK_EVENT_NO_KEY:
417 break;
418 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800419 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800420 DVR_PB_INFO("reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800421 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800422 break;
423 case DVR_PLAYBACK_EVENT_REACHED_END:
424 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800425 DVR_PB_INFO("reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800426 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800427 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800428 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800429 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800430 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800431 default:
432 break;
433 }
434 if (player->openParams.event_fn != NULL)
435 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800436 return DVR_SUCCESS;
437}
hualing chen2932d372020-04-29 13:44:00 +0800438static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800439{
440 DVR_Play_Notify_t notify;
441 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
442 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
443 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800444 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800445 return DVR_SUCCESS;
446}
447
hualing chen2932d372020-04-29 13:44:00 +0800448static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800449{
450 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800451
Wentao MA16f870e2022-09-09 11:00:22 +0800452 if (player == NULL) {
453 DVR_PB_ERROR("player is NULL");
454 return DVR_FAILURE;
455 }
hualing chene3797f02021-01-13 14:53:28 +0800456 if (player->openParams.is_notify_time == DVR_FALSE) {
shenghui.gengbec6a462023-01-12 15:21:02 +0800457 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800458 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800459 }
hualing chena540a7e2020-03-27 16:44:05 +0800460
hualing chen03fd4942021-07-15 15:56:41 +0800461 if (player->send_time == 0) {
shenghui.gengbec6a462023-01-12 15:21:02 +0800462 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800463 player->send_time = _dvr_time_getClock() + 500;
464 else
465 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800466 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen56c0a162022-01-27 17:01:50 +0800467 if ((player->send_time - _dvr_time_getClock()) > 1000) {
468 player->send_time = _dvr_time_getClock() + 500;
Wentao MA96f68962022-06-15 19:45:35 +0800469 DVR_PB_INFO("player send time occur system time changed!!!!!");
hualing chen56c0a162022-01-27 17:01:50 +0800470 } else {
471 return DVR_SUCCESS;
472 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800473 }
shenghui.gengbec6a462023-01-12 15:21:02 +0800474 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800475 player->send_time = _dvr_time_getClock() + 500;
476 else
477 player->send_time = _dvr_time_getClock() + 20;
478
hualing chen6e4bfa52020-03-13 14:37:11 +0800479 DVR_Play_Notify_t notify;
480 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
481 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
482 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800483 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800484 return DVR_SUCCESS;
485}
486
hualing chen4b7c15d2020-04-07 16:13:48 +0800487static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
488 DVR_Playback_t *player = (DVR_Playback_t *) handle;
489 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800490 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800491 player->fffb_current = player->fffb_start;
492 //get segment current time pos
493 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800494 player->next_fffb_time = _dvr_time_getClock();
495
496 return DVR_SUCCESS;
497}
498
hualing chen2aba4022020-03-02 13:49:55 +0800499static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
500 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800501 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800502 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800503 player->fffb_current = player->fffb_start;
504 //get segment current time pos
505 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800506
hualing chen2aba4022020-03-02 13:49:55 +0800507 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800508 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800509 return DVR_SUCCESS;
510}
hualing chencc91e1c2020-02-28 13:26:17 +0800511//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800512static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
513
514 DVR_Playback_t *player = (DVR_Playback_t *) handle;
515 DVR_PlaybackSegmentInfo_t *segment;
516 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
517
hualing chena540a7e2020-03-27 16:44:05 +0800518 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800519 DVR_PB_INFO(" player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800520 return DVR_FAILURE;
521 }
522
hualing chen87072a82020-03-12 16:20:12 +0800523 int found = 0;
524 int found_eq_id = 0;
wentao.mafd5283f2022-10-14 09:51:13 +0800525 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800526 // prefetch() here incurring self_assign is used to avoid some compiling
527 // warnings.
528 // coverity[self_assign]
hualing chen87072a82020-03-12 16:20:12 +0800529 list_for_each_entry(segment, &player->segment_list, head)
530 {
531 if (player->segment_is_open == DVR_FALSE) {
532 //get first segment from list, case segment is not open
533 if (!IS_FB(player->speed))
534 found = 1;
535 } else if (segment->segment_id == segmentid) {
536 //find cur segment, we need get next one
537 found_eq_id = 1;
538 if (!IS_FB(player->speed)) {
539 found = 1;
540 continue;
541 } else {
542 //if is fb mode.we need used pre segment
543 if (pre_segment != NULL) {
544 found = 1;
545 } else {
546 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800547 DVR_PB_INFO("not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800548 return DVR_FAILURE;
549 }
550 }
551 }
552 if (found == 1) {
553 found = 2;
554 break;
555 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800556 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800557 }
558 if (found != 2) {
559 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800560 DVR_PB_INFO("not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800561 return DVR_FAILURE;
562 }
Wentao MA96f68962022-06-15 19:45:35 +0800563 DVR_PB_INFO("found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800564 return DVR_SUCCESS;
565}
566
567//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800568static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800569
hualing chen040df222020-01-17 13:35:02 +0800570 DVR_Playback_t *player = (DVR_Playback_t *) handle;
571 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800572 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800573 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800574 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800575 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800576 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800577 return DVR_FAILURE;
578 }
579
hualing chen03fd4942021-07-15 15:56:41 +0800580 if (IS_FB(player->speed)
581 && dvr_playback_check_limit(handle)) {
582 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
583 //case cur id < segment id
584 if (player->cur_segment_id <= segmentid) {
585 //expired ts data is player,return error
Wentao MA96f68962022-06-15 19:45:35 +0800586 DVR_PB_INFO("reach start segment ,return error");
hualing chen03fd4942021-07-15 15:56:41 +0800587 return DVR_FAILURE;
588 }
Wentao MA96f68962022-06-15 19:45:35 +0800589 DVR_PB_INFO("has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800590 }
591
hualing chen86e7d482020-01-16 15:13:33 +0800592 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800593 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800594
wentao.mafd5283f2022-10-14 09:51:13 +0800595 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800596 // prefetch() here incurring self_assign is used to avoid some compiling
597 // warnings.
598 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +0800599 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800600 {
hualing chencc91e1c2020-02-28 13:26:17 +0800601 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800602 //get first segment from list, case segment is not open
603 if (!IS_FB(player->speed))
604 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800605 } else if (segment->segment_id == player->cur_segment_id) {
606 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800607 found_eq_id = 1;
608 if (!IS_FB(player->speed)) {
609 found = 1;
610 continue;
611 } else {
612 //if is fb mode.we need used pre segment
613 if (pre_segment != NULL) {
614 found = 1;
615 } else {
616 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800617 DVR_PB_INFO("not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800618 return DVR_FAILURE;
619 }
620 }
hualing chen86e7d482020-01-16 15:13:33 +0800621 }
622 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800623 if (IS_FB(player->speed)) {
624 //used pre segment
625 segment = pre_segment;
626 }
hualing chencc91e1c2020-02-28 13:26:17 +0800627 //save segment info
628 player->last_segment_id = player->cur_segment_id;
Wentao MAf35c3882023-04-17 12:36:19 +0800629 if (player->segment_handle) {
630 player->last_segment_total = segment_tell_total_time(player->segment_handle);
631 }
hualing chen87072a82020-03-12 16:20:12 +0800632 player->last_segment.segment_id = player->cur_segment.segment_id;
633 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800634 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
635 //pids
636 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
637
hualing chen5cbe1a62020-02-10 16:36:36 +0800638 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800639 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800640 player->cur_segment_id = segment->segment_id;
641 player->cur_segment.segment_id = segment->segment_id;
642 player->cur_segment.flags = segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800643 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 +0800644 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800645 //pids
hualing chen040df222020-01-17 13:35:02 +0800646 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800647 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800648 break;
hualing chen86e7d482020-01-16 15:13:33 +0800649 }
hualing chen2aba4022020-03-02 13:49:55 +0800650 pre_segment = segment;
651 }
652 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
653 //used the last one segment to open
654 //get segment info
655 player->segment_is_open = DVR_TRUE;
656 player->cur_segment_id = pre_segment->segment_id;
657 player->cur_segment.segment_id = pre_segment->segment_id;
658 player->cur_segment.flags = pre_segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800659 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 +0800660 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
661 //pids
662 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
663 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800664 }
665 if (found != 2) {
666 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800667 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800668 }
669 return DVR_SUCCESS;
670}
hualing chen040df222020-01-17 13:35:02 +0800671//open next segment to play,if reach list end return errro.
672static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800673{
hualing chen040df222020-01-17 13:35:02 +0800674 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800675 Segment_OpenParams_t params;
676 int ret = DVR_SUCCESS;
677
hualing chena540a7e2020-03-27 16:44:05 +0800678 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800679 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800680 return DVR_FAILURE;
681 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800682 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800683retry:
hualing chena540a7e2020-03-27 16:44:05 +0800684 ret = _dvr_get_next_segmentId(handle);
685 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800686 DVR_PB_INFO("not found segment info");
hualing chen4b7c15d2020-04-07 16:13:48 +0800687 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800688 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800689 }
690
Wentao MAf35c3882023-04-17 12:36:19 +0800691 if (player->segment_handle != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800692 DVR_PB_INFO("close segment");
Wentao MAf35c3882023-04-17 12:36:19 +0800693 segment_close(player->segment_handle);
694 player->segment_handle = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800695 }
696
Wentao MA4d85ff32022-09-23 11:36:18 +0800697 memset((void*)&params,0,sizeof(params));
Wentao MA270dc0f2022-08-23 13:17:26 +0800698 //cp current segment path to location
hualing chen5cbe1a62020-02-10 16:36:36 +0800699 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800700 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800701 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800702 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 +0800703
Wentao MAf35c3882023-04-17 12:36:19 +0800704 ret = segment_open(&params, &(player->segment_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800705 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800706 DVR_PB_INFO("open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800707 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800708 }
Wentao MA01de0e62022-01-10 18:48:23 +0800709 // Keep the start segment_id when the first segment_open is called during a playback
710 if (player->first_start_id == UINT64_MAX) {
711 player->first_start_id = player->cur_segment.segment_id;
712 }
hualing chen87072a82020-03-12 16:20:12 +0800713 pthread_mutex_unlock(&player->segment_lock);
714 int total = _dvr_get_end_time( handle);
715 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800716 if (IS_FB(player->speed)) {
717 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800718 player->ts_cache_len = 0;
Wentao MAf35c3882023-04-17 12:36:19 +0800719 segment_seek(player->segment_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +0800720 DVR_PB_INFO("seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800721 }
hualing chen87072a82020-03-12 16:20:12 +0800722 player->dur = total;
wentao.mafdba9a02023-01-17 16:43:26 +0800723 player->con_spe.ply_dur = 0;
724 player->con_spe.ply_sta = 0;
725 player->con_spe.sys_dur = 0;
726 player->con_spe.sys_sta = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800727 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +0800728 DVR_PB_INFO("next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800729 return ret;
730}
731
hualing chen5cbe1a62020-02-10 16:36:36 +0800732//open next segment to play,if reach list end return errro.
733static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
734{
735 DVR_Playback_t *player = (DVR_Playback_t *) handle;
736 Segment_OpenParams_t params;
737 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800738 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800739 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800740 return DVR_FAILURE;
741 }
hualing chencc91e1c2020-02-28 13:26:17 +0800742 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800743 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800744 }
hualing chencc91e1c2020-02-28 13:26:17 +0800745 uint64_t id = segment_id;
Wentao MA07d3d742022-09-06 09:58:05 +0800746 DVR_PB_INFO("start finding segment[%lld] info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800747 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800748
749 DVR_PlaybackSegmentInfo_t *segment;
750
751 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800752
wentao.mafd5283f2022-10-14 09:51:13 +0800753 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800754 // prefetch() here incurring self_assign is used to avoid some compiling
755 // warnings.
756 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800757 list_for_each_entry(segment, &player->segment_list, head)
758 {
Wentao MA96f68962022-06-15 19:45:35 +0800759 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 +0800760 if (segment->segment_id == segment_id) {
761 found = 1;
762 }
763 if (found == 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800764 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 +0800765 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800766 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800767 player->cur_segment_id = segment->segment_id;
768 player->cur_segment.segment_id = segment->segment_id;
769 player->cur_segment.flags = segment->flags;
Wentao MAe88ad702022-09-02 10:35:00 +0800770 const int len = strlen(segment->location);
771 if (len >= DVR_MAX_LOCATION_SIZE || len <= 0) {
772 DVR_PB_ERROR("Invalid segment.location length %d",len);
773 pthread_mutex_unlock(&player->segment_lock);
774 return DVR_FAILURE;
775 }
776 strncpy(player->cur_segment.location, segment->location, len+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800777 //pids
778 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +0800779 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 +0800780 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800781 }
782 }
hualing chencc91e1c2020-02-28 13:26:17 +0800783 if (found == 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800784 DVR_PB_INFO("not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800785 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800786 return DVR_FAILURE;
787 }
Wentao MA4d85ff32022-09-23 11:36:18 +0800788 memset((void*)&params,0,sizeof(params));
Wentao MAe88ad702022-09-02 10:35:00 +0800789
790 const int len2 = strlen(player->cur_segment.location);
791 if (len2 >= DVR_MAX_LOCATION_SIZE || len2 <= 0) {
792 DVR_PB_ERROR("Invalid cur_segment.location length %d",len2);
793 pthread_mutex_unlock(&player->segment_lock);
794 return DVR_FAILURE;
795 }
796 strncpy(params.location, player->cur_segment.location, len2+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800797 params.segment_id = (uint64_t)player->cur_segment.segment_id;
798 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800799 DVR_PB_INFO("open segment location[%s][%lld]cur flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
Wentao MAf35c3882023-04-17 12:36:19 +0800800 if (player->segment_handle != NULL) {
801 segment_close(player->segment_handle);
802 player->segment_handle = NULL;
hualing chen2aba4022020-03-02 13:49:55 +0800803 }
Wentao MAf35c3882023-04-17 12:36:19 +0800804 ret = segment_open(&params, &(player->segment_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800805 if (ret == DVR_FAILURE) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800806 DVR_PB_INFO("segment open error");
hualing chen4b7c15d2020-04-07 16:13:48 +0800807 }
Wentao MA01de0e62022-01-10 18:48:23 +0800808 // Keep the start segment_id when the first segment_open is called during a playback
809 if (player->first_start_id == UINT64_MAX) {
810 player->first_start_id = player->cur_segment.segment_id;
811 }
hualing chen2aba4022020-03-02 13:49:55 +0800812 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800813 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800814
Wentao MA96f68962022-06-15 19:45:35 +0800815 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 +0800816 return ret;
817}
818
819
820//get play info by segment id
821static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
822 uint64_t segment_id,
Wentao MA270dc0f2022-08-23 13:17:26 +0800823 am_tsplayer_video_params *video_param,
824 am_tsplayer_audio_params *audio_param, am_tsplayer_audio_params *ad_param) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800825
826 DVR_Playback_t *player = (DVR_Playback_t *) handle;
827 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800828 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800829 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800830 return DVR_FAILURE;
831 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800832
833 int found = 0;
834
wentao.mafd5283f2022-10-14 09:51:13 +0800835 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800836 // prefetch() here incurring self_assign is used to avoid some compiling
837 // warnings.
838 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800839 list_for_each_entry(segment, &player->segment_list, head)
840 {
hualing chen87072a82020-03-12 16:20:12 +0800841 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800842 //get first segment from list
843 found = 1;
844 }
845 if (segment->segment_id == segment_id) {
846 found = 1;
847 }
848 if (found == 1) {
849 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800850 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800851 player->cur_segment_id = segment->segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800852 player->cur_segment.segment_id = segment->segment_id;
853 player->cur_segment.flags = segment->flags;
854 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800855 player->cur_segment.pids.video.pid = segment->pids.video.pid;
856 player->cur_segment.pids.video.format = segment->pids.video.format;
857 player->cur_segment.pids.video.type = segment->pids.video.type;
858 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
859 player->cur_segment.pids.audio.format = segment->pids.audio.format;
860 player->cur_segment.pids.audio.type = segment->pids.audio.type;
861 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
862 player->cur_segment.pids.ad.format = segment->pids.ad.format;
863 player->cur_segment.pids.ad.type = segment->pids.ad.type;
864 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800865 //
Wentao MA270dc0f2022-08-23 13:17:26 +0800866 video_param->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
867 video_param->pid = segment->pids.video.pid;
868 audio_param->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
869 audio_param->pid = segment->pids.audio.pid;
870 ad_param->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
871 ad_param->pid =segment->pids.ad.pid;
Wentao MA804bab12022-11-29 10:01:26 +0800872 DVR_PB_DEBUG("get_playinfo, segment_id:%lld, vpid[0x%x], apid[0x%x], vfmt[%d], afmt[%d]",
873 player->cur_segment_id, video_param->pid, audio_param->pid,
874 video_param->codectype, audio_param->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800875 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800876 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800877 }
878 }
hualing chencc91e1c2020-02-28 13:26:17 +0800879 if (found != 2) {
880 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800881 DVR_PB_INFO("get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800882 return DVR_FAILURE;
883 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800884
885 return DVR_SUCCESS;
886}
hualing chencc91e1c2020-02-28 13:26:17 +0800887static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
888 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800889 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800890 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800891 return DVR_FAILURE;
892 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800893
hualing chencc91e1c2020-02-28 13:26:17 +0800894 //compare cur segment
895 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
896 {
897 //check video pids, stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800898 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800899 //check sub audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800900 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800901 //check audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800902 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 1);
Wentao MA96f68962022-06-15 19:45:35 +0800903 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 +0800904 //check pcr pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800905 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800906 }
hualing chena540a7e2020-03-27 16:44:05 +0800907 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800908}
hualing chen5cbe1a62020-02-10 16:36:36 +0800909
hualing chend241c7a2021-06-22 13:34:27 +0800910static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
911{
912 DVR_Playback_t *player = (DVR_Playback_t *) handle;
913 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800914 DVR_PB_INFO("player is NULL");
hualing chend241c7a2021-06-22 13:34:27 +0800915 return DVR_TRUE;
916 }
hualing chend241c7a2021-06-22 13:34:27 +0800917
wentao.mafdba9a02023-01-17 16:43:26 +0800918 DVR_PB_INFO(":play speed: %f ply dur: %d sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800919 player->speed,
920 player->con_spe.ply_dur,
921 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800922
923 if (player->speed != 1.0f)
924 return DVR_TRUE;
925
926 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800927 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800928 return DVR_FALSE;
929
930 return DVR_TRUE;
931}
932
hualing chencc91e1c2020-02-28 13:26:17 +0800933static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
934{
935 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800936 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800937 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800938 return DVR_FAILURE;
939 }
Wentao MA292380e2022-12-14 14:46:19 +0800940 if (player->vendor != DVR_PLAYBACK_VENDOR_DEF) {
941 DVR_PB_INFO("In case of vendor Amlogic/Amazon, do not control AV display");
hualing chenf43b8ba2020-07-28 13:11:42 +0800942 return DVR_SUCCESS;
943 }
Wentao MA96f68962022-06-15 19:45:35 +0800944 DVR_PB_INFO("flag[0x%x]id[%lld]last[0x%x][%llu]",
hualing chen03fd4942021-07-15 15:56:41 +0800945 player->cur_segment.flags,
946 player->cur_segment.segment_id,
947 player->last_segment.flags,
948 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800949 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
950 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800951 //enable display
Wentao MA96f68962022-06-15 19:45:35 +0800952 DVR_PB_INFO("unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800953 AmTsPlayer_showVideo(player->handle);
954 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800955 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
956 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800957 //disable display
Wentao MA96f68962022-06-15 19:45:35 +0800958 DVR_PB_INFO("mute");
hualing chen2aba4022020-03-02 13:49:55 +0800959 AmTsPlayer_hideVideo(player->handle);
960 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800961 }
962 return DVR_SUCCESS;
963}
hualing chene3797f02021-01-13 14:53:28 +0800964/*
Wentao MA270dc0f2022-08-23 13:17:26 +0800965if decode success first time.
966success: return true
hualing chene3797f02021-01-13 14:53:28 +0800967fail: return false
968*/
Wentao MA270dc0f2022-08-23 13:17:26 +0800969static DVR_Bool_t _dvr_pauselive_decode_success(DVR_PlaybackHandle_t handle) {
hualing chena540a7e2020-03-27 16:44:05 +0800970 DVR_Playback_t *player = (DVR_Playback_t *) handle;
971 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800972 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800973 return DVR_TRUE;
974 }
hualing chene3797f02021-01-13 14:53:28 +0800975 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800976 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800977 } else {
978 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800979 }
980}
hualing chen86e7d482020-01-16 15:13:33 +0800981static void* _dvr_playback_thread(void *arg)
982{
hualing chen040df222020-01-17 13:35:02 +0800983 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800984 //int need_open_segment = 1;
Wentao MA270dc0f2022-08-23 13:17:26 +0800985 am_tsplayer_input_buffer input_buffer;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800986 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800987 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800988
hualing chen39628212020-05-14 10:35:13 +0800989 #define MAX_REACHEND_TIMEOUT (3000)
990 int reach_end_timeout = 0;//ms
991 int cache_time = 0;
hualing chen40dd5462021-11-26 19:56:20 +0800992 int check_no_data_time = 4;
hualing chen040df222020-01-17 13:35:02 +0800993 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800994 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +0800995 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800996 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800997 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800998 DVR_Bool_t goto_rewrite = DVR_FALSE;
wentao ma7d642782022-10-23 18:26:16 -0700999 int read = 0;
yinming ding0ce94922021-09-08 15:09:15 +08001000
Wentao MA361eaac2023-03-21 13:12:28 +08001001 prctl(PR_SET_NAME,"DvrPlayback");
1002
wentao ma7d642782022-10-23 18:26:16 -07001003 const uint64_t write_timeout_ms = (uint64_t)dvr_prop_read_int("vendor.tv.libdvr.writetm",50);
1004 const int timeout = dvr_prop_read_int("vendor.tv.libdvr.waittm",200);
hualing chen56c0a162022-01-27 17:01:50 +08001005
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001006 if (player->is_secure_mode) {
1007 if (dec_buf_size > player->secure_buffer_size) {
Wentao MA96f68962022-06-15 19:45:35 +08001008 DVR_PB_INFO("playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001009 return NULL;
1010 }
1011 }
wentao.maa210e5e2022-10-12 16:10:03 +08001012
1013 uint8_t *buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001014 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +08001015 DVR_PB_INFO("Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001016 return NULL;
1017 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001018 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1019 input_buffer.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001020
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001021 dec_bufs.buf_data = malloc(dec_buf_size);
1022 if (!dec_bufs.buf_data) {
Wentao MA96f68962022-06-15 19:45:35 +08001023 DVR_PB_INFO("Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +08001024 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001025 return NULL;
1026 }
1027 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1028 dec_bufs.buf_size = dec_buf_size;
1029
hualing chencc91e1c2020-02-28 13:26:17 +08001030 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001031 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1032 }
hualing chen86e7d482020-01-16 15:13:33 +08001033
hualing chen86e7d482020-01-16 15:13:33 +08001034 if (ret != DVR_SUCCESS) {
1035 if (buf != NULL) {
1036 free(buf);
hualing chen86e7d482020-01-16 15:13:33 +08001037 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001038 free(dec_bufs.buf_data);
Wentao MA96f68962022-06-15 19:45:35 +08001039 DVR_PB_INFO("get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001040 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001041 }
Wentao MA96f68962022-06-15 19:45:35 +08001042 DVR_PB_INFO("--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001043 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001044 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1045 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1046 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1047 player->first_trans_ok = DVR_TRUE;
1048 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1049 }
hualing chencc91e1c2020-02-28 13:26:17 +08001050 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001051 //set video show
1052 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001053 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1054 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001055 int trick_stat = 0;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001056
1057 player->control_speed_enable = player->fake_mode;
1058 if (player->control_speed_enable == 1
1059 && player->control_speed_enable != player->control_speed_enable_last) {
1060 player->control_speed_enable_last = player->control_speed_enable;
1061 player->con_spe.ply_dur = 0;
1062 player->con_spe.ply_sta = 0;
1063 player->con_spe.sys_dur = 0;
1064 player->con_spe.sys_sta = 0;
1065 }
1066 DVR_PB_INFO("sc: playback thread start with enable:%d", player->control_speed_enable);
1067
hualing chen86e7d482020-01-16 15:13:33 +08001068 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001069
hualing chen86e7d482020-01-16 15:13:33 +08001070 //check trick stat
Wentao MA96f68962022-06-15 19:45:35 +08001071 //DVR_PB_INFO("lock check_no_data_time:%d", check_no_data_time);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001072 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001073
Wentao MA907b6432022-08-01 06:23:08 +00001074 {
Wentao MA9a164002022-08-29 11:20:24 +08001075 static struct timespec _prev_ts={0,0};
Wentao MA907b6432022-08-01 06:23:08 +00001076 struct timespec _nowts,_diffts;
1077 clock_gettime(CLOCK_MONOTONIC, &_nowts);
Wentao MA9a164002022-08-29 11:20:24 +08001078 clock_timespec_subtract(&_nowts,&_prev_ts,&_diffts);
Wentao MA907b6432022-08-01 06:23:08 +00001079 if (_diffts.tv_sec>0) {
1080 char _logbuf[512]={0};
1081 char* _pbuf=_logbuf;
1082 int _nchar=0;
1083 DVR_PlaybackSegmentInfo_t* _segment;
wentao.mafd5283f2022-10-14 09:51:13 +08001084 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08001085 // prefetch() here incurring self_assign is used to avoid some compiling
1086 // warnings.
1087 // coverity[self_assign]
Wentao MA907b6432022-08-01 06:23:08 +00001088 list_for_each_entry(_segment, &player->segment_list, head) {
1089 if (player->cur_segment_id == _segment->segment_id) {
Wentao MAf35c3882023-04-17 12:36:19 +08001090 int seg_size = segment_get_cur_segment_size(player->segment_handle);
1091 int read_ptr = segment_tell_position(player->segment_handle);
Wentao MA907b6432022-08-01 06:23:08 +00001092 float progress = -1.0f;
Wentao MA9a164002022-08-29 11:20:24 +08001093 if (seg_size>0) {
1094 progress = (float)read_ptr*100/seg_size;
Wentao MA907b6432022-08-01 06:23:08 +00001095 }
Wentao MA4d85ff32022-09-23 11:36:18 +08001096 _nchar=sprintf(_pbuf,"%lld(%.1f%%), ",_segment->segment_id,progress);
Wentao MA907b6432022-08-01 06:23:08 +00001097 } else {
1098 _nchar=sprintf(_pbuf,"%lld, ",_segment->segment_id);
1099 }
1100 if (_nchar<0) {
1101 break;
1102 }
1103 _pbuf+=_nchar;
1104 if (_pbuf-_logbuf+10 >= sizeof(_logbuf)) {
1105 sprintf(_pbuf,"...");
1106 break;
1107 }
1108 }
Wentao MA9a164002022-08-29 11:20:24 +08001109 DVR_PB_INFO("clk: %08u, seg_list: %s",_nowts.tv_sec,_logbuf);
1110 _prev_ts=_nowts;
Wentao MA907b6432022-08-01 06:23:08 +00001111 }
1112 }
1113
Zhiqiang Hand5e2d752024-01-10 17:52:47 +08001114 #define __IS_SPEED() \
1115 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF \
1116 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB \
1117 || player->speed > FF_SPEED ||player->speed <= FB_SPEED)
1118
1119 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK
1120 || __IS_SPEED()
1121 || player->state == DVR_PLAYBACK_STATE_PAUSE
1122 || (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001123 {
hualing chen2aba4022020-03-02 13:49:55 +08001124 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
Zhiqiang Hand5e2d752024-01-10 17:52:47 +08001125 if (trick_stat > 0 || (__IS_SPEED() && _dvr_time_getClock() > player->next_fffb_time)) {
dongsheng.Li98c618a2023-12-13 04:02:32 +00001126 DVR_PB_INFO("trick stat[%d], cur cmd[%d]last cmd[%d]flag[0x%x], now[%u]>next_fffb_time[%u]",
1127 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag, _dvr_time_getClock(), player->next_fffb_time);
hualing chen87072a82020-03-12 16:20:12 +08001128 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 +08001129 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001130 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001131 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001132 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
Wentao MA270dc0f2022-08-23 13:17:26 +08001133 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_V_START
1134 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_A_START
hualing chen2aba4022020-03-02 13:49:55 +08001135 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
Wentao MA96f68962022-06-15 19:45:35 +08001136 DVR_PB_INFO("pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001137 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001138 //need change to pause state
1139 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1140 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00001141 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08001142 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001143 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001144 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001145 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
Wentao MA06313782024-05-13 13:48:41 +08001146 if (player->has_video == DVR_TRUE) {
1147 AmTsPlayer_pauseVideoDecoding(player->handle);
1148 }
hualing chen2aba4022020-03-02 13:49:55 +08001149 AmTsPlayer_pauseAudioDecoding(player->handle);
Wentao MA6dcdc342023-01-30 17:03:19 +08001150
1151 // Audio is unmuted here, for it was muted before receiving first frame event.
1152 if (player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
1153 AmTsPlayer_setAudioMute(player->handle,0,0);
1154 }
hualing chen2bd8a7a2020-04-02 11:31:03 +08001155 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001156 DVR_PB_INFO("clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001157 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001158 }
1159 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1160 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001161 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001162 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001163 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001164 DVR_PB_INFO("fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001165 player->speed,
1166 player->fffb_current,
1167 _dvr_time_getClock(),
1168 _dvr_playback_state_toString(player->state),
1169 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001170 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001171 //dvr_mutex_unlock(&player->lock);
1172 //dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001173 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001174 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001175 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001176 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001177 } else if (_dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001178 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 +08001179 player->speed,
1180 player->fffb_current,
1181 _dvr_time_getClock(),
1182 _dvr_playback_state_toString(player->state),
1183 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +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 chenb5cd42e2020-04-15 17:03:34 +08001187 AmTsPlayer_pauseVideoDecoding(player->handle);
1188 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001189 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001190 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001191 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001192 }
Wentao MA96f68962022-06-15 19:45:35 +08001193 DVR_PB_INFO("fffb play-------speed[%f][%d][%d][%s][%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001194 player->speed,
1195 goto_rewrite,
1196 real_read,
1197 _dvr_playback_state_toString(player->state),
1198 player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001199 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001200 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001201 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1202 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001203 DVR_PB_INFO("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001204 dvr_mutex_unlock(&player->lock);
1205
hualing chen2aba4022020-03-02 13:49:55 +08001206 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001207 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001208 dvr_mutex_lock(&player->lock);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001209 player->fffb_play = DVR_FALSE;
hualing chen1ffd85b2021-08-16 15:18:43 +08001210 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1211 //on pause state,user seek to new pos,we need pause and wait
1212 //user to resume
Wentao MA96f68962022-06-15 19:45:35 +08001213 DVR_PB_INFO("pause, when got first frame event when user seek end");
hualing chen1ffd85b2021-08-16 15:18:43 +08001214 player->first_frame = 0;
1215 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1216 AmTsPlayer_pauseVideoDecoding(player->handle);
1217 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001218 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001219 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001220 //for first into fffb when reset speed
1221 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1222 _dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001223 DVR_PB_INFO("fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001224 player->speed,
1225 player->fffb_current,
1226 _dvr_time_getClock(),
1227 _dvr_playback_state_toString(player->state),
1228 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001229 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001230 //dvr_mutex_unlock(&player->lock);
1231 //dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001232 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001233 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001234 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001235 continue;
1236 }
Wentao MA96f68962022-06-15 19:45:35 +08001237 DVR_PB_INFO("fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001238 player->speed,
1239 goto_rewrite,
1240 real_read,
1241 _dvr_playback_state_toString(player->state),
1242 player->cmd.cur_cmd,
1243 player->fffb_play);
Wentao MA96f68962022-06-15 19:45:35 +08001244 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001245 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001246 goto_rewrite = DVR_FALSE;
1247 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001248 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001249 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001250 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1251 player->first_frame = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001252 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001253 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001254 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001255 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001256 }
hualing chenb31a6c62020-01-13 17:27:00 +08001257 }
hualing chen86e7d482020-01-16 15:13:33 +08001258
hualing chen30423862021-04-16 14:39:12 +08001259 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1260 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001261 //check is need send time send end
Wentao MA96f68962022-06-15 19:45:35 +08001262 DVR_PB_INFO("pause, continue");
1263 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001264 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001265 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001266 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001267 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001268 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001269 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001270 continue;
1271 }
hualing chen266b9502020-04-04 17:39:39 +08001272 //when seek action is done. we need drop write timeout data.
1273 if (player->drop_ts == DVR_TRUE) {
1274 goto_rewrite = DVR_FALSE;
1275 real_read = 0;
1276 player->drop_ts = DVR_FALSE;
1277 }
hualing chen2aba4022020-03-02 13:49:55 +08001278 if (goto_rewrite == DVR_TRUE) {
1279 goto_rewrite = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001280 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001281 dvr_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001282 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Wentao MA96f68962022-06-15 19:45:35 +08001283 //DVR_PB_INFO("rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001284 goto rewrite;
1285 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001286 //.check is need send time send end
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001287 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001288 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001289 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001290 pthread_mutex_lock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001291 //DVR_PB_INFO("start read");
Wentao MAf35c3882023-04-17 12:36:19 +08001292 read = segment_read(player->segment_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001293 real_read = real_read + read;
1294 player->ts_cache_len = real_read;
Wentao MA96f68962022-06-15 19:45:35 +08001295 //DVR_PB_INFO("start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001296 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001297 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001298 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001299 if (read < 0 && errno == EIO) {
1300 //EIO ERROR, EXIT THRAD
Wentao MA96f68962022-06-15 19:45:35 +08001301 DVR_PB_INFO("read error.EIO error, exit thread");
hualing chenb5cd42e2020-04-15 17:03:34 +08001302 DVR_Play_Notify_t notify;
1303 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1304 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001305 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001306 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001307 goto end;
1308 } else if (read < 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001309 DVR_PB_INFO("read error.:%d EIO:%d", errno, EIO);
hualing chenb5cd42e2020-04-15 17:03:34 +08001310 }
hualing chen87072a82020-03-12 16:20:12 +08001311 //if on fb mode and read file end , we need calculate pos to retry read.
1312 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001313 DVR_PB_INFO("recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
hualing chen03fd4942021-07-15 15:56:41 +08001314 read,
1315 real_read,
1316 buf_len,
1317 player->speed,
1318 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001319 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001320 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001321 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001322 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001323 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001324 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001325 continue;
1326 }
Wentao MA96f68962022-06-15 19:45:35 +08001327 //DVR_PB_INFO("read ts [%d]buf_len[%d]speed[%f]real_read:%d", read, buf_len, player->speed, real_read);
wentao.ma54e6aa32023-12-13 18:07:04 +08001328 if (read == 0 && !IS_FB(player->speed)) {
hualing chen2aba4022020-03-02 13:49:55 +08001329 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001330 #define MIN_CACHE_TIME (3000)
Wentao MA804bab12022-11-29 10:01:26 +08001331 int delay = 0;
1332 get_effective_tsplayer_delay_time(player,&delay);
hualing chene3797f02021-01-13 14:53:28 +08001333 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
Wentao MA804bab12022-11-29 10:01:26 +08001334 if (delay > MIN_CACHE_TIME) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001335 //dvr_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001336 /*if cache time > 20s , we think get time is error,*/
Wentao MA804bab12022-11-29 10:01:26 +08001337 if (delay - MIN_CACHE_TIME > 20 * 1000) {
1338 DVR_PB_WARN("read end but cache time is %d > 20s, this is an error at media_hal", delay);
hualing chene3797f02021-01-13 14:53:28 +08001339 }
hualing chene41f4372020-06-06 16:29:17 +08001340 }
hualing chen969fe7b2021-05-26 15:13:17 +08001341
hualing chen040df222020-01-17 13:35:02 +08001342 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001343 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001344 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001345
Wentao MA804bab12022-11-29 10:01:26 +08001346 get_effective_tsplayer_delay_time(player,&delay);
hualing chen1679f812021-11-08 15:17:46 +08001347 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1348 player->noData++;
Wentao MA96f68962022-06-15 19:45:35 +08001349 DVR_PB_INFO("playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001350 if (player->noData == check_no_data_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001351 DVR_PB_INFO("playback send nodata event nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001352 //send event here and pause
1353 DVR_Play_Notify_t notify;
1354 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1355 notify.event = DVR_PLAYBACK_EVENT_NODATA;
Wentao MA96f68962022-06-15 19:45:35 +08001356 DVR_PB_INFO("send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001357 //get play statue not here
1358 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1359 }
1360 }
Wentao MAa0b9c002022-11-10 17:47:27 +08001361
1362 DVR_Bool_t cond1 = (ret != DVR_SUCCESS);
1363 DVR_Bool_t cond2 = (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON);
1364 DVR_Bool_t cond3 = (delay <= MIN_TSPLAYER_DELAY_TIME);
1365 DVR_Bool_t cond4 = (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF);
1366 DVR_Bool_t cond5 = (player->delay_is_effective == DVR_TRUE);
1367 DVR_Bool_t cond6 = (reach_end_timeout >= MAX_REACHEND_TIMEOUT);
1368 if ((cond1 && cond2 && (cond3 || cond4) && cond5) || cond6) {
1369 DVR_PB_INFO("REACHED_END conditions: cond1:%d, cond2:%d, (cond3:%d, cond4:%d),"
1370 " cond5:%d, cond6:%d. delay:%d, reach_end_timeout:%d",
1371 (int)cond1,(int)cond2,(int)cond3,(int)cond4,(int)cond5,(int)cond6,
1372 delay,reach_end_timeout);
Wentao MA804bab12022-11-29 10:01:26 +08001373 DVR_Play_Notify_t notify;
1374 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1375 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1376 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
1377 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
1378 dvr_mutex_lock(&player->lock);
1379 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1380 dvr_mutex_unlock(&player->lock);
1381 continue;
1382 } else if (ret != DVR_SUCCESS) {
1383 DVR_PB_INFO("delay:%d pauselive:%d", delay, _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player));
1384 dvr_mutex_lock(&player->lock);
1385 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1386 dvr_mutex_unlock(&player->lock);
1387
1388 get_effective_tsplayer_delay_time(player,&delay);
1389 //not send event and pause,sleep and go to next time to recheck
1390 if (delay < cache_time) {
1391 //delay time is changed and then has data to play, so not start timeout
1392 reach_end_timeout = 0;
1393 } else {
1394 reach_end_timeout = reach_end_timeout + timeout;
1395 }
1396 cache_time = delay;
1397 continue;
1398 }
hualing chen39628212020-05-14 10:35:13 +08001399 reach_end_timeout = 0;
1400 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001401 //change next segment success case
1402 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001403 dvr_mutex_lock(&player->lock);
hualing chen40dd5462021-11-26 19:56:20 +08001404 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001405 DVR_PB_INFO("_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001406 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1407 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001408 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08001409 read = segment_read(player->segment_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001410 real_read = real_read + read;
1411 player->ts_cache_len = real_read;
1412 pthread_mutex_unlock(&player->segment_lock);
1413
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001414 dvr_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001415 }//read len 0 check end
Wentao MA92a14892023-09-12 18:54:47 +08001416
Wentao MAfae6ce82023-12-29 17:55:55 +08001417#ifdef FOR_OTT_49490
Wentao MA92a14892023-09-12 18:54:47 +08001418 if (player->openParams.is_timeshift == DVR_TRUE && player->speed >= FF_SPEED)
1419 {
1420 DVR_PlaybackSegmentInfo_t *newest_segment
1421 = list_last_entry(&player->segment_list, DVR_PlaybackSegmentInfo_t, head);
1422 DVR_Bool_t cond1 = (player->cur_segment_id == newest_segment->segment_id);
1423 int32_t time_end = _dvr_get_end_time((DVR_PlaybackHandle_t)player);
1424 uint64_t cur_seg_id = 0;
1425 int32_t time_cur = _dvr_get_play_cur_time((DVR_PlaybackHandle_t)player, &cur_seg_id);
1426 DVR_Bool_t cond2 = (cur_seg_id == player->cur_segment_id && time_end - time_cur < 1000);
1427 if (cond1 && cond2)
1428 {
1429 DVR_PlaybackSpeed_t normal_speed = {PLAYBACK_SPEED_X1,0};
1430 DVR_PB_INFO("Change to normal speed due to FF reaching end");
1431 dvr_playback_set_speed((DVR_PlaybackHandle_t)player,normal_speed);
Wentao MA9e31f692023-09-26 17:42:18 +08001432
1433 DVR_Play_Notify_t notify;
1434 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1435 notify.event = DVR_PLAYBACK_EVENT_TIMESHIFT_FF_REACHED_END;
1436 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, notify.event, &notify, 0);
Wentao MA92a14892023-09-12 18:54:47 +08001437 }
1438 }
1439#endif
1440
hualing chen40dd5462021-11-26 19:56:20 +08001441 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001442 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001443 DVR_PB_INFO("playback send data event resume[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001444 //send event here and pause
1445 DVR_Play_Notify_t notify;
1446 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1447 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
Wentao MA96f68962022-06-15 19:45:35 +08001448 DVR_PB_INFO("----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001449 //get play statue not here
1450 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001451 }
hualing chen39628212020-05-14 10:35:13 +08001452 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001453 //real_read = real_read + read;
Wentao MA270dc0f2022-08-23 13:17:26 +08001454 input_buffer.buf_size = real_read;
1455 input_buffer.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001456
Wentao MA270dc0f2022-08-23 13:17:26 +08001457 //check read data len,if len < 0, we need continue
1458 if (input_buffer.buf_size <= 0 || input_buffer.buf_data == NULL) {
1459 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 +08001460 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001461 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001462 player->ts_cache_len = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001463 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001464 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001465 }
hualing chen266b9502020-04-04 17:39:39 +08001466 //if need write whole block size, we need check read buf len is eq block size.
Wentao MAa0b9c002022-11-10 17:47:27 +08001467 if (b_writed_whole_block == DVR_TRUE
1468 && (player->has_video || player->dec_func || player->cryptor)) {
hualing chen266b9502020-04-04 17:39:39 +08001469 //buf_len is block size value.
1470 if (real_read < buf_len) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001471 //continue to read data from file
Wentao MA96f68962022-06-15 19:45:35 +08001472 DVR_PB_INFO("read buf len[%d] is < block size [%d]", real_read, buf_len);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001473 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001474 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1475 dvr_mutex_unlock(&player->lock);
1476 DVR_PB_INFO("read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001477 continue;
1478 } else if (real_read > buf_len) {
Wentao MA96f68962022-06-15 19:45:35 +08001479 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 +08001480 }
1481 }
1482
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001483 if (player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001484 DVR_CryptoParams_t crypto_params;
1485
1486 memset(&crypto_params, 0, sizeof(crypto_params));
1487 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1488 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1489 crypto_params.segment_id = player->cur_segment.segment_id;
Wentao MAf35c3882023-04-17 12:36:19 +08001490 crypto_params.offset = segment_tell_position(player->segment_handle) - input_buffer.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001491 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
Wentao MA96f68962022-06-15 19:45:35 +08001492 DVR_PB_INFO("offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001493 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1494 crypto_params.input_buffer.addr = (size_t)buf;
1495 crypto_params.input_buffer.size = real_read;
1496
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001497 if (player->is_secure_mode) {
1498 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1499 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1500 crypto_params.output_buffer.size = dec_buf_size;
1501 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001502 input_buffer.buf_data = player->secure_buffer;
1503 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001504 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001505 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001506 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001507 input_buffer.buf_size = crypto_params.output_size;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001508 } else { // only for NAGRA
1509 crypto_params.output_buffer.type = crypto_params.input_buffer.type;
1510 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1511 crypto_params.output_buffer.size = crypto_params.input_buffer.size;
1512 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001513 input_buffer.buf_data = (uint8_t*)crypto_params.output_buffer.addr;
1514 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001515 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001516 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001517 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001518 input_buffer.buf_size = crypto_params.output_buffer.size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001519 }
Yahui Han1fbf3292021-11-08 18:17:19 +08001520 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001521 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001522 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
Wentao MA270dc0f2022-08-23 13:17:26 +08001523 input_buffer.buf_data = dec_bufs.buf_data;
1524 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1525 input_buffer.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001526 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001527rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001528 if (player->drop_ts == DVR_TRUE) {
1529 //need drop ts data when seek occur.we need read next loop,drop this ts data
1530 goto_rewrite = DVR_FALSE;
1531 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001532 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001533 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001534 player->drop_ts = DVR_FALSE;
Wentao MA63c6cba2022-09-20 10:14:29 +08001535 pthread_mutex_unlock(&player->segment_lock);
1536 DVR_PB_INFO("----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001537 continue;
1538 }
hualing chen21a40372021-10-29 11:07:26 +08001539
1540 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001541 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001542 //used for printf first write data time.
1543 //to check change channel kpi.
1544 if (first_write == 0) {
1545 first_write++;
Wentao MA270dc0f2022-08-23 13:17:26 +08001546 DVR_PB_INFO("----first write ts data");
hualing chenb9a02922021-12-14 11:29:47 +08001547 }
1548
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001549 if (!player->has_audio && player->fake_mode) {
1550 DVR_PB_INFO("sc: force enable=1 in video fake mode.");
1551 player->control_speed_enable = 1;
1552 } else {
1553 player->control_speed_enable = player->control_speed_enable_user;
1554 }
1555 if (player->control_speed_enable == 1
1556 && player->control_speed_enable != player->control_speed_enable_last) {
1557 player->control_speed_enable_last = player->control_speed_enable;
1558 player->con_spe.ply_dur = 0;
1559 player->con_spe.ply_sta = 0;
1560 player->con_spe.sys_dur = 0;
1561 player->con_spe.sys_sta = 0;
1562 }
1563
Wentao MA270dc0f2022-08-23 13:17:26 +08001564 ret = AmTsPlayer_writeData(player->handle, &input_buffer, write_timeout_ms);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001565 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001566 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001567 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001568 real_read = 0;
1569 write_success++;
shenghui.gengbec6a462023-01-12 15:21:02 +08001570 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001571check0:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001572 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001573 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001574 break;
1575 }
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001576
1577 if (!player->has_audio && player->fake_mode) {
1578 /*fine tune for fake mode*/
1579 uint64_t seg_id;
1580 int32_t play_cur = _dvr_get_play_cur_time((DVR_PlaybackHandle_t)player, &seg_id);
1581
1582 calc_speed_control(player, play_cur);
1583 }
1584
hualing chend241c7a2021-06-22 13:34:27 +08001585 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001586 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001587 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001588 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001589 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1590 goto check0;
1591 }
1592 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001593 //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 +08001594 } else {
Wentao MA804bab12022-11-29 10:01:26 +08001595 pthread_mutex_unlock(&player->segment_lock);
wentao.ma4ee43022022-12-14 13:22:57 +08001596 DVR_PB_DEBUG("write time out write_success:%d buf_size:%d systime:%u",
1597 write_success, input_buffer.buf_size, _dvr_time_getClock());
hualing chena540a7e2020-03-27 16:44:05 +08001598 write_success = 0;
shenghui.gengbec6a462023-01-12 15:21:02 +08001599 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001600check1:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001601 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001602 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001603 break;
1604 }
hualing chend241c7a2021-06-22 13:34:27 +08001605 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001606 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001607 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001608 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001609 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1610 goto check1;
1611 }
1612 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001613 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001614 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001615 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001616 if (!player->is_running) {
Wentao MA96f68962022-06-15 19:45:35 +08001617 DVR_PB_INFO("playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001618 break;
1619 }
hualing chen2aba4022020-03-02 13:49:55 +08001620 goto_rewrite = DVR_TRUE;
1621 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001622 }
1623 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001624end:
Wentao MA96f68962022-06-15 19:45:35 +08001625 DVR_PB_INFO("playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001626 free(buf);
1627 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001628 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001629}
1630
1631
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001632static int _start_playback_thread(DVR_PlaybackHandle_t handle, int fake_mode)
hualing chenb31a6c62020-01-13 17:27:00 +08001633{
hualing chen040df222020-01-17 13:35:02 +08001634 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001635
1636 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001637 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001638 return DVR_FAILURE;
1639 }
Wentao MA96f68962022-06-15 19:45:35 +08001640 DVR_PB_INFO("start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001641 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001642 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001643 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001644 player->is_running = DVR_TRUE;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001645 player->fake_mode = fake_mode;
hualing chen86e7d482020-01-16 15:13:33 +08001646 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001647 if (rc < 0)
1648 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001649 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001650}
1651
1652
hualing chen040df222020-01-17 13:35:02 +08001653static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001654{
hualing chen040df222020-01-17 13:35:02 +08001655 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001656
1657 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001658 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001659 return DVR_FAILURE;
1660 }
1661
Wentao MA96f68962022-06-15 19:45:35 +08001662 DVR_PB_INFO("stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001663 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001664 {
1665 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001666 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001667 pthread_join(player->playback_thread, NULL);
1668 }
Wentao MAf35c3882023-04-17 12:36:19 +08001669 if (player->segment_handle) {
1670 segment_close(player->segment_handle);
1671 player->segment_handle = NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001672 }
Wentao MA96f68962022-06-15 19:45:35 +08001673 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001674 return 0;
1675}
1676
hualing chen1679f812021-11-08 15:17:46 +08001677static int getFakePid()
1678{
wentao ma7d642782022-10-23 18:26:16 -07001679 return dvr_prop_read_int("vendor.tv.dtv.fake_pid",0xffff);
hualing chen1679f812021-11-08 15:17:46 +08001680}
1681
1682void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1683
1684 DVR_ASSERT(handle);
1685 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1686 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001687 DVR_PB_INFO("player is NULL");
hualing chen1679f812021-11-08 15:17:46 +08001688 return ;
1689 }
1690 if (player->need_seek_start == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001691 DVR_PB_INFO("player need_seek_start is false");
hualing chen1679f812021-11-08 15:17:46 +08001692 return ;
1693 }
1694
hualing chena5f03222021-12-02 11:22:35 +08001695 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001696 player->need_seek_start = DVR_FALSE;
1697 }
Wentao MA96f68962022-06-15 19:45:35 +08001698 DVR_PB_INFO("player player->need_seek_start=%d", player->need_seek_start);
hualing chen1679f812021-11-08 15:17:46 +08001699}
1700
hualing chenb31a6c62020-01-13 17:27:00 +08001701/**\brief Open an dvr palyback
1702 * \param[out] p_handle dvr playback addr
1703 * \param[in] params dvr playback open parameters
1704 * \retval DVR_SUCCESS On success
1705 * \return Error code
1706 */
hualing chen040df222020-01-17 13:35:02 +08001707int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001708
hualing chen040df222020-01-17 13:35:02 +08001709 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001710 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001711
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001712 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
wentao.maa22bc852022-10-13 12:18:06 +08001713 DVR_RETURN_IF_FALSE(player);
hualing chenb31a6c62020-01-13 17:27:00 +08001714
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001715 dvr_mutex_init(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001716 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001717 pthread_condattr_init(&cattr);
1718 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1719 pthread_cond_init(&player->cond, &cattr);
1720 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001721
hualing chen5cbe1a62020-02-10 16:36:36 +08001722 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001723 INIT_LIST_HEAD(&player->segment_list);
1724 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1725 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001726 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001727 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00001728 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen86e7d482020-01-16 15:13:33 +08001729 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001730 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001731 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001732
hualing chen86e7d482020-01-16 15:13:33 +08001733 //store open params
hualing chen040df222020-01-17 13:35:02 +08001734 player->openParams.dmx_dev_id = params->dmx_dev_id;
1735 player->openParams.block_size = params->block_size;
Wentao MA96f68962022-06-15 19:45:35 +08001736 DVR_PB_INFO("playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001737 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001738 player->openParams.event_fn = params->event_fn;
1739 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001740 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001741 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001742
hualing chen5cbe1a62020-02-10 16:36:36 +08001743 player->has_pids = params->has_pids;
1744
hualing chen2aba4022020-03-02 13:49:55 +08001745 player->handle = params->player_handle ;
shenghui.gengbec6a462023-01-12 15:21:02 +08001746 player->control_speed_enable = params->control_speed_enable;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001747 player->control_speed_enable_user = player->control_speed_enable;
1748 player->control_speed_enable_last = player->control_speed_enable;
hualing chen6e4bfa52020-03-13 14:37:11 +08001749
1750 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1751 //for test get callback
1752 if (0 && player->player_callback_func == NULL) {
1753 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1754 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
Wentao MA96f68962022-06-15 19:45:35 +08001755 DVR_PB_INFO("playback open get callback[%p][%p][%p][%p]",
hualing chen03fd4942021-07-15 15:56:41 +08001756 player->player_callback_func,
1757 player->player_callback_userdata,
1758 _dvr_tsplayer_callback_test,
1759 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001760 }
1761 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001762
hualing chen86e7d482020-01-16 15:13:33 +08001763 //init has audio and video
1764 player->has_video = DVR_FALSE;
1765 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001766 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001767 player->last_segment_id = 0LL;
1768 player->segment_is_open = DVR_FALSE;
Wentao MA5629ad82022-08-24 10:03:02 +08001769 player->audio_presentation_id = -1;
hualing chenb31a6c62020-01-13 17:27:00 +08001770
hualing chen5cbe1a62020-02-10 16:36:36 +08001771 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001772 player->fffb_current = 0;
1773 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001774 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001775 //seek time
1776 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001777 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001778
Yahui Han1fbf3292021-11-08 18:17:19 +08001779 //allocate cryptor if have clearkey
1780 if (params->keylen > 0) {
1781 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +08001782 (uint8_t *)params->cleariv,
1783 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +08001784 if (!player->cryptor) {
Wentao MA96f68962022-06-15 19:45:35 +08001785 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +08001786 }
1787 } else {
1788 player->cryptor = NULL;
1789 }
1790
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001791 //init secure stuff
1792 player->dec_func = NULL;
1793 player->dec_userdata = NULL;
1794 player->is_secure_mode = 0;
1795 player->secure_buffer = NULL;
1796 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001797 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001798
hualing chen4b7c15d2020-04-07 16:13:48 +08001799 player->fffb_play = DVR_FALSE;
1800
1801 player->last_send_time_id = UINT64_MAX;
1802 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001803 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001804
hualing chend241c7a2021-06-22 13:34:27 +08001805 //speed con init
shenghui.gengbec6a462023-01-12 15:21:02 +08001806 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001807 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001808 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001809 player->con_spe.sys_dur = 0;
1810 player->con_spe.sys_sta = 0;
1811 }
1812
hualing chen03fd4942021-07-15 15:56:41 +08001813 //limit info
1814 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001815 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001816 //need seek to start pos
1817 player->first_start_time = 0;
Wentao MA01de0e62022-01-10 18:48:23 +08001818 player->first_start_id = UINT64_MAX;
Wentao MAa0b9c002022-11-10 17:47:27 +08001819 player->delay_is_effective = DVR_FALSE;
hualing chen8a657f32021-08-30 13:12:49 +08001820 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001821 //fake_pid init
1822 player->fake_pid = getFakePid();
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001823
1824 player->fake_mode = 1;
1825
hualing chen86e7d482020-01-16 15:13:33 +08001826 *p_handle = player;
1827 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001828}
1829
1830/**\brief Close an dvr palyback
1831 * \param[in] handle playback handle
1832 * \retval DVR_SUCCESS On success
1833 * \return Error code
1834 */
hualing chen040df222020-01-17 13:35:02 +08001835int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001836
hualing chen86e7d482020-01-16 15:13:33 +08001837 DVR_ASSERT(handle);
Wentao MA96f68962022-06-15 19:45:35 +08001838 DVR_PB_INFO(":into");
hualing chen040df222020-01-17 13:35:02 +08001839 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001840 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001841 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001842 return DVR_FAILURE;
1843 }
1844
hualing chencc91e1c2020-02-28 13:26:17 +08001845 if (player->state != DVR_PLAYBACK_STATE_STOP)
1846 {
Wentao MA96f68962022-06-15 19:45:35 +08001847 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001848 if (player->cryptor) {
1849 am_crypt_des_close(player->cryptor);
1850 player->cryptor = NULL;
1851 }
hualing chencc91e1c2020-02-28 13:26:17 +08001852 dvr_playback_stop(handle, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08001853 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
hualing chenb96aa2c2020-04-15 14:13:53 +08001854 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001855 DVR_PB_INFO(":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001856 }
Wentao MA96f68962022-06-15 19:45:35 +08001857 DVR_PB_INFO(":into");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001858 dvr_mutex_destroy(&player->lock);
Zhiqiang Hanc9513462022-06-21 09:55:23 +08001859 pthread_mutex_destroy(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001860 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001861
1862 if (player) {
1863 free(player);
hualing chen040df222020-01-17 13:35:02 +08001864 }
Wentao MA96f68962022-06-15 19:45:35 +08001865 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001866 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001867}
1868
Wentao MA270dc0f2022-08-23 13:17:26 +08001869/**\brief Start play audio and video, used start audio api and start video api
hualing chenb31a6c62020-01-13 17:27:00 +08001870 * \param[in] handle playback handle
1871 * \param[in] params audio playback params,contains fmt and pid...
1872 * \retval DVR_SUCCESS On success
1873 * \return Error code
1874 */
hualing chen040df222020-01-17 13:35:02 +08001875int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1876 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA270dc0f2022-08-23 13:17:26 +08001877 am_tsplayer_video_params video_params;
1878 am_tsplayer_audio_params audio_params;
1879 am_tsplayer_audio_params ad_params;
hualing chena540a7e2020-03-27 16:44:05 +08001880
Wentao MA270dc0f2022-08-23 13:17:26 +08001881 memset(&video_params, 0, sizeof(video_params));
1882 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001883
hualing chena540a7e2020-03-27 16:44:05 +08001884 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001885 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001886 return DVR_FAILURE;
1887 }
hualing chencc91e1c2020-02-28 13:26:17 +08001888 uint64_t segment_id = player->cur_segment_id;
Wentao MA96f68962022-06-15 19:45:35 +08001889 DVR_PB_INFO("[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001890
hualing chena540a7e2020-03-27 16:44:05 +08001891 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001892 //can used start api to resume playback
1893 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1894 return dvr_playback_resume(handle);
1895 }
hualing chen87072a82020-03-12 16:20:12 +08001896 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001897 //if flag is paused and not decode first frame. if user resume, we need
hualing chen9b434f02020-06-10 15:06:54 +08001898 //clear flag and set trickmode none
1899 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001900 DVR_PB_INFO("[%p]clear pause live flag and clear trick mode", handle);
hualing chen9b434f02020-06-10 15:06:54 +08001901 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1902 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1903 }
Wentao MA96f68962022-06-15 19:45:35 +08001904 DVR_PB_INFO("stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001905 return DVR_SUCCESS;
1906 }
hualing chen86e7d482020-01-16 15:13:33 +08001907 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001908 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001909 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08001910 DVR_PB_INFO("lock flag:0x%x", flag);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001911 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001912 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08001913 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08001914 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
1915 //audio and video pids are all invalid, return error.
1916 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 +08001917 dvr_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001918 DVR_Play_Notify_t notify;
1919 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1920 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1921 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1922 notify.info.transition_failed_data.segment_id = segment_id;
1923 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001924 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001925 return -1;
1926 }
hualing chen31140872020-03-25 12:29:26 +08001927
hualing chencc91e1c2020-02-28 13:26:17 +08001928 {
Wentao MA270dc0f2022-08-23 13:17:26 +08001929 if (VALID_PID(video_params.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001930 player->has_video = DVR_TRUE;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001931 player->fake_mode = (video_params.pid == player->fake_pid)? 1 : 0;
hualing chen86e7d482020-01-16 15:13:33 +08001932 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001933 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001934 DVR_PB_INFO("set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001935 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1936 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001937 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
Wentao MA96f68962022-06-15 19:45:35 +08001938 DVR_PB_INFO("set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001939 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001940 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001941 DVR_PB_INFO("set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001942 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001943 }
hualing chena93bbbc2020-12-22 17:23:42 +08001944 AmTsPlayer_showVideo(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08001945 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08001946 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001947 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001948 }
hualing chena540a7e2020-03-27 16:44:05 +08001949
Wentao MA270dc0f2022-08-23 13:17:26 +08001950 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 +08001951 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001952 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1953 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1954 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 } else {
1957 player->cmd.last_cmd = player->cmd.cur_cmd;
1958 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001959 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001960 //set fast play
Wentao MA96f68962022-06-15 19:45:35 +08001961 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08001962 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001963 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08001964 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08001965 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08001966 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08001967 dvr_playback_change_seek_state(handle, ad_params.pid);
1968 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08001969 AmTsPlayer_enableADMix(player->handle);
1970 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001971 if (VALID_PID(audio_params.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001972 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08001973 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08001974 dvr_playback_change_seek_state(handle, audio_params.pid);
1975 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08001976 if (player->audio_presentation_id > -1) {
1977 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
1978 }
hualing chen969fe7b2021-05-26 15:13:17 +08001979 AmTsPlayer_startAudioDecoding(player->handle);
1980 }
hualing chen31140872020-03-25 12:29:26 +08001981 }
hualing chencc91e1c2020-02-28 13:26:17 +08001982 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001983 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001984 }
hualing chen86e7d482020-01-16 15:13:33 +08001985 }
hualing chen43a89bc2022-01-19 14:31:20 +08001986#ifdef AVSYNC_USED_PCR
1987 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001988 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08001989 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
1990 }
1991#endif
Wentao MA96f68962022-06-15 19:45:35 +08001992 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001993 dvr_mutex_unlock(&player->lock);
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08001994 _start_playback_thread(handle, (video_params.pid == player->fake_pid)? 1 : 0);
hualing chen86e7d482020-01-16 15:13:33 +08001995 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001996}
hualing chen040df222020-01-17 13:35:02 +08001997/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001998 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001999 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08002000 * \retval DVR_SUCCESS On success
2001 * \return Error code
2002 */
hualing chen040df222020-01-17 13:35:02 +08002003int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
2004 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa22bc852022-10-13 12:18:06 +08002005 DVR_RETURN_IF_FALSE(player);
hualing chena540a7e2020-03-27 16:44:05 +08002006
Wentao MA96f68962022-06-15 19:45:35 +08002007 DVR_PB_INFO("add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08002008 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08002009
hualing chen040df222020-01-17 13:35:02 +08002010 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
wentao.maa22bc852022-10-13 12:18:06 +08002011 DVR_RETURN_IF_FALSE(segment);
hualing chen040df222020-01-17 13:35:02 +08002012 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08002013
Wentao MA270dc0f2022-08-23 13:17:26 +08002014 //not memcpy chunk info.
hualing chen040df222020-01-17 13:35:02 +08002015 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08002016 //cp location
hualing chen040df222020-01-17 13:35:02 +08002017 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08002018
Wentao MA96f68962022-06-15 19:45:35 +08002019 DVR_PB_INFO("add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08002020 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08002021
2022 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08002023 segment->pids.video.pid = info->pids.video.pid;
2024 segment->pids.video.format = info->pids.video.format;
2025 segment->pids.video.type = info->pids.video.type;
2026
hualing chen2aba4022020-03-02 13:49:55 +08002027 segment->pids.audio.pid = info->pids.audio.pid;
2028 segment->pids.audio.format = info->pids.audio.format;
2029 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08002030
hualing chen2aba4022020-03-02 13:49:55 +08002031 segment->pids.ad.pid = info->pids.ad.pid;
2032 segment->pids.ad.format = info->pids.ad.format;
2033 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08002034
2035 segment->pids.pcr.pid = info->pids.pcr.pid;
2036
Wentao MA96f68962022-06-15 19:45:35 +08002037 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 +08002038 dvr_mutex_lock(&player->lock);
wentao.maa22bc852022-10-13 12:18:06 +08002039 list_add_tail(segment, &player->segment_list);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002040 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002041 DVR_PB_DEBUG("unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08002042
hualing chen5cbe1a62020-02-10 16:36:36 +08002043 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002044}
hualing chen040df222020-01-17 13:35:02 +08002045/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08002046 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08002047 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002048 * \retval DVR_SUCCESS On success
2049 * \return Error code
2050 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002051int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08002052 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08002053 DVR_PB_INFO("remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08002054 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002055 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002056 return DVR_FAILURE;
2057 }
2058
hualing chencc91e1c2020-02-28 13:26:17 +08002059 if (segment_id == player->cur_segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08002060 DVR_PB_INFO("not support remove current segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08002061 return DVR_FAILURE;
2062 }
Wentao MA96f68962022-06-15 19:45:35 +08002063 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002064 dvr_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08002065 DVR_PlaybackSegmentInfo_t *segment = NULL;
2066 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
2067 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002068 {
hualing chen040df222020-01-17 13:35:02 +08002069 if (segment->segment_id == segment_id) {
2070 list_del(&segment->head);
2071 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002072 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002073 }
hualing chen86e7d482020-01-16 15:13:33 +08002074 }
Wentao MA96f68962022-06-15 19:45:35 +08002075 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002076 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002077
2078 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002079}
hualing chen040df222020-01-17 13:35:02 +08002080/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08002081 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08002082 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08002083 * \retval DVR_SUCCESS On success
2084 * \return Error code
2085 */
hualing chen040df222020-01-17 13:35:02 +08002086int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002087 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08002088 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08002089 DVR_PB_INFO("update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08002090 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002091 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002092 return DVR_FAILURE;
2093 }
Wentao MA292380e2022-12-14 14:46:19 +08002094 if (player->vendor != DVR_PLAYBACK_VENDOR_DEF) {
2095 DVR_PB_INFO("In case of vendor Amlogic/Amazon, do not control AV display");
hualing chenf43b8ba2020-07-28 13:11:42 +08002096 return DVR_SUCCESS;
2097 }
hualing chena540a7e2020-03-27 16:44:05 +08002098
hualing chen040df222020-01-17 13:35:02 +08002099 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002100 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002101 dvr_mutex_lock(&player->lock);
wentao.mafd5283f2022-10-14 09:51:13 +08002102 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002103 // prefetch() here incurring self_assign is used to avoid some compiling
2104 // warnings.
2105 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002106 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002107 {
hualing chen040df222020-01-17 13:35:02 +08002108 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08002109 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08002110 }
hualing chen86e7d482020-01-16 15:13:33 +08002111 // if encramble to free, only set flag and return;
2112
2113 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08002114 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002115 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
2116 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08002117 //disable display, mute
Wentao MA96f68962022-06-15 19:45:35 +08002118 DVR_PB_INFO("mute av");
hualing chen2aba4022020-03-02 13:49:55 +08002119 AmTsPlayer_hideVideo(player->handle);
2120 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002121 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
2122 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002123 //enable display, unmute
Wentao MA96f68962022-06-15 19:45:35 +08002124 DVR_PB_INFO("unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08002125 AmTsPlayer_showVideo(player->handle);
2126 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002127 } else {
2128 //do nothing
2129 }
2130 } else {
2131 //do nothing
2132 }
2133 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08002134 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08002135 }
Wentao MA96f68962022-06-15 19:45:35 +08002136 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002137 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002138 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002139}
2140
2141
Wentao MA6dcdc342023-01-30 17:03:19 +08002142static int _do_handle_pid_update(DVR_PlaybackHandle_t handle, DVR_PlaybackPids_t now_pids, DVR_PlaybackPids_t set_pids, int type) {
hualing chen040df222020-01-17 13:35:02 +08002143 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08002144 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08002145 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08002146
Wentao MA6dcdc342023-01-30 17:03:19 +08002147 if (player == NULL) {
2148 DVR_PB_INFO("player is NULL");
2149 return DVR_FAILURE;
2150 }
2151
hualing chen275379e2021-06-15 17:57:21 +08002152 if (type == 0) {
2153 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08002154 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08002155 } else if (type == 1) {
2156 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08002157 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08002158 } else if (type == 2) {
2159 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08002160 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08002161 } else {
2162 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08002163 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08002164 }
2165
Wentao MA6dcdc342023-01-30 17:03:19 +08002166 if (type == 1 && VALID_PID(set_pid.pid) && player->cmd.state == DVR_PLAYBACK_STATE_START
2167 && player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
2168 // Here we mute audio no matter it is displayable or not in starting phase of a playback.
2169 // Audio will be unmuted shortly on receiving first frame event.
2170 AmTsPlayer_setAudioMute(player->handle,1,1);
hualing chena540a7e2020-03-27 16:44:05 +08002171 }
Wentao MA6dcdc342023-01-30 17:03:19 +08002172
hualing chen86e7d482020-01-16 15:13:33 +08002173 if (now_pid.pid == set_pid.pid) {
2174 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08002175 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08002176 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08002177 if (VALID_PID(now_pid.pid)) {
2178 //stop now stream
2179 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002180 //stop video
hualing chenc70a8df2020-05-12 19:23:11 +08002181 if (player->has_video == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002182 DVR_PB_INFO("stop video");
hualing chenc70a8df2020-05-12 19:23:11 +08002183 AmTsPlayer_stopVideoDecoding(player->handle);
2184 player->has_video = DVR_FALSE;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08002185 player->fake_mode = 0;
hualing chenc70a8df2020-05-12 19:23:11 +08002186 }
hualing chen86e7d482020-01-16 15:13:33 +08002187 } else if (type == 1) {
2188 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002189 if (player->has_audio == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002190 DVR_PB_INFO("stop audio");
hualing chenc70a8df2020-05-12 19:23:11 +08002191 AmTsPlayer_stopAudioDecoding(player->handle);
2192 player->has_audio = DVR_FALSE;
2193 }
hualing chen86e7d482020-01-16 15:13:33 +08002194 } else if (type == 2) {
2195 //stop sub audio
Wentao MA96f68962022-06-15 19:45:35 +08002196 DVR_PB_INFO("stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002197 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002198 } else if (type == 3) {
2199 //pcr
2200 }
2201 }
2202 if (VALID_PID(set_pid.pid)) {
2203 //start
2204 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002205 //start video
2206 am_tsplayer_video_params video_params;
2207 video_params.pid = set_pid.pid;
2208 video_params.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002209 player->has_video = DVR_TRUE;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08002210 player->fake_mode = (video_params.pid == player->fake_pid)? 1 : 0;
Wentao MA270dc0f2022-08-23 13:17:26 +08002211 DVR_PB_INFO("start video pid[%d]fmt[%d]",video_params.pid, video_params.codectype);
2212 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen2aba4022020-03-02 13:49:55 +08002213 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002214 //playback_device_video_start(player->handle,&video_params);
hualing chen86e7d482020-01-16 15:13:33 +08002215 } else if (type == 1) {
2216 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002217 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002218 if (VALID_PID(set_pids.ad.pid)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002219 am_tsplayer_audio_params ad_params;
2220 ad_params.pid = set_pids.ad.pid;
2221 ad_params.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2222 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",ad_params.pid, ad_params.codectype);
2223 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen275379e2021-06-15 17:57:21 +08002224 AmTsPlayer_enableADMix(player->handle);
2225 }
2226
Wentao MA270dc0f2022-08-23 13:17:26 +08002227 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002228
Wentao MA270dc0f2022-08-23 13:17:26 +08002229 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002230
Wentao MA270dc0f2022-08-23 13:17:26 +08002231 audio_params.pid = set_pid.pid;
2232 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002233 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002234 DVR_PB_INFO("start audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2235 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002236 if (player->audio_presentation_id > -1) {
2237 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2238 }
Wentao MA6dcdc342023-01-30 17:03:19 +08002239
hualing chenc70a8df2020-05-12 19:23:11 +08002240 AmTsPlayer_startAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002241 //playback_device_audio_start(player->handle,&audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002242 }
hualing chen86e7d482020-01-16 15:13:33 +08002243 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002244 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002245 if (set_pids.audio.pid == now_pids.audio.pid) {
2246 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002247 DVR_PB_INFO("stop audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002248 AmTsPlayer_stopAudioDecoding(player->handle);
2249 }
Wentao MA270dc0f2022-08-23 13:17:26 +08002250 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002251
Wentao MA270dc0f2022-08-23 13:17:26 +08002252 memset(&audio_params, 0, sizeof(audio_params));
2253 audio_params.pid = set_pid.pid;
2254 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002255 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002256 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2257 AmTsPlayer_setADParams(player->handle, &audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002258 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002259
2260 if (set_pids.audio.pid == now_pids.audio.pid) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002261 am_tsplayer_audio_params audio_params;
hualing chen99508642021-10-18 15:41:17 +08002262
Wentao MA270dc0f2022-08-23 13:17:26 +08002263 memset(&audio_params, 0, sizeof(audio_params));
hualing chen99508642021-10-18 15:41:17 +08002264
Wentao MA270dc0f2022-08-23 13:17:26 +08002265 audio_params.pid = set_pids.audio.pid;
2266 audio_params.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
hualing chen99508642021-10-18 15:41:17 +08002267 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002268 DVR_PB_INFO("restart audio when start ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002269 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002270 if (player->audio_presentation_id > -1) {
2271 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2272 }
hualing chen99508642021-10-18 15:41:17 +08002273 AmTsPlayer_startAudioDecoding(player->handle);
2274 }
hualing chenc70a8df2020-05-12 19:23:11 +08002275 }
hualing chen86e7d482020-01-16 15:13:33 +08002276 } else if (type == 3) {
2277 //pcr
Wentao MA96f68962022-06-15 19:45:35 +08002278 DVR_PB_INFO("start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002279 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002280 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002281 //audio and video all close
2282 if (!player->has_audio && !player->has_video) {
Wentao MA907b6432022-08-01 06:23:08 +00002283 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen5cbe1a62020-02-10 16:36:36 +08002284 }
hualing chen43a89bc2022-01-19 14:31:20 +08002285 } else if (type == 2) {
2286 //case disable ad
Wentao MA96f68962022-06-15 19:45:35 +08002287 DVR_PB_INFO("restart audio when stop ad");
hualing chen43a89bc2022-01-19 14:31:20 +08002288 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
Wentao MA6d045b32022-02-18 18:47:25 +08002289 if (VALID_PID(now_pids.audio.pid)) {
2290 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002291 DVR_PB_INFO("stop audio when stop ad pid [0x%x]", now_pids.audio.pid);
Wentao MA6d045b32022-02-18 18:47:25 +08002292 AmTsPlayer_stopAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002293 am_tsplayer_audio_params audio_params;
hualing chen43a89bc2022-01-19 14:31:20 +08002294
Wentao MA270dc0f2022-08-23 13:17:26 +08002295 memset(&audio_params, 0, sizeof(audio_params));
hualing chen43a89bc2022-01-19 14:31:20 +08002296
Wentao MA270dc0f2022-08-23 13:17:26 +08002297 audio_params.pid = now_pids.audio.pid;
2298 audio_params.codectype= _dvr_convert_stream_fmt(now_pids.audio.format, DVR_TRUE);
Wentao MA6d045b32022-02-18 18:47:25 +08002299 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002300 DVR_PB_INFO("restart audio when stop ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002301 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002302 if (player->audio_presentation_id > -1) {
2303 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2304 }
Wentao MA6d045b32022-02-18 18:47:25 +08002305 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen43a89bc2022-01-19 14:31:20 +08002306 }
Wentao MA6d045b32022-02-18 18:47:25 +08002307 }
hualing chen86e7d482020-01-16 15:13:33 +08002308 }
2309 }
2310 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002311}
hualing chena5f03222021-12-02 11:22:35 +08002312/**\brief dvr play back only update segment pids info
2313 * only update pid info not to start stop codec.
2314 * \param[in] handle playback handle
2315 * \param[in] segment_id need updated pids segment id
2316 * \param[in] p_pids need updated pids
2317 * \retval DVR_SUCCESS On success
2318 * \return Error code
2319 */
2320int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2321 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2322 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002323 DVR_PB_INFO("player is NULL");
hualing chena5f03222021-12-02 11:22:35 +08002324 return DVR_FAILURE;
2325 }
2326
2327 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002328 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002329 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002330 DVR_PB_INFO("get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
wentao.mafd5283f2022-10-14 09:51:13 +08002331 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002332 // prefetch() here incurring self_assign is used to avoid some compiling
2333 // warnings.
2334 // coverity[self_assign]
hualing chena5f03222021-12-02 11:22:35 +08002335 list_for_each_entry(segment, &player->segment_list, head)
2336 {
2337 if (segment->segment_id == segment_id) {
2338 if (player->cur_segment_id == segment_id) {
2339 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002340 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chena5f03222021-12-02 11:22:35 +08002341 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002342 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002343 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002344 return 0;
2345 }
2346 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2347 }
2348 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002349 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002350 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002351 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002352 break;
2353 }
2354 }
Wentao MA96f68962022-06-15 19:45:35 +08002355 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002356 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002357 return DVR_SUCCESS;
2358}
2359
hualing chen5cbe1a62020-02-10 16:36:36 +08002360/**\brief dvr play back update segment pids
2361 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002362 * add pid stream and stop remove pid stream.
2363 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002364 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002365 * \retval DVR_SUCCESS On success
2366 * \return Error code
2367 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002368int 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 +08002369 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002370 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002371 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002372 return DVR_FAILURE;
2373 }
2374
hualing chen040df222020-01-17 13:35:02 +08002375 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002376 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002377 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002378 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 +08002379
wentao.mafd5283f2022-10-14 09:51:13 +08002380 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002381 // prefetch() here incurring self_assign is used to avoid some compiling
2382 // warnings.
2383 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002384 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002385 {
hualing chen040df222020-01-17 13:35:02 +08002386 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002387
2388 if (player->cur_segment_id == segment_id) {
2389 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002390 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002391 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002392 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002393 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002394 return 0;
2395 }
2396
2397 //if segment is on going segment,we need stop start stream
2398 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA96f68962022-06-15 19:45:35 +08002399 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002400 dvr_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002401 if (segment->pids.audio.pid != p_pids->audio.pid &&
2402 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002403 //not used this to seek to start pos.we will
Wentao MA9a164002022-08-29 11:20:24 +08002404 //add update only api. if need seek to start
hualing chena5f03222021-12-02 11:22:35 +08002405 //pos, we will call only update api and used seek api
2406 //to start and stop av codec
2407 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002408 player->need_seek_start = DVR_FALSE;
2409 pthread_mutex_lock(&player->segment_lock);
2410 player->drop_ts = DVR_TRUE;
2411 player->ts_cache_len = 0;
2412 if (player->first_start_time > 0)
2413 player->first_start_time = player->first_start_time - 1;
Wentao MAf35c3882023-04-17 12:36:19 +08002414 segment_seek(player->segment_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002415 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 +08002416 pthread_mutex_unlock(&player->segment_lock);
2417 }
2418 }
hualing chen1679f812021-11-08 15:17:46 +08002419 //check video pids, stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002420 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
hualing chen1679f812021-11-08 15:17:46 +08002421 //check sub audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002422 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
hualing chen1679f812021-11-08 15:17:46 +08002423 //check audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002424 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
hualing chen1679f812021-11-08 15:17:46 +08002425 //check pcr pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002426 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
hualing chen1679f812021-11-08 15:17:46 +08002427
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002428 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002429 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2430 //if state is pause, we need process at resume api. we only record change info
2431 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2432 int a_cmd = DVR_PLAYBACK_CMD_NONE;
Zhiqiang Han83923642023-11-03 12:06:48 +08002433
2434 #define CHECK_IF_NEED_RESTART(_now, _next, _cmd, _v_cmd) \
2435 if (VALID_PID(_now) && VALID_PID(_next) && (_now) != (_next)) \
2436 (_cmd) = (_v_cmd);
2437
2438 #define CHECK_IF_NEED_STOP(_now, _next, _cmd, _v_cmd) \
2439 if (VALID_PID(_now) && !VALID_PID(_next)) \
2440 (_cmd) = (_v_cmd);
2441
2442 #define CHECK_IF_NEED_START(_now, _next, _cmd, _v_cmd) \
2443 if (!VALID_PID(_now) && VALID_PID(_next)) \
2444 (_cmd) = (_v_cmd);
2445
2446 CHECK_IF_NEED_RESTART(segment->pids.video.pid, p_pids->video.pid, v_cmd, DVR_PLAYBACK_CMD_V_RESTART);
2447 CHECK_IF_NEED_STOP(segment->pids.video.pid, p_pids->video.pid, v_cmd, DVR_PLAYBACK_CMD_V_STOP);
2448 CHECK_IF_NEED_START(segment->pids.video.pid, p_pids->video.pid, v_cmd, DVR_PLAYBACK_CMD_V_START);
2449
2450 CHECK_IF_NEED_RESTART(segment->pids.audio.pid, p_pids->audio.pid, a_cmd, DVR_PLAYBACK_CMD_A_RESTART);
2451 CHECK_IF_NEED_STOP(segment->pids.audio.pid, p_pids->audio.pid, a_cmd, DVR_PLAYBACK_CMD_A_STOP);
2452 CHECK_IF_NEED_START(segment->pids.audio.pid, p_pids->audio.pid, a_cmd, DVR_PLAYBACK_CMD_A_START);
Zhiqiang Han400e2a12023-10-23 09:12:32 +08002453
2454 /*process the ad, if main audio exists, but no action*/
2455 if (a_cmd == DVR_PLAYBACK_CMD_NONE && VALID_PID(p_pids->audio.pid)) {
2456
Zhiqiang Han83923642023-11-03 12:06:48 +08002457 CHECK_IF_NEED_RESTART(segment->pids.ad.pid, p_pids->ad.pid, a_cmd, DVR_PLAYBACK_CMD_A_RESTART);
2458 CHECK_IF_NEED_STOP(segment->pids.ad.pid, p_pids->ad.pid, a_cmd, DVR_PLAYBACK_CMD_A_RESTART);
2459 CHECK_IF_NEED_START(segment->pids.ad.pid, p_pids->ad.pid, a_cmd, DVR_PLAYBACK_CMD_A_RESTART);
Zhiqiang Han400e2a12023-10-23 09:12:32 +08002460
2461 }
2462
Zhiqiang Han83923642023-11-03 12:06:48 +08002463 DVR_PB_INFO("%s, v_cmd[%#x] a_cmd[%#x]", __func__, v_cmd, a_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002464
Zhiqiang Han83923642023-11-03 12:06:48 +08002465 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
2466 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_NONE) {
2467 /*another cmd coming in pause mode, should check and merge with last cmd*/
2468 player->cmd.cur_cmd |= a_cmd | v_cmd;
2469 } else {
2470 player->cmd.cur_cmd = a_cmd | v_cmd;
hualing chen5cbe1a62020-02-10 16:36:36 +08002471 }
Zhiqiang Han83923642023-11-03 12:06:48 +08002472 player->cmd.last_cmd = DVR_PLAYBACK_CMD_PAUSE;
2473
2474 DVR_PB_INFO("%s, last_cmd[%#x] cur_cmd[%#x]", __func__, player->cmd.last_cmd, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002475 }
Zhiqiang Han83923642023-11-03 12:06:48 +08002476
hualing chene10666f2020-04-14 13:58:37 +08002477 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002478 }
hualing chen86e7d482020-01-16 15:13:33 +08002479 //save pids info
Zhiqiang Han83923642023-11-03 12:06:48 +08002480 DVR_PB_INFO(":vpid :%d -> %d", segment->pids.video.pid, p_pids->video.pid);
2481 DVR_PB_INFO(":apid :%d -> %d", segment->pids.audio.pid, p_pids->audio.pid);
2482 DVR_PB_INFO(":adpid :%d -> %d", segment->pids.ad.pid, p_pids->ad.pid);
hualing chen040df222020-01-17 13:35:02 +08002483 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +08002484 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002485 }
hualing chen86e7d482020-01-16 15:13:33 +08002486 }
Wentao MA96f68962022-06-15 19:45:35 +08002487 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002488 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002489 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002490}
2491/**\brief Stop play, will stop video and audio
2492 * \param[in] handle playback handle
2493 * \param[in] clear is clear last frame
2494 * \retval DVR_SUCCESS On success
2495 * \return Error code
2496 */
hualing chen040df222020-01-17 13:35:02 +08002497int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2498 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002499 DVR_UNUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002500 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002501 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002502 return DVR_FAILURE;
2503 }
Zhiqiang Han1f279702024-03-18 13:55:56 +08002504
hualing chen87072a82020-03-12 16:20:12 +08002505 _stop_playback_thread(handle);
Zhiqiang Han1f279702024-03-18 13:55:56 +08002506
2507 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2508 DVR_PB_INFO(":playback is stoped");
2509 return DVR_SUCCESS;
2510 }
2511
Wentao MA96f68962022-06-15 19:45:35 +08002512 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002513 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002514 DVR_PB_INFO(":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002515 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002516 if (player->has_video) {
2517 AmTsPlayer_resumeVideoDecoding(player->handle);
2518 }
2519 if (player->has_audio) {
2520 AmTsPlayer_resumeAudioDecoding(player->handle);
2521 }
2522 if (player->has_video) {
2523 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002524 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002525 AmTsPlayer_stopVideoDecoding(player->handle);
2526 }
2527 if (player->has_audio) {
2528 player->has_audio = DVR_FALSE;
2529 AmTsPlayer_stopAudioDecoding(player->handle);
2530 }
hualing chendf118dd2020-05-21 15:49:11 +08002531 if (player->has_ad_audio) {
2532 player->has_ad_audio =DVR_FALSE;
2533 AmTsPlayer_disableADMix(player->handle);
2534 }
hualing chen266b9502020-04-04 17:39:39 +08002535
hualing chen86e7d482020-01-16 15:13:33 +08002536 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002537 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2538 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002539 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen87072a82020-03-12 16:20:12 +08002540 player->cur_segment_id = UINT64_MAX;
2541 player->segment_is_open = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08002542 DVR_PB_DEBUG("unlock");
2543 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002544 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002545 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002546}
2547/**\brief Start play audio
2548 * \param[in] handle playback handle
2549 * \param[in] params audio playback params,contains fmt and pid...
2550 * \retval DVR_SUCCESS On success
2551 * \return Error code
2552 */
hualing chen2aba4022020-03-02 13:49:55 +08002553
Wentao MA270dc0f2022-08-23 13:17:26 +08002554int 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 +08002555 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002556
2557 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002558 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002559 return DVR_FAILURE;
2560 }
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08002561 _start_playback_thread(handle, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002562 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002563 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002564 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002565
Wentao MA270dc0f2022-08-23 13:17:26 +08002566 if (VALID_PID(ad_param->pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08002567 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002568 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002569 AmTsPlayer_setADParams(player->handle, ad_param);
hualing chendf118dd2020-05-21 15:49:11 +08002570 AmTsPlayer_enableADMix(player->handle);
2571 }
hualing chen969fe7b2021-05-26 15:13:17 +08002572 if (VALID_PID(param->pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08002573 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08002574 player->has_audio = DVR_TRUE;
2575 AmTsPlayer_setAudioParams(player->handle, param);
Wentao MA5629ad82022-08-24 10:03:02 +08002576 if (player->audio_presentation_id > -1) {
2577 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2578 }
hualing chen969fe7b2021-05-26 15:13:17 +08002579 AmTsPlayer_startAudioDecoding(player->handle);
2580 }
hualing chendf118dd2020-05-21 15:49:11 +08002581
hualing chen86e7d482020-01-16 15:13:33 +08002582 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002583 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen040df222020-01-17 13:35:02 +08002584 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002585 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002586 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002587 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002588 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002589}
2590/**\brief Stop play audio
2591 * \param[in] handle playback handle
2592 * \retval DVR_SUCCESS On success
2593 * \return Error code
2594 */
hualing chen040df222020-01-17 13:35:02 +08002595int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2596 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002597
2598 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002599 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002600 return DVR_FAILURE;
2601 }
2602
hualing chen2aba4022020-03-02 13:49:55 +08002603 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002604 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002605 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002606 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002607 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002608 _stop_playback_thread(handle);
2609 } else {
2610 //do nothing.video is playing
2611 }
Wentao MA96f68962022-06-15 19:45:35 +08002612 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002613 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002614
hualing chenf00cdc82020-06-10 14:23:35 +08002615 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002616 player->has_audio = DVR_FALSE;
2617 AmTsPlayer_stopAudioDecoding(player->handle);
2618 }
hualing chen87072a82020-03-12 16:20:12 +08002619
hualing chendf118dd2020-05-21 15:49:11 +08002620 if (player->has_ad_audio) {
2621 player->has_ad_audio =DVR_FALSE;
2622 AmTsPlayer_disableADMix(player->handle);
2623 }
2624
hualing chen87072a82020-03-12 16:20:12 +08002625 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002626 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002627
Wentao MA96f68962022-06-15 19:45:35 +08002628 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002629 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002630 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002631}
2632/**\brief Start play video
2633 * \param[in] handle playback handle
2634 * \param[in] params video playback params,contains fmt and pid...
2635 * \retval DVR_SUCCESS On success
2636 * \return Error code
2637 */
hualing chen2aba4022020-03-02 13:49:55 +08002638int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002639 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002640
2641 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002642 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002643 return DVR_FAILURE;
2644 }
2645
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08002646 _start_playback_thread(handle, (param->pid == player->fake_pid)? 1 : 0);
hualing chen86e7d482020-01-16 15:13:33 +08002647 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002648 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002649 dvr_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002650 player->has_video = DVR_TRUE;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08002651 player->fake_mode = (param->pid == player->fake_pid)? 1 : 0;
hualing chena540a7e2020-03-27 16:44:05 +08002652 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002653 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002654 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002655
2656 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002657 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002658 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08002659 DVR_PB_INFO("settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002660 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2661 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002662 }
2663 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002664 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen040df222020-01-17 13:35:02 +08002665 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002666 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002667 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002668 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002669 return DVR_SUCCESS;
2670}
2671/**\brief Stop play video
2672 * \param[in] handle playback handle
2673 * \retval DVR_SUCCESS On success
2674 * \return Error code
2675 */
hualing chen040df222020-01-17 13:35:02 +08002676int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2677 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002678
2679 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002680 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002681 return DVR_FAILURE;
2682 }
2683
hualing chen86e7d482020-01-16 15:13:33 +08002684 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002685 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002686 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002687 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002688 _stop_playback_thread(handle);
2689 } else {
2690 //do nothing.audio is playing
2691 }
hualing chen7a56cba2020-04-14 14:09:27 +08002692
Wentao MA96f68962022-06-15 19:45:35 +08002693 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002694 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002695
hualing chen87072a82020-03-12 16:20:12 +08002696 player->has_video = DVR_FALSE;
2697
2698 AmTsPlayer_stopVideoDecoding(player->handle);
2699 //playback_device_video_stop(player->handle);
2700
2701 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002702 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002703
Wentao MA96f68962022-06-15 19:45:35 +08002704 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002705 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002706 return DVR_SUCCESS;
2707}
2708/**\brief Pause play
2709 * \param[in] handle playback handle
2710 * \param[in] flush whether its internal buffers should be flushed
2711 * \retval DVR_SUCCESS On success
2712 * \return Error code
2713 */
hualing chen040df222020-01-17 13:35:02 +08002714int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2715 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002716 DVR_UNUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002717 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002718 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002719 return DVR_FAILURE;
2720 }
hualing chenf00cdc82020-06-10 14:23:35 +08002721 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
Wentao MA96f68962022-06-15 19:45:35 +08002722 DVR_PB_INFO("player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002723 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002724 }
Wentao MA96f68962022-06-15 19:45:35 +08002725 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002726 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002727 DVR_PB_DEBUG("get lock");
hualing chen266b9502020-04-04 17:39:39 +08002728 if (player->has_video)
2729 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002730 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002731 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002732
2733 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002734 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2735 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2736 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002737 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002738 } else {
2739 player->cmd.last_cmd = player->cmd.cur_cmd;
2740 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2741 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002742 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002743 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002744 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002745 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002746
hualing chen86e7d482020-01-16 15:13:33 +08002747 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002748}
2749
hualing chen5cbe1a62020-02-10 16:36:36 +08002750//not add lock
2751static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2752{
2753 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2754
hualing chena540a7e2020-03-27 16:44:05 +08002755 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002756 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002757 return DVR_FAILURE;
2758 }
2759
hualing chen5cbe1a62020-02-10 16:36:36 +08002760 //get video params and audio params
Wentao MA96f68962022-06-15 19:45:35 +08002761 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002762 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08002763 am_tsplayer_video_params video_params;
2764 am_tsplayer_audio_params audio_params;
2765 am_tsplayer_audio_params ad_params;
hualing chencc91e1c2020-02-28 13:26:17 +08002766 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002767
Wentao MA270dc0f2022-08-23 13:17:26 +08002768 memset(&video_params, 0, sizeof(video_params));
2769 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002770
Wentao MA270dc0f2022-08-23 13:17:26 +08002771 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
Zhiqiang Han83923642023-11-03 12:06:48 +08002772 DVR_PB_INFO("unlock, _dvr_cmd: %#x", cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002773 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002774
Zhiqiang Han83923642023-11-03 12:06:48 +08002775 if (DVR_PLAYBACK_CMD_IS_V_RESTART(cmd) && DVR_PLAYBACK_CMD_IS_A_RESTART(cmd)) {
2776
2777 DVR_PB_INFO("do_cmd av_restart");
2778 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
2779
2780 } else if (cmd == DVR_PLAYBACK_CMD_FF || cmd == DVR_PLAYBACK_CMD_FB) {
2781
2782 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
2783
2784 } else if (cmd == DVR_PLAYBACK_CMD_START || cmd == DVR_PLAYBACK_CMD_STOP) {
2785
2786 //nop
2787
2788 } else {
2789
2790 if (DVR_PLAYBACK_CMD_IS_A_STOP(cmd)) {
2791 DVR_PB_INFO("do_cmd a_stop");
2792 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2793 }
2794
2795 if (DVR_PLAYBACK_CMD_IS_V_STOP(cmd)) {
2796 DVR_PB_INFO("do_cmd v_stop");
hualing chen2aba4022020-03-02 13:49:55 +08002797 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Zhiqiang Han83923642023-11-03 12:06:48 +08002798 }
2799
2800 if (DVR_PLAYBACK_CMD_IS_V_START(cmd)) {
2801 DVR_PB_INFO("do_cmd v_start");
Wentao MA270dc0f2022-08-23 13:17:26 +08002802 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
Zhiqiang Han83923642023-11-03 12:06:48 +08002803 }
2804
2805 if (DVR_PLAYBACK_CMD_IS_A_START(cmd)) {
2806 DVR_PB_INFO("do_cmd a_start");
Wentao MA270dc0f2022-08-23 13:17:26 +08002807 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
Zhiqiang Han83923642023-11-03 12:06:48 +08002808 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002809 }
Zhiqiang Han83923642023-11-03 12:06:48 +08002810
hualing chen5cbe1a62020-02-10 16:36:36 +08002811 return DVR_SUCCESS;
2812}
2813
2814/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002815 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002816 * \retval DVR_SUCCESS On success
2817 * \return Error code
2818 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002819int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2820 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002821 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002822 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002823 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002824 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002825 return DVR_FAILURE;
2826 }
2827
hualing chena991aa82021-08-16 10:21:15 +08002828 if (dvr_playback_check_limit(handle)) {
2829 //get id and pos to check if we can seek to this pos
Wentao MA96f68962022-06-15 19:45:35 +08002830 DVR_PB_INFO("player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002831 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2832 if (segmentid != player->cur_segment_id ||
2833 (segmentid == player->cur_segment_id &&
2834 pos > _dvr_get_cur_time(handle))) {
2835 //first to seek new pos and to resume
Wentao MA96f68962022-06-15 19:45:35 +08002836 DVR_PB_INFO("seek new pos and to resume");
hualing chena991aa82021-08-16 10:21:15 +08002837 dvr_playback_seek(handle, segmentid, pos);
2838 }
hualing chen7ea70a72021-09-09 11:25:13 +08002839 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002840 DVR_PB_INFO("player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002841 }
hualing chena991aa82021-08-16 10:21:15 +08002842
hualing chen5cbe1a62020-02-10 16:36:36 +08002843 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08002844 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002845 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002846 player->first_frame = 0;
2847 if (player->has_video)
2848 AmTsPlayer_pauseVideoDecoding(player->handle);
2849 if (player->has_audio)
2850 AmTsPlayer_pauseAudioDecoding(player->handle);
2851
hualing chen266b9502020-04-04 17:39:39 +08002852 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002853 DVR_PB_INFO("dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002854 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2855 AmTsPlayer_resumeVideoDecoding(player->handle);
2856 }
2857 if (player->has_audio) {
2858 AmTsPlayer_resumeAudioDecoding(player->handle);
2859 }
2860 //check is has audio param,if has audio .we need start audio,
2861 //we will stop audio when ff fb, if reach end, we will pause.so we need
2862 //start audio when resume play
2863
Wentao MA270dc0f2022-08-23 13:17:26 +08002864 am_tsplayer_video_params video_params;
2865 am_tsplayer_audio_params audio_params;
2866 am_tsplayer_audio_params ad_params;
hualing chen266b9502020-04-04 17:39:39 +08002867 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002868
Wentao MA270dc0f2022-08-23 13:17:26 +08002869 memset(&video_params, 0, sizeof(video_params));
2870 memset(&audio_params, 0, sizeof(audio_params));
2871 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
hualing chen266b9502020-04-04 17:39:39 +08002872 //valid audio pid, start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002873 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 +08002874 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002875 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002876 dvr_playback_change_seek_state(handle, ad_params.pid);
2877 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen969fe7b2021-05-26 15:13:17 +08002878 AmTsPlayer_enableADMix(player->handle);
2879 }
2880
Wentao MA270dc0f2022-08-23 13:17:26 +08002881 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 +08002882 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002883 dvr_playback_change_seek_state(handle, audio_params.pid);
2884 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002885 if (player->audio_presentation_id > -1) {
2886 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2887 }
hualing chen266b9502020-04-04 17:39:39 +08002888 AmTsPlayer_startAudioDecoding(player->handle);
2889 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08002890 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 +08002891 }
hualing chendf118dd2020-05-21 15:49:11 +08002892
hualing chen87072a82020-03-12 16:20:12 +08002893 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2894 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2895 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002896 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002897 } else {
2898 player->cmd.last_cmd = player->cmd.cur_cmd;
2899 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2900 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002901 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002902 }
Wentao MA96f68962022-06-15 19:45:35 +08002903 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002904 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002905 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
Wentao MA96f68962022-06-15 19:45:35 +08002906 DVR_PB_INFO("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002907 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002908 player->first_frame = 0;
2909 if (player->has_video)
2910 AmTsPlayer_pauseVideoDecoding(player->handle);
2911 if (player->has_audio)
2912 AmTsPlayer_pauseAudioDecoding(player->handle);
2913
Zhiqiang Hane82b61f2023-12-27 16:05:05 +08002914 DVR_PB_INFO("set start state cur cmd[%d]", player->cmd.cur_cmd);
2915 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2916 _dvr_cmd(handle, player->cmd.cur_cmd);
2917
hualing chene41f4372020-06-06 16:29:17 +08002918 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002919 DVR_PB_INFO("dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002920 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002921 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002922 }
hualing chen041c4092020-04-05 15:11:50 +08002923 if (player->has_audio)
2924 AmTsPlayer_resumeAudioDecoding(player->handle);
Zhiqiang Hane82b61f2023-12-27 16:05:05 +08002925
hualing chend1686e52022-01-05 17:10:42 +08002926 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002927 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002928 DVR_PB_INFO("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002929 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002930 } else {
2931 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2932 {
Wentao MA96f68962022-06-15 19:45:35 +08002933 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002934 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002935 player->first_frame = 0;
2936 if (player->has_video)
2937 AmTsPlayer_pauseVideoDecoding(player->handle);
2938 if (player->has_audio)
2939 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002940 //clear flag
Wentao MA96f68962022-06-15 19:45:35 +08002941 DVR_PB_INFO("clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002942 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2943 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002944 if (player->has_video) {
2945 AmTsPlayer_resumeVideoDecoding(player->handle);
2946 }
2947 if (player->has_audio)
2948 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002949 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002950 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002951 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002952 }
2953 return DVR_SUCCESS;
2954}
2955
hualing chena540a7e2020-03-27 16:44:05 +08002956static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2957
2958 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2959 DVR_PlaybackSegmentInfo_t *segment = NULL;
2960 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2961 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2962
wentao.mafd5283f2022-10-14 09:51:13 +08002963 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002964 // prefetch() here incurring self_assign is used to avoid some compiling
2965 // warnings.
2966 // coverity[self_assign]
hualing chena540a7e2020-03-27 16:44:05 +08002967 list_for_each_entry(segment, &player->segment_list, head)
2968 {
2969 if (segment->segment_id == segment_id) {
2970 cur_segment = segment;
2971 }
2972 if (segment->segment_id == set_seg_id) {
2973 set_segment = segment;
2974 }
2975 if (cur_segment != NULL && set_segment != NULL) {
2976 break;
2977 }
2978 }
2979 if (cur_segment == NULL || set_segment == NULL) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002980 DVR_PB_INFO("set segment or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002981 return DVR_TRUE;
2982 }
2983 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2984 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2985 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2986 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
Wentao MA96f68962022-06-15 19:45:35 +08002987 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 +08002988 return DVR_TRUE;
2989 }
Wentao MA96f68962022-06-15 19:45:35 +08002990 DVR_PB_INFO("play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002991 return DVR_FALSE;
2992}
2993
hualing chen03fd4942021-07-15 15:56:41 +08002994/**\brief set limit
2995 * \param[in] handle playback handle
2996 * \param[in] rec start time ms
2997 * \param[in] rec limit time ms
2998 * \retval DVR_SUCCESS On success
2999 * \return Error code
3000 */
hualing chen7ea70a72021-09-09 11:25:13 +08003001int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08003002{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
3003
3004 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003005 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003006 return DVR_FAILURE;
3007 }
hualing chen7ea70a72021-09-09 11:25:13 +08003008 _dvr_getClock_sec();
Wentao MA96f68962022-06-15 19:45:35 +08003009 DVR_PB_INFO("lock time %lu limit: %u player->state:%d", time, limit, player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003010 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003011 player->rec_start = time;
3012 player->limit = limit;
Wentao MA96f68962022-06-15 19:45:35 +08003013 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003014 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003015 return DVR_SUCCESS;
3016}
3017
hualing chen5cbe1a62020-02-10 16:36:36 +08003018/**\brief seek
3019 * \param[in] handle playback handle
3020 * \param[in] time_offset time offset base cur segment
3021 * \retval DVR_SUCCESS On success
3022 * \return Error code
3023 */
hualing chencc91e1c2020-02-28 13:26:17 +08003024int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08003025 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08003026 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08003027 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003028 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003029 return DVR_FAILURE;
3030 }
3031
Wentao MA96f68962022-06-15 19:45:35 +08003032 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 +08003033 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003034
hualing chena540a7e2020-03-27 16:44:05 +08003035 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
Wentao MA96f68962022-06-15 19:45:35 +08003036 DVR_PB_INFO("player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08003037
hualing chen5cbe1a62020-02-10 16:36:36 +08003038 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08003039 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08003040 if (ret ==DVR_FAILURE) {
wentao.maa210e5e2022-10-12 16:10:03 +08003041 DVR_PB_ERROR("unlock seek error at open segment");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003042 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003043 return DVR_FAILURE;
3044 }
3045 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
Wentao MAf35c3882023-04-17 12:36:19 +08003046 if (segment_ongoing(player->segment_handle) == DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08003047 DVR_PB_INFO("is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08003048 time_offset = _dvr_get_end_time(handle);
3049 } else {
wentao.maa210e5e2022-10-12 16:10:03 +08003050 DVR_PB_ERROR("is not ongoing segment when seek end, return failure");
Zhiqiang Han447cff02022-12-15 11:13:41 +08003051 dvr_mutex_unlock(&player->lock);
wentao.maa210e5e2022-10-12 16:10:03 +08003052 return DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08003053 }
3054 }
3055
Wentao MA96f68962022-06-15 19:45:35 +08003056 DVR_PB_INFO("seek open id[%lld]flag[0x%x] time_offset %u",
hualing chen03fd4942021-07-15 15:56:41 +08003057 player->cur_segment.segment_id,
3058 player->cur_segment.flags,
3059 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08003060 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08003061 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3062 //forward playback.not seek end of file
3063 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
3064 //default -2000ms
3065 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
3066 }
hualing chen86e7d482020-01-16 15:13:33 +08003067 }
Wentao MA01de0e62022-01-10 18:48:23 +08003068 // Seek can be regarded as a new playback, so keep the start segment_id for it also
hualing chen8a657f32021-08-30 13:12:49 +08003069 if (player->need_seek_start == DVR_TRUE) {
3070 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
Wentao MA01de0e62022-01-10 18:48:23 +08003071 player->first_start_id = player->cur_segment.segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003072 }
hualing chen2aba4022020-03-02 13:49:55 +08003073 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08003074 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08003075 player->ts_cache_len = 0;
Wentao MAf35c3882023-04-17 12:36:19 +08003076 int offset = segment_seek(player->segment_handle, (uint64_t)time_offset, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08003077 DVR_PB_ERROR("seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08003078 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08003079 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08003080
hualing chen2aba4022020-03-02 13:49:55 +08003081 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08003082
3083 player->last_send_time_id = UINT64_MAX;
Wentao MA270dc0f2022-08-23 13:17:26 +08003084 player->last_segment_total = 0LL;
hualing chen03fd4942021-07-15 15:56:41 +08003085 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08003086 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08003087 player->fffb_current = _dvr_time_getClock();
3088 player->fffb_start = player->fffb_current;
3089 player->fffb_start_pcr = _dvr_get_cur_time(handle);
3090 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08003091 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08003092 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003093 //only seek file,not start
Wentao MA96f68962022-06-15 19:45:35 +08003094 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003095 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003096 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08003097 }
hualing chen86e7d482020-01-16 15:13:33 +08003098 //stop play
Wentao MA96f68962022-06-15 19:45:35 +08003099 DVR_PB_ERROR("seek stop play, not inject data has video[%d]audio[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003100 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08003101
hualing chen266b9502020-04-04 17:39:39 +08003102 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08003103 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003104 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003105 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003106 }
3107
hualing chen40dd5462021-11-26 19:56:20 +08003108
hualing chen266b9502020-04-04 17:39:39 +08003109 if (player->has_audio) {
3110 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003111 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003112 }
hualing chendf118dd2020-05-21 15:49:11 +08003113 if (player->has_ad_audio) {
3114 player->has_ad_audio =DVR_FALSE;
3115 AmTsPlayer_disableADMix(player->handle);
3116 }
3117
hualing chen86e7d482020-01-16 15:13:33 +08003118 //start play
Wentao MA270dc0f2022-08-23 13:17:26 +08003119 am_tsplayer_video_params video_params;
3120 am_tsplayer_audio_params audio_params;
3121 am_tsplayer_audio_params ad_params;
hualing chenb31a6c62020-01-13 17:27:00 +08003122
Wentao MA270dc0f2022-08-23 13:17:26 +08003123 memset(&video_params, 0, sizeof(video_params));
3124 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003125
hualing chen040df222020-01-17 13:35:02 +08003126 player->cur_segment_id = segment_id;
3127
3128 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08003129 //get segment info and audio video pid fmt ;
Wentao MA270dc0f2022-08-23 13:17:26 +08003130 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08003131 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003132 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chena5f03222021-12-02 11:22:35 +08003133 //audio and video pid is all invalid, return error.
Wentao MA270dc0f2022-08-23 13:17:26 +08003134 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 +08003135 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08003136 return -1;
3137 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003138 DVR_PB_ERROR("seek start[0x%x]", video_params.pid);
hualing chen86e7d482020-01-16 15:13:33 +08003139 //add
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003140 int v_restarted = 0;
3141 int a_restarted = 0;
hualing chen040df222020-01-17 13:35:02 +08003142 if (sync == DVR_PLAYBACK_SYNC) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003143 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003144 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08003145 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08003146 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08003147 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08003148 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003149 //if is pause state. we need set trick mode.
Wentao MA96f68962022-06-15 19:45:35 +08003150 DVR_PB_INFO("seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003151 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08003152 }
Wentao MA96f68962022-06-15 19:45:35 +08003153 DVR_PB_INFO("start video");
Wentao MA270dc0f2022-08-23 13:17:26 +08003154 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003155 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003156 AmTsPlayer_startVideoDecoding(player->handle);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003157 v_restarted = 1;
hualing chene41f4372020-06-06 16:29:17 +08003158 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
3159 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
3160 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
3161 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
3162 AmTsPlayer_stopFast(player->handle);
3163 }
hualing chen266b9502020-04-04 17:39:39 +08003164 player->has_video = DVR_TRUE;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08003165 player->fake_mode = (video_params.pid == player->fake_pid)? 1 : 0;
hualing chen7e14e532021-09-23 11:23:28 +08003166 } else {
3167 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08003168 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003169 if (VALID_PID(ad_params.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08003170 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003171 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003172 dvr_playback_change_seek_state(handle, ad_params.pid);
3173 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003174 AmTsPlayer_enableADMix(player->handle);
3175 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003176 if (VALID_PID(audio_params.pid) && player->speed == 1.0) {
Wentao MA96f68962022-06-15 19:45:35 +08003177 DVR_PB_INFO("start audio seek");
Wentao MA270dc0f2022-08-23 13:17:26 +08003178 dvr_playback_change_seek_state(handle, audio_params.pid);
3179 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003180 if (player->audio_presentation_id > -1) {
3181 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3182 }
hualing chen969fe7b2021-05-26 15:13:17 +08003183 AmTsPlayer_startAudioDecoding(player->handle);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003184 a_restarted = 1;
hualing chen969fe7b2021-05-26 15:13:17 +08003185 player->has_audio = DVR_TRUE;
3186 }
hualing chen43a89bc2022-01-19 14:31:20 +08003187#ifdef AVSYNC_USED_PCR
3188 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003189 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003190 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3191 }
3192#endif
hualing chen86e7d482020-01-16 15:13:33 +08003193 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003194 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Zhiqiang Han83923642023-11-03 12:06:48 +08003195
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003196 if (v_restarted) {
Zhiqiang Han83923642023-11-03 12:06:48 +08003197 DVR_PLAYBACK_CMD_RESET_V(player->cmd.cur_cmd);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003198 }
3199 if (a_restarted) {
Zhiqiang Han83923642023-11-03 12:06:48 +08003200 DVR_PLAYBACK_CMD_RESET_A(player->cmd.cur_cmd);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003201 }
Zhiqiang Han83923642023-11-03 12:06:48 +08003202
hualing chen2aba4022020-03-02 13:49:55 +08003203 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00003204 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
Wentao MA270dc0f2022-08-23 13:17:26 +08003205 if (VALID_PID(audio_params.pid) || VALID_PID(video_params.pid))
hualing chena5f03222021-12-02 11:22:35 +08003206 player->seek_pause = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08003207 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 +08003208 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
Wentao MA16f870e2022-09-09 11:00:22 +08003209 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chen31140872020-03-25 12:29:26 +08003210 player->speed > 1.0f||
3211 player->speed <= -1.0f) {
Wentao MA96f68962022-06-15 19:45:35 +08003212 DVR_PB_INFO("not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003213 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003214 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003215 DVR_PB_INFO("set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003216 player->cmd.last_cmd = player->cmd.cur_cmd;
3217 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3218 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003219 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen2aba4022020-03-02 13:49:55 +08003220 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003221 player->last_send_time_id = UINT64_MAX;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08003222
3223 player->con_spe.ply_dur = 0;
3224 player->con_spe.ply_sta = 0;
3225 player->con_spe.sys_dur = 0;
3226 player->con_spe.sys_sta = 0;
3227
Wentao MA96f68962022-06-15 19:45:35 +08003228 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003229 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003230
3231 return DVR_SUCCESS;
3232}
hualing chen5cbe1a62020-02-10 16:36:36 +08003233
Wentao MAac5ea062022-08-11 11:44:27 +08003234// Get current playback time position of the ongoing segment.
3235// Notice the return value may be negative. This is because previous segment's
3236// data cached in demux buffer need to be considered.
hualing chen5cbe1a62020-02-10 16:36:36 +08003237static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3238 //get cur time of segment
3239 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003240
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003241 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003242 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003243 return DVR_FAILURE;
3244 }
3245
Wentao MA270dc0f2022-08-23 13:17:26 +08003246 int64_t cache = 0;//default es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003247 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003248 loff_t pos = segment_tell_position(player->segment_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003249 uint64_t cur = 0;
3250 if (player->ts_cache_len > 0 && pos < 0) {
3251 //this case is open new segment end,but cache data is last segment.
3252 //we need used last segment len to send play time.
3253 cur = 0;
3254 } else {
Wentao MAf35c3882023-04-17 12:36:19 +08003255 cur = segment_tell_position_time(player->segment_handle, pos);
hualing chena5f03222021-12-02 11:22:35 +08003256 }
hualing chen21a40372021-10-29 11:07:26 +08003257 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003258 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08003259 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 +08003260 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3261 cache = 0;
3262 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003263 int cur_time = (int)(cur > cache ? cur - cache : 0);
3264 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003265}
3266
Wentao MAac5ea062022-08-11 11:44:27 +08003267// Get current playback time position of the ongoing segment.
3268// Notice the return value may be negative. This is because previous segment's
3269// data cached in demux buffer need to be considered.
hualing chen969fe7b2021-05-26 15:13:17 +08003270static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3271 //get cur time of segment
3272 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA804bab12022-11-29 10:01:26 +08003273 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MAf35c3882023-04-17 12:36:19 +08003274 DVR_RETURN_IF_FALSE(player->segment_handle != NULL);
hualing chen969fe7b2021-05-26 15:13:17 +08003275
hualing chen969fe7b2021-05-26 15:13:17 +08003276 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003277 const loff_t pos = segment_tell_position(player->segment_handle);
3278 const uint64_t cur = segment_tell_position_time(player->segment_handle, pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003279 pthread_mutex_unlock(&player->segment_lock);
Wentao MA01de0e62022-01-10 18:48:23 +08003280
Wentao MA804bab12022-11-29 10:01:26 +08003281 int cache = 0;
3282 get_effective_tsplayer_delay_time(player, &cache);
Wentao MA01de0e62022-01-10 18:48:23 +08003283
hualing chen969fe7b2021-05-26 15:13:17 +08003284 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3285 cache = 0;
3286 }
Wentao MA804bab12022-11-29 10:01:26 +08003287
Wentao MA3e2dc452022-12-20 11:17:16 +08003288 int cur_time = (int)(cur - cache);
Wentao MA804bab12022-11-29 10:01:26 +08003289 *id = player->cur_segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003290
Wentao MA3e2dc452022-12-20 11:17:16 +08003291 if (*id == 0 && cur_time<0) {
3292 cur_time = 0;
3293 }
3294
Wentao MA80179512022-11-03 12:20:03 +08003295 DVR_PB_INFO("***get playback slider position within segment. segment_id [%lld],"
wentao.ma4ee43022022-12-14 13:22:57 +08003296 " segment_slider_pos[%7d ms] = segment_read_pos[%7lld ms] - tsplayer_cache_len[%5ld ms],"
Wentao MA80179512022-11-03 12:20:03 +08003297 " last id [%lld] pos [%lld]",
3298 player->cur_segment_id,cur_time,cur,cache,player->last_send_time_id,pos);
Wentao MA804bab12022-11-29 10:01:26 +08003299
hualing chen969fe7b2021-05-26 15:13:17 +08003300 return cur_time;
3301}
3302
hualing chencc91e1c2020-02-28 13:26:17 +08003303//get current segment current pcr time of read pos
3304static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3305 //get cur time of segment
3306 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAf35c3882023-04-17 12:36:19 +08003307 DVR_RETURN_IF_FALSE(player != NULL);
3308 DVR_RETURN_IF_FALSE(player->segment_handle != NULL);
hualing chena540a7e2020-03-27 16:44:05 +08003309
3310 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003311 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003312 return DVR_FAILURE;
3313 }
3314
hualing chen2aba4022020-03-02 13:49:55 +08003315 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003316 uint64_t end = segment_tell_total_time(player->segment_handle);
hualing chen2aba4022020-03-02 13:49:55 +08003317 pthread_mutex_unlock(&player->segment_lock);
3318 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003319}
3320
hualing chen03fd4942021-07-15 15:56:41 +08003321DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3322{
3323 //check is set limit info
3324 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3325
3326 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003327 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003328 return DVR_FALSE;
3329 }
3330 if (player->rec_start > 0 || player->limit > 0) {
3331 return DVR_TRUE;
3332 }
3333 return DVR_FALSE;
3334}
3335
3336/**\brief set DVR playback calculate expired time len
3337 * \param[in] handle, DVR playback session handle
3338 * \return DVR_SUCCESS on success
3339 * \return error code on failure
3340 */
hualing chen7ea70a72021-09-09 11:25:13 +08003341uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003342{
3343 //calculate expired time to play
3344 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003345 uint32_t cur_time;
3346 uint32_t tmp_time;
3347 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003348 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003349 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003350 return expired;
3351 }
hualing chen7ea70a72021-09-09 11:25:13 +08003352 if (player->rec_start == 0 || player->limit == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003353 DVR_PB_INFO("rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003354 return expired;
3355 }
3356 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003357 cur_time = _dvr_getClock_sec();
3358 if ((cur_time - player->rec_start) > player->limit) {
3359 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3360 expired = *(int*)&tmp_time;
Wentao MA96f68962022-06-15 19:45:35 +08003361 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 +08003362 cur_time,
3363 player->rec_start,
3364 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003365 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3366 }
hualing chen03fd4942021-07-15 15:56:41 +08003367 return expired;
3368}
3369
3370/**\brief set DVR playback obsolete time
3371 * \param[in] handle, DVR playback session handle
3372 * \param[in] obsolete, obsolete len
3373 * \return DVR_SUCCESS on success
3374 * \return error code on failure
3375 */
3376int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3377{
3378 int expired = 0;
3379 //calculate expired time to play
3380 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3381
3382 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003383 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003384 return DVR_FALSE;
3385 }
3386 //get system time
Wentao MA96f68962022-06-15 19:45:35 +08003387 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003388 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003389 player->obsolete = obsolete;
Wentao MA96f68962022-06-15 19:45:35 +08003390 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003391 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003392 return expired;
3393}
3394
3395/**\brief update DVR playback newest segment duration
3396 * \param[in] handle, DVR playback session handle
3397 * \param[in] segmentid, newest segment id
3398 * \param[in] dur dur time ms
3399 * \return DVR_SUCCESS on success
3400 * \return error code on failure
3401 */
3402int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3403uint64_t segmentid, int dur)
3404{
3405 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3406 DVR_PlaybackSegmentInfo_t *segment;
3407 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3408
3409 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003410 DVR_PB_INFO(" player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003411 return DVR_FAILURE;
3412 }
3413 //update the newest segment duration on timeshift mode
wentao.mafd5283f2022-10-14 09:51:13 +08003414 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003415 // prefetch() here incurring self_assign is used to avoid some compiling
3416 // warnings.
3417 // coverity[self_assign]
hualing chen03fd4942021-07-15 15:56:41 +08003418 list_for_each_entry(segment, &player->segment_list, head)
3419 {
3420 if (segment->segment_id == segmentid) {
3421 segment->duration = dur;
3422 break;
3423 }
3424 pre_segment = segment;
3425 }
3426
3427 return DVR_SUCCESS;
3428}
3429
hualing chen7ea70a72021-09-09 11:25:13 +08003430static uint32_t dvr_playback_calculate_last_valid_segment(
3431 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003432{
hualing chen7ea70a72021-09-09 11:25:13 +08003433 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003434 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003435 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003436 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003437 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003438 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3439
3440 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003441 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003442 return DVR_FAILURE;
3443 }
3444 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003445 if (expired == 0) {
3446 *segmentid = player->cur_segment_id;
3447 *pos = 0;
3448 return DVR_SUCCESS;
3449 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003450 DVR_PlaybackSegmentInfo_t *p_seg;
wentao.mafd5283f2022-10-14 09:51:13 +08003451 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003452 // prefetch() here incurring self_assign is used to avoid some compiling
3453 // warnings.
3454 // coverity[self_assign]
Wentao MA270dc0f2022-08-23 13:17:26 +08003455 list_for_each_entry_reverse(p_seg, &player->segment_list, head) {
3456 segment_id = p_seg->segment_id;
hualing chen03fd4942021-07-15 15:56:41 +08003457
Wentao MA270dc0f2022-08-23 13:17:26 +08003458 if ((player->obsolete + pre_off + p_seg->duration) > expired)
hualing chen03fd4942021-07-15 15:56:41 +08003459 break;
3460
Wentao MA270dc0f2022-08-23 13:17:26 +08003461 last_segment_id = p_seg->segment_id;
3462 pre_off += p_seg->duration;
hualing chen03fd4942021-07-15 15:56:41 +08003463 }
3464
3465 if (last_segment_id == segment_id) {
3466 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3467 off = expired;
3468 } else if (player->obsolete >= expired) {
3469 off = 0;
3470 } else {
3471 off = expired - pre_off - player->obsolete;
3472 }
3473 *segmentid = segment_id;
3474 *pos = off;
3475 return DVR_SUCCESS;
3476}
3477
hualing chen4b7c15d2020-04-07 16:13:48 +08003478#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003479//start replay
3480static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3481
3482 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3483 //calculate pcr seek time
3484 int t_diff = 0;
3485 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003486 uint64_t segmentid = 0;
3487 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003488 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003489 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003490 return DVR_FAILURE;
3491 }
3492
hualing chen5cbe1a62020-02-10 16:36:36 +08003493 if (player->fffb_start == -1) {
3494 //set fffb start time ms
3495 player->fffb_start = _dvr_time_getClock();
3496 player->fffb_current = player->fffb_start;
3497 //get segment current time pos
3498 player->fffb_start_pcr = _dvr_get_cur_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003499 DVR_PB_INFO("calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
hualing chen03fd4942021-07-15 15:56:41 +08003500 player->fffb_start_pcr, player->speed);
hualing chene41f4372020-06-06 16:29:17 +08003501 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003502 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003503 } else {
3504 player->fffb_current = _dvr_time_getClock();
3505 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003506 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003507 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003508 if (seek_time <= 0) {
3509 //need seek to pre one segment
3510 seek_time = 0;
3511 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003512 //seek segment pos
Wentao MAf35c3882023-04-17 12:36:19 +08003513 if (player->segment_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003514 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003515 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003516 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3517 //set seek time to 0;
Wentao MA96f68962022-06-15 19:45:35 +08003518 DVR_PB_INFO("segment seek to 0 at fb mode [%d]id[%lld]",
hualing chen03fd4942021-07-15 15:56:41 +08003519 seek_time,
3520 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003521 seek_time = 0;
3522 }
hualing chen03fd4942021-07-15 15:56:41 +08003523 if (IS_FB(player->speed)
3524 && dvr_playback_check_limit(handle)) {
3525 //fb case.check expired time
3526 //get id and pos to check if we can seek to this pos
3527 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3528 //case cur id < segment id
3529 if (player->cur_segment_id < segmentid) {
3530 //expired ts data is player,return error
3531 //
3532 pthread_mutex_unlock(&player->segment_lock);
3533 return 0;
3534 } else if (player->cur_segment_id == segmentid) {
3535 //id is same,compare seek pos
3536 if (seek_time < pos) {
3537 //expired ts data is player,return error
3538 //
3539 pthread_mutex_unlock(&player->segment_lock);
3540 return 0;
3541 }
3542 }
3543 //case can play
3544 }
Wentao MAf35c3882023-04-17 12:36:19 +08003545 if (segment_seek(player->segment_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
hualing chen041c4092020-04-05 15:11:50 +08003546 seek_time = 0;
3547 }
hualing chen2aba4022020-03-02 13:49:55 +08003548 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003549 } else {
3550 //
Wentao MA96f68962022-06-15 19:45:35 +08003551 DVR_PB_INFO("segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003552 }
Wentao MA96f68962022-06-15 19:45:35 +08003553 DVR_PB_INFO("calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003554 seek_time,
3555 player->speed,
3556 player->cur_segment_id,
3557 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003558 }
hualing chen2aba4022020-03-02 13:49:55 +08003559 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003560}
3561
3562
3563//start replay
3564static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3565 //
3566 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003567
3568 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003569 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003570 return DVR_FAILURE;
3571 }
3572
hualing chen5cbe1a62020-02-10 16:36:36 +08003573 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003574 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08003575 DVR_PB_INFO("fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003576 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003577 AmTsPlayer_stopVideoDecoding(player->handle);
3578 }
3579 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003580 DVR_PB_INFO("fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003581 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003582 AmTsPlayer_stopAudioDecoding(player->handle);
3583 }
hualing chendf118dd2020-05-21 15:49:11 +08003584 if (player->has_ad_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003585 DVR_PB_INFO("fffb stop audio");
hualing chendf118dd2020-05-21 15:49:11 +08003586 player->has_ad_audio =DVR_FALSE;
3587 AmTsPlayer_disableADMix(player->handle);
3588 }
hualing chen2aba4022020-03-02 13:49:55 +08003589
hualing chen5cbe1a62020-02-10 16:36:36 +08003590 //start video and audio
3591
Wentao MA270dc0f2022-08-23 13:17:26 +08003592 am_tsplayer_video_params video_params;
3593 am_tsplayer_audio_params audio_params;
3594 am_tsplayer_audio_params ad_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003595
Wentao MA270dc0f2022-08-23 13:17:26 +08003596 memset(&video_params, 0, sizeof(video_params));
3597 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003598
hualing chen87072a82020-03-12 16:20:12 +08003599 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003600
3601 //get segment info and audio video pid fmt ;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003602 //dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08003603 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003604 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003605 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
3606 //audio and video pids are all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003607 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003608 return -1;
3609 }
3610
Wentao MA270dc0f2022-08-23 13:17:26 +08003611 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003612 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003613 DVR_PB_INFO("fffb start video");
3614 //DVR_PB_INFO("fffb start video and save last frame");
hualing chen0888c032020-12-18 17:54:57 +08003615 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003616 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003617 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
Wentao MA270dc0f2022-08-23 13:17:26 +08003618 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003619 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003620 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003621 //playback_device_video_start(player->handle , &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003622 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003623 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003624 }
hualing chen31140872020-03-25 12:29:26 +08003625 //fffb mode need stop fast;
Wentao MA96f68962022-06-15 19:45:35 +08003626 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003627 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003628 return 0;
3629}
3630
3631static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3632 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003633 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003634 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003635 return DVR_FAILURE;
3636 }
3637
3638 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003639 DVR_PB_INFO("lock speed [%f]", player->speed);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003640 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003641
hualing chen2aba4022020-03-02 13:49:55 +08003642 int seek_time = _dvr_playback_calculate_seekpos(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003643 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 +08003644
hualing chen87072a82020-03-12 16:20:12 +08003645 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3646 //seek time set 0
3647 seek_time = 0;
3648 }
hualing chen041c4092020-04-05 15:11:50 +08003649 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003650 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3651 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003652 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
wentao.ma4ee43022022-12-14 13:22:57 +08003653
3654 // An fffb_replay is required here to help finish the last FB play
3655 // at beginning position of a recording. In addition to function
3656 // correctness, another benefit is that after play, demux buffer
3657 // is cleared due to stopVideoDecoding invocation in the process.
3658 // The following resume operation will not be affected by the invalid
3659 // cache length.
3660 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
3661 _dvr_playback_fffb_replay(handle);
3662
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003663 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003664 DVR_PB_DEBUG("unlock");
Wentao MAfae6ce82023-12-29 17:55:55 +08003665#ifdef FOR_OTT_49490
Wentao MA75775d22023-09-25 16:53:24 +08003666 DVR_PlaybackSpeed_t normal_speed = {PLAYBACK_SPEED_X1,0};
3667 DVR_PB_INFO("Change to normal speed due to FB reaching beginning");
3668 dvr_playback_set_speed((DVR_PlaybackHandle_t)player,normal_speed);
Wentao MA9e31f692023-09-26 17:42:18 +08003669
3670 {
3671 DVR_Play_Notify_t notify;
3672 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
3673 notify.event = DVR_PLAYBACK_EVENT_TIMESHIFT_FR_REACHED_BEGIN;
3674 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, notify.event, &notify, 0);
3675 }
Wentao MA75775d22023-09-25 16:53:24 +08003676#else
Wentao MA9e31f692023-09-26 17:42:18 +08003677 DVR_PB_INFO("Change to pause due to FB reaching beginning");
hualing chen87072a82020-03-12 16:20:12 +08003678 dvr_playback_pause(handle, DVR_FALSE);
Wentao MA75775d22023-09-25 16:53:24 +08003679#endif
Wentao MA9e31f692023-09-26 17:42:18 +08003680 {
3681 //send event here and pause
3682 DVR_Play_Notify_t notify;
3683 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
3684 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
3685 //get play statue not here
3686 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
3687 DVR_PB_INFO("*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
3688 }
hualing chen2aba4022020-03-02 13:49:55 +08003689 return DVR_SUCCESS;
3690 }
hualing chen2932d372020-04-29 13:44:00 +08003691 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003692 _dvr_init_fffb_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003693 DVR_PB_INFO("*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003694 }
3695 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003696 _dvr_playback_fffb_replay(handle);
3697
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003698 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003699 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003700
hualing chen5cbe1a62020-02-10 16:36:36 +08003701 return DVR_SUCCESS;
3702}
3703
hualing chen87072a82020-03-12 16:20:12 +08003704//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003705static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003706 //
3707 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003708
3709 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003710 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003711 return DVR_FAILURE;
3712 }
3713
hualing chen5cbe1a62020-02-10 16:36:36 +08003714 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003715 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003716 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003717 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003718 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003719 }
3720
3721 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003722 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003723 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003724 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003725 //start video and audio
3726
Wentao MA270dc0f2022-08-23 13:17:26 +08003727 am_tsplayer_video_params video_params;
3728 am_tsplayer_audio_params audio_params;
3729 am_tsplayer_audio_params ad_params;
hualing chen87072a82020-03-12 16:20:12 +08003730 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003731
Wentao MA270dc0f2022-08-23 13:17:26 +08003732 memset(&video_params, 0, sizeof(video_params));
3733 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003734
hualing chen5cbe1a62020-02-10 16:36:36 +08003735 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08003736 DVR_PB_INFO("into");
Wentao MA270dc0f2022-08-23 13:17:26 +08003737 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003738 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003739 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003740 //audio and video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003741 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003742 return -1;
3743 }
3744
Wentao MA270dc0f2022-08-23 13:17:26 +08003745 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003746 player->has_video = DVR_TRUE;
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08003747 player->fake_mode = (video_params.pid == player->fake_pid)? 1 : 0;
hualing chen87072a82020-03-12 16:20:12 +08003748 if (trick == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003749 DVR_PB_INFO("settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003750 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003751 }
hualing chen266b9502020-04-04 17:39:39 +08003752 else {
hualing chen2aba4022020-03-02 13:49:55 +08003753 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003754 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003755 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003756 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003757 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003758 }
hualing chena540a7e2020-03-27 16:44:05 +08003759
3760 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
Wentao MA96f68962022-06-15 19:45:35 +08003761 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08003762 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003763 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003764 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08003765 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08003766 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003767 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003768 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003769 AmTsPlayer_enableADMix(player->handle);
3770 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003771 if (VALID_PID(audio_params.pid)) {
hualing chen969fe7b2021-05-26 15:13:17 +08003772 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003773 DVR_PB_INFO("start audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003774 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003775 if (player->audio_presentation_id > -1) {
3776 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3777 }
hualing chen969fe7b2021-05-26 15:13:17 +08003778 AmTsPlayer_startAudioDecoding(player->handle);
3779 }
hualing chendf118dd2020-05-21 15:49:11 +08003780
Wentao MA96f68962022-06-15 19:45:35 +08003781 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003782 AmTsPlayer_stopFast(player->handle);
3783 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3784 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3785 }
hualing chen43a89bc2022-01-19 14:31:20 +08003786#ifdef AVSYNC_USED_PCR
3787 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003788 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003789 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3790 }
3791#endif
hualing chen2aba4022020-03-02 13:49:55 +08003792 player->cmd.last_cmd = player->cmd.cur_cmd;
3793 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003794 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003795 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen5cbe1a62020-02-10 16:36:36 +08003796 return 0;
3797}
3798
3799
hualing chenb31a6c62020-01-13 17:27:00 +08003800/**\brief Set play speed
3801 * \param[in] handle playback handle
3802 * \param[in] speed playback speed
3803 * \retval DVR_SUCCESS On success
3804 * \return Error code
3805 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003806int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3807
3808 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003809
3810 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003811 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003812 return DVR_FAILURE;
3813 }
3814
hualing chena540a7e2020-03-27 16:44:05 +08003815 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08003816 DVR_PB_INFO(" func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003817 return DVR_FAILURE;
3818 }
hualing chenf00cdc82020-06-10 14:23:35 +08003819 if (speed.speed.speed == player->cmd.speed.speed.speed) {
Wentao MA96f68962022-06-15 19:45:35 +08003820 DVR_PB_INFO(" func: eq speed [%d]", speed.speed.speed);
hualing chenf00cdc82020-06-10 14:23:35 +08003821 return DVR_SUCCESS;
3822 }
Wentao MA96f68962022-06-15 19:45:35 +08003823 DVR_PB_INFO("lock func: speed [%d]", speed.speed.speed);
hualing chen1679f812021-11-08 15:17:46 +08003824
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003825 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003826 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3827 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3828 player->cmd.last_cmd = player->cmd.cur_cmd;
3829 }
hualing chene41f4372020-06-06 16:29:17 +08003830
hualing chen31140872020-03-25 12:29:26 +08003831 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003832 IS_KERNEL_SPEED(speed.speed.speed) ) {
3833 //case 1. not start play.only set speed
3834 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3835 //only set speed.and return;
3836 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3837 player->cmd.speed.speed = speed.speed;
3838 player->speed = (float)speed.speed.speed/(float)100;
3839 player->fffb_play = DVR_FALSE;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003840 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003841 DVR_PB_DEBUG("unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003842 return DVR_SUCCESS;
3843 }
3844 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003845 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3846 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003847 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003848 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3849 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003850 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003851 AmTsPlayer_stopFast(player->handle);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003852 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003853 DVR_PB_DEBUG("unlock ---\r\n");
Wentao MA270dc0f2022-08-23 13:17:26 +08003854 _dvr_cmd(handle, DVR_PLAYBACK_CMD_A_START);
Wentao MA96f68962022-06-15 19:45:35 +08003855 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003856 dvr_mutex_lock(&player->lock);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003857 } else {
3858 //set play speed and if audio is start, stop audio.
3859 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003860 DVR_PB_INFO("fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003861 AmTsPlayer_stopAudioDecoding(player->handle);
3862 player->has_audio = DVR_FALSE;
3863 }
Wentao MA96f68962022-06-15 19:45:35 +08003864 DVR_PB_INFO("start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003865 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003866 }
hualing chenbcada022020-04-22 14:27:01 +08003867 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003868 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003869 player->cmd.speed.speed = speed.speed;
3870 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA96f68962022-06-15 19:45:35 +08003871 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003872 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003873 return DVR_SUCCESS;
3874 }
hualing chen31140872020-03-25 12:29:26 +08003875 //case 3 fffb mode
3876 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3877 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3878 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003879 DVR_PB_INFO("set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003880 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003881 player->cmd.speed.speed = speed.speed;
3882 player->speed = (float)speed.speed.speed/(float)100;
3883 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003884 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003885 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003886 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003887 return DVR_SUCCESS;
3888 }
3889 }
3890 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003891 IS_KERNEL_SPEED(speed.speed.speed)) {
3892 //case 1. cur speed is kernel support speed,set kernel speed.
3893 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003894 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003895 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3896 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003897 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003898 AmTsPlayer_stopFast(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003899 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
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 at pause");
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 chenf00cdc82020-06-10 14:23:35 +08003908 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003909 }
hualing chena540a7e2020-03-27 16:44:05 +08003910 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003911 player->cmd.speed.speed = speed.speed;
3912 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003913 player->fffb_play = DVR_FALSE;
Zhiqiang Han923a24b2024-09-24 18:32:14 +08003914
3915 _dvr_playback_replay(player, DVR_FALSE);
3916
Wentao MA96f68962022-06-15 19:45:35 +08003917 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003918 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003919 return DVR_SUCCESS;
3920 }
3921 //case 2 fffb mode
3922 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3923 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3924 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003925 DVR_PB_INFO("set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003926 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003927 player->cmd.speed.speed = speed.speed;
3928 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA270dc0f2022-08-23 13:17:26 +08003929 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
hualing chenbcada022020-04-22 14:27:01 +08003930 player->fffb_play = DVR_FALSE;
Zhiqiang Han68ba6bc2024-04-02 15:02:34 +08003931
3932 /*paused in fffb and set speed(>0), resume the playback*/
3933 dvr_playback_resume(player);
3934
Wentao MA96f68962022-06-15 19:45:35 +08003935 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003936 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003937 return DVR_SUCCESS;
3938 }
Zhiqiang Han923a24b2024-09-24 18:32:14 +08003939 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
3940 //not kernel speed, quit pause mode
3941 _dvr_playback_replay(player, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08003942 }
Zhiqiang Han923a24b2024-09-24 18:32:14 +08003943
hualing chena540a7e2020-03-27 16:44:05 +08003944 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3945 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003946 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003947 } else {
hualing chen31140872020-03-25 12:29:26 +08003948 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003949 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3950 else
3951 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003952 player->fffb_play = DVR_TRUE;
3953 }
3954 DVR_Bool_t init_last_time = DVR_FALSE;
3955 if (player->speed > 0.0f && speed.speed.speed < 0) {
3956 init_last_time = DVR_TRUE;
3957 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3958 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003959 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003960 player->cmd.speed.mode = speed.mode;
3961 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003962 player->speed = (float)speed.speed.speed/(float)100;
3963 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003964 _dvr_init_fffb_t(handle);
3965 if (init_last_time == DVR_TRUE)
3966 player->last_send_time_id = UINT64_MAX;
3967
hualing chen87072a82020-03-12 16:20:12 +08003968 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003969 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3970 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003971 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003972 DVR_PB_INFO("set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003973 _dvr_playback_replay(handle, DVR_FALSE);
3974 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3975 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003976 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
Wentao MA96f68962022-06-15 19:45:35 +08003977 DVR_PB_INFO("set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003978 }
Wentao MA96f68962022-06-15 19:45:35 +08003979 DVR_PB_INFO("unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003980 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003981 return DVR_SUCCESS;
3982}
hualing chen2932d372020-04-29 13:44:00 +08003983
hualing chenb31a6c62020-01-13 17:27:00 +08003984/**\brief Get playback status
3985 * \param[in] handle playback handle
3986 * \param[out] p_status playback status
3987 * \retval DVR_SUCCESS On success
3988 * \return Error code
3989 */
hualing chen2932d372020-04-29 13:44:00 +08003990static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3991 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003992//
3993 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003994 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003995 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003996 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003997 return DVR_FAILURE;
3998 }
hualing chen1679f812021-11-08 15:17:46 +08003999 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08004000 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004001 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08004002 }
4003
hualing chen5cbe1a62020-02-10 16:36:36 +08004004 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08004005 //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 +08004006 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
4007 player->state == DVR_PLAYBACK_STATE_START) {
4008 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
4009 }
hualing chen041c4092020-04-05 15:11:50 +08004010
hualing chencc91e1c2020-02-28 13:26:17 +08004011 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08004012 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08004013
Zhiqiang Hand5c1c042024-09-14 14:32:28 +08004014 if (player->control_speed_enable == 1)
4015 calc_speed_control(player, p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08004016
hualing chen4b7c15d2020-04-07 16:13:48 +08004017 if (player->last_send_time_id == UINT64_MAX) {
4018 player->last_send_time_id = player->cur_segment_id;
4019 player->last_cur_time = p_status->time_cur;
4020 }
4021 if (player->last_send_time_id == player->cur_segment_id) {
Wentao MA80179512022-11-03 12:20:03 +08004022 if (player->speed > 1.0f ) {
hualing chen4b7c15d2020-04-07 16:13:48 +08004023 //ff
4024 if (p_status->time_cur < player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004025 DVR_PB_INFO("get ff time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004026 player->last_cur_time,
4027 p_status->time_cur,
4028 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08004029 p_status->time_cur = player->last_cur_time;
4030 } else {
4031 player->last_cur_time = p_status->time_cur;
4032 }
hualing chene41f4372020-06-06 16:29:17 +08004033 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08004034 //fb
4035 if (p_status->time_cur > player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004036 DVR_PB_INFO("get fb time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004037 player->last_cur_time,
4038 p_status->time_cur,
4039 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08004040 p_status->time_cur = player->last_cur_time;
4041 } else {
4042 player->last_cur_time = p_status->time_cur;
4043 }
4044 }
hualing chend241c7a2021-06-22 13:34:27 +08004045 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08004046 player->last_cur_time = p_status->time_cur;
4047 }
hualing chen969fe7b2021-05-26 15:13:17 +08004048 player->last_send_time_id = segment_id;
4049 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08004050
hualing chen5cbe1a62020-02-10 16:36:36 +08004051 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08004052 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08004053 p_status->flags = player->cur_segment.flags;
Wentao MA96f68962022-06-15 19:45:35 +08004054 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 +08004055 _dvr_playback_state_toString(player->state),
4056 _dvr_playback_state_toString(p_status->state),
4057 p_status->time_cur, p_status->time_end,
4058 p_status->segment_id,player->play_flag,
4059 player->speed,
4060 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08004061 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08004062 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004063 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08004064 }
hualing chen2932d372020-04-29 13:44:00 +08004065 return DVR_SUCCESS;
4066}
4067
4068
4069/**\brief Get playback status
4070 * \param[in] handle playback handle
4071 * \param[out] p_status playback status
4072 * \retval DVR_SUCCESS On success
4073 * \return Error code
4074 */
4075int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
4076 DVR_PlaybackStatus_t *p_status) {
4077//
4078 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4079
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004080 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
4081
hualing chen2932d372020-04-29 13:44:00 +08004082 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004083 DVR_PB_INFO("player is NULL");
hualing chen2932d372020-04-29 13:44:00 +08004084 return DVR_FAILURE;
4085 }
Wentao MA96f68962022-06-15 19:45:35 +08004086 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004087 dvr_mutex_lock(&player->lock);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004088 if (!player->has_video && !player->has_audio)
4089 p_status->time_cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08004090 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004091 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08004092
hualing chenb31a6c62020-01-13 17:27:00 +08004093 return DVR_SUCCESS;
4094}
4095
hualing chen040df222020-01-17 13:35:02 +08004096void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
4097 if (segment != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004098 DVR_PB_INFO("segment id: %lld", segment->segment_id);
4099 DVR_PB_INFO("segment flag: %d", segment->flags);
4100 DVR_PB_INFO("segment location: [%s]", segment->location);
4101 DVR_PB_INFO("segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
4102 DVR_PB_INFO("segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
4103 DVR_PB_INFO("segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
4104 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 +08004105 }
hualing chenb31a6c62020-01-13 17:27:00 +08004106}
4107
hualing chen5cbe1a62020-02-10 16:36:36 +08004108int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004109 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08004110
hualing chena540a7e2020-03-27 16:44:05 +08004111 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004112 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004113 return DVR_FAILURE;
4114 }
4115
hualing chen040df222020-01-17 13:35:02 +08004116 DVR_PlaybackSegmentInfo_t *segment;
wentao.mafd5283f2022-10-14 09:51:13 +08004117 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08004118 // prefetch() here incurring self_assign is used to avoid some compiling
4119 // warnings.
4120 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08004121 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08004122 {
Wentao MA07d3d742022-09-06 09:58:05 +08004123 if (segment->segment_id == segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004124 _dvr_dump_segment(segment);
Wentao MA07d3d742022-09-06 09:58:05 +08004125 break;
hualing chen86e7d482020-01-16 15:13:33 +08004126 }
4127 }
4128 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08004129}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004130
pengfei.liu27cc4ec2020-04-03 16:28:16 +08004131int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004132{
4133 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4134 DVR_RETURN_IF_FALSE(player);
4135 DVR_RETURN_IF_FALSE(func);
4136
Wentao MA96f68962022-06-15 19:45:35 +08004137 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004138 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004139
4140 player->dec_func = func;
4141 player->dec_userdata = userdata;
4142
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004143 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004144 DVR_PB_INFO("out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004145 return DVR_SUCCESS;
4146}
4147
4148int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
4149{
4150 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4151 DVR_RETURN_IF_FALSE(player);
4152 DVR_RETURN_IF_FALSE(p_secure_buf);
4153 DVR_RETURN_IF_FALSE(len);
4154
Wentao MA96f68962022-06-15 19:45:35 +08004155 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004156 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004157
4158 player->is_secure_mode = 1;
4159 player->secure_buffer = p_secure_buf;
4160 player->secure_buffer_size = len;
4161
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004162 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004163 DVR_PB_INFO("out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004164 return DVR_SUCCESS;
4165}
Wentao MA5629ad82022-08-24 10:03:02 +08004166
4167int dvr_playback_set_ac4_preselection_id(DVR_PlaybackHandle_t handle, int presel_id)
4168{
4169 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa210e5e2022-10-12 16:10:03 +08004170 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MA5629ad82022-08-24 10:03:02 +08004171
4172 player->audio_presentation_id = presel_id;
4173 am_tsplayer_result ret = AmTsPlayer_setParams(player->handle,
4174 AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &presel_id);
4175 DVR_RETURN_IF_FALSE(ret == AM_TSPLAYER_OK);
4176
4177 return DVR_SUCCESS;
4178}
Wentao MAa0b9c002022-11-10 17:47:27 +08004179
4180// This function ensures a valid TsPlayer delay time is provided or else it
4181// returns DVR_FAILURE. It is designed to workaround a weakness of
4182// AmTsPlayer_getDelayTime at starting phase of a playback in a short period
4183// of 20ms or less. During the said period, getDelayTime does NOT work as
4184// expect to return real delay length because demux isn't actually running
4185// to provide valid pts to TsPlayer.
Wentao MA804bab12022-11-29 10:01:26 +08004186static int get_effective_tsplayer_delay_time(DVR_Playback_t* play, int *time)
Wentao MAa0b9c002022-11-10 17:47:27 +08004187{
4188 int64_t delay=0;
4189 uint64_t pts_a=0;
4190 uint64_t pts_v=0;
4191
Wentao MA804bab12022-11-29 10:01:26 +08004192 DVR_RETURN_IF_FALSE(play != NULL);
4193 DVR_RETURN_IF_FALSE(play->handle != NULL);
Wentao MAa0b9c002022-11-10 17:47:27 +08004194
Wentao MA804bab12022-11-29 10:01:26 +08004195 AmTsPlayer_getDelayTime(play->handle, &delay);
4196 // In scambled stream situation, the returned TsPlayer delay time is
4197 // invalid and dirty. An additional time check agaginst 15 minutes (900s)
4198 // is introduced to insure such error condition is handled properly.
4199 DVR_RETURN_IF_FALSE((delay >= 0) && (delay <= 900*1000));
Wentao MAa0b9c002022-11-10 17:47:27 +08004200
Wentao MA804bab12022-11-29 10:01:26 +08004201 if (play->delay_is_effective) {
4202 *time = (int)delay;
Wentao MAa0b9c002022-11-10 17:47:27 +08004203 return DVR_SUCCESS;
4204 } else if (delay > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004205 *time = (int)delay;
4206 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004207 return DVR_SUCCESS;
4208 }
4209
Wentao MA804bab12022-11-29 10:01:26 +08004210 AmTsPlayer_getPts(play->handle, TS_STREAM_AUDIO, &pts_a);
4211 AmTsPlayer_getPts(play->handle, TS_STREAM_VIDEO, &pts_v);
Wentao MAa0b9c002022-11-10 17:47:27 +08004212 if ((int64_t)pts_a > 0 || (int64_t)pts_v > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004213 *time = (int)delay;
4214 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004215 return DVR_SUCCESS;
4216 }
4217
4218 return DVR_FAILURE;
4219}
4220