blob: 30673415ac6c8403db5cfde5cf238ad6664464e2 [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
hualing chenb31a6c62020-01-13 17:27:00 +080043
hualing chenb5cd42e2020-04-15 17:03:34 +080044#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080045#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080046//if tsplayer delay time < 200 and no data can read, we will pause
47#define MIN_TSPLAYER_DELAY_TIME (200)
48
hualing chen041c4092020-04-05 15:11:50 +080049#define MAX_CACHE_TIME (30000)
hualing chen43a89bc2022-01-19 14:31:20 +080050//used pcr to control avsync,default not used
51//#define AVSYNC_USED_PCR 1
hualing chena540a7e2020-03-27 16:44:05 +080052static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080053//
54static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
Wentao MA6dcdc342023-01-30 17:03:19 +080055static 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 +080056static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
57static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080058static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080059static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080060static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
61 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080062static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen7ea70a72021-09-09 11:25:13 +080063static uint32_t dvr_playback_calculate_last_valid_segment(
64 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos);
Wentao MA804bab12022-11-29 10:01:26 +080065static int get_effective_tsplayer_delay_time(DVR_Playback_t* playback, int *time);
hualing chen87072a82020-03-12 16:20:12 +080066
hualing chenbcada022020-04-22 14:27:01 +080067
hualing chena5f03222021-12-02 11:22:35 +080068
hualing chenbcada022020-04-22 14:27:01 +080069static char* _cmd_toString(int cmd)
70{
71
72 char *string[DVR_PLAYBACK_CMD_NONE+1]={
73 "start",
74 "stop",
Wentao MA270dc0f2022-08-23 13:17:26 +080075 "v_start",
76 "a_start",
77 "v_stop",
78 "a_stop",
79 "v_restart",
80 "a_restart",
81 "av_restart",
82 "v_stop_a_start",
83 "a_stop_v_start",
84 "v_stop_a_restart",
85 "a_stop_v_restart",
86 "v_start_a_restart",
87 "a_start_v_restart",
hualing chenbcada022020-04-22 14:27:01 +080088 "pause",
89 "resume",
90 "seek",
91 "ff",
92 "fb",
93 "NONE"
94 };
95
96 if (cmd > DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +080097 return "unknown";
hualing chenbcada022020-04-22 14:27:01 +080098 } else {
99 return string[cmd];
100 }
101}
102
103
Wentao MA907b6432022-08-01 06:23:08 +0000104static char* _dvr_playback_state_toString(int state)
hualing chen6d24aa92020-03-23 18:43:47 +0800105{
Wentao MA907b6432022-08-01 06:23:08 +0000106 char *strings[5]={
107 "START",
108 "STOP",
109 "PAUSE",
110 "FF",
111 "FB",
hualing chen6d24aa92020-03-23 18:43:47 +0800112 };
113
Wentao MA907b6432022-08-01 06:23:08 +0000114 if (state >= 5 || state < 0) {
115 return "UNKNOWN";
hualing chen6d24aa92020-03-23 18:43:47 +0800116 }
Wentao MA907b6432022-08-01 06:23:08 +0000117 return strings[state];
hualing chen6d24aa92020-03-23 18:43:47 +0800118}
hualing chena540a7e2020-03-27 16:44:05 +0800119
120static DVR_Bool_t _dvr_support_speed(int speed) {
121
122 DVR_Bool_t ret = DVR_FALSE;
123
124 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800125 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800126 case PLAYBACK_SPEED_FBX2:
127 case PLAYBACK_SPEED_FBX4:
128 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800129 case PLAYBACK_SPEED_FBX16:
130 case PLAYBACK_SPEED_FBX12:
131 case PLAYBACK_SPEED_FBX32:
132 case PLAYBACK_SPEED_FBX48:
133 case PLAYBACK_SPEED_FBX64:
134 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800135 case PLAYBACK_SPEED_S2:
136 case PLAYBACK_SPEED_S4:
137 case PLAYBACK_SPEED_S8:
138 case PLAYBACK_SPEED_X1:
139 case PLAYBACK_SPEED_X2:
140 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800141 case PLAYBACK_SPEED_X3:
142 case PLAYBACK_SPEED_X5:
143 case PLAYBACK_SPEED_X6:
144 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800145 case PLAYBACK_SPEED_X8:
146 case PLAYBACK_SPEED_X12:
147 case PLAYBACK_SPEED_X16:
148 case PLAYBACK_SPEED_X32:
149 case PLAYBACK_SPEED_X48:
150 case PLAYBACK_SPEED_X64:
151 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800152 ret = DVR_TRUE;
153 break;
154 default:
Wentao MA96f68962022-06-15 19:45:35 +0800155 DVR_PB_INFO("not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800156 break;
157 }
158 return ret;
159}
Wentao MA907b6432022-08-01 06:23:08 +0000160
hualing chen6e4bfa52020-03-13 14:37:11 +0800161void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
162{
Wentao MA96f68962022-06-15 19:45:35 +0800163 DVR_PB_INFO("in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800164 DVR_Playback_t *player = NULL;
165 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800166 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800167 DVR_PB_INFO("play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800168 }
169 switch (event->type) {
170 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
171 {
Wentao MA96f68962022-06-15 19:45:35 +0800172 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800173 event->event.video_format.frame_width,
174 event->event.video_format.frame_height,
175 event->event.video_format.frame_rate);
176 break;
177 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800178 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
179 {
Wentao MA16f870e2022-09-09 11:00:22 +0800180 if (player == NULL) {
181 DVR_PB_WARN("player is null at line %d",__LINE__);
182 break;
183 }
Wentao MA96f68962022-06-15 19:45:35 +0800184 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800185 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800186 break;
187 }
188 default:
189 break;
190 }
191}
Wentao MA804bab12022-11-29 10:01:26 +0800192
hualing chen2aba4022020-03-02 13:49:55 +0800193void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
194{
Wentao MA804bab12022-11-29 10:01:26 +0800195 DVR_Playback_t *play = (DVR_Playback_t*)user_data;
196 if (play == NULL) {
197 DVR_PB_WARN("play is invalid in %s",__func__);
198 return;
hualing chen6e4bfa52020-03-13 14:37:11 +0800199 }
hualing chen2aba4022020-03-02 13:49:55 +0800200 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800201 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
Wentao MA804bab12022-11-29 10:01:26 +0800202 DVR_PB_INFO("Received AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME");
203 if (play->first_trans_ok == DVR_FALSE) {
204 play->first_trans_ok = DVR_TRUE;
205 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)play, DVR_FALSE);
206 }
207 play->first_frame = 1;
208 play->seek_pause = DVR_FALSE;
209 break;
hualing chen487ae6d2020-07-22 10:34:11 +0800210 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
Wentao MA804bab12022-11-29 10:01:26 +0800211 DVR_PB_INFO("Received AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO");
212 if (play->first_trans_ok == DVR_FALSE && play->has_video == DVR_FALSE) {
213 play->first_trans_ok = DVR_TRUE;
214 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)play, DVR_FALSE);
215 }
216 if (play->has_video == DVR_FALSE) {
217 play->first_frame = 1;
218 play->seek_pause = DVR_FALSE;
219 }
hualing chen487ae6d2020-07-22 10:34:11 +0800220 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800221 default:
222 break;
223 }
Wentao MA804bab12022-11-29 10:01:26 +0800224 if (play->player_callback_func == NULL) {
225 DVR_PB_WARN("play callback function %p is invalid",play->player_callback_func);
226 return;
hualing chen2aba4022020-03-02 13:49:55 +0800227 }
Wentao MA804bab12022-11-29 10:01:26 +0800228 play->player_callback_func(play->player_callback_userdata, event);
hualing chen2aba4022020-03-02 13:49:55 +0800229}
hualing chencc91e1c2020-02-28 13:26:17 +0800230
hualing chen5cbe1a62020-02-10 16:36:36 +0800231//convert video and audio fmt
232static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
233 int format = 0;
234 if (is_audio == DVR_FALSE) {
235 //for video fmt
236 switch (fmt)
237 {
238 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800239 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800240 break;
241 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800242 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800243 break;
244 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800245 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800246 break;
247 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800248 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800249 break;
hualing chena540a7e2020-03-27 16:44:05 +0800250 case DVR_VIDEO_FORMAT_VP9:
251 format = AV_VIDEO_CODEC_VP9;
252 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800253 }
254 } else {
255 //for audio fmt
256 switch (fmt)
257 {
258 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800259 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800260 break;
261 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800262 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800263 break;
264 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800265 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800266 break;
267 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800268 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800269 break;
hualing chena540a7e2020-03-27 16:44:05 +0800270 case DVR_AUDIO_FORMAT_AAC:
271 format = AV_AUDIO_CODEC_AAC;
272 break;
273 case DVR_AUDIO_FORMAT_LATM:
274 format = AV_AUDIO_CODEC_LATM;
275 break;
276 case DVR_AUDIO_FORMAT_PCM:
277 format = AV_AUDIO_CODEC_PCM;
278 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800279 case DVR_AUDIO_FORMAT_AC4:
280 format = AV_AUDIO_CODEC_AC4;
281 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800282 }
283 }
284 return format;
285}
hualing chen040df222020-01-17 13:35:02 +0800286static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800287{
hualing chen040df222020-01-17 13:35:02 +0800288 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800289
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800290 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800291 return -1;
292
hualing chena540a7e2020-03-27 16:44:05 +0800293 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800294}
hualing chena540a7e2020-03-27 16:44:05 +0800295
hualing chen7ea70a72021-09-09 11:25:13 +0800296
297//get sys time sec
298static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800299{
300 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800301 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800302 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800303 s = (uint32_t)(ts.tv_sec);
Wentao MA96f68962022-06-15 19:45:35 +0800304 DVR_PB_INFO("n:%u", s);
hualing chen7ea70a72021-09-09 11:25:13 +0800305 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800306}
hualing chen86e7d482020-01-16 15:13:33 +0800307
hualing chen7ea70a72021-09-09 11:25:13 +0800308//get sys time ms
309static uint32_t _dvr_time_getClock(void)
310{
311 struct timespec ts;
312 uint32_t ms;
313 clock_gettime(CLOCK_REALTIME, &ts);
314 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
315 return ms;
316}
hualing chenb31a6c62020-01-13 17:27:00 +0800317
Wentao MA270dc0f2022-08-23 13:17:26 +0800318//timeout wait signal
hualing chen040df222020-01-17 13:35:02 +0800319static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800320{
hualing chen040df222020-01-17 13:35:02 +0800321 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800322
hualing chena540a7e2020-03-27 16:44:05 +0800323
324 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800325 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800326 return DVR_FAILURE;
327 }
328
hualing chen86e7d482020-01-16 15:13:33 +0800329 struct timespec ts;
330 clock_gettime(CLOCK_MONOTONIC, &ts);
331 //ms为毫秒,换算成秒
332 ts.tv_sec += ms/1000;
333 //在outtime的基础上,增加ms毫秒
334 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
335 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
336 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
337 //us的值有可能超过1秒,
338 ts.tv_sec += us / 1000000;
339 us = us % 1000000;
340 ts.tv_nsec = us * 1000;//换算成纳秒
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800341
342 int val = dvr_mutex_save(&player->lock);
343 pthread_cond_timedwait(&player->cond, &player->lock.lock, &ts);
344 dvr_mutex_restore(&player->lock, val);
hualing chen86e7d482020-01-16 15:13:33 +0800345 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800346}
Wentao MA804bab12022-11-29 10:01:26 +0800347
hualing chenb31a6c62020-01-13 17:27:00 +0800348//send signal
hualing chen040df222020-01-17 13:35:02 +0800349static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800350{
hualing chen87072a82020-03-12 16:20:12 +0800351 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800352
353 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800354 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800355 return DVR_FAILURE;
356 }
Wentao MA96f68962022-06-15 19:45:35 +0800357 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800358 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800359 pthread_cond_signal(&player->cond);
Wentao MA96f68962022-06-15 19:45:35 +0800360 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800361 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800362 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800363}
364
hualing chen2932d372020-04-29 13:44:00 +0800365//send playback event, need check is need lock first
366static 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 +0800367
368 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800369
370 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800371 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800372 return DVR_FAILURE;
373 }
374
hualing chencc91e1c2020-02-28 13:26:17 +0800375 switch (evt) {
376 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800377 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800378 break;
379 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
380 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800381 DVR_PB_INFO("trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800382 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800383 break;
384 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
385 break;
386 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
387 break;
388 case DVR_PLAYBACK_EVENT_NO_KEY:
389 break;
390 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800391 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800392 DVR_PB_INFO("reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800393 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800394 break;
395 case DVR_PLAYBACK_EVENT_REACHED_END:
396 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800397 DVR_PB_INFO("reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800398 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800399 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800400 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800401 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800402 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800403 default:
404 break;
405 }
406 if (player->openParams.event_fn != NULL)
407 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800408 return DVR_SUCCESS;
409}
hualing chen2932d372020-04-29 13:44:00 +0800410static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800411{
412 DVR_Play_Notify_t notify;
413 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
414 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
415 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800416 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800417 return DVR_SUCCESS;
418}
419
hualing chen2932d372020-04-29 13:44:00 +0800420static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800421{
422 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800423
Wentao MA16f870e2022-09-09 11:00:22 +0800424 if (player == NULL) {
425 DVR_PB_ERROR("player is NULL");
426 return DVR_FAILURE;
427 }
hualing chene3797f02021-01-13 14:53:28 +0800428 if (player->openParams.is_notify_time == DVR_FALSE) {
shenghui.gengbec6a462023-01-12 15:21:02 +0800429 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800430 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800431 }
hualing chena540a7e2020-03-27 16:44:05 +0800432
hualing chen03fd4942021-07-15 15:56:41 +0800433 if (player->send_time == 0) {
shenghui.gengbec6a462023-01-12 15:21:02 +0800434 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800435 player->send_time = _dvr_time_getClock() + 500;
436 else
437 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800438 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen56c0a162022-01-27 17:01:50 +0800439 if ((player->send_time - _dvr_time_getClock()) > 1000) {
440 player->send_time = _dvr_time_getClock() + 500;
Wentao MA96f68962022-06-15 19:45:35 +0800441 DVR_PB_INFO("player send time occur system time changed!!!!!");
hualing chen56c0a162022-01-27 17:01:50 +0800442 } else {
443 return DVR_SUCCESS;
444 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800445 }
shenghui.gengbec6a462023-01-12 15:21:02 +0800446 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800447 player->send_time = _dvr_time_getClock() + 500;
448 else
449 player->send_time = _dvr_time_getClock() + 20;
450
hualing chen6e4bfa52020-03-13 14:37:11 +0800451 DVR_Play_Notify_t notify;
452 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
453 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
454 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800455 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800456 return DVR_SUCCESS;
457}
458
hualing chen4b7c15d2020-04-07 16:13:48 +0800459static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
460 DVR_Playback_t *player = (DVR_Playback_t *) handle;
461 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800462 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800463 player->fffb_current = player->fffb_start;
464 //get segment current time pos
465 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800466 player->next_fffb_time = _dvr_time_getClock();
467
468 return DVR_SUCCESS;
469}
470
hualing chen2aba4022020-03-02 13:49:55 +0800471static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
472 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800473 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800474 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800475 player->fffb_current = player->fffb_start;
476 //get segment current time pos
477 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800478
hualing chen2aba4022020-03-02 13:49:55 +0800479 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800480 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800481 return DVR_SUCCESS;
482}
hualing chencc91e1c2020-02-28 13:26:17 +0800483//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800484static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
485
486 DVR_Playback_t *player = (DVR_Playback_t *) handle;
487 DVR_PlaybackSegmentInfo_t *segment;
488 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
489
hualing chena540a7e2020-03-27 16:44:05 +0800490 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800491 DVR_PB_INFO(" player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800492 return DVR_FAILURE;
493 }
494
hualing chen87072a82020-03-12 16:20:12 +0800495 int found = 0;
496 int found_eq_id = 0;
wentao.mafd5283f2022-10-14 09:51:13 +0800497 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800498 // prefetch() here incurring self_assign is used to avoid some compiling
499 // warnings.
500 // coverity[self_assign]
hualing chen87072a82020-03-12 16:20:12 +0800501 list_for_each_entry(segment, &player->segment_list, head)
502 {
503 if (player->segment_is_open == DVR_FALSE) {
504 //get first segment from list, case segment is not open
505 if (!IS_FB(player->speed))
506 found = 1;
507 } else if (segment->segment_id == segmentid) {
508 //find cur segment, we need get next one
509 found_eq_id = 1;
510 if (!IS_FB(player->speed)) {
511 found = 1;
512 continue;
513 } else {
514 //if is fb mode.we need used pre segment
515 if (pre_segment != NULL) {
516 found = 1;
517 } else {
518 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800519 DVR_PB_INFO("not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800520 return DVR_FAILURE;
521 }
522 }
523 }
524 if (found == 1) {
525 found = 2;
526 break;
527 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800528 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800529 }
530 if (found != 2) {
531 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800532 DVR_PB_INFO("not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800533 return DVR_FAILURE;
534 }
Wentao MA96f68962022-06-15 19:45:35 +0800535 DVR_PB_INFO("found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800536 return DVR_SUCCESS;
537}
538
539//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800540static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800541
hualing chen040df222020-01-17 13:35:02 +0800542 DVR_Playback_t *player = (DVR_Playback_t *) handle;
543 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800544 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800545 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800546 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800547 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800548 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800549 return DVR_FAILURE;
550 }
551
hualing chen03fd4942021-07-15 15:56:41 +0800552 if (IS_FB(player->speed)
553 && dvr_playback_check_limit(handle)) {
554 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
555 //case cur id < segment id
556 if (player->cur_segment_id <= segmentid) {
557 //expired ts data is player,return error
Wentao MA96f68962022-06-15 19:45:35 +0800558 DVR_PB_INFO("reach start segment ,return error");
hualing chen03fd4942021-07-15 15:56:41 +0800559 return DVR_FAILURE;
560 }
Wentao MA96f68962022-06-15 19:45:35 +0800561 DVR_PB_INFO("has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800562 }
563
hualing chen86e7d482020-01-16 15:13:33 +0800564 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800565 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800566
wentao.mafd5283f2022-10-14 09:51:13 +0800567 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800568 // prefetch() here incurring self_assign is used to avoid some compiling
569 // warnings.
570 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +0800571 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800572 {
hualing chencc91e1c2020-02-28 13:26:17 +0800573 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800574 //get first segment from list, case segment is not open
575 if (!IS_FB(player->speed))
576 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800577 } else if (segment->segment_id == player->cur_segment_id) {
578 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800579 found_eq_id = 1;
580 if (!IS_FB(player->speed)) {
581 found = 1;
582 continue;
583 } else {
584 //if is fb mode.we need used pre segment
585 if (pre_segment != NULL) {
586 found = 1;
587 } else {
588 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800589 DVR_PB_INFO("not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800590 return DVR_FAILURE;
591 }
592 }
hualing chen86e7d482020-01-16 15:13:33 +0800593 }
594 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800595 if (IS_FB(player->speed)) {
596 //used pre segment
597 segment = pre_segment;
598 }
hualing chencc91e1c2020-02-28 13:26:17 +0800599 //save segment info
600 player->last_segment_id = player->cur_segment_id;
Wentao MAf35c3882023-04-17 12:36:19 +0800601 if (player->segment_handle) {
602 player->last_segment_total = segment_tell_total_time(player->segment_handle);
603 }
hualing chen87072a82020-03-12 16:20:12 +0800604 player->last_segment.segment_id = player->cur_segment.segment_id;
605 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800606 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
607 //pids
608 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
609
hualing chen5cbe1a62020-02-10 16:36:36 +0800610 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800611 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800612 player->cur_segment_id = segment->segment_id;
613 player->cur_segment.segment_id = segment->segment_id;
614 player->cur_segment.flags = segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800615 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 +0800616 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800617 //pids
hualing chen040df222020-01-17 13:35:02 +0800618 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800619 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800620 break;
hualing chen86e7d482020-01-16 15:13:33 +0800621 }
hualing chen2aba4022020-03-02 13:49:55 +0800622 pre_segment = segment;
623 }
624 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
625 //used the last one segment to open
626 //get segment info
627 player->segment_is_open = DVR_TRUE;
628 player->cur_segment_id = pre_segment->segment_id;
629 player->cur_segment.segment_id = pre_segment->segment_id;
630 player->cur_segment.flags = pre_segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800631 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 +0800632 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
633 //pids
634 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
635 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800636 }
637 if (found != 2) {
638 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800639 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800640 }
641 return DVR_SUCCESS;
642}
hualing chen040df222020-01-17 13:35:02 +0800643//open next segment to play,if reach list end return errro.
644static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800645{
hualing chen040df222020-01-17 13:35:02 +0800646 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800647 Segment_OpenParams_t params;
648 int ret = DVR_SUCCESS;
649
hualing chena540a7e2020-03-27 16:44:05 +0800650 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800651 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800652 return DVR_FAILURE;
653 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800654 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800655retry:
hualing chena540a7e2020-03-27 16:44:05 +0800656 ret = _dvr_get_next_segmentId(handle);
657 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800658 DVR_PB_INFO("not found segment info");
hualing chen4b7c15d2020-04-07 16:13:48 +0800659 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800660 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800661 }
662
Wentao MAf35c3882023-04-17 12:36:19 +0800663 if (player->segment_handle != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800664 DVR_PB_INFO("close segment");
Wentao MAf35c3882023-04-17 12:36:19 +0800665 segment_close(player->segment_handle);
666 player->segment_handle = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800667 }
668
Wentao MA4d85ff32022-09-23 11:36:18 +0800669 memset((void*)&params,0,sizeof(params));
Wentao MA270dc0f2022-08-23 13:17:26 +0800670 //cp current segment path to location
hualing chen5cbe1a62020-02-10 16:36:36 +0800671 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800672 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800673 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800674 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 +0800675
Wentao MAf35c3882023-04-17 12:36:19 +0800676 ret = segment_open(&params, &(player->segment_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800677 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800678 DVR_PB_INFO("open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800679 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800680 }
Wentao MA01de0e62022-01-10 18:48:23 +0800681 // Keep the start segment_id when the first segment_open is called during a playback
682 if (player->first_start_id == UINT64_MAX) {
683 player->first_start_id = player->cur_segment.segment_id;
684 }
hualing chen87072a82020-03-12 16:20:12 +0800685 pthread_mutex_unlock(&player->segment_lock);
686 int total = _dvr_get_end_time( handle);
687 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800688 if (IS_FB(player->speed)) {
689 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800690 player->ts_cache_len = 0;
Wentao MAf35c3882023-04-17 12:36:19 +0800691 segment_seek(player->segment_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +0800692 DVR_PB_INFO("seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800693 }
hualing chen87072a82020-03-12 16:20:12 +0800694 player->dur = total;
wentao.mafdba9a02023-01-17 16:43:26 +0800695 player->con_spe.ply_dur = 0;
696 player->con_spe.ply_sta = 0;
697 player->con_spe.sys_dur = 0;
698 player->con_spe.sys_sta = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800699 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +0800700 DVR_PB_INFO("next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800701 return ret;
702}
703
hualing chen5cbe1a62020-02-10 16:36:36 +0800704//open next segment to play,if reach list end return errro.
705static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
706{
707 DVR_Playback_t *player = (DVR_Playback_t *) handle;
708 Segment_OpenParams_t params;
709 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800710 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800711 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800712 return DVR_FAILURE;
713 }
hualing chencc91e1c2020-02-28 13:26:17 +0800714 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800715 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800716 }
hualing chencc91e1c2020-02-28 13:26:17 +0800717 uint64_t id = segment_id;
Wentao MA07d3d742022-09-06 09:58:05 +0800718 DVR_PB_INFO("start finding segment[%lld] info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800719 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800720
721 DVR_PlaybackSegmentInfo_t *segment;
722
723 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800724
wentao.mafd5283f2022-10-14 09:51:13 +0800725 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800726 // prefetch() here incurring self_assign is used to avoid some compiling
727 // warnings.
728 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800729 list_for_each_entry(segment, &player->segment_list, head)
730 {
Wentao MA96f68962022-06-15 19:45:35 +0800731 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 +0800732 if (segment->segment_id == segment_id) {
733 found = 1;
734 }
735 if (found == 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800736 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 +0800737 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800738 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800739 player->cur_segment_id = segment->segment_id;
740 player->cur_segment.segment_id = segment->segment_id;
741 player->cur_segment.flags = segment->flags;
Wentao MAe88ad702022-09-02 10:35:00 +0800742 const int len = strlen(segment->location);
743 if (len >= DVR_MAX_LOCATION_SIZE || len <= 0) {
744 DVR_PB_ERROR("Invalid segment.location length %d",len);
745 pthread_mutex_unlock(&player->segment_lock);
746 return DVR_FAILURE;
747 }
748 strncpy(player->cur_segment.location, segment->location, len+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800749 //pids
750 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +0800751 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 +0800752 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800753 }
754 }
hualing chencc91e1c2020-02-28 13:26:17 +0800755 if (found == 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800756 DVR_PB_INFO("not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800757 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800758 return DVR_FAILURE;
759 }
Wentao MA4d85ff32022-09-23 11:36:18 +0800760 memset((void*)&params,0,sizeof(params));
Wentao MAe88ad702022-09-02 10:35:00 +0800761
762 const int len2 = strlen(player->cur_segment.location);
763 if (len2 >= DVR_MAX_LOCATION_SIZE || len2 <= 0) {
764 DVR_PB_ERROR("Invalid cur_segment.location length %d",len2);
765 pthread_mutex_unlock(&player->segment_lock);
766 return DVR_FAILURE;
767 }
768 strncpy(params.location, player->cur_segment.location, len2+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800769 params.segment_id = (uint64_t)player->cur_segment.segment_id;
770 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800771 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 +0800772 if (player->segment_handle != NULL) {
773 segment_close(player->segment_handle);
774 player->segment_handle = NULL;
hualing chen2aba4022020-03-02 13:49:55 +0800775 }
Wentao MAf35c3882023-04-17 12:36:19 +0800776 ret = segment_open(&params, &(player->segment_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800777 if (ret == DVR_FAILURE) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800778 DVR_PB_INFO("segment open error");
hualing chen4b7c15d2020-04-07 16:13:48 +0800779 }
Wentao MA01de0e62022-01-10 18:48:23 +0800780 // Keep the start segment_id when the first segment_open is called during a playback
781 if (player->first_start_id == UINT64_MAX) {
782 player->first_start_id = player->cur_segment.segment_id;
783 }
hualing chen2aba4022020-03-02 13:49:55 +0800784 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800785 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800786
Wentao MA96f68962022-06-15 19:45:35 +0800787 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 +0800788 return ret;
789}
790
791
792//get play info by segment id
793static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
794 uint64_t segment_id,
Wentao MA270dc0f2022-08-23 13:17:26 +0800795 am_tsplayer_video_params *video_param,
796 am_tsplayer_audio_params *audio_param, am_tsplayer_audio_params *ad_param) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800797
798 DVR_Playback_t *player = (DVR_Playback_t *) handle;
799 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800800 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800801 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800802 return DVR_FAILURE;
803 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800804
805 int found = 0;
806
wentao.mafd5283f2022-10-14 09:51:13 +0800807 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800808 // prefetch() here incurring self_assign is used to avoid some compiling
809 // warnings.
810 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800811 list_for_each_entry(segment, &player->segment_list, head)
812 {
hualing chen87072a82020-03-12 16:20:12 +0800813 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800814 //get first segment from list
815 found = 1;
816 }
817 if (segment->segment_id == segment_id) {
818 found = 1;
819 }
820 if (found == 1) {
821 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800822 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800823 player->cur_segment_id = segment->segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800824 player->cur_segment.segment_id = segment->segment_id;
825 player->cur_segment.flags = segment->flags;
826 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800827 player->cur_segment.pids.video.pid = segment->pids.video.pid;
828 player->cur_segment.pids.video.format = segment->pids.video.format;
829 player->cur_segment.pids.video.type = segment->pids.video.type;
830 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
831 player->cur_segment.pids.audio.format = segment->pids.audio.format;
832 player->cur_segment.pids.audio.type = segment->pids.audio.type;
833 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
834 player->cur_segment.pids.ad.format = segment->pids.ad.format;
835 player->cur_segment.pids.ad.type = segment->pids.ad.type;
836 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800837 //
Wentao MA270dc0f2022-08-23 13:17:26 +0800838 video_param->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
839 video_param->pid = segment->pids.video.pid;
840 audio_param->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
841 audio_param->pid = segment->pids.audio.pid;
842 ad_param->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
843 ad_param->pid =segment->pids.ad.pid;
Wentao MA804bab12022-11-29 10:01:26 +0800844 DVR_PB_DEBUG("get_playinfo, segment_id:%lld, vpid[0x%x], apid[0x%x], vfmt[%d], afmt[%d]",
845 player->cur_segment_id, video_param->pid, audio_param->pid,
846 video_param->codectype, audio_param->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800847 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800848 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800849 }
850 }
hualing chencc91e1c2020-02-28 13:26:17 +0800851 if (found != 2) {
852 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800853 DVR_PB_INFO("get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800854 return DVR_FAILURE;
855 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800856
857 return DVR_SUCCESS;
858}
hualing chencc91e1c2020-02-28 13:26:17 +0800859static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
860 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800861 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800862 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800863 return DVR_FAILURE;
864 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800865
hualing chencc91e1c2020-02-28 13:26:17 +0800866 //compare cur segment
867 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
868 {
869 //check video pids, stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800870 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800871 //check sub audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800872 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800873 //check audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800874 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 1);
Wentao MA96f68962022-06-15 19:45:35 +0800875 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 +0800876 //check pcr pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800877 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800878 }
hualing chena540a7e2020-03-27 16:44:05 +0800879 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800880}
hualing chen5cbe1a62020-02-10 16:36:36 +0800881
hualing chend241c7a2021-06-22 13:34:27 +0800882static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
883{
884 DVR_Playback_t *player = (DVR_Playback_t *) handle;
885 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800886 DVR_PB_INFO("player is NULL");
hualing chend241c7a2021-06-22 13:34:27 +0800887 return DVR_TRUE;
888 }
hualing chend241c7a2021-06-22 13:34:27 +0800889
wentao.mafdba9a02023-01-17 16:43:26 +0800890 DVR_PB_INFO(":play speed: %f ply dur: %d sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800891 player->speed,
892 player->con_spe.ply_dur,
893 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800894
895 if (player->speed != 1.0f)
896 return DVR_TRUE;
897
898 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800899 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800900 return DVR_FALSE;
901
902 return DVR_TRUE;
903}
904
hualing chencc91e1c2020-02-28 13:26:17 +0800905static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
906{
907 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800908 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800909 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800910 return DVR_FAILURE;
911 }
Wentao MA292380e2022-12-14 14:46:19 +0800912 if (player->vendor != DVR_PLAYBACK_VENDOR_DEF) {
913 DVR_PB_INFO("In case of vendor Amlogic/Amazon, do not control AV display");
hualing chenf43b8ba2020-07-28 13:11:42 +0800914 return DVR_SUCCESS;
915 }
Wentao MA96f68962022-06-15 19:45:35 +0800916 DVR_PB_INFO("flag[0x%x]id[%lld]last[0x%x][%llu]",
hualing chen03fd4942021-07-15 15:56:41 +0800917 player->cur_segment.flags,
918 player->cur_segment.segment_id,
919 player->last_segment.flags,
920 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800921 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
922 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800923 //enable display
Wentao MA96f68962022-06-15 19:45:35 +0800924 DVR_PB_INFO("unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800925 AmTsPlayer_showVideo(player->handle);
926 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800927 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
928 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800929 //disable display
Wentao MA96f68962022-06-15 19:45:35 +0800930 DVR_PB_INFO("mute");
hualing chen2aba4022020-03-02 13:49:55 +0800931 AmTsPlayer_hideVideo(player->handle);
932 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800933 }
934 return DVR_SUCCESS;
935}
hualing chene3797f02021-01-13 14:53:28 +0800936/*
Wentao MA270dc0f2022-08-23 13:17:26 +0800937if decode success first time.
938success: return true
hualing chene3797f02021-01-13 14:53:28 +0800939fail: return false
940*/
Wentao MA270dc0f2022-08-23 13:17:26 +0800941static DVR_Bool_t _dvr_pauselive_decode_success(DVR_PlaybackHandle_t handle) {
hualing chena540a7e2020-03-27 16:44:05 +0800942 DVR_Playback_t *player = (DVR_Playback_t *) handle;
943 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800944 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800945 return DVR_TRUE;
946 }
hualing chene3797f02021-01-13 14:53:28 +0800947 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800948 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800949 } else {
950 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800951 }
952}
hualing chen86e7d482020-01-16 15:13:33 +0800953static void* _dvr_playback_thread(void *arg)
954{
hualing chen040df222020-01-17 13:35:02 +0800955 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800956 //int need_open_segment = 1;
Wentao MA270dc0f2022-08-23 13:17:26 +0800957 am_tsplayer_input_buffer input_buffer;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800958 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800959 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800960
hualing chen39628212020-05-14 10:35:13 +0800961 #define MAX_REACHEND_TIMEOUT (3000)
962 int reach_end_timeout = 0;//ms
963 int cache_time = 0;
hualing chen40dd5462021-11-26 19:56:20 +0800964 int check_no_data_time = 4;
hualing chen040df222020-01-17 13:35:02 +0800965 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800966 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +0800967 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800968 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800969 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800970 DVR_Bool_t goto_rewrite = DVR_FALSE;
wentao ma7d642782022-10-23 18:26:16 -0700971 int read = 0;
yinming ding0ce94922021-09-08 15:09:15 +0800972
Wentao MA361eaac2023-03-21 13:12:28 +0800973 prctl(PR_SET_NAME,"DvrPlayback");
974
wentao ma7d642782022-10-23 18:26:16 -0700975 const uint64_t write_timeout_ms = (uint64_t)dvr_prop_read_int("vendor.tv.libdvr.writetm",50);
976 const int timeout = dvr_prop_read_int("vendor.tv.libdvr.waittm",200);
hualing chen56c0a162022-01-27 17:01:50 +0800977
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800978 if (player->is_secure_mode) {
979 if (dec_buf_size > player->secure_buffer_size) {
Wentao MA96f68962022-06-15 19:45:35 +0800980 DVR_PB_INFO("playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800981 return NULL;
982 }
983 }
wentao.maa210e5e2022-10-12 16:10:03 +0800984
985 uint8_t *buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800986 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +0800987 DVR_PB_INFO("Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800988 return NULL;
989 }
Wentao MA270dc0f2022-08-23 13:17:26 +0800990 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
991 input_buffer.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800992
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800993 dec_bufs.buf_data = malloc(dec_buf_size);
994 if (!dec_bufs.buf_data) {
Wentao MA96f68962022-06-15 19:45:35 +0800995 DVR_PB_INFO("Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800996 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800997 return NULL;
998 }
999 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1000 dec_bufs.buf_size = dec_buf_size;
1001
hualing chencc91e1c2020-02-28 13:26:17 +08001002 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001003 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1004 }
hualing chen86e7d482020-01-16 15:13:33 +08001005
hualing chen86e7d482020-01-16 15:13:33 +08001006 if (ret != DVR_SUCCESS) {
1007 if (buf != NULL) {
1008 free(buf);
hualing chen86e7d482020-01-16 15:13:33 +08001009 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001010 free(dec_bufs.buf_data);
Wentao MA96f68962022-06-15 19:45:35 +08001011 DVR_PB_INFO("get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001012 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001013 }
Wentao MA96f68962022-06-15 19:45:35 +08001014 DVR_PB_INFO("--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001015 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001016 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1017 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1018 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1019 player->first_trans_ok = DVR_TRUE;
1020 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1021 }
hualing chencc91e1c2020-02-28 13:26:17 +08001022 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001023 //set video show
1024 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001025 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1026 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001027 int trick_stat = 0;
1028 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001029
hualing chen86e7d482020-01-16 15:13:33 +08001030 //check trick stat
Wentao MA96f68962022-06-15 19:45:35 +08001031 //DVR_PB_INFO("lock check_no_data_time:%d", check_no_data_time);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001032 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001033
Wentao MA907b6432022-08-01 06:23:08 +00001034 {
Wentao MA9a164002022-08-29 11:20:24 +08001035 static struct timespec _prev_ts={0,0};
Wentao MA907b6432022-08-01 06:23:08 +00001036 struct timespec _nowts,_diffts;
1037 clock_gettime(CLOCK_MONOTONIC, &_nowts);
Wentao MA9a164002022-08-29 11:20:24 +08001038 clock_timespec_subtract(&_nowts,&_prev_ts,&_diffts);
Wentao MA907b6432022-08-01 06:23:08 +00001039 if (_diffts.tv_sec>0) {
1040 char _logbuf[512]={0};
1041 char* _pbuf=_logbuf;
1042 int _nchar=0;
1043 DVR_PlaybackSegmentInfo_t* _segment;
wentao.mafd5283f2022-10-14 09:51:13 +08001044 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08001045 // prefetch() here incurring self_assign is used to avoid some compiling
1046 // warnings.
1047 // coverity[self_assign]
Wentao MA907b6432022-08-01 06:23:08 +00001048 list_for_each_entry(_segment, &player->segment_list, head) {
1049 if (player->cur_segment_id == _segment->segment_id) {
Wentao MAf35c3882023-04-17 12:36:19 +08001050 int seg_size = segment_get_cur_segment_size(player->segment_handle);
1051 int read_ptr = segment_tell_position(player->segment_handle);
Wentao MA907b6432022-08-01 06:23:08 +00001052 float progress = -1.0f;
Wentao MA9a164002022-08-29 11:20:24 +08001053 if (seg_size>0) {
1054 progress = (float)read_ptr*100/seg_size;
Wentao MA907b6432022-08-01 06:23:08 +00001055 }
Wentao MA4d85ff32022-09-23 11:36:18 +08001056 _nchar=sprintf(_pbuf,"%lld(%.1f%%), ",_segment->segment_id,progress);
Wentao MA907b6432022-08-01 06:23:08 +00001057 } else {
1058 _nchar=sprintf(_pbuf,"%lld, ",_segment->segment_id);
1059 }
1060 if (_nchar<0) {
1061 break;
1062 }
1063 _pbuf+=_nchar;
1064 if (_pbuf-_logbuf+10 >= sizeof(_logbuf)) {
1065 sprintf(_pbuf,"...");
1066 break;
1067 }
1068 }
Wentao MA9a164002022-08-29 11:20:24 +08001069 DVR_PB_INFO("clk: %08u, seg_list: %s",_nowts.tv_sec,_logbuf);
1070 _prev_ts=_nowts;
Wentao MA907b6432022-08-01 06:23:08 +00001071 }
1072 }
1073
hualing chen2aba4022020-03-02 13:49:55 +08001074 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1075 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001076 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001077 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001078 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001079 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001080 {
hualing chen2aba4022020-03-02 13:49:55 +08001081 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1082 if (trick_stat > 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001083 DVR_PB_INFO("trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001084 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001085 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 +08001086 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001087 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001088 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001089 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
Wentao MA270dc0f2022-08-23 13:17:26 +08001090 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_V_START
1091 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_A_START
hualing chen2aba4022020-03-02 13:49:55 +08001092 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
Wentao MA96f68962022-06-15 19:45:35 +08001093 DVR_PB_INFO("pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001094 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001095 //need change to pause state
1096 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1097 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00001098 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08001099 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001100 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001101 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001102 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001103 AmTsPlayer_pauseVideoDecoding(player->handle);
1104 AmTsPlayer_pauseAudioDecoding(player->handle);
Wentao MA6dcdc342023-01-30 17:03:19 +08001105
1106 // Audio is unmuted here, for it was muted before receiving first frame event.
1107 if (player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
1108 AmTsPlayer_setAudioMute(player->handle,0,0);
1109 }
hualing chen2bd8a7a2020-04-02 11:31:03 +08001110 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001111 DVR_PB_INFO("clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001112 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001113 }
1114 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1115 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001116 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001117 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001118 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001119 DVR_PB_INFO("fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001120 player->speed,
1121 player->fffb_current,
1122 _dvr_time_getClock(),
1123 _dvr_playback_state_toString(player->state),
1124 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001125 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001126 //dvr_mutex_unlock(&player->lock);
1127 //dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001128 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001129 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001130 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001131 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001132 } else if (_dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001133 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 +08001134 player->speed,
1135 player->fffb_current,
1136 _dvr_time_getClock(),
1137 _dvr_playback_state_toString(player->state),
1138 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001139 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001140 //dvr_mutex_unlock(&player->lock);
1141 //dvr_mutex_lock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001142 AmTsPlayer_pauseVideoDecoding(player->handle);
1143 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001144 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001145 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001146 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001147 }
Wentao MA96f68962022-06-15 19:45:35 +08001148 DVR_PB_INFO("fffb play-------speed[%f][%d][%d][%s][%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001149 player->speed,
1150 goto_rewrite,
1151 real_read,
1152 _dvr_playback_state_toString(player->state),
1153 player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001154 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001155 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001156 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1157 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001158 DVR_PB_INFO("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001159 dvr_mutex_unlock(&player->lock);
1160
hualing chen2aba4022020-03-02 13:49:55 +08001161 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001162 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001163 dvr_mutex_lock(&player->lock);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001164 player->fffb_play = DVR_FALSE;
hualing chen1ffd85b2021-08-16 15:18:43 +08001165 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1166 //on pause state,user seek to new pos,we need pause and wait
1167 //user to resume
Wentao MA96f68962022-06-15 19:45:35 +08001168 DVR_PB_INFO("pause, when got first frame event when user seek end");
hualing chen1ffd85b2021-08-16 15:18:43 +08001169 player->first_frame = 0;
1170 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1171 AmTsPlayer_pauseVideoDecoding(player->handle);
1172 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001173 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001174 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001175 //for first into fffb when reset speed
1176 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1177 _dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001178 DVR_PB_INFO("fffb timeout-fffb play---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 chen4b7c15d2020-04-07 16:13:48 +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 chen4b7c15d2020-04-07 16:13:48 +08001187 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001188 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001189 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001190 continue;
1191 }
Wentao MA96f68962022-06-15 19:45:35 +08001192 DVR_PB_INFO("fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001193 player->speed,
1194 goto_rewrite,
1195 real_read,
1196 _dvr_playback_state_toString(player->state),
1197 player->cmd.cur_cmd,
1198 player->fffb_play);
Wentao MA96f68962022-06-15 19:45:35 +08001199 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001200 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001201 goto_rewrite = DVR_FALSE;
1202 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001203 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001204 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001205 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1206 player->first_frame = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001207 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001208 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001209 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001210 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001211 }
hualing chenb31a6c62020-01-13 17:27:00 +08001212 }
hualing chen86e7d482020-01-16 15:13:33 +08001213
hualing chen30423862021-04-16 14:39:12 +08001214 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1215 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001216 //check is need send time send end
Wentao MA96f68962022-06-15 19:45:35 +08001217 DVR_PB_INFO("pause, continue");
1218 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001219 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001220 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001221 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001222 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001223 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001224 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001225 continue;
1226 }
hualing chen266b9502020-04-04 17:39:39 +08001227 //when seek action is done. we need drop write timeout data.
1228 if (player->drop_ts == DVR_TRUE) {
1229 goto_rewrite = DVR_FALSE;
1230 real_read = 0;
1231 player->drop_ts = DVR_FALSE;
1232 }
hualing chen2aba4022020-03-02 13:49:55 +08001233 if (goto_rewrite == DVR_TRUE) {
1234 goto_rewrite = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001235 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001236 dvr_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001237 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Wentao MA96f68962022-06-15 19:45:35 +08001238 //DVR_PB_INFO("rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001239 goto rewrite;
1240 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001241 //.check is need send time send end
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001242 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001243 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001244 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001245 pthread_mutex_lock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001246 //DVR_PB_INFO("start read");
Wentao MAf35c3882023-04-17 12:36:19 +08001247 read = segment_read(player->segment_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001248 real_read = real_read + read;
1249 player->ts_cache_len = real_read;
Wentao MA96f68962022-06-15 19:45:35 +08001250 //DVR_PB_INFO("start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001251 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001252 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001253 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001254 if (read < 0 && errno == EIO) {
1255 //EIO ERROR, EXIT THRAD
Wentao MA96f68962022-06-15 19:45:35 +08001256 DVR_PB_INFO("read error.EIO error, exit thread");
hualing chenb5cd42e2020-04-15 17:03:34 +08001257 DVR_Play_Notify_t notify;
1258 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1259 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001260 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001261 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001262 goto end;
1263 } else if (read < 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001264 DVR_PB_INFO("read error.:%d EIO:%d", errno, EIO);
hualing chenb5cd42e2020-04-15 17:03:34 +08001265 }
hualing chen87072a82020-03-12 16:20:12 +08001266 //if on fb mode and read file end , we need calculate pos to retry read.
1267 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001268 DVR_PB_INFO("recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
hualing chen03fd4942021-07-15 15:56:41 +08001269 read,
1270 real_read,
1271 buf_len,
1272 player->speed,
1273 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001274 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001275 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001276 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001277 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001278 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001279 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001280 continue;
1281 }
Wentao MA96f68962022-06-15 19:45:35 +08001282 //DVR_PB_INFO("read ts [%d]buf_len[%d]speed[%f]real_read:%d", read, buf_len, player->speed, real_read);
hualing chen86e7d482020-01-16 15:13:33 +08001283 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001284 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001285 #define MIN_CACHE_TIME (3000)
Wentao MA804bab12022-11-29 10:01:26 +08001286 int delay = 0;
1287 get_effective_tsplayer_delay_time(player,&delay);
hualing chene3797f02021-01-13 14:53:28 +08001288 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
Wentao MA804bab12022-11-29 10:01:26 +08001289 if (delay > MIN_CACHE_TIME) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001290 //dvr_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001291 /*if cache time > 20s , we think get time is error,*/
Wentao MA804bab12022-11-29 10:01:26 +08001292 if (delay - MIN_CACHE_TIME > 20 * 1000) {
1293 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 +08001294 }
hualing chene41f4372020-06-06 16:29:17 +08001295 }
hualing chen969fe7b2021-05-26 15:13:17 +08001296
hualing chen040df222020-01-17 13:35:02 +08001297 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001298 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001299 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001300
Wentao MA804bab12022-11-29 10:01:26 +08001301 get_effective_tsplayer_delay_time(player,&delay);
hualing chen1679f812021-11-08 15:17:46 +08001302 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1303 player->noData++;
Wentao MA96f68962022-06-15 19:45:35 +08001304 DVR_PB_INFO("playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001305 if (player->noData == check_no_data_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001306 DVR_PB_INFO("playback send nodata event nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001307 //send event here and pause
1308 DVR_Play_Notify_t notify;
1309 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1310 notify.event = DVR_PLAYBACK_EVENT_NODATA;
Wentao MA96f68962022-06-15 19:45:35 +08001311 DVR_PB_INFO("send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001312 //get play statue not here
1313 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1314 }
1315 }
Wentao MAa0b9c002022-11-10 17:47:27 +08001316
1317 DVR_Bool_t cond1 = (ret != DVR_SUCCESS);
1318 DVR_Bool_t cond2 = (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON);
1319 DVR_Bool_t cond3 = (delay <= MIN_TSPLAYER_DELAY_TIME);
1320 DVR_Bool_t cond4 = (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF);
1321 DVR_Bool_t cond5 = (player->delay_is_effective == DVR_TRUE);
1322 DVR_Bool_t cond6 = (reach_end_timeout >= MAX_REACHEND_TIMEOUT);
1323 if ((cond1 && cond2 && (cond3 || cond4) && cond5) || cond6) {
1324 DVR_PB_INFO("REACHED_END conditions: cond1:%d, cond2:%d, (cond3:%d, cond4:%d),"
1325 " cond5:%d, cond6:%d. delay:%d, reach_end_timeout:%d",
1326 (int)cond1,(int)cond2,(int)cond3,(int)cond4,(int)cond5,(int)cond6,
1327 delay,reach_end_timeout);
Wentao MA804bab12022-11-29 10:01:26 +08001328 DVR_Play_Notify_t notify;
1329 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1330 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1331 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
1332 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
1333 dvr_mutex_lock(&player->lock);
1334 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1335 dvr_mutex_unlock(&player->lock);
1336 continue;
1337 } else if (ret != DVR_SUCCESS) {
1338 DVR_PB_INFO("delay:%d pauselive:%d", delay, _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player));
1339 dvr_mutex_lock(&player->lock);
1340 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1341 dvr_mutex_unlock(&player->lock);
1342
1343 get_effective_tsplayer_delay_time(player,&delay);
1344 //not send event and pause,sleep and go to next time to recheck
1345 if (delay < cache_time) {
1346 //delay time is changed and then has data to play, so not start timeout
1347 reach_end_timeout = 0;
1348 } else {
1349 reach_end_timeout = reach_end_timeout + timeout;
1350 }
1351 cache_time = delay;
1352 continue;
1353 }
hualing chen39628212020-05-14 10:35:13 +08001354 reach_end_timeout = 0;
1355 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001356 //change next segment success case
1357 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001358 dvr_mutex_lock(&player->lock);
hualing chen40dd5462021-11-26 19:56:20 +08001359 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001360 DVR_PB_INFO("_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001361 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1362 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001363 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08001364 read = segment_read(player->segment_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001365 real_read = real_read + read;
1366 player->ts_cache_len = real_read;
1367 pthread_mutex_unlock(&player->segment_lock);
1368
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001369 dvr_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001370 }//read len 0 check end
hualing chen40dd5462021-11-26 19:56:20 +08001371 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001372 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001373 DVR_PB_INFO("playback send data event resume[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001374 //send event here and pause
1375 DVR_Play_Notify_t notify;
1376 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1377 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
Wentao MA96f68962022-06-15 19:45:35 +08001378 DVR_PB_INFO("----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001379 //get play statue not here
1380 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001381 }
hualing chen39628212020-05-14 10:35:13 +08001382 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001383 //real_read = real_read + read;
Wentao MA270dc0f2022-08-23 13:17:26 +08001384 input_buffer.buf_size = real_read;
1385 input_buffer.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001386
Wentao MA270dc0f2022-08-23 13:17:26 +08001387 //check read data len,if len < 0, we need continue
1388 if (input_buffer.buf_size <= 0 || input_buffer.buf_data == NULL) {
1389 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 +08001390 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001391 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001392 player->ts_cache_len = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001393 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001394 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001395 }
hualing chen266b9502020-04-04 17:39:39 +08001396 //if need write whole block size, we need check read buf len is eq block size.
Wentao MAa0b9c002022-11-10 17:47:27 +08001397 if (b_writed_whole_block == DVR_TRUE
1398 && (player->has_video || player->dec_func || player->cryptor)) {
hualing chen266b9502020-04-04 17:39:39 +08001399 //buf_len is block size value.
1400 if (real_read < buf_len) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001401 //continue to read data from file
Wentao MA96f68962022-06-15 19:45:35 +08001402 DVR_PB_INFO("read buf len[%d] is < block size [%d]", real_read, buf_len);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001403 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001404 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1405 dvr_mutex_unlock(&player->lock);
1406 DVR_PB_INFO("read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001407 continue;
1408 } else if (real_read > buf_len) {
Wentao MA96f68962022-06-15 19:45:35 +08001409 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 +08001410 }
1411 }
1412
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001413 if (player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001414 DVR_CryptoParams_t crypto_params;
1415
1416 memset(&crypto_params, 0, sizeof(crypto_params));
1417 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1418 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1419 crypto_params.segment_id = player->cur_segment.segment_id;
Wentao MAf35c3882023-04-17 12:36:19 +08001420 crypto_params.offset = segment_tell_position(player->segment_handle) - input_buffer.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001421 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
Wentao MA96f68962022-06-15 19:45:35 +08001422 DVR_PB_INFO("offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001423 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1424 crypto_params.input_buffer.addr = (size_t)buf;
1425 crypto_params.input_buffer.size = real_read;
1426
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001427 if (player->is_secure_mode) {
1428 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1429 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1430 crypto_params.output_buffer.size = dec_buf_size;
1431 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001432 input_buffer.buf_data = player->secure_buffer;
1433 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001434 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001435 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001436 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001437 input_buffer.buf_size = crypto_params.output_size;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001438 } else { // only for NAGRA
1439 crypto_params.output_buffer.type = crypto_params.input_buffer.type;
1440 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1441 crypto_params.output_buffer.size = crypto_params.input_buffer.size;
1442 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001443 input_buffer.buf_data = (uint8_t*)crypto_params.output_buffer.addr;
1444 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001445 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001446 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001447 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001448 input_buffer.buf_size = crypto_params.output_buffer.size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001449 }
Yahui Han1fbf3292021-11-08 18:17:19 +08001450 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001451 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001452 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
Wentao MA270dc0f2022-08-23 13:17:26 +08001453 input_buffer.buf_data = dec_bufs.buf_data;
1454 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1455 input_buffer.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001456 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001457rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001458 if (player->drop_ts == DVR_TRUE) {
1459 //need drop ts data when seek occur.we need read next loop,drop this ts data
1460 goto_rewrite = DVR_FALSE;
1461 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001462 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001463 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001464 player->drop_ts = DVR_FALSE;
Wentao MA63c6cba2022-09-20 10:14:29 +08001465 pthread_mutex_unlock(&player->segment_lock);
1466 DVR_PB_INFO("----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001467 continue;
1468 }
hualing chen21a40372021-10-29 11:07:26 +08001469
1470 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001471 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001472 //used for printf first write data time.
1473 //to check change channel kpi.
1474 if (first_write == 0) {
1475 first_write++;
Wentao MA270dc0f2022-08-23 13:17:26 +08001476 DVR_PB_INFO("----first write ts data");
hualing chenb9a02922021-12-14 11:29:47 +08001477 }
1478
Wentao MA270dc0f2022-08-23 13:17:26 +08001479 ret = AmTsPlayer_writeData(player->handle, &input_buffer, write_timeout_ms);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001480 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001481 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001482 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001483 real_read = 0;
1484 write_success++;
shenghui.gengbec6a462023-01-12 15:21:02 +08001485 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001486check0:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001487 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001488 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001489 break;
1490 }
hualing chend241c7a2021-06-22 13:34:27 +08001491 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001492 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001493 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001494 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001495 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1496 goto check0;
1497 }
1498 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001499 //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 +08001500 } else {
Wentao MA804bab12022-11-29 10:01:26 +08001501 pthread_mutex_unlock(&player->segment_lock);
wentao.ma4ee43022022-12-14 13:22:57 +08001502 DVR_PB_DEBUG("write time out write_success:%d buf_size:%d systime:%u",
1503 write_success, input_buffer.buf_size, _dvr_time_getClock());
hualing chena540a7e2020-03-27 16:44:05 +08001504 write_success = 0;
shenghui.gengbec6a462023-01-12 15:21:02 +08001505 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001506check1:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001507 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001508 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001509 break;
1510 }
hualing chend241c7a2021-06-22 13:34:27 +08001511 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001512 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001513 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001514 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001515 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1516 goto check1;
1517 }
1518 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001519 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001520 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001521 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001522 if (!player->is_running) {
Wentao MA96f68962022-06-15 19:45:35 +08001523 DVR_PB_INFO("playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001524 break;
1525 }
hualing chen2aba4022020-03-02 13:49:55 +08001526 goto_rewrite = DVR_TRUE;
1527 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001528 }
1529 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001530end:
Wentao MA96f68962022-06-15 19:45:35 +08001531 DVR_PB_INFO("playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001532 free(buf);
1533 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001534 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001535}
1536
1537
hualing chen040df222020-01-17 13:35:02 +08001538static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001539{
hualing chen040df222020-01-17 13:35:02 +08001540 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001541
1542 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001543 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001544 return DVR_FAILURE;
1545 }
Wentao MA96f68962022-06-15 19:45:35 +08001546 DVR_PB_INFO("start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001547 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001548 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001549 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001550 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001551 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001552 if (rc < 0)
1553 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001554 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001555}
1556
1557
hualing chen040df222020-01-17 13:35:02 +08001558static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001559{
hualing chen040df222020-01-17 13:35:02 +08001560 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001561
1562 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001563 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001564 return DVR_FAILURE;
1565 }
1566
Wentao MA96f68962022-06-15 19:45:35 +08001567 DVR_PB_INFO("stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001568 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001569 {
1570 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001571 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001572 pthread_join(player->playback_thread, NULL);
1573 }
Wentao MAf35c3882023-04-17 12:36:19 +08001574 if (player->segment_handle) {
1575 segment_close(player->segment_handle);
1576 player->segment_handle = NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001577 }
Wentao MA96f68962022-06-15 19:45:35 +08001578 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001579 return 0;
1580}
1581
hualing chen1679f812021-11-08 15:17:46 +08001582static int getFakePid()
1583{
wentao ma7d642782022-10-23 18:26:16 -07001584 return dvr_prop_read_int("vendor.tv.dtv.fake_pid",0xffff);
hualing chen1679f812021-11-08 15:17:46 +08001585}
1586
1587void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1588
1589 DVR_ASSERT(handle);
1590 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1591 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001592 DVR_PB_INFO("player is NULL");
hualing chen1679f812021-11-08 15:17:46 +08001593 return ;
1594 }
1595 if (player->need_seek_start == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001596 DVR_PB_INFO("player need_seek_start is false");
hualing chen1679f812021-11-08 15:17:46 +08001597 return ;
1598 }
1599
hualing chena5f03222021-12-02 11:22:35 +08001600 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001601 player->need_seek_start = DVR_FALSE;
1602 }
Wentao MA96f68962022-06-15 19:45:35 +08001603 DVR_PB_INFO("player player->need_seek_start=%d", player->need_seek_start);
hualing chen1679f812021-11-08 15:17:46 +08001604}
1605
hualing chenb31a6c62020-01-13 17:27:00 +08001606/**\brief Open an dvr palyback
1607 * \param[out] p_handle dvr playback addr
1608 * \param[in] params dvr playback open parameters
1609 * \retval DVR_SUCCESS On success
1610 * \return Error code
1611 */
hualing chen040df222020-01-17 13:35:02 +08001612int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001613
hualing chen040df222020-01-17 13:35:02 +08001614 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001615 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001616
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001617 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
wentao.maa22bc852022-10-13 12:18:06 +08001618 DVR_RETURN_IF_FALSE(player);
hualing chenb31a6c62020-01-13 17:27:00 +08001619
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001620 dvr_mutex_init(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001621 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001622 pthread_condattr_init(&cattr);
1623 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1624 pthread_cond_init(&player->cond, &cattr);
1625 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001626
hualing chen5cbe1a62020-02-10 16:36:36 +08001627 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001628 INIT_LIST_HEAD(&player->segment_list);
1629 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1630 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001631 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001632 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00001633 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen86e7d482020-01-16 15:13:33 +08001634 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001635 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001636 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001637
hualing chen86e7d482020-01-16 15:13:33 +08001638 //store open params
hualing chen040df222020-01-17 13:35:02 +08001639 player->openParams.dmx_dev_id = params->dmx_dev_id;
1640 player->openParams.block_size = params->block_size;
Wentao MA96f68962022-06-15 19:45:35 +08001641 DVR_PB_INFO("playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001642 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001643 player->openParams.event_fn = params->event_fn;
1644 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001645 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001646 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001647
hualing chen5cbe1a62020-02-10 16:36:36 +08001648 player->has_pids = params->has_pids;
1649
hualing chen2aba4022020-03-02 13:49:55 +08001650 player->handle = params->player_handle ;
shenghui.gengbec6a462023-01-12 15:21:02 +08001651 player->control_speed_enable = params->control_speed_enable;
hualing chen6e4bfa52020-03-13 14:37:11 +08001652
1653 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1654 //for test get callback
1655 if (0 && player->player_callback_func == NULL) {
1656 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1657 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
Wentao MA96f68962022-06-15 19:45:35 +08001658 DVR_PB_INFO("playback open get callback[%p][%p][%p][%p]",
hualing chen03fd4942021-07-15 15:56:41 +08001659 player->player_callback_func,
1660 player->player_callback_userdata,
1661 _dvr_tsplayer_callback_test,
1662 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001663 }
1664 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001665
hualing chen86e7d482020-01-16 15:13:33 +08001666 //init has audio and video
1667 player->has_video = DVR_FALSE;
1668 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001669 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001670 player->last_segment_id = 0LL;
1671 player->segment_is_open = DVR_FALSE;
Wentao MA5629ad82022-08-24 10:03:02 +08001672 player->audio_presentation_id = -1;
hualing chenb31a6c62020-01-13 17:27:00 +08001673
hualing chen5cbe1a62020-02-10 16:36:36 +08001674 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001675 player->fffb_current = 0;
1676 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001677 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001678 //seek time
1679 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001680 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001681
Yahui Han1fbf3292021-11-08 18:17:19 +08001682 //allocate cryptor if have clearkey
1683 if (params->keylen > 0) {
1684 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +08001685 (uint8_t *)params->cleariv,
1686 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +08001687 if (!player->cryptor) {
Wentao MA96f68962022-06-15 19:45:35 +08001688 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +08001689 }
1690 } else {
1691 player->cryptor = NULL;
1692 }
1693
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001694 //init secure stuff
1695 player->dec_func = NULL;
1696 player->dec_userdata = NULL;
1697 player->is_secure_mode = 0;
1698 player->secure_buffer = NULL;
1699 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001700 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001701
hualing chen4b7c15d2020-04-07 16:13:48 +08001702 player->fffb_play = DVR_FALSE;
1703
1704 player->last_send_time_id = UINT64_MAX;
1705 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001706 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001707
hualing chend241c7a2021-06-22 13:34:27 +08001708 //speed con init
shenghui.gengbec6a462023-01-12 15:21:02 +08001709 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001710 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001711 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001712 player->con_spe.sys_dur = 0;
1713 player->con_spe.sys_sta = 0;
1714 }
1715
hualing chen03fd4942021-07-15 15:56:41 +08001716 //limit info
1717 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001718 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001719 //need seek to start pos
1720 player->first_start_time = 0;
Wentao MA01de0e62022-01-10 18:48:23 +08001721 player->first_start_id = UINT64_MAX;
Wentao MAa0b9c002022-11-10 17:47:27 +08001722 player->delay_is_effective = DVR_FALSE;
hualing chen8a657f32021-08-30 13:12:49 +08001723 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001724 //fake_pid init
1725 player->fake_pid = getFakePid();
hualing chen86e7d482020-01-16 15:13:33 +08001726 *p_handle = player;
1727 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001728}
1729
1730/**\brief Close an dvr palyback
1731 * \param[in] handle playback handle
1732 * \retval DVR_SUCCESS On success
1733 * \return Error code
1734 */
hualing chen040df222020-01-17 13:35:02 +08001735int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001736
hualing chen86e7d482020-01-16 15:13:33 +08001737 DVR_ASSERT(handle);
Wentao MA96f68962022-06-15 19:45:35 +08001738 DVR_PB_INFO(":into");
hualing chen040df222020-01-17 13:35:02 +08001739 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001740 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001741 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001742 return DVR_FAILURE;
1743 }
1744
hualing chencc91e1c2020-02-28 13:26:17 +08001745 if (player->state != DVR_PLAYBACK_STATE_STOP)
1746 {
Wentao MA96f68962022-06-15 19:45:35 +08001747 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001748 if (player->cryptor) {
1749 am_crypt_des_close(player->cryptor);
1750 player->cryptor = NULL;
1751 }
hualing chencc91e1c2020-02-28 13:26:17 +08001752 dvr_playback_stop(handle, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08001753 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
hualing chenb96aa2c2020-04-15 14:13:53 +08001754 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001755 DVR_PB_INFO(":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001756 }
Wentao MA96f68962022-06-15 19:45:35 +08001757 DVR_PB_INFO(":into");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001758 dvr_mutex_destroy(&player->lock);
Zhiqiang Hanc9513462022-06-21 09:55:23 +08001759 pthread_mutex_destroy(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001760 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001761
1762 if (player) {
1763 free(player);
hualing chen040df222020-01-17 13:35:02 +08001764 }
Wentao MA96f68962022-06-15 19:45:35 +08001765 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001766 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001767}
1768
Wentao MA270dc0f2022-08-23 13:17:26 +08001769/**\brief Start play audio and video, used start audio api and start video api
hualing chenb31a6c62020-01-13 17:27:00 +08001770 * \param[in] handle playback handle
1771 * \param[in] params audio playback params,contains fmt and pid...
1772 * \retval DVR_SUCCESS On success
1773 * \return Error code
1774 */
hualing chen040df222020-01-17 13:35:02 +08001775int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1776 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA270dc0f2022-08-23 13:17:26 +08001777 am_tsplayer_video_params video_params;
1778 am_tsplayer_audio_params audio_params;
1779 am_tsplayer_audio_params ad_params;
hualing chena540a7e2020-03-27 16:44:05 +08001780
Wentao MA270dc0f2022-08-23 13:17:26 +08001781 memset(&video_params, 0, sizeof(video_params));
1782 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001783
hualing chena540a7e2020-03-27 16:44:05 +08001784 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001785 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001786 return DVR_FAILURE;
1787 }
hualing chencc91e1c2020-02-28 13:26:17 +08001788 uint64_t segment_id = player->cur_segment_id;
Wentao MA96f68962022-06-15 19:45:35 +08001789 DVR_PB_INFO("[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001790
hualing chena540a7e2020-03-27 16:44:05 +08001791 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001792 //can used start api to resume playback
1793 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1794 return dvr_playback_resume(handle);
1795 }
hualing chen87072a82020-03-12 16:20:12 +08001796 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001797 //if flag is paused and not decode first frame. if user resume, we need
hualing chen9b434f02020-06-10 15:06:54 +08001798 //clear flag and set trickmode none
1799 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001800 DVR_PB_INFO("[%p]clear pause live flag and clear trick mode", handle);
hualing chen9b434f02020-06-10 15:06:54 +08001801 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1802 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1803 }
Wentao MA96f68962022-06-15 19:45:35 +08001804 DVR_PB_INFO("stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001805 return DVR_SUCCESS;
1806 }
hualing chen86e7d482020-01-16 15:13:33 +08001807 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001808 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001809 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08001810 DVR_PB_INFO("lock flag:0x%x", flag);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001811 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001812 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08001813 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08001814 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
1815 //audio and video pids are all invalid, return error.
1816 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 +08001817 dvr_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001818 DVR_Play_Notify_t notify;
1819 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1820 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1821 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1822 notify.info.transition_failed_data.segment_id = segment_id;
1823 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001824 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001825 return -1;
1826 }
hualing chen31140872020-03-25 12:29:26 +08001827
hualing chencc91e1c2020-02-28 13:26:17 +08001828 {
Wentao MA270dc0f2022-08-23 13:17:26 +08001829 if (VALID_PID(video_params.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001830 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001831 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001832 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001833 DVR_PB_INFO("set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001834 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1835 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001836 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
Wentao MA96f68962022-06-15 19:45:35 +08001837 DVR_PB_INFO("set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001838 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001839 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001840 DVR_PB_INFO("set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001841 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001842 }
hualing chena93bbbc2020-12-22 17:23:42 +08001843 AmTsPlayer_showVideo(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08001844 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08001845 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001846 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001847 }
hualing chena540a7e2020-03-27 16:44:05 +08001848
Wentao MA270dc0f2022-08-23 13:17:26 +08001849 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 +08001850 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001851 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1852 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1853 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001854 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001855 } else {
1856 player->cmd.last_cmd = player->cmd.cur_cmd;
1857 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001858 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001859 //set fast play
Wentao MA96f68962022-06-15 19:45:35 +08001860 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08001861 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001862 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08001863 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08001864 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08001865 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08001866 dvr_playback_change_seek_state(handle, ad_params.pid);
1867 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08001868 AmTsPlayer_enableADMix(player->handle);
1869 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001870 if (VALID_PID(audio_params.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001871 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08001872 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08001873 dvr_playback_change_seek_state(handle, audio_params.pid);
1874 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08001875 if (player->audio_presentation_id > -1) {
1876 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
1877 }
hualing chen969fe7b2021-05-26 15:13:17 +08001878 AmTsPlayer_startAudioDecoding(player->handle);
1879 }
hualing chen31140872020-03-25 12:29:26 +08001880 }
hualing chencc91e1c2020-02-28 13:26:17 +08001881 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001882 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001883 }
hualing chen86e7d482020-01-16 15:13:33 +08001884 }
hualing chen43a89bc2022-01-19 14:31:20 +08001885#ifdef AVSYNC_USED_PCR
1886 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001887 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08001888 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
1889 }
1890#endif
Wentao MA96f68962022-06-15 19:45:35 +08001891 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001892 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001893 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001894 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001895}
hualing chen040df222020-01-17 13:35:02 +08001896/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001897 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001898 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001899 * \retval DVR_SUCCESS On success
1900 * \return Error code
1901 */
hualing chen040df222020-01-17 13:35:02 +08001902int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1903 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa22bc852022-10-13 12:18:06 +08001904 DVR_RETURN_IF_FALSE(player);
hualing chena540a7e2020-03-27 16:44:05 +08001905
Wentao MA96f68962022-06-15 19:45:35 +08001906 DVR_PB_INFO("add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001907 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001908
hualing chen040df222020-01-17 13:35:02 +08001909 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
wentao.maa22bc852022-10-13 12:18:06 +08001910 DVR_RETURN_IF_FALSE(segment);
hualing chen040df222020-01-17 13:35:02 +08001911 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001912
Wentao MA270dc0f2022-08-23 13:17:26 +08001913 //not memcpy chunk info.
hualing chen040df222020-01-17 13:35:02 +08001914 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001915 //cp location
hualing chen040df222020-01-17 13:35:02 +08001916 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001917
Wentao MA96f68962022-06-15 19:45:35 +08001918 DVR_PB_INFO("add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001919 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001920
1921 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001922 segment->pids.video.pid = info->pids.video.pid;
1923 segment->pids.video.format = info->pids.video.format;
1924 segment->pids.video.type = info->pids.video.type;
1925
hualing chen2aba4022020-03-02 13:49:55 +08001926 segment->pids.audio.pid = info->pids.audio.pid;
1927 segment->pids.audio.format = info->pids.audio.format;
1928 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001929
hualing chen2aba4022020-03-02 13:49:55 +08001930 segment->pids.ad.pid = info->pids.ad.pid;
1931 segment->pids.ad.format = info->pids.ad.format;
1932 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001933
1934 segment->pids.pcr.pid = info->pids.pcr.pid;
1935
Wentao MA96f68962022-06-15 19:45:35 +08001936 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 +08001937 dvr_mutex_lock(&player->lock);
wentao.maa22bc852022-10-13 12:18:06 +08001938 list_add_tail(segment, &player->segment_list);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001939 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001940 DVR_PB_DEBUG("unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001941
hualing chen5cbe1a62020-02-10 16:36:36 +08001942 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001943}
hualing chen040df222020-01-17 13:35:02 +08001944/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001945 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001946 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001947 * \retval DVR_SUCCESS On success
1948 * \return Error code
1949 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001950int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001951 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001952 DVR_PB_INFO("remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001953 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001954 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001955 return DVR_FAILURE;
1956 }
1957
hualing chencc91e1c2020-02-28 13:26:17 +08001958 if (segment_id == player->cur_segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08001959 DVR_PB_INFO("not support remove current segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001960 return DVR_FAILURE;
1961 }
Wentao MA96f68962022-06-15 19:45:35 +08001962 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001963 dvr_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001964 DVR_PlaybackSegmentInfo_t *segment = NULL;
1965 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1966 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001967 {
hualing chen040df222020-01-17 13:35:02 +08001968 if (segment->segment_id == segment_id) {
1969 list_del(&segment->head);
1970 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001971 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001972 }
hualing chen86e7d482020-01-16 15:13:33 +08001973 }
Wentao MA96f68962022-06-15 19:45:35 +08001974 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001975 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001976
1977 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001978}
hualing chen040df222020-01-17 13:35:02 +08001979/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001980 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001981 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001982 * \retval DVR_SUCCESS On success
1983 * \return Error code
1984 */
hualing chen040df222020-01-17 13:35:02 +08001985int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001986 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001987 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001988 DVR_PB_INFO("update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001989 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001990 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001991 return DVR_FAILURE;
1992 }
Wentao MA292380e2022-12-14 14:46:19 +08001993 if (player->vendor != DVR_PLAYBACK_VENDOR_DEF) {
1994 DVR_PB_INFO("In case of vendor Amlogic/Amazon, do not control AV display");
hualing chenf43b8ba2020-07-28 13:11:42 +08001995 return DVR_SUCCESS;
1996 }
hualing chena540a7e2020-03-27 16:44:05 +08001997
hualing chen040df222020-01-17 13:35:02 +08001998 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08001999 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002000 dvr_mutex_lock(&player->lock);
wentao.mafd5283f2022-10-14 09:51:13 +08002001 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002002 // prefetch() here incurring self_assign is used to avoid some compiling
2003 // warnings.
2004 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002005 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002006 {
hualing chen040df222020-01-17 13:35:02 +08002007 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08002008 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08002009 }
hualing chen86e7d482020-01-16 15:13:33 +08002010 // if encramble to free, only set flag and return;
2011
2012 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08002013 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002014 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
2015 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08002016 //disable display, mute
Wentao MA96f68962022-06-15 19:45:35 +08002017 DVR_PB_INFO("mute av");
hualing chen2aba4022020-03-02 13:49:55 +08002018 AmTsPlayer_hideVideo(player->handle);
2019 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002020 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
2021 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002022 //enable display, unmute
Wentao MA96f68962022-06-15 19:45:35 +08002023 DVR_PB_INFO("unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08002024 AmTsPlayer_showVideo(player->handle);
2025 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002026 } else {
2027 //do nothing
2028 }
2029 } else {
2030 //do nothing
2031 }
2032 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08002033 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08002034 }
Wentao MA96f68962022-06-15 19:45:35 +08002035 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002036 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002037 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002038}
2039
2040
Wentao MA6dcdc342023-01-30 17:03:19 +08002041static 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 +08002042 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08002043 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08002044 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08002045
Wentao MA6dcdc342023-01-30 17:03:19 +08002046 if (player == NULL) {
2047 DVR_PB_INFO("player is NULL");
2048 return DVR_FAILURE;
2049 }
2050
hualing chen275379e2021-06-15 17:57:21 +08002051 if (type == 0) {
2052 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08002053 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08002054 } else if (type == 1) {
2055 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08002056 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08002057 } else if (type == 2) {
2058 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08002059 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08002060 } else {
2061 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08002062 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08002063 }
2064
Wentao MA6dcdc342023-01-30 17:03:19 +08002065 if (type == 1 && VALID_PID(set_pid.pid) && player->cmd.state == DVR_PLAYBACK_STATE_START
2066 && player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
2067 // Here we mute audio no matter it is displayable or not in starting phase of a playback.
2068 // Audio will be unmuted shortly on receiving first frame event.
2069 AmTsPlayer_setAudioMute(player->handle,1,1);
hualing chena540a7e2020-03-27 16:44:05 +08002070 }
Wentao MA6dcdc342023-01-30 17:03:19 +08002071
hualing chen86e7d482020-01-16 15:13:33 +08002072 if (now_pid.pid == set_pid.pid) {
2073 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08002074 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08002075 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08002076 if (VALID_PID(now_pid.pid)) {
2077 //stop now stream
2078 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002079 //stop video
hualing chenc70a8df2020-05-12 19:23:11 +08002080 if (player->has_video == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002081 DVR_PB_INFO("stop video");
hualing chenc70a8df2020-05-12 19:23:11 +08002082 AmTsPlayer_stopVideoDecoding(player->handle);
2083 player->has_video = DVR_FALSE;
2084 }
hualing chen86e7d482020-01-16 15:13:33 +08002085 } else if (type == 1) {
2086 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002087 if (player->has_audio == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002088 DVR_PB_INFO("stop audio");
hualing chenc70a8df2020-05-12 19:23:11 +08002089 AmTsPlayer_stopAudioDecoding(player->handle);
2090 player->has_audio = DVR_FALSE;
2091 }
hualing chen86e7d482020-01-16 15:13:33 +08002092 } else if (type == 2) {
2093 //stop sub audio
Wentao MA96f68962022-06-15 19:45:35 +08002094 DVR_PB_INFO("stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002095 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002096 } else if (type == 3) {
2097 //pcr
2098 }
2099 }
2100 if (VALID_PID(set_pid.pid)) {
2101 //start
2102 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002103 //start video
2104 am_tsplayer_video_params video_params;
2105 video_params.pid = set_pid.pid;
2106 video_params.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002107 player->has_video = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002108 DVR_PB_INFO("start video pid[%d]fmt[%d]",video_params.pid, video_params.codectype);
2109 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen2aba4022020-03-02 13:49:55 +08002110 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002111 //playback_device_video_start(player->handle,&video_params);
hualing chen86e7d482020-01-16 15:13:33 +08002112 } else if (type == 1) {
2113 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002114 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002115 if (VALID_PID(set_pids.ad.pid)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002116 am_tsplayer_audio_params ad_params;
2117 ad_params.pid = set_pids.ad.pid;
2118 ad_params.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2119 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",ad_params.pid, ad_params.codectype);
2120 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen275379e2021-06-15 17:57:21 +08002121 AmTsPlayer_enableADMix(player->handle);
2122 }
2123
Wentao MA270dc0f2022-08-23 13:17:26 +08002124 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002125
Wentao MA270dc0f2022-08-23 13:17:26 +08002126 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002127
Wentao MA270dc0f2022-08-23 13:17:26 +08002128 audio_params.pid = set_pid.pid;
2129 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002130 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002131 DVR_PB_INFO("start audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2132 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002133 if (player->audio_presentation_id > -1) {
2134 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2135 }
Wentao MA6dcdc342023-01-30 17:03:19 +08002136
hualing chenc70a8df2020-05-12 19:23:11 +08002137 AmTsPlayer_startAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002138 //playback_device_audio_start(player->handle,&audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002139 }
hualing chen86e7d482020-01-16 15:13:33 +08002140 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002141 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002142 if (set_pids.audio.pid == now_pids.audio.pid) {
2143 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002144 DVR_PB_INFO("stop audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002145 AmTsPlayer_stopAudioDecoding(player->handle);
2146 }
Wentao MA270dc0f2022-08-23 13:17:26 +08002147 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002148
Wentao MA270dc0f2022-08-23 13:17:26 +08002149 memset(&audio_params, 0, sizeof(audio_params));
2150 audio_params.pid = set_pid.pid;
2151 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002152 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002153 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2154 AmTsPlayer_setADParams(player->handle, &audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002155 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002156
2157 if (set_pids.audio.pid == now_pids.audio.pid) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002158 am_tsplayer_audio_params audio_params;
hualing chen99508642021-10-18 15:41:17 +08002159
Wentao MA270dc0f2022-08-23 13:17:26 +08002160 memset(&audio_params, 0, sizeof(audio_params));
hualing chen99508642021-10-18 15:41:17 +08002161
Wentao MA270dc0f2022-08-23 13:17:26 +08002162 audio_params.pid = set_pids.audio.pid;
2163 audio_params.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
hualing chen99508642021-10-18 15:41:17 +08002164 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002165 DVR_PB_INFO("restart audio when start ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002166 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002167 if (player->audio_presentation_id > -1) {
2168 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2169 }
hualing chen99508642021-10-18 15:41:17 +08002170 AmTsPlayer_startAudioDecoding(player->handle);
2171 }
hualing chenc70a8df2020-05-12 19:23:11 +08002172 }
hualing chen86e7d482020-01-16 15:13:33 +08002173 } else if (type == 3) {
2174 //pcr
Wentao MA96f68962022-06-15 19:45:35 +08002175 DVR_PB_INFO("start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002176 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002177 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002178 //audio and video all close
2179 if (!player->has_audio && !player->has_video) {
Wentao MA907b6432022-08-01 06:23:08 +00002180 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen5cbe1a62020-02-10 16:36:36 +08002181 }
hualing chen43a89bc2022-01-19 14:31:20 +08002182 } else if (type == 2) {
2183 //case disable ad
Wentao MA96f68962022-06-15 19:45:35 +08002184 DVR_PB_INFO("restart audio when stop ad");
hualing chen43a89bc2022-01-19 14:31:20 +08002185 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
Wentao MA6d045b32022-02-18 18:47:25 +08002186 if (VALID_PID(now_pids.audio.pid)) {
2187 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002188 DVR_PB_INFO("stop audio when stop ad pid [0x%x]", now_pids.audio.pid);
Wentao MA6d045b32022-02-18 18:47:25 +08002189 AmTsPlayer_stopAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002190 am_tsplayer_audio_params audio_params;
hualing chen43a89bc2022-01-19 14:31:20 +08002191
Wentao MA270dc0f2022-08-23 13:17:26 +08002192 memset(&audio_params, 0, sizeof(audio_params));
hualing chen43a89bc2022-01-19 14:31:20 +08002193
Wentao MA270dc0f2022-08-23 13:17:26 +08002194 audio_params.pid = now_pids.audio.pid;
2195 audio_params.codectype= _dvr_convert_stream_fmt(now_pids.audio.format, DVR_TRUE);
Wentao MA6d045b32022-02-18 18:47:25 +08002196 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002197 DVR_PB_INFO("restart audio when stop ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002198 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002199 if (player->audio_presentation_id > -1) {
2200 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2201 }
Wentao MA6d045b32022-02-18 18:47:25 +08002202 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen43a89bc2022-01-19 14:31:20 +08002203 }
Wentao MA6d045b32022-02-18 18:47:25 +08002204 }
hualing chen86e7d482020-01-16 15:13:33 +08002205 }
2206 }
2207 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002208}
hualing chena5f03222021-12-02 11:22:35 +08002209/**\brief dvr play back only update segment pids info
2210 * only update pid info not to start stop codec.
2211 * \param[in] handle playback handle
2212 * \param[in] segment_id need updated pids segment id
2213 * \param[in] p_pids need updated pids
2214 * \retval DVR_SUCCESS On success
2215 * \return Error code
2216 */
2217int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2218 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2219 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002220 DVR_PB_INFO("player is NULL");
hualing chena5f03222021-12-02 11:22:35 +08002221 return DVR_FAILURE;
2222 }
2223
2224 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002225 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002226 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002227 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 +08002228 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002229 // prefetch() here incurring self_assign is used to avoid some compiling
2230 // warnings.
2231 // coverity[self_assign]
hualing chena5f03222021-12-02 11:22:35 +08002232 list_for_each_entry(segment, &player->segment_list, head)
2233 {
2234 if (segment->segment_id == segment_id) {
2235 if (player->cur_segment_id == segment_id) {
2236 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002237 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chena5f03222021-12-02 11:22:35 +08002238 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002239 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002240 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002241 return 0;
2242 }
2243 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2244 }
2245 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002246 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002247 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002248 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002249 break;
2250 }
2251 }
Wentao MA96f68962022-06-15 19:45:35 +08002252 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002253 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002254 return DVR_SUCCESS;
2255}
2256
hualing chen5cbe1a62020-02-10 16:36:36 +08002257/**\brief dvr play back update segment pids
2258 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002259 * add pid stream and stop remove pid stream.
2260 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002261 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002262 * \retval DVR_SUCCESS On success
2263 * \return Error code
2264 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002265int 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 +08002266 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002267 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002268 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002269 return DVR_FAILURE;
2270 }
2271
hualing chen040df222020-01-17 13:35:02 +08002272 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002273 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002274 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002275 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 +08002276
wentao.mafd5283f2022-10-14 09:51:13 +08002277 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002278 // prefetch() here incurring self_assign is used to avoid some compiling
2279 // warnings.
2280 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002281 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002282 {
hualing chen040df222020-01-17 13:35:02 +08002283 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002284
2285 if (player->cur_segment_id == segment_id) {
2286 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002287 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002288 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002289 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002290 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002291 return 0;
2292 }
2293
2294 //if segment is on going segment,we need stop start stream
2295 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA96f68962022-06-15 19:45:35 +08002296 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002297 dvr_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002298 if (segment->pids.audio.pid != p_pids->audio.pid &&
2299 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002300 //not used this to seek to start pos.we will
Wentao MA9a164002022-08-29 11:20:24 +08002301 //add update only api. if need seek to start
hualing chena5f03222021-12-02 11:22:35 +08002302 //pos, we will call only update api and used seek api
2303 //to start and stop av codec
2304 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002305 player->need_seek_start = DVR_FALSE;
2306 pthread_mutex_lock(&player->segment_lock);
2307 player->drop_ts = DVR_TRUE;
2308 player->ts_cache_len = 0;
2309 if (player->first_start_time > 0)
2310 player->first_start_time = player->first_start_time - 1;
Wentao MAf35c3882023-04-17 12:36:19 +08002311 segment_seek(player->segment_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002312 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 +08002313 pthread_mutex_unlock(&player->segment_lock);
2314 }
2315 }
hualing chen1679f812021-11-08 15:17:46 +08002316 //check video pids, stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002317 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
hualing chen1679f812021-11-08 15:17:46 +08002318 //check sub audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002319 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
hualing chen1679f812021-11-08 15:17:46 +08002320 //check audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002321 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
hualing chen1679f812021-11-08 15:17:46 +08002322 //check pcr pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002323 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
hualing chen1679f812021-11-08 15:17:46 +08002324
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002325 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002326 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2327 //if state is pause, we need process at resume api. we only record change info
2328 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2329 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2330 if (VALID_PID(segment->pids.video.pid)
2331 && VALID_PID(p_pids->video.pid)
2332 && segment->pids.video.pid != p_pids->video.pid) {
2333 //restart video
Wentao MA270dc0f2022-08-23 13:17:26 +08002334 v_cmd = DVR_PLAYBACK_CMD_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002335 }
2336 if (!VALID_PID(segment->pids.video.pid)
2337 && VALID_PID(p_pids->video.pid)
2338 && segment->pids.video.pid != p_pids->video.pid) {
2339 //start video
Wentao MA270dc0f2022-08-23 13:17:26 +08002340 v_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002341 }
2342 if (VALID_PID(segment->pids.video.pid)
2343 && !VALID_PID(p_pids->video.pid)
2344 && segment->pids.video.pid != p_pids->video.pid) {
2345 //stop video
Wentao MA270dc0f2022-08-23 13:17:26 +08002346 v_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002347 }
2348 if (VALID_PID(segment->pids.audio.pid)
2349 && VALID_PID(p_pids->audio.pid)
2350 && segment->pids.audio.pid != p_pids->audio.pid) {
2351 //restart audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002352 a_cmd = DVR_PLAYBACK_CMD_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002353 }
2354 if (!VALID_PID(segment->pids.audio.pid)
2355 && VALID_PID(p_pids->audio.pid)
2356 && segment->pids.audio.pid != p_pids->audio.pid) {
2357 //start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002358 a_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002359 }
2360 if (VALID_PID(segment->pids.audio.pid)
2361 && !VALID_PID(p_pids->audio.pid)
2362 && segment->pids.audio.pid != p_pids->audio.pid) {
2363 //stop audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002364 a_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002365 }
2366 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2367 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2368 //do nothing
2369 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2370 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2371 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2372 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2373 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2374 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002375 if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2376 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002377 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002378 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
2379 }else if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2380 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002381 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002382 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002383 } else {
2384 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002385 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002386 }
2387
Wentao MA270dc0f2022-08-23 13:17:26 +08002388 if (v_cmd == DVR_PLAYBACK_CMD_V_START
2389 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002390 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002391 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START_A_RESTART;
2392 } else if (v_cmd == DVR_PLAYBACK_CMD_V_START
2393 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002394 //not occur this case
2395 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2396 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2397 } else {
2398 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002399 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002400 }
2401
Wentao MA270dc0f2022-08-23 13:17:26 +08002402 if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2403 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002404 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002405 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_START;
2406 } else if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2407 && a_cmd == DVR_PLAYBACK_CMD_A_RESTART) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002408 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002409 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002410 } else {
2411 //not occur this case
2412 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2413 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2414 }
2415 }
2416 }
hualing chene10666f2020-04-14 13:58:37 +08002417 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002418 }
hualing chen86e7d482020-01-16 15:13:33 +08002419 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002420 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002421 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002422 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002423 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002424 }
hualing chen86e7d482020-01-16 15:13:33 +08002425 }
Wentao MA96f68962022-06-15 19:45:35 +08002426 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002427 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002428 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002429}
2430/**\brief Stop play, will stop video and audio
2431 * \param[in] handle playback handle
2432 * \param[in] clear is clear last frame
2433 * \retval DVR_SUCCESS On success
2434 * \return Error code
2435 */
hualing chen040df222020-01-17 13:35:02 +08002436int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2437 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002438 DVR_UNUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002439 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002440 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002441 return DVR_FAILURE;
2442 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002443 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002444 DVR_PB_INFO(":playback is stoped");
hualing chenb96aa2c2020-04-15 14:13:53 +08002445 return DVR_SUCCESS;
2446 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002447 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002448 DVR_PB_INFO(":playback is stoped");
Ke Gong3c0caba2020-04-21 22:58:18 -07002449 return DVR_SUCCESS;
2450 }
hualing chen87072a82020-03-12 16:20:12 +08002451 _stop_playback_thread(handle);
Wentao MA96f68962022-06-15 19:45:35 +08002452 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002453 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002454 DVR_PB_INFO(":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002455 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002456 if (player->has_video) {
2457 AmTsPlayer_resumeVideoDecoding(player->handle);
2458 }
2459 if (player->has_audio) {
2460 AmTsPlayer_resumeAudioDecoding(player->handle);
2461 }
2462 if (player->has_video) {
2463 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002464 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002465 AmTsPlayer_stopVideoDecoding(player->handle);
2466 }
2467 if (player->has_audio) {
2468 player->has_audio = DVR_FALSE;
2469 AmTsPlayer_stopAudioDecoding(player->handle);
2470 }
hualing chendf118dd2020-05-21 15:49:11 +08002471 if (player->has_ad_audio) {
2472 player->has_ad_audio =DVR_FALSE;
2473 AmTsPlayer_disableADMix(player->handle);
2474 }
hualing chen266b9502020-04-04 17:39:39 +08002475
hualing chen86e7d482020-01-16 15:13:33 +08002476 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002477 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2478 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002479 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen87072a82020-03-12 16:20:12 +08002480 player->cur_segment_id = UINT64_MAX;
2481 player->segment_is_open = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08002482 DVR_PB_DEBUG("unlock");
2483 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002484 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002485 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002486}
2487/**\brief Start play audio
2488 * \param[in] handle playback handle
2489 * \param[in] params audio playback params,contains fmt and pid...
2490 * \retval DVR_SUCCESS On success
2491 * \return Error code
2492 */
hualing chen2aba4022020-03-02 13:49:55 +08002493
Wentao MA270dc0f2022-08-23 13:17:26 +08002494int 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 +08002495 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002496
2497 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002498 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002499 return DVR_FAILURE;
2500 }
hualing chen86e7d482020-01-16 15:13:33 +08002501 _start_playback_thread(handle);
2502 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002503 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002504 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002505
Wentao MA270dc0f2022-08-23 13:17:26 +08002506 if (VALID_PID(ad_param->pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08002507 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002508 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002509 AmTsPlayer_setADParams(player->handle, ad_param);
hualing chendf118dd2020-05-21 15:49:11 +08002510 AmTsPlayer_enableADMix(player->handle);
2511 }
hualing chen969fe7b2021-05-26 15:13:17 +08002512 if (VALID_PID(param->pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08002513 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08002514 player->has_audio = DVR_TRUE;
2515 AmTsPlayer_setAudioParams(player->handle, param);
Wentao MA5629ad82022-08-24 10:03:02 +08002516 if (player->audio_presentation_id > -1) {
2517 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2518 }
hualing chen969fe7b2021-05-26 15:13:17 +08002519 AmTsPlayer_startAudioDecoding(player->handle);
2520 }
hualing chendf118dd2020-05-21 15:49:11 +08002521
hualing chen86e7d482020-01-16 15:13:33 +08002522 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002523 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen040df222020-01-17 13:35:02 +08002524 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002525 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002526 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002527 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002528 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002529}
2530/**\brief Stop play audio
2531 * \param[in] handle playback handle
2532 * \retval DVR_SUCCESS On success
2533 * \return Error code
2534 */
hualing chen040df222020-01-17 13:35:02 +08002535int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2536 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002537
2538 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002539 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002540 return DVR_FAILURE;
2541 }
2542
hualing chen2aba4022020-03-02 13:49:55 +08002543 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002544 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002545 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002546 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002547 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002548 _stop_playback_thread(handle);
2549 } else {
2550 //do nothing.video is playing
2551 }
Wentao MA96f68962022-06-15 19:45:35 +08002552 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002553 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002554
hualing chenf00cdc82020-06-10 14:23:35 +08002555 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002556 player->has_audio = DVR_FALSE;
2557 AmTsPlayer_stopAudioDecoding(player->handle);
2558 }
hualing chen87072a82020-03-12 16:20:12 +08002559
hualing chendf118dd2020-05-21 15:49:11 +08002560 if (player->has_ad_audio) {
2561 player->has_ad_audio =DVR_FALSE;
2562 AmTsPlayer_disableADMix(player->handle);
2563 }
2564
hualing chen87072a82020-03-12 16:20:12 +08002565 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002566 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002567
Wentao MA96f68962022-06-15 19:45:35 +08002568 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002569 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002570 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002571}
2572/**\brief Start play video
2573 * \param[in] handle playback handle
2574 * \param[in] params video playback params,contains fmt and pid...
2575 * \retval DVR_SUCCESS On success
2576 * \return Error code
2577 */
hualing chen2aba4022020-03-02 13:49:55 +08002578int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002579 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002580
2581 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002582 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002583 return DVR_FAILURE;
2584 }
2585
hualing chen86e7d482020-01-16 15:13:33 +08002586 _start_playback_thread(handle);
2587 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002588 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002589 dvr_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002590 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002591 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002592 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002593 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002594
2595 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002596 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002597 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08002598 DVR_PB_INFO("settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002599 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2600 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002601 }
2602 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002603 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen040df222020-01-17 13:35:02 +08002604 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002605 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002606 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002607 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002608 return DVR_SUCCESS;
2609}
2610/**\brief Stop play video
2611 * \param[in] handle playback handle
2612 * \retval DVR_SUCCESS On success
2613 * \return Error code
2614 */
hualing chen040df222020-01-17 13:35:02 +08002615int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2616 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002617
2618 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002619 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002620 return DVR_FAILURE;
2621 }
2622
hualing chen86e7d482020-01-16 15:13:33 +08002623 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002624 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002625 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002626 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002627 _stop_playback_thread(handle);
2628 } else {
2629 //do nothing.audio is playing
2630 }
hualing chen7a56cba2020-04-14 14:09:27 +08002631
Wentao MA96f68962022-06-15 19:45:35 +08002632 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002633 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002634
hualing chen87072a82020-03-12 16:20:12 +08002635 player->has_video = DVR_FALSE;
2636
2637 AmTsPlayer_stopVideoDecoding(player->handle);
2638 //playback_device_video_stop(player->handle);
2639
2640 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002641 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002642
Wentao MA96f68962022-06-15 19:45:35 +08002643 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002644 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002645 return DVR_SUCCESS;
2646}
2647/**\brief Pause play
2648 * \param[in] handle playback handle
2649 * \param[in] flush whether its internal buffers should be flushed
2650 * \retval DVR_SUCCESS On success
2651 * \return Error code
2652 */
hualing chen040df222020-01-17 13:35:02 +08002653int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2654 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002655 DVR_UNUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002656 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002657 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002658 return DVR_FAILURE;
2659 }
hualing chenf00cdc82020-06-10 14:23:35 +08002660 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
Wentao MA96f68962022-06-15 19:45:35 +08002661 DVR_PB_INFO("player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002662 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002663 }
Wentao MA96f68962022-06-15 19:45:35 +08002664 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002665 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002666 DVR_PB_DEBUG("get lock");
hualing chen266b9502020-04-04 17:39:39 +08002667 if (player->has_video)
2668 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002669 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002670 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002671
2672 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002673 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2674 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2675 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002676 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002677 } else {
2678 player->cmd.last_cmd = player->cmd.cur_cmd;
2679 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2680 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002681 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002682 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002683 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002684 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002685
hualing chen86e7d482020-01-16 15:13:33 +08002686 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002687}
2688
hualing chen5cbe1a62020-02-10 16:36:36 +08002689//not add lock
2690static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2691{
2692 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2693
hualing chena540a7e2020-03-27 16:44:05 +08002694 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002695 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002696 return DVR_FAILURE;
2697 }
2698
hualing chen5cbe1a62020-02-10 16:36:36 +08002699 //get video params and audio params
Wentao MA96f68962022-06-15 19:45:35 +08002700 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002701 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08002702 am_tsplayer_video_params video_params;
2703 am_tsplayer_audio_params audio_params;
2704 am_tsplayer_audio_params ad_params;
hualing chencc91e1c2020-02-28 13:26:17 +08002705 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002706
Wentao MA270dc0f2022-08-23 13:17:26 +08002707 memset(&video_params, 0, sizeof(video_params));
2708 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002709
Wentao MA270dc0f2022-08-23 13:17:26 +08002710 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
Wentao MA96f68962022-06-15 19:45:35 +08002711 DVR_PB_INFO("unlock cmd: %d", cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002712 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002713
2714 switch (cmd) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002715 case DVR_PLAYBACK_CMD_AV_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002716 //av restart
Wentao MA270dc0f2022-08-23 13:17:26 +08002717 DVR_PB_INFO("do_cmd av_restart");
hualing chen87072a82020-03-12 16:20:12 +08002718 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002719 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002720 case DVR_PLAYBACK_CMD_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002721 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002722 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002723 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002724 case DVR_PLAYBACK_CMD_V_START:
2725 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002726 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002727 case DVR_PLAYBACK_CMD_V_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002728 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002729 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002730 case DVR_PLAYBACK_CMD_A_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002731 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002732 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002733 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002734 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002735 case DVR_PLAYBACK_CMD_A_START:
2736 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002737 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002738 case DVR_PLAYBACK_CMD_A_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002739 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002740 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002741 case DVR_PLAYBACK_CMD_A_STOP_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002742 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2743 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002744 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002745 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002746 case DVR_PLAYBACK_CMD_A_STOP_V_START:
hualing chen2aba4022020-03-02 13:49:55 +08002747 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002748 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002749 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002750 case DVR_PLAYBACK_CMD_V_STOP_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002751 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2752 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002753 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002754 break;
2755 case DVR_PLAYBACK_CMD_STOP:
2756 break;
2757 case DVR_PLAYBACK_CMD_START:
2758 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002759 case DVR_PLAYBACK_CMD_A_START_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002760 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002761 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2762 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002763 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002764 case DVR_PLAYBACK_CMD_V_START_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002765 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002766 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2767 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002768 break;
2769 case DVR_PLAYBACK_CMD_FF:
2770 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002771 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002772 break;
2773 default:
2774 break;
2775 }
2776 return DVR_SUCCESS;
2777}
2778
2779/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002780 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002781 * \retval DVR_SUCCESS On success
2782 * \return Error code
2783 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002784int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2785 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002786 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002787 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002788 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002789 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002790 return DVR_FAILURE;
2791 }
2792
hualing chena991aa82021-08-16 10:21:15 +08002793 if (dvr_playback_check_limit(handle)) {
2794 //get id and pos to check if we can seek to this pos
Wentao MA96f68962022-06-15 19:45:35 +08002795 DVR_PB_INFO("player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002796 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2797 if (segmentid != player->cur_segment_id ||
2798 (segmentid == player->cur_segment_id &&
2799 pos > _dvr_get_cur_time(handle))) {
2800 //first to seek new pos and to resume
Wentao MA96f68962022-06-15 19:45:35 +08002801 DVR_PB_INFO("seek new pos and to resume");
hualing chena991aa82021-08-16 10:21:15 +08002802 dvr_playback_seek(handle, segmentid, pos);
2803 }
hualing chen7ea70a72021-09-09 11:25:13 +08002804 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002805 DVR_PB_INFO("player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002806 }
hualing chena991aa82021-08-16 10:21:15 +08002807
hualing chen5cbe1a62020-02-10 16:36:36 +08002808 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08002809 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002810 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002811 player->first_frame = 0;
2812 if (player->has_video)
2813 AmTsPlayer_pauseVideoDecoding(player->handle);
2814 if (player->has_audio)
2815 AmTsPlayer_pauseAudioDecoding(player->handle);
2816
hualing chen266b9502020-04-04 17:39:39 +08002817 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002818 DVR_PB_INFO("dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002819 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2820 AmTsPlayer_resumeVideoDecoding(player->handle);
2821 }
2822 if (player->has_audio) {
2823 AmTsPlayer_resumeAudioDecoding(player->handle);
2824 }
2825 //check is has audio param,if has audio .we need start audio,
2826 //we will stop audio when ff fb, if reach end, we will pause.so we need
2827 //start audio when resume play
2828
Wentao MA270dc0f2022-08-23 13:17:26 +08002829 am_tsplayer_video_params video_params;
2830 am_tsplayer_audio_params audio_params;
2831 am_tsplayer_audio_params ad_params;
hualing chen266b9502020-04-04 17:39:39 +08002832 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002833
Wentao MA270dc0f2022-08-23 13:17:26 +08002834 memset(&video_params, 0, sizeof(video_params));
2835 memset(&audio_params, 0, sizeof(audio_params));
2836 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
hualing chen266b9502020-04-04 17:39:39 +08002837 //valid audio pid, start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002838 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 +08002839 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002840 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002841 dvr_playback_change_seek_state(handle, ad_params.pid);
2842 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen969fe7b2021-05-26 15:13:17 +08002843 AmTsPlayer_enableADMix(player->handle);
2844 }
2845
Wentao MA270dc0f2022-08-23 13:17:26 +08002846 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 +08002847 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002848 dvr_playback_change_seek_state(handle, audio_params.pid);
2849 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002850 if (player->audio_presentation_id > -1) {
2851 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2852 }
hualing chen266b9502020-04-04 17:39:39 +08002853 AmTsPlayer_startAudioDecoding(player->handle);
2854 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08002855 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 +08002856 }
hualing chendf118dd2020-05-21 15:49:11 +08002857
hualing chen87072a82020-03-12 16:20:12 +08002858 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2859 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2860 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002861 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002862 } else {
2863 player->cmd.last_cmd = player->cmd.cur_cmd;
2864 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2865 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002866 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002867 }
Wentao MA96f68962022-06-15 19:45:35 +08002868 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002869 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002870 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
Wentao MA96f68962022-06-15 19:45:35 +08002871 DVR_PB_INFO("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002872 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002873 player->first_frame = 0;
2874 if (player->has_video)
2875 AmTsPlayer_pauseVideoDecoding(player->handle);
2876 if (player->has_audio)
2877 AmTsPlayer_pauseAudioDecoding(player->handle);
2878
hualing chene41f4372020-06-06 16:29:17 +08002879 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002880 DVR_PB_INFO("dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002881 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002882 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002883 }
hualing chen041c4092020-04-05 15:11:50 +08002884 if (player->has_audio)
2885 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002886 DVR_PB_INFO("set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen9811b212020-10-29 11:21:44 +08002887 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2888 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chend1686e52022-01-05 17:10:42 +08002889 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002890 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002891 DVR_PB_INFO("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002892 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002893 } else {
2894 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2895 {
Wentao MA96f68962022-06-15 19:45:35 +08002896 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002897 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002898 player->first_frame = 0;
2899 if (player->has_video)
2900 AmTsPlayer_pauseVideoDecoding(player->handle);
2901 if (player->has_audio)
2902 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002903 //clear flag
Wentao MA96f68962022-06-15 19:45:35 +08002904 DVR_PB_INFO("clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002905 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2906 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002907 if (player->has_video) {
2908 AmTsPlayer_resumeVideoDecoding(player->handle);
2909 }
2910 if (player->has_audio)
2911 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002912 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002913 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002914 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002915 }
2916 return DVR_SUCCESS;
2917}
2918
hualing chena540a7e2020-03-27 16:44:05 +08002919static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2920
2921 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2922 DVR_PlaybackSegmentInfo_t *segment = NULL;
2923 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2924 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2925
wentao.mafd5283f2022-10-14 09:51:13 +08002926 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002927 // prefetch() here incurring self_assign is used to avoid some compiling
2928 // warnings.
2929 // coverity[self_assign]
hualing chena540a7e2020-03-27 16:44:05 +08002930 list_for_each_entry(segment, &player->segment_list, head)
2931 {
2932 if (segment->segment_id == segment_id) {
2933 cur_segment = segment;
2934 }
2935 if (segment->segment_id == set_seg_id) {
2936 set_segment = segment;
2937 }
2938 if (cur_segment != NULL && set_segment != NULL) {
2939 break;
2940 }
2941 }
2942 if (cur_segment == NULL || set_segment == NULL) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002943 DVR_PB_INFO("set segment or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002944 return DVR_TRUE;
2945 }
2946 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2947 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2948 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2949 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
Wentao MA96f68962022-06-15 19:45:35 +08002950 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 +08002951 return DVR_TRUE;
2952 }
Wentao MA96f68962022-06-15 19:45:35 +08002953 DVR_PB_INFO("play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002954 return DVR_FALSE;
2955}
2956
hualing chen03fd4942021-07-15 15:56:41 +08002957/**\brief set limit
2958 * \param[in] handle playback handle
2959 * \param[in] rec start time ms
2960 * \param[in] rec limit time ms
2961 * \retval DVR_SUCCESS On success
2962 * \return Error code
2963 */
hualing chen7ea70a72021-09-09 11:25:13 +08002964int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08002965{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2966
2967 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002968 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08002969 return DVR_FAILURE;
2970 }
hualing chen7ea70a72021-09-09 11:25:13 +08002971 _dvr_getClock_sec();
Wentao MA96f68962022-06-15 19:45:35 +08002972 DVR_PB_INFO("lock time %lu limit: %u player->state:%d", time, limit, player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002973 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002974 player->rec_start = time;
2975 player->limit = limit;
Wentao MA96f68962022-06-15 19:45:35 +08002976 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002977 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002978 return DVR_SUCCESS;
2979}
2980
hualing chen5cbe1a62020-02-10 16:36:36 +08002981/**\brief seek
2982 * \param[in] handle playback handle
2983 * \param[in] time_offset time offset base cur segment
2984 * \retval DVR_SUCCESS On success
2985 * \return Error code
2986 */
hualing chencc91e1c2020-02-28 13:26:17 +08002987int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002988 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002989 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08002990 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002991 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002992 return DVR_FAILURE;
2993 }
2994
Wentao MA96f68962022-06-15 19:45:35 +08002995 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 +08002996 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002997
hualing chena540a7e2020-03-27 16:44:05 +08002998 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
Wentao MA96f68962022-06-15 19:45:35 +08002999 DVR_PB_INFO("player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08003000
hualing chen5cbe1a62020-02-10 16:36:36 +08003001 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08003002 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08003003 if (ret ==DVR_FAILURE) {
wentao.maa210e5e2022-10-12 16:10:03 +08003004 DVR_PB_ERROR("unlock seek error at open segment");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003005 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003006 return DVR_FAILURE;
3007 }
3008 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
Wentao MAf35c3882023-04-17 12:36:19 +08003009 if (segment_ongoing(player->segment_handle) == DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08003010 DVR_PB_INFO("is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08003011 time_offset = _dvr_get_end_time(handle);
3012 } else {
wentao.maa210e5e2022-10-12 16:10:03 +08003013 DVR_PB_ERROR("is not ongoing segment when seek end, return failure");
Zhiqiang Han447cff02022-12-15 11:13:41 +08003014 dvr_mutex_unlock(&player->lock);
wentao.maa210e5e2022-10-12 16:10:03 +08003015 return DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08003016 }
3017 }
3018
Wentao MA96f68962022-06-15 19:45:35 +08003019 DVR_PB_INFO("seek open id[%lld]flag[0x%x] time_offset %u",
hualing chen03fd4942021-07-15 15:56:41 +08003020 player->cur_segment.segment_id,
3021 player->cur_segment.flags,
3022 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08003023 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08003024 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3025 //forward playback.not seek end of file
3026 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
3027 //default -2000ms
3028 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
3029 }
hualing chen86e7d482020-01-16 15:13:33 +08003030 }
Wentao MA01de0e62022-01-10 18:48:23 +08003031 // Seek can be regarded as a new playback, so keep the start segment_id for it also
hualing chen8a657f32021-08-30 13:12:49 +08003032 if (player->need_seek_start == DVR_TRUE) {
3033 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
Wentao MA01de0e62022-01-10 18:48:23 +08003034 player->first_start_id = player->cur_segment.segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003035 }
hualing chen2aba4022020-03-02 13:49:55 +08003036 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08003037 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08003038 player->ts_cache_len = 0;
Wentao MAf35c3882023-04-17 12:36:19 +08003039 int offset = segment_seek(player->segment_handle, (uint64_t)time_offset, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08003040 DVR_PB_ERROR("seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08003041 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08003042 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08003043
hualing chen2aba4022020-03-02 13:49:55 +08003044 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08003045
3046 player->last_send_time_id = UINT64_MAX;
Wentao MA270dc0f2022-08-23 13:17:26 +08003047 player->last_segment_total = 0LL;
hualing chen03fd4942021-07-15 15:56:41 +08003048 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08003049 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08003050 player->fffb_current = _dvr_time_getClock();
3051 player->fffb_start = player->fffb_current;
3052 player->fffb_start_pcr = _dvr_get_cur_time(handle);
3053 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08003054 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08003055 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003056 //only seek file,not start
Wentao MA96f68962022-06-15 19:45:35 +08003057 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003058 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003059 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08003060 }
hualing chen86e7d482020-01-16 15:13:33 +08003061 //stop play
Wentao MA96f68962022-06-15 19:45:35 +08003062 DVR_PB_ERROR("seek stop play, not inject data has video[%d]audio[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003063 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08003064
hualing chen266b9502020-04-04 17:39:39 +08003065 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08003066 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003067 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003068 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003069 }
3070
hualing chen40dd5462021-11-26 19:56:20 +08003071
hualing chen266b9502020-04-04 17:39:39 +08003072 if (player->has_audio) {
3073 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003074 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003075 }
hualing chendf118dd2020-05-21 15:49:11 +08003076 if (player->has_ad_audio) {
3077 player->has_ad_audio =DVR_FALSE;
3078 AmTsPlayer_disableADMix(player->handle);
3079 }
3080
hualing chen86e7d482020-01-16 15:13:33 +08003081 //start play
Wentao MA270dc0f2022-08-23 13:17:26 +08003082 am_tsplayer_video_params video_params;
3083 am_tsplayer_audio_params audio_params;
3084 am_tsplayer_audio_params ad_params;
hualing chenb31a6c62020-01-13 17:27:00 +08003085
Wentao MA270dc0f2022-08-23 13:17:26 +08003086 memset(&video_params, 0, sizeof(video_params));
3087 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003088
hualing chen040df222020-01-17 13:35:02 +08003089 player->cur_segment_id = segment_id;
3090
3091 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08003092 //get segment info and audio video pid fmt ;
Wentao MA270dc0f2022-08-23 13:17:26 +08003093 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08003094 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003095 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chena5f03222021-12-02 11:22:35 +08003096 //audio and video pid is all invalid, return error.
Wentao MA270dc0f2022-08-23 13:17:26 +08003097 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 +08003098 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08003099 return -1;
3100 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003101 DVR_PB_ERROR("seek start[0x%x]", video_params.pid);
hualing chen86e7d482020-01-16 15:13:33 +08003102 //add
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003103 int v_restarted = 0;
3104 int a_restarted = 0;
hualing chen040df222020-01-17 13:35:02 +08003105 if (sync == DVR_PLAYBACK_SYNC) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003106 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003107 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08003108 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08003109 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08003110 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08003111 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003112 //if is pause state. we need set trick mode.
Wentao MA96f68962022-06-15 19:45:35 +08003113 DVR_PB_INFO("seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003114 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08003115 }
Wentao MA96f68962022-06-15 19:45:35 +08003116 DVR_PB_INFO("start video");
Wentao MA270dc0f2022-08-23 13:17:26 +08003117 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003118 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003119 AmTsPlayer_startVideoDecoding(player->handle);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003120 v_restarted = 1;
hualing chene41f4372020-06-06 16:29:17 +08003121 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
3122 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
3123 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
3124 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
3125 AmTsPlayer_stopFast(player->handle);
3126 }
hualing chen266b9502020-04-04 17:39:39 +08003127 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08003128 } else {
3129 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08003130 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003131 if (VALID_PID(ad_params.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08003132 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003133 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003134 dvr_playback_change_seek_state(handle, ad_params.pid);
3135 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003136 AmTsPlayer_enableADMix(player->handle);
3137 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003138 if (VALID_PID(audio_params.pid) && player->speed == 1.0) {
Wentao MA96f68962022-06-15 19:45:35 +08003139 DVR_PB_INFO("start audio seek");
Wentao MA270dc0f2022-08-23 13:17:26 +08003140 dvr_playback_change_seek_state(handle, audio_params.pid);
3141 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003142 if (player->audio_presentation_id > -1) {
3143 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3144 }
hualing chen969fe7b2021-05-26 15:13:17 +08003145 AmTsPlayer_startAudioDecoding(player->handle);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003146 a_restarted = 1;
hualing chen969fe7b2021-05-26 15:13:17 +08003147 player->has_audio = DVR_TRUE;
3148 }
hualing chen43a89bc2022-01-19 14:31:20 +08003149#ifdef AVSYNC_USED_PCR
3150 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003151 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003152 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3153 }
3154#endif
hualing chen86e7d482020-01-16 15:13:33 +08003155 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003156 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003157 if (v_restarted) {
3158 switch (player->cmd.cur_cmd) {
3159 case DVR_PLAYBACK_CMD_V_RESTART:
3160 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_NONE;
3161 break;
3162 case DVR_PLAYBACK_CMD_A_STOP_V_RESTART:
3163 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
3164 break;
3165 case DVR_PLAYBACK_CMD_A_START_V_RESTART:
3166 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
3167 break;
3168 case DVR_PLAYBACK_CMD_AV_RESTART:
3169 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_RESTART;
3170 break;
3171 default:
3172 break;
3173 }
3174 }
3175 if (a_restarted) {
3176 switch (player->cmd.cur_cmd) {
3177 case DVR_PLAYBACK_CMD_A_RESTART:
3178 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_NONE;
3179 break;
3180 case DVR_PLAYBACK_CMD_V_STOP_A_RESTART:
3181 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
3182 break;
3183 case DVR_PLAYBACK_CMD_V_START_A_RESTART:
3184 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
3185 break;
3186 case DVR_PLAYBACK_CMD_AV_RESTART:
3187 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_RESTART;
3188 break;
3189 default:
3190 break;
3191 }
3192 }
hualing chen2aba4022020-03-02 13:49:55 +08003193 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00003194 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
Wentao MA270dc0f2022-08-23 13:17:26 +08003195 if (VALID_PID(audio_params.pid) || VALID_PID(video_params.pid))
hualing chena5f03222021-12-02 11:22:35 +08003196 player->seek_pause = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08003197 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 +08003198 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
Wentao MA16f870e2022-09-09 11:00:22 +08003199 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chen31140872020-03-25 12:29:26 +08003200 player->speed > 1.0f||
3201 player->speed <= -1.0f) {
Wentao MA96f68962022-06-15 19:45:35 +08003202 DVR_PB_INFO("not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003203 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003204 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003205 DVR_PB_INFO("set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003206 player->cmd.last_cmd = player->cmd.cur_cmd;
3207 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3208 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003209 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen2aba4022020-03-02 13:49:55 +08003210 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003211 player->last_send_time_id = UINT64_MAX;
Wentao MA96f68962022-06-15 19:45:35 +08003212 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003213 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003214
3215 return DVR_SUCCESS;
3216}
hualing chen5cbe1a62020-02-10 16:36:36 +08003217
Wentao MAac5ea062022-08-11 11:44:27 +08003218// Get current playback time position of the ongoing segment.
3219// Notice the return value may be negative. This is because previous segment's
3220// data cached in demux buffer need to be considered.
hualing chen5cbe1a62020-02-10 16:36:36 +08003221static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3222 //get cur time of segment
3223 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003224
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003225 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003226 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003227 return DVR_FAILURE;
3228 }
3229
Wentao MA270dc0f2022-08-23 13:17:26 +08003230 int64_t cache = 0;//default es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003231 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003232 loff_t pos = segment_tell_position(player->segment_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003233 uint64_t cur = 0;
3234 if (player->ts_cache_len > 0 && pos < 0) {
3235 //this case is open new segment end,but cache data is last segment.
3236 //we need used last segment len to send play time.
3237 cur = 0;
3238 } else {
Wentao MAf35c3882023-04-17 12:36:19 +08003239 cur = segment_tell_position_time(player->segment_handle, pos);
hualing chena5f03222021-12-02 11:22:35 +08003240 }
hualing chen21a40372021-10-29 11:07:26 +08003241 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003242 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08003243 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 +08003244 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3245 cache = 0;
3246 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003247 int cur_time = (int)(cur > cache ? cur - cache : 0);
3248 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003249}
3250
Wentao MAac5ea062022-08-11 11:44:27 +08003251// Get current playback time position of the ongoing segment.
3252// Notice the return value may be negative. This is because previous segment's
3253// data cached in demux buffer need to be considered.
hualing chen969fe7b2021-05-26 15:13:17 +08003254static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3255 //get cur time of segment
3256 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA804bab12022-11-29 10:01:26 +08003257 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MAf35c3882023-04-17 12:36:19 +08003258 DVR_RETURN_IF_FALSE(player->segment_handle != NULL);
hualing chen969fe7b2021-05-26 15:13:17 +08003259
hualing chen969fe7b2021-05-26 15:13:17 +08003260 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003261 const loff_t pos = segment_tell_position(player->segment_handle);
3262 const uint64_t cur = segment_tell_position_time(player->segment_handle, pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003263 pthread_mutex_unlock(&player->segment_lock);
Wentao MA01de0e62022-01-10 18:48:23 +08003264
Wentao MA804bab12022-11-29 10:01:26 +08003265 int cache = 0;
3266 get_effective_tsplayer_delay_time(player, &cache);
Wentao MA01de0e62022-01-10 18:48:23 +08003267
hualing chen969fe7b2021-05-26 15:13:17 +08003268 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3269 cache = 0;
3270 }
Wentao MA804bab12022-11-29 10:01:26 +08003271
Wentao MA3e2dc452022-12-20 11:17:16 +08003272 int cur_time = (int)(cur - cache);
Wentao MA804bab12022-11-29 10:01:26 +08003273 *id = player->cur_segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003274
Wentao MA3e2dc452022-12-20 11:17:16 +08003275 if (*id == 0 && cur_time<0) {
3276 cur_time = 0;
3277 }
3278
Wentao MA80179512022-11-03 12:20:03 +08003279 DVR_PB_INFO("***get playback slider position within segment. segment_id [%lld],"
wentao.ma4ee43022022-12-14 13:22:57 +08003280 " segment_slider_pos[%7d ms] = segment_read_pos[%7lld ms] - tsplayer_cache_len[%5ld ms],"
Wentao MA80179512022-11-03 12:20:03 +08003281 " last id [%lld] pos [%lld]",
3282 player->cur_segment_id,cur_time,cur,cache,player->last_send_time_id,pos);
Wentao MA804bab12022-11-29 10:01:26 +08003283
hualing chen969fe7b2021-05-26 15:13:17 +08003284 return cur_time;
3285}
3286
hualing chencc91e1c2020-02-28 13:26:17 +08003287//get current segment current pcr time of read pos
3288static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3289 //get cur time of segment
3290 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAf35c3882023-04-17 12:36:19 +08003291 DVR_RETURN_IF_FALSE(player != NULL);
3292 DVR_RETURN_IF_FALSE(player->segment_handle != NULL);
hualing chena540a7e2020-03-27 16:44:05 +08003293
3294 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003295 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003296 return DVR_FAILURE;
3297 }
3298
hualing chen2aba4022020-03-02 13:49:55 +08003299 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003300 uint64_t end = segment_tell_total_time(player->segment_handle);
hualing chen2aba4022020-03-02 13:49:55 +08003301 pthread_mutex_unlock(&player->segment_lock);
3302 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003303}
3304
hualing chen03fd4942021-07-15 15:56:41 +08003305DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3306{
3307 //check is set limit info
3308 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3309
3310 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003311 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003312 return DVR_FALSE;
3313 }
3314 if (player->rec_start > 0 || player->limit > 0) {
3315 return DVR_TRUE;
3316 }
3317 return DVR_FALSE;
3318}
3319
3320/**\brief set DVR playback calculate expired time len
3321 * \param[in] handle, DVR playback session handle
3322 * \return DVR_SUCCESS on success
3323 * \return error code on failure
3324 */
hualing chen7ea70a72021-09-09 11:25:13 +08003325uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003326{
3327 //calculate expired time to play
3328 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003329 uint32_t cur_time;
3330 uint32_t tmp_time;
3331 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003332 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003333 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003334 return expired;
3335 }
hualing chen7ea70a72021-09-09 11:25:13 +08003336 if (player->rec_start == 0 || player->limit == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003337 DVR_PB_INFO("rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003338 return expired;
3339 }
3340 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003341 cur_time = _dvr_getClock_sec();
3342 if ((cur_time - player->rec_start) > player->limit) {
3343 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3344 expired = *(int*)&tmp_time;
Wentao MA96f68962022-06-15 19:45:35 +08003345 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 +08003346 cur_time,
3347 player->rec_start,
3348 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003349 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3350 }
hualing chen03fd4942021-07-15 15:56:41 +08003351 return expired;
3352}
3353
3354/**\brief set DVR playback obsolete time
3355 * \param[in] handle, DVR playback session handle
3356 * \param[in] obsolete, obsolete len
3357 * \return DVR_SUCCESS on success
3358 * \return error code on failure
3359 */
3360int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3361{
3362 int expired = 0;
3363 //calculate expired time to play
3364 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3365
3366 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003367 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003368 return DVR_FALSE;
3369 }
3370 //get system time
Wentao MA96f68962022-06-15 19:45:35 +08003371 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003372 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003373 player->obsolete = obsolete;
Wentao MA96f68962022-06-15 19:45:35 +08003374 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003375 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003376 return expired;
3377}
3378
3379/**\brief update DVR playback newest segment duration
3380 * \param[in] handle, DVR playback session handle
3381 * \param[in] segmentid, newest segment id
3382 * \param[in] dur dur time ms
3383 * \return DVR_SUCCESS on success
3384 * \return error code on failure
3385 */
3386int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3387uint64_t segmentid, int dur)
3388{
3389 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3390 DVR_PlaybackSegmentInfo_t *segment;
3391 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3392
3393 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003394 DVR_PB_INFO(" player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003395 return DVR_FAILURE;
3396 }
3397 //update the newest segment duration on timeshift mode
wentao.mafd5283f2022-10-14 09:51:13 +08003398 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003399 // prefetch() here incurring self_assign is used to avoid some compiling
3400 // warnings.
3401 // coverity[self_assign]
hualing chen03fd4942021-07-15 15:56:41 +08003402 list_for_each_entry(segment, &player->segment_list, head)
3403 {
3404 if (segment->segment_id == segmentid) {
3405 segment->duration = dur;
3406 break;
3407 }
3408 pre_segment = segment;
3409 }
3410
3411 return DVR_SUCCESS;
3412}
3413
hualing chen7ea70a72021-09-09 11:25:13 +08003414static uint32_t dvr_playback_calculate_last_valid_segment(
3415 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003416{
hualing chen7ea70a72021-09-09 11:25:13 +08003417 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003418 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003419 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003420 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003421 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003422 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3423
3424 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003425 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003426 return DVR_FAILURE;
3427 }
3428 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003429 if (expired == 0) {
3430 *segmentid = player->cur_segment_id;
3431 *pos = 0;
3432 return DVR_SUCCESS;
3433 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003434 DVR_PlaybackSegmentInfo_t *p_seg;
wentao.mafd5283f2022-10-14 09:51:13 +08003435 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003436 // prefetch() here incurring self_assign is used to avoid some compiling
3437 // warnings.
3438 // coverity[self_assign]
Wentao MA270dc0f2022-08-23 13:17:26 +08003439 list_for_each_entry_reverse(p_seg, &player->segment_list, head) {
3440 segment_id = p_seg->segment_id;
hualing chen03fd4942021-07-15 15:56:41 +08003441
Wentao MA270dc0f2022-08-23 13:17:26 +08003442 if ((player->obsolete + pre_off + p_seg->duration) > expired)
hualing chen03fd4942021-07-15 15:56:41 +08003443 break;
3444
Wentao MA270dc0f2022-08-23 13:17:26 +08003445 last_segment_id = p_seg->segment_id;
3446 pre_off += p_seg->duration;
hualing chen03fd4942021-07-15 15:56:41 +08003447 }
3448
3449 if (last_segment_id == segment_id) {
3450 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3451 off = expired;
3452 } else if (player->obsolete >= expired) {
3453 off = 0;
3454 } else {
3455 off = expired - pre_off - player->obsolete;
3456 }
3457 *segmentid = segment_id;
3458 *pos = off;
3459 return DVR_SUCCESS;
3460}
3461
hualing chen4b7c15d2020-04-07 16:13:48 +08003462#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003463//start replay
3464static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3465
3466 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3467 //calculate pcr seek time
3468 int t_diff = 0;
3469 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003470 uint64_t segmentid = 0;
3471 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003472 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003473 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003474 return DVR_FAILURE;
3475 }
3476
hualing chen5cbe1a62020-02-10 16:36:36 +08003477 if (player->fffb_start == -1) {
3478 //set fffb start time ms
3479 player->fffb_start = _dvr_time_getClock();
3480 player->fffb_current = player->fffb_start;
3481 //get segment current time pos
3482 player->fffb_start_pcr = _dvr_get_cur_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003483 DVR_PB_INFO("calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
hualing chen03fd4942021-07-15 15:56:41 +08003484 player->fffb_start_pcr, player->speed);
hualing chene41f4372020-06-06 16:29:17 +08003485 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003486 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003487 } else {
3488 player->fffb_current = _dvr_time_getClock();
3489 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003490 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003491 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003492 if (seek_time <= 0) {
3493 //need seek to pre one segment
3494 seek_time = 0;
3495 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003496 //seek segment pos
Wentao MAf35c3882023-04-17 12:36:19 +08003497 if (player->segment_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003498 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003499 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003500 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3501 //set seek time to 0;
Wentao MA96f68962022-06-15 19:45:35 +08003502 DVR_PB_INFO("segment seek to 0 at fb mode [%d]id[%lld]",
hualing chen03fd4942021-07-15 15:56:41 +08003503 seek_time,
3504 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003505 seek_time = 0;
3506 }
hualing chen03fd4942021-07-15 15:56:41 +08003507 if (IS_FB(player->speed)
3508 && dvr_playback_check_limit(handle)) {
3509 //fb case.check expired time
3510 //get id and pos to check if we can seek to this pos
3511 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3512 //case cur id < segment id
3513 if (player->cur_segment_id < segmentid) {
3514 //expired ts data is player,return error
3515 //
3516 pthread_mutex_unlock(&player->segment_lock);
3517 return 0;
3518 } else if (player->cur_segment_id == segmentid) {
3519 //id is same,compare seek pos
3520 if (seek_time < pos) {
3521 //expired ts data is player,return error
3522 //
3523 pthread_mutex_unlock(&player->segment_lock);
3524 return 0;
3525 }
3526 }
3527 //case can play
3528 }
Wentao MAf35c3882023-04-17 12:36:19 +08003529 if (segment_seek(player->segment_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
hualing chen041c4092020-04-05 15:11:50 +08003530 seek_time = 0;
3531 }
hualing chen2aba4022020-03-02 13:49:55 +08003532 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003533 } else {
3534 //
Wentao MA96f68962022-06-15 19:45:35 +08003535 DVR_PB_INFO("segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003536 }
Wentao MA96f68962022-06-15 19:45:35 +08003537 DVR_PB_INFO("calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003538 seek_time,
3539 player->speed,
3540 player->cur_segment_id,
3541 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003542 }
hualing chen2aba4022020-03-02 13:49:55 +08003543 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003544}
3545
3546
3547//start replay
3548static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3549 //
3550 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003551
3552 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003553 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003554 return DVR_FAILURE;
3555 }
3556
hualing chen5cbe1a62020-02-10 16:36:36 +08003557 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003558 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08003559 DVR_PB_INFO("fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003560 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003561 AmTsPlayer_stopVideoDecoding(player->handle);
3562 }
3563 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003564 DVR_PB_INFO("fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003565 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003566 AmTsPlayer_stopAudioDecoding(player->handle);
3567 }
hualing chendf118dd2020-05-21 15:49:11 +08003568 if (player->has_ad_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003569 DVR_PB_INFO("fffb stop audio");
hualing chendf118dd2020-05-21 15:49:11 +08003570 player->has_ad_audio =DVR_FALSE;
3571 AmTsPlayer_disableADMix(player->handle);
3572 }
hualing chen2aba4022020-03-02 13:49:55 +08003573
hualing chen5cbe1a62020-02-10 16:36:36 +08003574 //start video and audio
3575
Wentao MA270dc0f2022-08-23 13:17:26 +08003576 am_tsplayer_video_params video_params;
3577 am_tsplayer_audio_params audio_params;
3578 am_tsplayer_audio_params ad_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003579
Wentao MA270dc0f2022-08-23 13:17:26 +08003580 memset(&video_params, 0, sizeof(video_params));
3581 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003582
hualing chen87072a82020-03-12 16:20:12 +08003583 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003584
3585 //get segment info and audio video pid fmt ;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003586 //dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08003587 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003588 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003589 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
3590 //audio and video pids are all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003591 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003592 return -1;
3593 }
3594
Wentao MA270dc0f2022-08-23 13:17:26 +08003595 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003596 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003597 DVR_PB_INFO("fffb start video");
3598 //DVR_PB_INFO("fffb start video and save last frame");
hualing chen0888c032020-12-18 17:54:57 +08003599 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003600 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003601 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
Wentao MA270dc0f2022-08-23 13:17:26 +08003602 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003603 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003604 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003605 //playback_device_video_start(player->handle , &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003606 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003607 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003608 }
hualing chen31140872020-03-25 12:29:26 +08003609 //fffb mode need stop fast;
Wentao MA96f68962022-06-15 19:45:35 +08003610 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003611 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003612 return 0;
3613}
3614
3615static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3616 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003617 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003618 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003619 return DVR_FAILURE;
3620 }
3621
3622 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003623 DVR_PB_INFO("lock speed [%f]", player->speed);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003624 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003625
hualing chen2aba4022020-03-02 13:49:55 +08003626 int seek_time = _dvr_playback_calculate_seekpos(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003627 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 +08003628
hualing chen87072a82020-03-12 16:20:12 +08003629 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3630 //seek time set 0
3631 seek_time = 0;
3632 }
hualing chen041c4092020-04-05 15:11:50 +08003633 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003634 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3635 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003636 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
wentao.ma4ee43022022-12-14 13:22:57 +08003637
3638 // An fffb_replay is required here to help finish the last FB play
3639 // at beginning position of a recording. In addition to function
3640 // correctness, another benefit is that after play, demux buffer
3641 // is cleared due to stopVideoDecoding invocation in the process.
3642 // The following resume operation will not be affected by the invalid
3643 // cache length.
3644 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
3645 _dvr_playback_fffb_replay(handle);
3646
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003647 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003648 DVR_PB_DEBUG("unlock");
hualing chen87072a82020-03-12 16:20:12 +08003649 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003650 //send event here and pause
3651 DVR_Play_Notify_t notify;
3652 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003653 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003654 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003655 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08003656 DVR_PB_INFO("*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08003657 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003658 return DVR_SUCCESS;
3659 }
hualing chen2932d372020-04-29 13:44:00 +08003660 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003661 _dvr_init_fffb_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003662 DVR_PB_INFO("*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003663 }
3664 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003665 _dvr_playback_fffb_replay(handle);
3666
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003667 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003668 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003669
hualing chen5cbe1a62020-02-10 16:36:36 +08003670 return DVR_SUCCESS;
3671}
3672
hualing chen87072a82020-03-12 16:20:12 +08003673//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003674static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003675 //
3676 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003677
3678 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003679 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003680 return DVR_FAILURE;
3681 }
3682
hualing chen5cbe1a62020-02-10 16:36:36 +08003683 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003684 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003685 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003686 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003687 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003688 }
3689
3690 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003691 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003692 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003693 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003694 //start video and audio
3695
Wentao MA270dc0f2022-08-23 13:17:26 +08003696 am_tsplayer_video_params video_params;
3697 am_tsplayer_audio_params audio_params;
3698 am_tsplayer_audio_params ad_params;
hualing chen87072a82020-03-12 16:20:12 +08003699 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003700
Wentao MA270dc0f2022-08-23 13:17:26 +08003701 memset(&video_params, 0, sizeof(video_params));
3702 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003703
hualing chen5cbe1a62020-02-10 16:36:36 +08003704 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08003705 DVR_PB_INFO("into");
Wentao MA270dc0f2022-08-23 13:17:26 +08003706 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003707 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003708 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003709 //audio and video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003710 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003711 return -1;
3712 }
3713
Wentao MA270dc0f2022-08-23 13:17:26 +08003714 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003715 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003716 if (trick == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003717 DVR_PB_INFO("settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003718 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003719 }
hualing chen266b9502020-04-04 17:39:39 +08003720 else {
hualing chen2aba4022020-03-02 13:49:55 +08003721 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003722 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003723 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003724 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003725 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003726 }
hualing chena540a7e2020-03-27 16:44:05 +08003727
3728 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
Wentao MA96f68962022-06-15 19:45:35 +08003729 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08003730 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003731 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003732 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08003733 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08003734 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003735 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003736 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003737 AmTsPlayer_enableADMix(player->handle);
3738 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003739 if (VALID_PID(audio_params.pid)) {
hualing chen969fe7b2021-05-26 15:13:17 +08003740 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003741 DVR_PB_INFO("start audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003742 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003743 if (player->audio_presentation_id > -1) {
3744 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3745 }
hualing chen969fe7b2021-05-26 15:13:17 +08003746 AmTsPlayer_startAudioDecoding(player->handle);
3747 }
hualing chendf118dd2020-05-21 15:49:11 +08003748
Wentao MA96f68962022-06-15 19:45:35 +08003749 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003750 AmTsPlayer_stopFast(player->handle);
3751 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3752 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3753 }
hualing chen43a89bc2022-01-19 14:31:20 +08003754#ifdef AVSYNC_USED_PCR
3755 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003756 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003757 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3758 }
3759#endif
hualing chen2aba4022020-03-02 13:49:55 +08003760 player->cmd.last_cmd = player->cmd.cur_cmd;
3761 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003762 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003763 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen5cbe1a62020-02-10 16:36:36 +08003764 return 0;
3765}
3766
3767
hualing chenb31a6c62020-01-13 17:27:00 +08003768/**\brief Set play speed
3769 * \param[in] handle playback handle
3770 * \param[in] speed playback speed
3771 * \retval DVR_SUCCESS On success
3772 * \return Error code
3773 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003774int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3775
3776 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003777
3778 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003779 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003780 return DVR_FAILURE;
3781 }
3782
hualing chena540a7e2020-03-27 16:44:05 +08003783 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08003784 DVR_PB_INFO(" func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003785 return DVR_FAILURE;
3786 }
hualing chenf00cdc82020-06-10 14:23:35 +08003787 if (speed.speed.speed == player->cmd.speed.speed.speed) {
Wentao MA96f68962022-06-15 19:45:35 +08003788 DVR_PB_INFO(" func: eq speed [%d]", speed.speed.speed);
hualing chenf00cdc82020-06-10 14:23:35 +08003789 return DVR_SUCCESS;
3790 }
Wentao MA96f68962022-06-15 19:45:35 +08003791 DVR_PB_INFO("lock func: speed [%d]", speed.speed.speed);
hualing chen1679f812021-11-08 15:17:46 +08003792
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003793 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003794 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3795 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3796 player->cmd.last_cmd = player->cmd.cur_cmd;
3797 }
hualing chene41f4372020-06-06 16:29:17 +08003798
hualing chen31140872020-03-25 12:29:26 +08003799 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003800 IS_KERNEL_SPEED(speed.speed.speed) ) {
3801 //case 1. not start play.only set speed
3802 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3803 //only set speed.and return;
3804 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3805 player->cmd.speed.speed = speed.speed;
3806 player->speed = (float)speed.speed.speed/(float)100;
3807 player->fffb_play = DVR_FALSE;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003808 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003809 DVR_PB_DEBUG("unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003810 return DVR_SUCCESS;
3811 }
3812 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003813 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3814 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003815 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003816 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3817 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003818 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003819 AmTsPlayer_stopFast(player->handle);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003820 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003821 DVR_PB_DEBUG("unlock ---\r\n");
Wentao MA270dc0f2022-08-23 13:17:26 +08003822 _dvr_cmd(handle, DVR_PLAYBACK_CMD_A_START);
Wentao MA96f68962022-06-15 19:45:35 +08003823 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003824 dvr_mutex_lock(&player->lock);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003825 } else {
3826 //set play speed and if audio is start, stop audio.
3827 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003828 DVR_PB_INFO("fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003829 AmTsPlayer_stopAudioDecoding(player->handle);
3830 player->has_audio = DVR_FALSE;
3831 }
Wentao MA96f68962022-06-15 19:45:35 +08003832 DVR_PB_INFO("start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003833 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003834 }
hualing chenbcada022020-04-22 14:27:01 +08003835 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003836 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003837 player->cmd.speed.speed = speed.speed;
3838 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA96f68962022-06-15 19:45:35 +08003839 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003840 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003841 return DVR_SUCCESS;
3842 }
hualing chen31140872020-03-25 12:29:26 +08003843 //case 3 fffb mode
3844 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3845 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3846 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003847 DVR_PB_INFO("set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003848 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003849 player->cmd.speed.speed = speed.speed;
3850 player->speed = (float)speed.speed.speed/(float)100;
3851 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003852 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003853 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003854 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003855 return DVR_SUCCESS;
3856 }
3857 }
3858 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003859 IS_KERNEL_SPEED(speed.speed.speed)) {
3860 //case 1. cur speed is kernel support speed,set kernel speed.
3861 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003862 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003863 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3864 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003865 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003866 AmTsPlayer_stopFast(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003867 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003868 } else {
3869 //set play speed and if audio is start, stop audio.
3870 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003871 DVR_PB_INFO("fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003872 AmTsPlayer_stopAudioDecoding(player->handle);
3873 player->has_audio = DVR_FALSE;
3874 }
Wentao MA96f68962022-06-15 19:45:35 +08003875 DVR_PB_INFO("start fast");
hualing chenf00cdc82020-06-10 14:23:35 +08003876 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003877 }
hualing chena540a7e2020-03-27 16:44:05 +08003878 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003879 player->cmd.speed.speed = speed.speed;
3880 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003881 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003882 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003883 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003884 return DVR_SUCCESS;
3885 }
3886 //case 2 fffb mode
3887 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3888 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3889 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003890 DVR_PB_INFO("set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003891 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003892 player->cmd.speed.speed = speed.speed;
3893 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA270dc0f2022-08-23 13:17:26 +08003894 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
hualing chenbcada022020-04-22 14:27:01 +08003895 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003896 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003897 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003898 return DVR_SUCCESS;
3899 }
hualing chen31140872020-03-25 12:29:26 +08003900 }
hualing chena540a7e2020-03-27 16:44:05 +08003901 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3902 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003903 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003904 } else {
hualing chen31140872020-03-25 12:29:26 +08003905 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003906 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3907 else
3908 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003909 player->fffb_play = DVR_TRUE;
3910 }
3911 DVR_Bool_t init_last_time = DVR_FALSE;
3912 if (player->speed > 0.0f && speed.speed.speed < 0) {
3913 init_last_time = DVR_TRUE;
3914 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3915 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003916 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003917 player->cmd.speed.mode = speed.mode;
3918 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003919 player->speed = (float)speed.speed.speed/(float)100;
3920 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003921 _dvr_init_fffb_t(handle);
3922 if (init_last_time == DVR_TRUE)
3923 player->last_send_time_id = UINT64_MAX;
3924
hualing chen87072a82020-03-12 16:20:12 +08003925 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003926 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3927 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003928 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003929 DVR_PB_INFO("set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003930 _dvr_playback_replay(handle, DVR_FALSE);
3931 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3932 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003933 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
Wentao MA96f68962022-06-15 19:45:35 +08003934 DVR_PB_INFO("set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003935 }
Wentao MA96f68962022-06-15 19:45:35 +08003936 DVR_PB_INFO("unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003937 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003938 return DVR_SUCCESS;
3939}
hualing chen2932d372020-04-29 13:44:00 +08003940
hualing chenb31a6c62020-01-13 17:27:00 +08003941/**\brief Get playback status
3942 * \param[in] handle playback handle
3943 * \param[out] p_status playback status
3944 * \retval DVR_SUCCESS On success
3945 * \return Error code
3946 */
hualing chen2932d372020-04-29 13:44:00 +08003947static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3948 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003949//
3950 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003951 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003952 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003953 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003954 return DVR_FAILURE;
3955 }
hualing chen1679f812021-11-08 15:17:46 +08003956 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003957 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003958 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003959 }
3960
hualing chen5cbe1a62020-02-10 16:36:36 +08003961 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003962 //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 +08003963 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3964 player->state == DVR_PLAYBACK_STATE_START) {
3965 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3966 }
hualing chen041c4092020-04-05 15:11:50 +08003967
hualing chencc91e1c2020-02-28 13:26:17 +08003968 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003969 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003970
shenghui.gengbec6a462023-01-12 15:21:02 +08003971 if (player->control_speed_enable == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08003972 if (player->con_spe.ply_sta == 0) {
wentao.mafdba9a02023-01-17 16:43:26 +08003973 DVR_PB_INFO("player dur[%d] sta[%d] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08003974 player->con_spe.ply_dur,
3975 player->con_spe.ply_sta,
3976 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003977 player->con_spe.ply_sta = p_status->time_cur;
3978 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3979 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
wentao.mafdba9a02023-01-17 16:43:26 +08003980 DVR_PB_INFO("player dur[%d] sta[%d] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003981 player->con_spe.ply_dur,
3982 player->con_spe.ply_sta,
3983 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003984 player->con_spe.ply_sta = p_status->time_cur;
3985 }
3986
3987 if (player->con_spe.sys_sta == 0) {
3988 player->con_spe.sys_sta = _dvr_time_getClock();
3989 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3990 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3991 player->con_spe.sys_sta = _dvr_time_getClock();
3992 }
3993 }
3994
hualing chen4b7c15d2020-04-07 16:13:48 +08003995 if (player->last_send_time_id == UINT64_MAX) {
3996 player->last_send_time_id = player->cur_segment_id;
3997 player->last_cur_time = p_status->time_cur;
3998 }
3999 if (player->last_send_time_id == player->cur_segment_id) {
Wentao MA80179512022-11-03 12:20:03 +08004000 if (player->speed > 1.0f ) {
hualing chen4b7c15d2020-04-07 16:13:48 +08004001 //ff
4002 if (p_status->time_cur < player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004003 DVR_PB_INFO("get ff time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004004 player->last_cur_time,
4005 p_status->time_cur,
4006 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08004007 p_status->time_cur = player->last_cur_time;
4008 } else {
4009 player->last_cur_time = p_status->time_cur;
4010 }
hualing chene41f4372020-06-06 16:29:17 +08004011 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08004012 //fb
4013 if (p_status->time_cur > player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004014 DVR_PB_INFO("get fb time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004015 player->last_cur_time,
4016 p_status->time_cur,
4017 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08004018 p_status->time_cur = player->last_cur_time;
4019 } else {
4020 player->last_cur_time = p_status->time_cur;
4021 }
4022 }
hualing chend241c7a2021-06-22 13:34:27 +08004023 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08004024 player->last_cur_time = p_status->time_cur;
4025 }
hualing chen969fe7b2021-05-26 15:13:17 +08004026 player->last_send_time_id = segment_id;
4027 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08004028
hualing chen5cbe1a62020-02-10 16:36:36 +08004029 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08004030 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08004031 p_status->flags = player->cur_segment.flags;
Wentao MA96f68962022-06-15 19:45:35 +08004032 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 +08004033 _dvr_playback_state_toString(player->state),
4034 _dvr_playback_state_toString(p_status->state),
4035 p_status->time_cur, p_status->time_end,
4036 p_status->segment_id,player->play_flag,
4037 player->speed,
4038 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08004039 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08004040 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004041 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08004042 }
hualing chen2932d372020-04-29 13:44:00 +08004043 return DVR_SUCCESS;
4044}
4045
4046
4047/**\brief Get playback status
4048 * \param[in] handle playback handle
4049 * \param[out] p_status playback status
4050 * \retval DVR_SUCCESS On success
4051 * \return Error code
4052 */
4053int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
4054 DVR_PlaybackStatus_t *p_status) {
4055//
4056 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4057
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004058 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
4059
hualing chen2932d372020-04-29 13:44:00 +08004060 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004061 DVR_PB_INFO("player is NULL");
hualing chen2932d372020-04-29 13:44:00 +08004062 return DVR_FAILURE;
4063 }
Wentao MA96f68962022-06-15 19:45:35 +08004064 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004065 dvr_mutex_lock(&player->lock);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004066 if (!player->has_video && !player->has_audio)
4067 p_status->time_cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08004068 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004069 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08004070
hualing chenb31a6c62020-01-13 17:27:00 +08004071 return DVR_SUCCESS;
4072}
4073
hualing chen040df222020-01-17 13:35:02 +08004074void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
4075 if (segment != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004076 DVR_PB_INFO("segment id: %lld", segment->segment_id);
4077 DVR_PB_INFO("segment flag: %d", segment->flags);
4078 DVR_PB_INFO("segment location: [%s]", segment->location);
4079 DVR_PB_INFO("segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
4080 DVR_PB_INFO("segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
4081 DVR_PB_INFO("segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
4082 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 +08004083 }
hualing chenb31a6c62020-01-13 17:27:00 +08004084}
4085
hualing chen5cbe1a62020-02-10 16:36:36 +08004086int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004087 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08004088
hualing chena540a7e2020-03-27 16:44:05 +08004089 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004090 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004091 return DVR_FAILURE;
4092 }
4093
hualing chen040df222020-01-17 13:35:02 +08004094 DVR_PlaybackSegmentInfo_t *segment;
wentao.mafd5283f2022-10-14 09:51:13 +08004095 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08004096 // prefetch() here incurring self_assign is used to avoid some compiling
4097 // warnings.
4098 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08004099 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08004100 {
Wentao MA07d3d742022-09-06 09:58:05 +08004101 if (segment->segment_id == segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004102 _dvr_dump_segment(segment);
Wentao MA07d3d742022-09-06 09:58:05 +08004103 break;
hualing chen86e7d482020-01-16 15:13:33 +08004104 }
4105 }
4106 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08004107}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004108
pengfei.liu27cc4ec2020-04-03 16:28:16 +08004109int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004110{
4111 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4112 DVR_RETURN_IF_FALSE(player);
4113 DVR_RETURN_IF_FALSE(func);
4114
Wentao MA96f68962022-06-15 19:45:35 +08004115 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004116 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004117
4118 player->dec_func = func;
4119 player->dec_userdata = userdata;
4120
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004121 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004122 DVR_PB_INFO("out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004123 return DVR_SUCCESS;
4124}
4125
4126int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
4127{
4128 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4129 DVR_RETURN_IF_FALSE(player);
4130 DVR_RETURN_IF_FALSE(p_secure_buf);
4131 DVR_RETURN_IF_FALSE(len);
4132
Wentao MA96f68962022-06-15 19:45:35 +08004133 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004134 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004135
4136 player->is_secure_mode = 1;
4137 player->secure_buffer = p_secure_buf;
4138 player->secure_buffer_size = len;
4139
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004140 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004141 DVR_PB_INFO("out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004142 return DVR_SUCCESS;
4143}
Wentao MA5629ad82022-08-24 10:03:02 +08004144
4145int dvr_playback_set_ac4_preselection_id(DVR_PlaybackHandle_t handle, int presel_id)
4146{
4147 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa210e5e2022-10-12 16:10:03 +08004148 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MA5629ad82022-08-24 10:03:02 +08004149
4150 player->audio_presentation_id = presel_id;
4151 am_tsplayer_result ret = AmTsPlayer_setParams(player->handle,
4152 AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &presel_id);
4153 DVR_RETURN_IF_FALSE(ret == AM_TSPLAYER_OK);
4154
4155 return DVR_SUCCESS;
4156}
Wentao MAa0b9c002022-11-10 17:47:27 +08004157
4158// This function ensures a valid TsPlayer delay time is provided or else it
4159// returns DVR_FAILURE. It is designed to workaround a weakness of
4160// AmTsPlayer_getDelayTime at starting phase of a playback in a short period
4161// of 20ms or less. During the said period, getDelayTime does NOT work as
4162// expect to return real delay length because demux isn't actually running
4163// to provide valid pts to TsPlayer.
Wentao MA804bab12022-11-29 10:01:26 +08004164static int get_effective_tsplayer_delay_time(DVR_Playback_t* play, int *time)
Wentao MAa0b9c002022-11-10 17:47:27 +08004165{
4166 int64_t delay=0;
4167 uint64_t pts_a=0;
4168 uint64_t pts_v=0;
4169
Wentao MA804bab12022-11-29 10:01:26 +08004170 DVR_RETURN_IF_FALSE(play != NULL);
4171 DVR_RETURN_IF_FALSE(play->handle != NULL);
Wentao MAa0b9c002022-11-10 17:47:27 +08004172
Wentao MA804bab12022-11-29 10:01:26 +08004173 AmTsPlayer_getDelayTime(play->handle, &delay);
4174 // In scambled stream situation, the returned TsPlayer delay time is
4175 // invalid and dirty. An additional time check agaginst 15 minutes (900s)
4176 // is introduced to insure such error condition is handled properly.
4177 DVR_RETURN_IF_FALSE((delay >= 0) && (delay <= 900*1000));
Wentao MAa0b9c002022-11-10 17:47:27 +08004178
Wentao MA804bab12022-11-29 10:01:26 +08004179 if (play->delay_is_effective) {
4180 *time = (int)delay;
Wentao MAa0b9c002022-11-10 17:47:27 +08004181 return DVR_SUCCESS;
4182 } else if (delay > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004183 *time = (int)delay;
4184 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004185 return DVR_SUCCESS;
4186 }
4187
Wentao MA804bab12022-11-29 10:01:26 +08004188 AmTsPlayer_getPts(play->handle, TS_STREAM_AUDIO, &pts_a);
4189 AmTsPlayer_getPts(play->handle, TS_STREAM_VIDEO, &pts_v);
Wentao MAa0b9c002022-11-10 17:47:27 +08004190 if ((int64_t)pts_a > 0 || (int64_t)pts_v > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004191 *time = (int)delay;
4192 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004193 return DVR_SUCCESS;
4194 }
4195
4196 return DVR_FAILURE;
4197}
4198