blob: 9c658f9b70daf3a7e31d1796e9f8632623eb0c51 [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
Wentao MA361eaac2023-03-21 13:12:28 +08008#include <sys/prctl.h>
hualing chenb31a6c62020-01-13 17:27:00 +08009#include <fcntl.h>
10#include <unistd.h>
11#include <poll.h>
12#include <errno.h>
13#include <signal.h>
14#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080015#include <errno.h>
hualing chen03fd4942021-07-15 15:56:41 +080016#include "dvr_utils.h"
17#include "dvr_types.h"
hualing chenb31a6c62020-01-13 17:27:00 +080018#include "dvr_playback.h"
Yahui Han1fbf3292021-11-08 18:17:19 +080019#include "am_crypt.h"
hualing chenb31a6c62020-01-13 17:27:00 +080020
Wentao MA96f68962022-06-15 19:45:35 +080021#define PB_LOG_TAG "libdvr-playback"
22#define DVR_PB_DEBUG(...) DVR_LOG_PRINT(LOG_LV_DEBUG, PB_LOG_TAG, __VA_ARGS__)
23#define DVR_PB_INFO(...) DVR_LOG_PRINT(LOG_LV_INFO, PB_LOG_TAG, __VA_ARGS__)
24#define DVR_PB_WARN(...) DVR_LOG_PRINT(LOG_LV_WARN, PB_LOG_TAG, __VA_ARGS__)
25#define DVR_PB_ERROR(...) DVR_LOG_PRINT(LOG_LV_ERROR, PB_LOG_TAG, __VA_ARGS__)
26#define DVR_PB_FATAL(...) DVR_LOG_PRINT(LOG_LV_FATAL, PB_LOG_TAG, __VA_ARGS__)
hualing chena540a7e2020-03-27 16:44:05 +080027
hualing chenb31a6c62020-01-13 17:27:00 +080028#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080029
hualing chena540a7e2020-03-27 16:44:05 +080030#define FF_SPEED (2.0f)
31#define FB_SPEED (-1.0f)
32#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080033#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080034
35#define IS_KERNEL_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_X1) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
36#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
37
Wentao MA907b6432022-08-01 06:23:08 +000038#define DVR_PLAYER_CHANGE_STATE(player,newstate)\
39 DVR_PB_INFO("%s:%d player %p changes state from %s to %s",__func__,__LINE__,\
40 player,_dvr_playback_state_toString(player->state),_dvr_playback_state_toString(newstate));\
41 player->state=newstate;
42
Wentao MAfae6ce82023-12-29 17:55:55 +080043//#define FOR_OTT_49490
hualing chenb31a6c62020-01-13 17:27:00 +080044
hualing chenb5cd42e2020-04-15 17:03:34 +080045#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080046#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080047//if tsplayer delay time < 200 and no data can read, we will pause
48#define MIN_TSPLAYER_DELAY_TIME (200)
49
hualing chen041c4092020-04-05 15:11:50 +080050#define MAX_CACHE_TIME (30000)
hualing chen43a89bc2022-01-19 14:31:20 +080051//used pcr to control avsync,default not used
52//#define AVSYNC_USED_PCR 1
hualing chena540a7e2020-03-27 16:44:05 +080053static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080054//
55static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
Wentao MA6dcdc342023-01-30 17:03:19 +080056static int _do_handle_pid_update(DVR_PlaybackHandle_t handle, DVR_PlaybackPids_t now_pids, DVR_PlaybackPids_t pids, int type);
hualing chencc91e1c2020-02-28 13:26:17 +080057static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
58static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080059static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080060static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080061static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
62 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080063static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen7ea70a72021-09-09 11:25:13 +080064static uint32_t dvr_playback_calculate_last_valid_segment(
65 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos);
Wentao MA804bab12022-11-29 10:01:26 +080066static int get_effective_tsplayer_delay_time(DVR_Playback_t* playback, int *time);
Wentao MA92a14892023-09-12 18:54:47 +080067static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id);
hualing chen87072a82020-03-12 16:20:12 +080068
hualing chenbcada022020-04-22 14:27:01 +080069
hualing chena5f03222021-12-02 11:22:35 +080070
hualing chenbcada022020-04-22 14:27:01 +080071static char* _cmd_toString(int cmd)
72{
73
74 char *string[DVR_PLAYBACK_CMD_NONE+1]={
75 "start",
76 "stop",
Wentao MA270dc0f2022-08-23 13:17:26 +080077 "v_start",
78 "a_start",
79 "v_stop",
80 "a_stop",
81 "v_restart",
82 "a_restart",
83 "av_restart",
84 "v_stop_a_start",
85 "a_stop_v_start",
86 "v_stop_a_restart",
87 "a_stop_v_restart",
88 "v_start_a_restart",
89 "a_start_v_restart",
hualing chenbcada022020-04-22 14:27:01 +080090 "pause",
91 "resume",
92 "seek",
93 "ff",
94 "fb",
95 "NONE"
96 };
97
98 if (cmd > DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +080099 return "unknown";
hualing chenbcada022020-04-22 14:27:01 +0800100 } else {
101 return string[cmd];
102 }
103}
104
105
Wentao MA907b6432022-08-01 06:23:08 +0000106static char* _dvr_playback_state_toString(int state)
hualing chen6d24aa92020-03-23 18:43:47 +0800107{
Wentao MA907b6432022-08-01 06:23:08 +0000108 char *strings[5]={
109 "START",
110 "STOP",
111 "PAUSE",
112 "FF",
113 "FB",
hualing chen6d24aa92020-03-23 18:43:47 +0800114 };
115
Wentao MA907b6432022-08-01 06:23:08 +0000116 if (state >= 5 || state < 0) {
117 return "UNKNOWN";
hualing chen6d24aa92020-03-23 18:43:47 +0800118 }
Wentao MA907b6432022-08-01 06:23:08 +0000119 return strings[state];
hualing chen6d24aa92020-03-23 18:43:47 +0800120}
hualing chena540a7e2020-03-27 16:44:05 +0800121
122static DVR_Bool_t _dvr_support_speed(int speed) {
123
124 DVR_Bool_t ret = DVR_FALSE;
125
126 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800127 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800128 case PLAYBACK_SPEED_FBX2:
129 case PLAYBACK_SPEED_FBX4:
130 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800131 case PLAYBACK_SPEED_FBX16:
132 case PLAYBACK_SPEED_FBX12:
133 case PLAYBACK_SPEED_FBX32:
134 case PLAYBACK_SPEED_FBX48:
135 case PLAYBACK_SPEED_FBX64:
136 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800137 case PLAYBACK_SPEED_S2:
138 case PLAYBACK_SPEED_S4:
139 case PLAYBACK_SPEED_S8:
140 case PLAYBACK_SPEED_X1:
141 case PLAYBACK_SPEED_X2:
142 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800143 case PLAYBACK_SPEED_X3:
144 case PLAYBACK_SPEED_X5:
145 case PLAYBACK_SPEED_X6:
146 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800147 case PLAYBACK_SPEED_X8:
148 case PLAYBACK_SPEED_X12:
149 case PLAYBACK_SPEED_X16:
150 case PLAYBACK_SPEED_X32:
151 case PLAYBACK_SPEED_X48:
152 case PLAYBACK_SPEED_X64:
153 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800154 ret = DVR_TRUE;
155 break;
156 default:
Wentao MA96f68962022-06-15 19:45:35 +0800157 DVR_PB_INFO("not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800158 break;
159 }
160 return ret;
161}
Wentao MA907b6432022-08-01 06:23:08 +0000162
hualing chen6e4bfa52020-03-13 14:37:11 +0800163void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
164{
Wentao MA96f68962022-06-15 19:45:35 +0800165 DVR_PB_INFO("in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800166 DVR_Playback_t *player = NULL;
167 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800168 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800169 DVR_PB_INFO("play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800170 }
171 switch (event->type) {
172 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
173 {
Wentao MA96f68962022-06-15 19:45:35 +0800174 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800175 event->event.video_format.frame_width,
176 event->event.video_format.frame_height,
177 event->event.video_format.frame_rate);
178 break;
179 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800180 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
181 {
Wentao MA16f870e2022-09-09 11:00:22 +0800182 if (player == NULL) {
183 DVR_PB_WARN("player is null at line %d",__LINE__);
184 break;
185 }
Wentao MA96f68962022-06-15 19:45:35 +0800186 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800187 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800188 break;
189 }
190 default:
191 break;
192 }
193}
Wentao MA804bab12022-11-29 10:01:26 +0800194
hualing chen2aba4022020-03-02 13:49:55 +0800195void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
196{
Wentao MA804bab12022-11-29 10:01:26 +0800197 DVR_Playback_t *play = (DVR_Playback_t*)user_data;
198 if (play == NULL) {
199 DVR_PB_WARN("play is invalid in %s",__func__);
200 return;
hualing chen6e4bfa52020-03-13 14:37:11 +0800201 }
hualing chen2aba4022020-03-02 13:49:55 +0800202 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800203 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
Wentao MA804bab12022-11-29 10:01:26 +0800204 DVR_PB_INFO("Received AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME");
205 if (play->first_trans_ok == DVR_FALSE) {
206 play->first_trans_ok = DVR_TRUE;
207 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)play, DVR_FALSE);
208 }
209 play->first_frame = 1;
210 play->seek_pause = DVR_FALSE;
211 break;
hualing chen487ae6d2020-07-22 10:34:11 +0800212 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
Wentao MA804bab12022-11-29 10:01:26 +0800213 DVR_PB_INFO("Received AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO");
214 if (play->first_trans_ok == DVR_FALSE && play->has_video == DVR_FALSE) {
215 play->first_trans_ok = DVR_TRUE;
216 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)play, DVR_FALSE);
217 }
218 if (play->has_video == DVR_FALSE) {
219 play->first_frame = 1;
220 play->seek_pause = DVR_FALSE;
221 }
hualing chen487ae6d2020-07-22 10:34:11 +0800222 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800223 default:
224 break;
225 }
Wentao MA804bab12022-11-29 10:01:26 +0800226 if (play->player_callback_func == NULL) {
227 DVR_PB_WARN("play callback function %p is invalid",play->player_callback_func);
228 return;
hualing chen2aba4022020-03-02 13:49:55 +0800229 }
Wentao MA804bab12022-11-29 10:01:26 +0800230 play->player_callback_func(play->player_callback_userdata, event);
hualing chen2aba4022020-03-02 13:49:55 +0800231}
hualing chencc91e1c2020-02-28 13:26:17 +0800232
hualing chen5cbe1a62020-02-10 16:36:36 +0800233//convert video and audio fmt
234static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
235 int format = 0;
236 if (is_audio == DVR_FALSE) {
237 //for video fmt
238 switch (fmt)
239 {
240 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800241 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800242 break;
243 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800244 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800245 break;
246 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800247 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800248 break;
249 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800250 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800251 break;
hualing chena540a7e2020-03-27 16:44:05 +0800252 case DVR_VIDEO_FORMAT_VP9:
253 format = AV_VIDEO_CODEC_VP9;
254 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800255 }
256 } else {
257 //for audio fmt
258 switch (fmt)
259 {
260 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800261 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800262 break;
263 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800264 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800265 break;
266 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800267 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800268 break;
269 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800270 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800271 break;
hualing chena540a7e2020-03-27 16:44:05 +0800272 case DVR_AUDIO_FORMAT_AAC:
273 format = AV_AUDIO_CODEC_AAC;
274 break;
275 case DVR_AUDIO_FORMAT_LATM:
276 format = AV_AUDIO_CODEC_LATM;
277 break;
278 case DVR_AUDIO_FORMAT_PCM:
279 format = AV_AUDIO_CODEC_PCM;
280 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800281 case DVR_AUDIO_FORMAT_AC4:
282 format = AV_AUDIO_CODEC_AC4;
283 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800284 }
285 }
286 return format;
287}
hualing chen040df222020-01-17 13:35:02 +0800288static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800289{
hualing chen040df222020-01-17 13:35:02 +0800290 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800291
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800292 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800293 return -1;
294
hualing chena540a7e2020-03-27 16:44:05 +0800295 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800296}
hualing chena540a7e2020-03-27 16:44:05 +0800297
hualing chen7ea70a72021-09-09 11:25:13 +0800298
299//get sys time sec
300static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800301{
302 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800303 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800304 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800305 s = (uint32_t)(ts.tv_sec);
Wentao MA96f68962022-06-15 19:45:35 +0800306 DVR_PB_INFO("n:%u", s);
hualing chen7ea70a72021-09-09 11:25:13 +0800307 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800308}
hualing chen86e7d482020-01-16 15:13:33 +0800309
hualing chen7ea70a72021-09-09 11:25:13 +0800310//get sys time ms
311static uint32_t _dvr_time_getClock(void)
312{
313 struct timespec ts;
314 uint32_t ms;
Zhiqiang Han71703652023-09-18 11:05:34 +0800315 clock_gettime(CLOCK_MONOTONIC, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800316 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
317 return ms;
318}
hualing chenb31a6c62020-01-13 17:27:00 +0800319
Wentao MA270dc0f2022-08-23 13:17:26 +0800320//timeout wait signal
hualing chen040df222020-01-17 13:35:02 +0800321static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800322{
hualing chen040df222020-01-17 13:35:02 +0800323 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800324
hualing chena540a7e2020-03-27 16:44:05 +0800325 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800326 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800327 return DVR_FAILURE;
328 }
329
hualing chen86e7d482020-01-16 15:13:33 +0800330 struct timespec ts;
331 clock_gettime(CLOCK_MONOTONIC, &ts);
hualing chen86e7d482020-01-16 15:13:33 +0800332 ts.tv_sec += ms/1000;
wentao.ma54e6aa32023-12-13 18:07:04 +0800333 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000);
hualing chen86e7d482020-01-16 15:13:33 +0800334 ts.tv_sec += us / 1000000;
335 us = us % 1000000;
wentao.ma54e6aa32023-12-13 18:07:04 +0800336 ts.tv_nsec = us * 1000;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800337
338 int val = dvr_mutex_save(&player->lock);
339 pthread_cond_timedwait(&player->cond, &player->lock.lock, &ts);
340 dvr_mutex_restore(&player->lock, val);
hualing chen86e7d482020-01-16 15:13:33 +0800341 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800342}
Wentao MA804bab12022-11-29 10:01:26 +0800343
hualing chenb31a6c62020-01-13 17:27:00 +0800344//send signal
hualing chen040df222020-01-17 13:35:02 +0800345static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800346{
hualing chen87072a82020-03-12 16:20:12 +0800347 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800348
349 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800350 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800351 return DVR_FAILURE;
352 }
Wentao MA96f68962022-06-15 19:45:35 +0800353 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800354 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800355 pthread_cond_signal(&player->cond);
Wentao MA96f68962022-06-15 19:45:35 +0800356 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800357 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800358 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800359}
360
hualing chen2932d372020-04-29 13:44:00 +0800361//send playback event, need check is need lock first
362static 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 +0800363
364 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800365
366 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800367 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800368 return DVR_FAILURE;
369 }
370
hualing chencc91e1c2020-02-28 13:26:17 +0800371 switch (evt) {
372 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800373 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800374 break;
375 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
376 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800377 DVR_PB_INFO("trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800378 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800379 break;
380 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
381 break;
382 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
383 break;
384 case DVR_PLAYBACK_EVENT_NO_KEY:
385 break;
386 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800387 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800388 DVR_PB_INFO("reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800389 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800390 break;
391 case DVR_PLAYBACK_EVENT_REACHED_END:
392 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800393 DVR_PB_INFO("reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800394 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800395 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800396 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800397 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800398 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800399 default:
400 break;
401 }
402 if (player->openParams.event_fn != NULL)
403 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800404 return DVR_SUCCESS;
405}
hualing chen2932d372020-04-29 13:44:00 +0800406static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800407{
408 DVR_Play_Notify_t notify;
409 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
410 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
411 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800412 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800413 return DVR_SUCCESS;
414}
415
hualing chen2932d372020-04-29 13:44:00 +0800416static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800417{
418 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800419
Wentao MA16f870e2022-09-09 11:00:22 +0800420 if (player == NULL) {
421 DVR_PB_ERROR("player is NULL");
422 return DVR_FAILURE;
423 }
hualing chene3797f02021-01-13 14:53:28 +0800424 if (player->openParams.is_notify_time == DVR_FALSE) {
shenghui.gengbec6a462023-01-12 15:21:02 +0800425 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800426 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800427 }
hualing chena540a7e2020-03-27 16:44:05 +0800428
hualing chen03fd4942021-07-15 15:56:41 +0800429 if (player->send_time == 0) {
shenghui.gengbec6a462023-01-12 15:21:02 +0800430 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800431 player->send_time = _dvr_time_getClock() + 500;
432 else
433 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800434 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen56c0a162022-01-27 17:01:50 +0800435 if ((player->send_time - _dvr_time_getClock()) > 1000) {
436 player->send_time = _dvr_time_getClock() + 500;
Wentao MA96f68962022-06-15 19:45:35 +0800437 DVR_PB_INFO("player send time occur system time changed!!!!!");
hualing chen56c0a162022-01-27 17:01:50 +0800438 } else {
439 return DVR_SUCCESS;
440 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800441 }
shenghui.gengbec6a462023-01-12 15:21:02 +0800442 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800443 player->send_time = _dvr_time_getClock() + 500;
444 else
445 player->send_time = _dvr_time_getClock() + 20;
446
hualing chen6e4bfa52020-03-13 14:37:11 +0800447 DVR_Play_Notify_t notify;
448 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
449 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
450 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800451 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800452 return DVR_SUCCESS;
453}
454
hualing chen4b7c15d2020-04-07 16:13:48 +0800455static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
456 DVR_Playback_t *player = (DVR_Playback_t *) handle;
457 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800458 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800459 player->fffb_current = player->fffb_start;
460 //get segment current time pos
461 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800462 player->next_fffb_time = _dvr_time_getClock();
463
464 return DVR_SUCCESS;
465}
466
hualing chen2aba4022020-03-02 13:49:55 +0800467static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
468 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800469 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800470 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800471 player->fffb_current = player->fffb_start;
472 //get segment current time pos
473 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800474
hualing chen2aba4022020-03-02 13:49:55 +0800475 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800476 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800477 return DVR_SUCCESS;
478}
hualing chencc91e1c2020-02-28 13:26:17 +0800479//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800480static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
481
482 DVR_Playback_t *player = (DVR_Playback_t *) handle;
483 DVR_PlaybackSegmentInfo_t *segment;
484 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
485
hualing chena540a7e2020-03-27 16:44:05 +0800486 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800487 DVR_PB_INFO(" player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800488 return DVR_FAILURE;
489 }
490
hualing chen87072a82020-03-12 16:20:12 +0800491 int found = 0;
492 int found_eq_id = 0;
wentao.mafd5283f2022-10-14 09:51:13 +0800493 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800494 // prefetch() here incurring self_assign is used to avoid some compiling
495 // warnings.
496 // coverity[self_assign]
hualing chen87072a82020-03-12 16:20:12 +0800497 list_for_each_entry(segment, &player->segment_list, head)
498 {
499 if (player->segment_is_open == DVR_FALSE) {
500 //get first segment from list, case segment is not open
501 if (!IS_FB(player->speed))
502 found = 1;
503 } else if (segment->segment_id == segmentid) {
504 //find cur segment, we need get next one
505 found_eq_id = 1;
506 if (!IS_FB(player->speed)) {
507 found = 1;
508 continue;
509 } else {
510 //if is fb mode.we need used pre segment
511 if (pre_segment != NULL) {
512 found = 1;
513 } else {
514 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800515 DVR_PB_INFO("not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800516 return DVR_FAILURE;
517 }
518 }
519 }
520 if (found == 1) {
521 found = 2;
522 break;
523 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800524 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800525 }
526 if (found != 2) {
527 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800528 DVR_PB_INFO("not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800529 return DVR_FAILURE;
530 }
Wentao MA96f68962022-06-15 19:45:35 +0800531 DVR_PB_INFO("found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800532 return DVR_SUCCESS;
533}
534
535//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800536static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800537
hualing chen040df222020-01-17 13:35:02 +0800538 DVR_Playback_t *player = (DVR_Playback_t *) handle;
539 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800540 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800541 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800542 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800543 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800544 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800545 return DVR_FAILURE;
546 }
547
hualing chen03fd4942021-07-15 15:56:41 +0800548 if (IS_FB(player->speed)
549 && dvr_playback_check_limit(handle)) {
550 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
551 //case cur id < segment id
552 if (player->cur_segment_id <= segmentid) {
553 //expired ts data is player,return error
Wentao MA96f68962022-06-15 19:45:35 +0800554 DVR_PB_INFO("reach start segment ,return error");
hualing chen03fd4942021-07-15 15:56:41 +0800555 return DVR_FAILURE;
556 }
Wentao MA96f68962022-06-15 19:45:35 +0800557 DVR_PB_INFO("has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800558 }
559
hualing chen86e7d482020-01-16 15:13:33 +0800560 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800561 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800562
wentao.mafd5283f2022-10-14 09:51:13 +0800563 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800564 // prefetch() here incurring self_assign is used to avoid some compiling
565 // warnings.
566 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +0800567 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800568 {
hualing chencc91e1c2020-02-28 13:26:17 +0800569 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800570 //get first segment from list, case segment is not open
571 if (!IS_FB(player->speed))
572 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800573 } else if (segment->segment_id == player->cur_segment_id) {
574 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800575 found_eq_id = 1;
576 if (!IS_FB(player->speed)) {
577 found = 1;
578 continue;
579 } else {
580 //if is fb mode.we need used pre segment
581 if (pre_segment != NULL) {
582 found = 1;
583 } else {
584 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800585 DVR_PB_INFO("not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800586 return DVR_FAILURE;
587 }
588 }
hualing chen86e7d482020-01-16 15:13:33 +0800589 }
590 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800591 if (IS_FB(player->speed)) {
592 //used pre segment
593 segment = pre_segment;
594 }
hualing chencc91e1c2020-02-28 13:26:17 +0800595 //save segment info
596 player->last_segment_id = player->cur_segment_id;
Wentao MAf35c3882023-04-17 12:36:19 +0800597 if (player->segment_handle) {
598 player->last_segment_total = segment_tell_total_time(player->segment_handle);
599 }
hualing chen87072a82020-03-12 16:20:12 +0800600 player->last_segment.segment_id = player->cur_segment.segment_id;
601 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800602 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
603 //pids
604 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
605
hualing chen5cbe1a62020-02-10 16:36:36 +0800606 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800607 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800608 player->cur_segment_id = segment->segment_id;
609 player->cur_segment.segment_id = segment->segment_id;
610 player->cur_segment.flags = segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800611 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 +0800612 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800613 //pids
hualing chen040df222020-01-17 13:35:02 +0800614 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800615 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800616 break;
hualing chen86e7d482020-01-16 15:13:33 +0800617 }
hualing chen2aba4022020-03-02 13:49:55 +0800618 pre_segment = segment;
619 }
620 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
621 //used the last one segment to open
622 //get segment info
623 player->segment_is_open = DVR_TRUE;
624 player->cur_segment_id = pre_segment->segment_id;
625 player->cur_segment.segment_id = pre_segment->segment_id;
626 player->cur_segment.flags = pre_segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800627 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 +0800628 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
629 //pids
630 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
631 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800632 }
633 if (found != 2) {
634 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800635 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800636 }
637 return DVR_SUCCESS;
638}
hualing chen040df222020-01-17 13:35:02 +0800639//open next segment to play,if reach list end return errro.
640static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800641{
hualing chen040df222020-01-17 13:35:02 +0800642 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800643 Segment_OpenParams_t params;
644 int ret = DVR_SUCCESS;
645
hualing chena540a7e2020-03-27 16:44:05 +0800646 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800647 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800648 return DVR_FAILURE;
649 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800650 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800651retry:
hualing chena540a7e2020-03-27 16:44:05 +0800652 ret = _dvr_get_next_segmentId(handle);
653 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800654 DVR_PB_INFO("not found segment info");
hualing chen4b7c15d2020-04-07 16:13:48 +0800655 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800656 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800657 }
658
Wentao MAf35c3882023-04-17 12:36:19 +0800659 if (player->segment_handle != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800660 DVR_PB_INFO("close segment");
Wentao MAf35c3882023-04-17 12:36:19 +0800661 segment_close(player->segment_handle);
662 player->segment_handle = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800663 }
664
Wentao MA4d85ff32022-09-23 11:36:18 +0800665 memset((void*)&params,0,sizeof(params));
Wentao MA270dc0f2022-08-23 13:17:26 +0800666 //cp current segment path to location
hualing chen5cbe1a62020-02-10 16:36:36 +0800667 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800668 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800669 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800670 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 +0800671
Wentao MAf35c3882023-04-17 12:36:19 +0800672 ret = segment_open(&params, &(player->segment_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800673 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800674 DVR_PB_INFO("open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800675 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800676 }
Wentao MA01de0e62022-01-10 18:48:23 +0800677 // Keep the start segment_id when the first segment_open is called during a playback
678 if (player->first_start_id == UINT64_MAX) {
679 player->first_start_id = player->cur_segment.segment_id;
680 }
hualing chen87072a82020-03-12 16:20:12 +0800681 pthread_mutex_unlock(&player->segment_lock);
682 int total = _dvr_get_end_time( handle);
683 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800684 if (IS_FB(player->speed)) {
685 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800686 player->ts_cache_len = 0;
Wentao MAf35c3882023-04-17 12:36:19 +0800687 segment_seek(player->segment_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +0800688 DVR_PB_INFO("seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800689 }
hualing chen87072a82020-03-12 16:20:12 +0800690 player->dur = total;
wentao.mafdba9a02023-01-17 16:43:26 +0800691 player->con_spe.ply_dur = 0;
692 player->con_spe.ply_sta = 0;
693 player->con_spe.sys_dur = 0;
694 player->con_spe.sys_sta = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800695 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +0800696 DVR_PB_INFO("next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800697 return ret;
698}
699
hualing chen5cbe1a62020-02-10 16:36:36 +0800700//open next segment to play,if reach list end return errro.
701static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
702{
703 DVR_Playback_t *player = (DVR_Playback_t *) handle;
704 Segment_OpenParams_t params;
705 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800706 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800707 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800708 return DVR_FAILURE;
709 }
hualing chencc91e1c2020-02-28 13:26:17 +0800710 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800711 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800712 }
hualing chencc91e1c2020-02-28 13:26:17 +0800713 uint64_t id = segment_id;
Wentao MA07d3d742022-09-06 09:58:05 +0800714 DVR_PB_INFO("start finding segment[%lld] info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800715 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800716
717 DVR_PlaybackSegmentInfo_t *segment;
718
719 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800720
wentao.mafd5283f2022-10-14 09:51:13 +0800721 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800722 // prefetch() here incurring self_assign is used to avoid some compiling
723 // warnings.
724 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800725 list_for_each_entry(segment, &player->segment_list, head)
726 {
Wentao MA96f68962022-06-15 19:45:35 +0800727 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 +0800728 if (segment->segment_id == segment_id) {
729 found = 1;
730 }
731 if (found == 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800732 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 +0800733 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800734 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800735 player->cur_segment_id = segment->segment_id;
736 player->cur_segment.segment_id = segment->segment_id;
737 player->cur_segment.flags = segment->flags;
Wentao MAe88ad702022-09-02 10:35:00 +0800738 const int len = strlen(segment->location);
739 if (len >= DVR_MAX_LOCATION_SIZE || len <= 0) {
740 DVR_PB_ERROR("Invalid segment.location length %d",len);
741 pthread_mutex_unlock(&player->segment_lock);
742 return DVR_FAILURE;
743 }
744 strncpy(player->cur_segment.location, segment->location, len+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800745 //pids
746 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +0800747 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 +0800748 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800749 }
750 }
hualing chencc91e1c2020-02-28 13:26:17 +0800751 if (found == 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800752 DVR_PB_INFO("not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800753 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800754 return DVR_FAILURE;
755 }
Wentao MA4d85ff32022-09-23 11:36:18 +0800756 memset((void*)&params,0,sizeof(params));
Wentao MAe88ad702022-09-02 10:35:00 +0800757
758 const int len2 = strlen(player->cur_segment.location);
759 if (len2 >= DVR_MAX_LOCATION_SIZE || len2 <= 0) {
760 DVR_PB_ERROR("Invalid cur_segment.location length %d",len2);
761 pthread_mutex_unlock(&player->segment_lock);
762 return DVR_FAILURE;
763 }
764 strncpy(params.location, player->cur_segment.location, len2+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800765 params.segment_id = (uint64_t)player->cur_segment.segment_id;
766 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800767 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 +0800768 if (player->segment_handle != NULL) {
769 segment_close(player->segment_handle);
770 player->segment_handle = NULL;
hualing chen2aba4022020-03-02 13:49:55 +0800771 }
Wentao MAf35c3882023-04-17 12:36:19 +0800772 ret = segment_open(&params, &(player->segment_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800773 if (ret == DVR_FAILURE) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800774 DVR_PB_INFO("segment open error");
hualing chen4b7c15d2020-04-07 16:13:48 +0800775 }
Wentao MA01de0e62022-01-10 18:48:23 +0800776 // Keep the start segment_id when the first segment_open is called during a playback
777 if (player->first_start_id == UINT64_MAX) {
778 player->first_start_id = player->cur_segment.segment_id;
779 }
hualing chen2aba4022020-03-02 13:49:55 +0800780 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800781 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800782
Wentao MA96f68962022-06-15 19:45:35 +0800783 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 +0800784 return ret;
785}
786
787
788//get play info by segment id
789static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
790 uint64_t segment_id,
Wentao MA270dc0f2022-08-23 13:17:26 +0800791 am_tsplayer_video_params *video_param,
792 am_tsplayer_audio_params *audio_param, am_tsplayer_audio_params *ad_param) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800793
794 DVR_Playback_t *player = (DVR_Playback_t *) handle;
795 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800796 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800797 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800798 return DVR_FAILURE;
799 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800800
801 int found = 0;
802
wentao.mafd5283f2022-10-14 09:51:13 +0800803 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800804 // prefetch() here incurring self_assign is used to avoid some compiling
805 // warnings.
806 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800807 list_for_each_entry(segment, &player->segment_list, head)
808 {
hualing chen87072a82020-03-12 16:20:12 +0800809 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800810 //get first segment from list
811 found = 1;
812 }
813 if (segment->segment_id == segment_id) {
814 found = 1;
815 }
816 if (found == 1) {
817 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800818 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800819 player->cur_segment_id = segment->segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800820 player->cur_segment.segment_id = segment->segment_id;
821 player->cur_segment.flags = segment->flags;
822 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800823 player->cur_segment.pids.video.pid = segment->pids.video.pid;
824 player->cur_segment.pids.video.format = segment->pids.video.format;
825 player->cur_segment.pids.video.type = segment->pids.video.type;
826 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
827 player->cur_segment.pids.audio.format = segment->pids.audio.format;
828 player->cur_segment.pids.audio.type = segment->pids.audio.type;
829 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
830 player->cur_segment.pids.ad.format = segment->pids.ad.format;
831 player->cur_segment.pids.ad.type = segment->pids.ad.type;
832 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800833 //
Wentao MA270dc0f2022-08-23 13:17:26 +0800834 video_param->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
835 video_param->pid = segment->pids.video.pid;
836 audio_param->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
837 audio_param->pid = segment->pids.audio.pid;
838 ad_param->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
839 ad_param->pid =segment->pids.ad.pid;
Wentao MA804bab12022-11-29 10:01:26 +0800840 DVR_PB_DEBUG("get_playinfo, segment_id:%lld, vpid[0x%x], apid[0x%x], vfmt[%d], afmt[%d]",
841 player->cur_segment_id, video_param->pid, audio_param->pid,
842 video_param->codectype, audio_param->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800843 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800844 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800845 }
846 }
hualing chencc91e1c2020-02-28 13:26:17 +0800847 if (found != 2) {
848 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800849 DVR_PB_INFO("get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800850 return DVR_FAILURE;
851 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800852
853 return DVR_SUCCESS;
854}
hualing chencc91e1c2020-02-28 13:26:17 +0800855static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
856 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800857 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800858 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800859 return DVR_FAILURE;
860 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800861
hualing chencc91e1c2020-02-28 13:26:17 +0800862 //compare cur segment
863 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
864 {
865 //check video pids, stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800866 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800867 //check sub audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800868 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800869 //check audio 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, 1);
Wentao MA96f68962022-06-15 19:45:35 +0800871 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 +0800872 //check pcr pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800873 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800874 }
hualing chena540a7e2020-03-27 16:44:05 +0800875 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800876}
hualing chen5cbe1a62020-02-10 16:36:36 +0800877
hualing chend241c7a2021-06-22 13:34:27 +0800878static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
879{
880 DVR_Playback_t *player = (DVR_Playback_t *) handle;
881 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800882 DVR_PB_INFO("player is NULL");
hualing chend241c7a2021-06-22 13:34:27 +0800883 return DVR_TRUE;
884 }
hualing chend241c7a2021-06-22 13:34:27 +0800885
wentao.mafdba9a02023-01-17 16:43:26 +0800886 DVR_PB_INFO(":play speed: %f ply dur: %d sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800887 player->speed,
888 player->con_spe.ply_dur,
889 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800890
891 if (player->speed != 1.0f)
892 return DVR_TRUE;
893
894 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800895 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800896 return DVR_FALSE;
897
898 return DVR_TRUE;
899}
900
hualing chencc91e1c2020-02-28 13:26:17 +0800901static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
902{
903 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800904 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800905 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800906 return DVR_FAILURE;
907 }
Wentao MA292380e2022-12-14 14:46:19 +0800908 if (player->vendor != DVR_PLAYBACK_VENDOR_DEF) {
909 DVR_PB_INFO("In case of vendor Amlogic/Amazon, do not control AV display");
hualing chenf43b8ba2020-07-28 13:11:42 +0800910 return DVR_SUCCESS;
911 }
Wentao MA96f68962022-06-15 19:45:35 +0800912 DVR_PB_INFO("flag[0x%x]id[%lld]last[0x%x][%llu]",
hualing chen03fd4942021-07-15 15:56:41 +0800913 player->cur_segment.flags,
914 player->cur_segment.segment_id,
915 player->last_segment.flags,
916 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800917 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
918 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800919 //enable display
Wentao MA96f68962022-06-15 19:45:35 +0800920 DVR_PB_INFO("unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800921 AmTsPlayer_showVideo(player->handle);
922 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800923 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
924 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800925 //disable display
Wentao MA96f68962022-06-15 19:45:35 +0800926 DVR_PB_INFO("mute");
hualing chen2aba4022020-03-02 13:49:55 +0800927 AmTsPlayer_hideVideo(player->handle);
928 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800929 }
930 return DVR_SUCCESS;
931}
hualing chene3797f02021-01-13 14:53:28 +0800932/*
Wentao MA270dc0f2022-08-23 13:17:26 +0800933if decode success first time.
934success: return true
hualing chene3797f02021-01-13 14:53:28 +0800935fail: return false
936*/
Wentao MA270dc0f2022-08-23 13:17:26 +0800937static DVR_Bool_t _dvr_pauselive_decode_success(DVR_PlaybackHandle_t handle) {
hualing chena540a7e2020-03-27 16:44:05 +0800938 DVR_Playback_t *player = (DVR_Playback_t *) handle;
939 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800940 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800941 return DVR_TRUE;
942 }
hualing chene3797f02021-01-13 14:53:28 +0800943 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800944 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800945 } else {
946 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800947 }
948}
hualing chen86e7d482020-01-16 15:13:33 +0800949static void* _dvr_playback_thread(void *arg)
950{
hualing chen040df222020-01-17 13:35:02 +0800951 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800952 //int need_open_segment = 1;
Wentao MA270dc0f2022-08-23 13:17:26 +0800953 am_tsplayer_input_buffer input_buffer;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800954 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800955 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800956
hualing chen39628212020-05-14 10:35:13 +0800957 #define MAX_REACHEND_TIMEOUT (3000)
958 int reach_end_timeout = 0;//ms
959 int cache_time = 0;
hualing chen40dd5462021-11-26 19:56:20 +0800960 int check_no_data_time = 4;
hualing chen040df222020-01-17 13:35:02 +0800961 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800962 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +0800963 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800964 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800965 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800966 DVR_Bool_t goto_rewrite = DVR_FALSE;
wentao ma7d642782022-10-23 18:26:16 -0700967 int read = 0;
yinming ding0ce94922021-09-08 15:09:15 +0800968
Wentao MA361eaac2023-03-21 13:12:28 +0800969 prctl(PR_SET_NAME,"DvrPlayback");
970
wentao ma7d642782022-10-23 18:26:16 -0700971 const uint64_t write_timeout_ms = (uint64_t)dvr_prop_read_int("vendor.tv.libdvr.writetm",50);
972 const int timeout = dvr_prop_read_int("vendor.tv.libdvr.waittm",200);
hualing chen56c0a162022-01-27 17:01:50 +0800973
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800974 if (player->is_secure_mode) {
975 if (dec_buf_size > player->secure_buffer_size) {
Wentao MA96f68962022-06-15 19:45:35 +0800976 DVR_PB_INFO("playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800977 return NULL;
978 }
979 }
wentao.maa210e5e2022-10-12 16:10:03 +0800980
981 uint8_t *buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800982 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +0800983 DVR_PB_INFO("Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800984 return NULL;
985 }
Wentao MA270dc0f2022-08-23 13:17:26 +0800986 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
987 input_buffer.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800988
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800989 dec_bufs.buf_data = malloc(dec_buf_size);
990 if (!dec_bufs.buf_data) {
Wentao MA96f68962022-06-15 19:45:35 +0800991 DVR_PB_INFO("Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800992 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800993 return NULL;
994 }
995 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
996 dec_bufs.buf_size = dec_buf_size;
997
hualing chencc91e1c2020-02-28 13:26:17 +0800998 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800999 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1000 }
hualing chen86e7d482020-01-16 15:13:33 +08001001
hualing chen86e7d482020-01-16 15:13:33 +08001002 if (ret != DVR_SUCCESS) {
1003 if (buf != NULL) {
1004 free(buf);
hualing chen86e7d482020-01-16 15:13:33 +08001005 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001006 free(dec_bufs.buf_data);
Wentao MA96f68962022-06-15 19:45:35 +08001007 DVR_PB_INFO("get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001008 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001009 }
Wentao MA96f68962022-06-15 19:45:35 +08001010 DVR_PB_INFO("--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001011 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001012 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1013 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1014 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1015 player->first_trans_ok = DVR_TRUE;
1016 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1017 }
hualing chencc91e1c2020-02-28 13:26:17 +08001018 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001019 //set video show
1020 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001021 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1022 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001023 int trick_stat = 0;
1024 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001025
hualing chen86e7d482020-01-16 15:13:33 +08001026 //check trick stat
Wentao MA96f68962022-06-15 19:45:35 +08001027 //DVR_PB_INFO("lock check_no_data_time:%d", check_no_data_time);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001028 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001029
Wentao MA907b6432022-08-01 06:23:08 +00001030 {
Wentao MA9a164002022-08-29 11:20:24 +08001031 static struct timespec _prev_ts={0,0};
Wentao MA907b6432022-08-01 06:23:08 +00001032 struct timespec _nowts,_diffts;
1033 clock_gettime(CLOCK_MONOTONIC, &_nowts);
Wentao MA9a164002022-08-29 11:20:24 +08001034 clock_timespec_subtract(&_nowts,&_prev_ts,&_diffts);
Wentao MA907b6432022-08-01 06:23:08 +00001035 if (_diffts.tv_sec>0) {
1036 char _logbuf[512]={0};
1037 char* _pbuf=_logbuf;
1038 int _nchar=0;
1039 DVR_PlaybackSegmentInfo_t* _segment;
wentao.mafd5283f2022-10-14 09:51:13 +08001040 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08001041 // prefetch() here incurring self_assign is used to avoid some compiling
1042 // warnings.
1043 // coverity[self_assign]
Wentao MA907b6432022-08-01 06:23:08 +00001044 list_for_each_entry(_segment, &player->segment_list, head) {
1045 if (player->cur_segment_id == _segment->segment_id) {
Wentao MAf35c3882023-04-17 12:36:19 +08001046 int seg_size = segment_get_cur_segment_size(player->segment_handle);
1047 int read_ptr = segment_tell_position(player->segment_handle);
Wentao MA907b6432022-08-01 06:23:08 +00001048 float progress = -1.0f;
Wentao MA9a164002022-08-29 11:20:24 +08001049 if (seg_size>0) {
1050 progress = (float)read_ptr*100/seg_size;
Wentao MA907b6432022-08-01 06:23:08 +00001051 }
Wentao MA4d85ff32022-09-23 11:36:18 +08001052 _nchar=sprintf(_pbuf,"%lld(%.1f%%), ",_segment->segment_id,progress);
Wentao MA907b6432022-08-01 06:23:08 +00001053 } else {
1054 _nchar=sprintf(_pbuf,"%lld, ",_segment->segment_id);
1055 }
1056 if (_nchar<0) {
1057 break;
1058 }
1059 _pbuf+=_nchar;
1060 if (_pbuf-_logbuf+10 >= sizeof(_logbuf)) {
1061 sprintf(_pbuf,"...");
1062 break;
1063 }
1064 }
Wentao MA9a164002022-08-29 11:20:24 +08001065 DVR_PB_INFO("clk: %08u, seg_list: %s",_nowts.tv_sec,_logbuf);
1066 _prev_ts=_nowts;
Wentao MA907b6432022-08-01 06:23:08 +00001067 }
1068 }
1069
Zhiqiang Hand5e2d752024-01-10 17:52:47 +08001070 #define __IS_SPEED() \
1071 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF \
1072 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB \
1073 || player->speed > FF_SPEED ||player->speed <= FB_SPEED)
1074
1075 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK
1076 || __IS_SPEED()
1077 || player->state == DVR_PLAYBACK_STATE_PAUSE
1078 || (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001079 {
hualing chen2aba4022020-03-02 13:49:55 +08001080 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
Zhiqiang Hand5e2d752024-01-10 17:52:47 +08001081 if (trick_stat > 0 || (__IS_SPEED() && _dvr_time_getClock() > player->next_fffb_time)) {
dongsheng.Li98c618a2023-12-13 04:02:32 +00001082 DVR_PB_INFO("trick stat[%d], cur cmd[%d]last cmd[%d]flag[0x%x], now[%u]>next_fffb_time[%u]",
1083 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag, _dvr_time_getClock(), player->next_fffb_time);
hualing chen87072a82020-03-12 16:20:12 +08001084 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 +08001085 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001086 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001087 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001088 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
Wentao MA270dc0f2022-08-23 13:17:26 +08001089 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_V_START
1090 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_A_START
hualing chen2aba4022020-03-02 13:49:55 +08001091 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
Wentao MA96f68962022-06-15 19:45:35 +08001092 DVR_PB_INFO("pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001093 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001094 //need change to pause state
1095 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1096 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00001097 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08001098 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001099 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001100 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001101 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001102 AmTsPlayer_pauseVideoDecoding(player->handle);
1103 AmTsPlayer_pauseAudioDecoding(player->handle);
Wentao MA6dcdc342023-01-30 17:03:19 +08001104
1105 // Audio is unmuted here, for it was muted before receiving first frame event.
1106 if (player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
1107 AmTsPlayer_setAudioMute(player->handle,0,0);
1108 }
hualing chen2bd8a7a2020-04-02 11:31:03 +08001109 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001110 DVR_PB_INFO("clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001111 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001112 }
1113 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1114 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001115 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001116 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001117 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001118 DVR_PB_INFO("fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001119 player->speed,
1120 player->fffb_current,
1121 _dvr_time_getClock(),
1122 _dvr_playback_state_toString(player->state),
1123 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001124 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001125 //dvr_mutex_unlock(&player->lock);
1126 //dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001127 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001128 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001129 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001130 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001131 } else if (_dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001132 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 +08001133 player->speed,
1134 player->fffb_current,
1135 _dvr_time_getClock(),
1136 _dvr_playback_state_toString(player->state),
1137 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001138 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001139 //dvr_mutex_unlock(&player->lock);
1140 //dvr_mutex_lock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001141 AmTsPlayer_pauseVideoDecoding(player->handle);
1142 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001143 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001144 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001145 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001146 }
Wentao MA96f68962022-06-15 19:45:35 +08001147 DVR_PB_INFO("fffb play-------speed[%f][%d][%d][%s][%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001148 player->speed,
1149 goto_rewrite,
1150 real_read,
1151 _dvr_playback_state_toString(player->state),
1152 player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001153 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001154 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001155 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1156 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001157 DVR_PB_INFO("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001158 dvr_mutex_unlock(&player->lock);
1159
hualing chen2aba4022020-03-02 13:49:55 +08001160 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001161 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001162 dvr_mutex_lock(&player->lock);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001163 player->fffb_play = DVR_FALSE;
hualing chen1ffd85b2021-08-16 15:18:43 +08001164 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1165 //on pause state,user seek to new pos,we need pause and wait
1166 //user to resume
Wentao MA96f68962022-06-15 19:45:35 +08001167 DVR_PB_INFO("pause, when got first frame event when user seek end");
hualing chen1ffd85b2021-08-16 15:18:43 +08001168 player->first_frame = 0;
1169 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1170 AmTsPlayer_pauseVideoDecoding(player->handle);
1171 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001172 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001173 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001174 //for first into fffb when reset speed
1175 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1176 _dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001177 DVR_PB_INFO("fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001178 player->speed,
1179 player->fffb_current,
1180 _dvr_time_getClock(),
1181 _dvr_playback_state_toString(player->state),
1182 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001183 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001184 //dvr_mutex_unlock(&player->lock);
1185 //dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001186 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001187 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001188 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001189 continue;
1190 }
Wentao MA96f68962022-06-15 19:45:35 +08001191 DVR_PB_INFO("fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001192 player->speed,
1193 goto_rewrite,
1194 real_read,
1195 _dvr_playback_state_toString(player->state),
1196 player->cmd.cur_cmd,
1197 player->fffb_play);
Wentao MA96f68962022-06-15 19:45:35 +08001198 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001199 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001200 goto_rewrite = DVR_FALSE;
1201 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001202 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001203 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001204 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1205 player->first_frame = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001206 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001207 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001208 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001209 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001210 }
hualing chenb31a6c62020-01-13 17:27:00 +08001211 }
hualing chen86e7d482020-01-16 15:13:33 +08001212
hualing chen30423862021-04-16 14:39:12 +08001213 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1214 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001215 //check is need send time send end
Wentao MA96f68962022-06-15 19:45:35 +08001216 DVR_PB_INFO("pause, continue");
1217 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001218 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001219 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001220 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001221 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001222 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001223 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001224 continue;
1225 }
hualing chen266b9502020-04-04 17:39:39 +08001226 //when seek action is done. we need drop write timeout data.
1227 if (player->drop_ts == DVR_TRUE) {
1228 goto_rewrite = DVR_FALSE;
1229 real_read = 0;
1230 player->drop_ts = DVR_FALSE;
1231 }
hualing chen2aba4022020-03-02 13:49:55 +08001232 if (goto_rewrite == DVR_TRUE) {
1233 goto_rewrite = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001234 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001235 dvr_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001236 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Wentao MA96f68962022-06-15 19:45:35 +08001237 //DVR_PB_INFO("rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001238 goto rewrite;
1239 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001240 //.check is need send time send end
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001241 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001242 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001243 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001244 pthread_mutex_lock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001245 //DVR_PB_INFO("start read");
Wentao MAf35c3882023-04-17 12:36:19 +08001246 read = segment_read(player->segment_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001247 real_read = real_read + read;
1248 player->ts_cache_len = real_read;
Wentao MA96f68962022-06-15 19:45:35 +08001249 //DVR_PB_INFO("start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001250 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001251 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001252 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001253 if (read < 0 && errno == EIO) {
1254 //EIO ERROR, EXIT THRAD
Wentao MA96f68962022-06-15 19:45:35 +08001255 DVR_PB_INFO("read error.EIO error, exit thread");
hualing chenb5cd42e2020-04-15 17:03:34 +08001256 DVR_Play_Notify_t notify;
1257 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1258 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001259 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001260 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001261 goto end;
1262 } else if (read < 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001263 DVR_PB_INFO("read error.:%d EIO:%d", errno, EIO);
hualing chenb5cd42e2020-04-15 17:03:34 +08001264 }
hualing chen87072a82020-03-12 16:20:12 +08001265 //if on fb mode and read file end , we need calculate pos to retry read.
1266 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001267 DVR_PB_INFO("recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
hualing chen03fd4942021-07-15 15:56:41 +08001268 read,
1269 real_read,
1270 buf_len,
1271 player->speed,
1272 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001273 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001274 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001275 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001276 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001277 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001278 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001279 continue;
1280 }
Wentao MA96f68962022-06-15 19:45:35 +08001281 //DVR_PB_INFO("read ts [%d]buf_len[%d]speed[%f]real_read:%d", read, buf_len, player->speed, real_read);
wentao.ma54e6aa32023-12-13 18:07:04 +08001282 if (read == 0 && !IS_FB(player->speed)) {
hualing chen2aba4022020-03-02 13:49:55 +08001283 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001284 #define MIN_CACHE_TIME (3000)
Wentao MA804bab12022-11-29 10:01:26 +08001285 int delay = 0;
1286 get_effective_tsplayer_delay_time(player,&delay);
hualing chene3797f02021-01-13 14:53:28 +08001287 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
Wentao MA804bab12022-11-29 10:01:26 +08001288 if (delay > MIN_CACHE_TIME) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001289 //dvr_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001290 /*if cache time > 20s , we think get time is error,*/
Wentao MA804bab12022-11-29 10:01:26 +08001291 if (delay - MIN_CACHE_TIME > 20 * 1000) {
1292 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 +08001293 }
hualing chene41f4372020-06-06 16:29:17 +08001294 }
hualing chen969fe7b2021-05-26 15:13:17 +08001295
hualing chen040df222020-01-17 13:35:02 +08001296 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001297 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001298 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001299
Wentao MA804bab12022-11-29 10:01:26 +08001300 get_effective_tsplayer_delay_time(player,&delay);
hualing chen1679f812021-11-08 15:17:46 +08001301 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1302 player->noData++;
Wentao MA96f68962022-06-15 19:45:35 +08001303 DVR_PB_INFO("playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001304 if (player->noData == check_no_data_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001305 DVR_PB_INFO("playback send nodata event nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001306 //send event here and pause
1307 DVR_Play_Notify_t notify;
1308 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1309 notify.event = DVR_PLAYBACK_EVENT_NODATA;
Wentao MA96f68962022-06-15 19:45:35 +08001310 DVR_PB_INFO("send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001311 //get play statue not here
1312 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1313 }
1314 }
Wentao MAa0b9c002022-11-10 17:47:27 +08001315
1316 DVR_Bool_t cond1 = (ret != DVR_SUCCESS);
1317 DVR_Bool_t cond2 = (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON);
1318 DVR_Bool_t cond3 = (delay <= MIN_TSPLAYER_DELAY_TIME);
1319 DVR_Bool_t cond4 = (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF);
1320 DVR_Bool_t cond5 = (player->delay_is_effective == DVR_TRUE);
1321 DVR_Bool_t cond6 = (reach_end_timeout >= MAX_REACHEND_TIMEOUT);
1322 if ((cond1 && cond2 && (cond3 || cond4) && cond5) || cond6) {
1323 DVR_PB_INFO("REACHED_END conditions: cond1:%d, cond2:%d, (cond3:%d, cond4:%d),"
1324 " cond5:%d, cond6:%d. delay:%d, reach_end_timeout:%d",
1325 (int)cond1,(int)cond2,(int)cond3,(int)cond4,(int)cond5,(int)cond6,
1326 delay,reach_end_timeout);
Wentao MA804bab12022-11-29 10:01:26 +08001327 DVR_Play_Notify_t notify;
1328 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1329 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1330 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
1331 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
1332 dvr_mutex_lock(&player->lock);
1333 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1334 dvr_mutex_unlock(&player->lock);
1335 continue;
1336 } else if (ret != DVR_SUCCESS) {
1337 DVR_PB_INFO("delay:%d pauselive:%d", delay, _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player));
1338 dvr_mutex_lock(&player->lock);
1339 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1340 dvr_mutex_unlock(&player->lock);
1341
1342 get_effective_tsplayer_delay_time(player,&delay);
1343 //not send event and pause,sleep and go to next time to recheck
1344 if (delay < cache_time) {
1345 //delay time is changed and then has data to play, so not start timeout
1346 reach_end_timeout = 0;
1347 } else {
1348 reach_end_timeout = reach_end_timeout + timeout;
1349 }
1350 cache_time = delay;
1351 continue;
1352 }
hualing chen39628212020-05-14 10:35:13 +08001353 reach_end_timeout = 0;
1354 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001355 //change next segment success case
1356 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001357 dvr_mutex_lock(&player->lock);
hualing chen40dd5462021-11-26 19:56:20 +08001358 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001359 DVR_PB_INFO("_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001360 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1361 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001362 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08001363 read = segment_read(player->segment_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001364 real_read = real_read + read;
1365 player->ts_cache_len = real_read;
1366 pthread_mutex_unlock(&player->segment_lock);
1367
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001368 dvr_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001369 }//read len 0 check end
Wentao MA92a14892023-09-12 18:54:47 +08001370
Wentao MAfae6ce82023-12-29 17:55:55 +08001371#ifdef FOR_OTT_49490
Wentao MA92a14892023-09-12 18:54:47 +08001372 if (player->openParams.is_timeshift == DVR_TRUE && player->speed >= FF_SPEED)
1373 {
1374 DVR_PlaybackSegmentInfo_t *newest_segment
1375 = list_last_entry(&player->segment_list, DVR_PlaybackSegmentInfo_t, head);
1376 DVR_Bool_t cond1 = (player->cur_segment_id == newest_segment->segment_id);
1377 int32_t time_end = _dvr_get_end_time((DVR_PlaybackHandle_t)player);
1378 uint64_t cur_seg_id = 0;
1379 int32_t time_cur = _dvr_get_play_cur_time((DVR_PlaybackHandle_t)player, &cur_seg_id);
1380 DVR_Bool_t cond2 = (cur_seg_id == player->cur_segment_id && time_end - time_cur < 1000);
1381 if (cond1 && cond2)
1382 {
1383 DVR_PlaybackSpeed_t normal_speed = {PLAYBACK_SPEED_X1,0};
1384 DVR_PB_INFO("Change to normal speed due to FF reaching end");
1385 dvr_playback_set_speed((DVR_PlaybackHandle_t)player,normal_speed);
Wentao MA9e31f692023-09-26 17:42:18 +08001386
1387 DVR_Play_Notify_t notify;
1388 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1389 notify.event = DVR_PLAYBACK_EVENT_TIMESHIFT_FF_REACHED_END;
1390 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, notify.event, &notify, 0);
Wentao MA92a14892023-09-12 18:54:47 +08001391 }
1392 }
1393#endif
1394
hualing chen40dd5462021-11-26 19:56:20 +08001395 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001396 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001397 DVR_PB_INFO("playback send data event resume[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001398 //send event here and pause
1399 DVR_Play_Notify_t notify;
1400 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1401 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
Wentao MA96f68962022-06-15 19:45:35 +08001402 DVR_PB_INFO("----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001403 //get play statue not here
1404 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001405 }
hualing chen39628212020-05-14 10:35:13 +08001406 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001407 //real_read = real_read + read;
Wentao MA270dc0f2022-08-23 13:17:26 +08001408 input_buffer.buf_size = real_read;
1409 input_buffer.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001410
Wentao MA270dc0f2022-08-23 13:17:26 +08001411 //check read data len,if len < 0, we need continue
1412 if (input_buffer.buf_size <= 0 || input_buffer.buf_data == NULL) {
1413 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 +08001414 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001415 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001416 player->ts_cache_len = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001417 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001418 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001419 }
hualing chen266b9502020-04-04 17:39:39 +08001420 //if need write whole block size, we need check read buf len is eq block size.
Wentao MAa0b9c002022-11-10 17:47:27 +08001421 if (b_writed_whole_block == DVR_TRUE
1422 && (player->has_video || player->dec_func || player->cryptor)) {
hualing chen266b9502020-04-04 17:39:39 +08001423 //buf_len is block size value.
1424 if (real_read < buf_len) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001425 //continue to read data from file
Wentao MA96f68962022-06-15 19:45:35 +08001426 DVR_PB_INFO("read buf len[%d] is < block size [%d]", real_read, buf_len);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001427 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001428 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1429 dvr_mutex_unlock(&player->lock);
1430 DVR_PB_INFO("read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001431 continue;
1432 } else if (real_read > buf_len) {
Wentao MA96f68962022-06-15 19:45:35 +08001433 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 +08001434 }
1435 }
1436
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001437 if (player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001438 DVR_CryptoParams_t crypto_params;
1439
1440 memset(&crypto_params, 0, sizeof(crypto_params));
1441 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1442 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1443 crypto_params.segment_id = player->cur_segment.segment_id;
Wentao MAf35c3882023-04-17 12:36:19 +08001444 crypto_params.offset = segment_tell_position(player->segment_handle) - input_buffer.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001445 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
Wentao MA96f68962022-06-15 19:45:35 +08001446 DVR_PB_INFO("offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001447 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1448 crypto_params.input_buffer.addr = (size_t)buf;
1449 crypto_params.input_buffer.size = real_read;
1450
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001451 if (player->is_secure_mode) {
1452 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1453 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1454 crypto_params.output_buffer.size = dec_buf_size;
1455 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001456 input_buffer.buf_data = player->secure_buffer;
1457 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001458 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001459 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001460 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001461 input_buffer.buf_size = crypto_params.output_size;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001462 } else { // only for NAGRA
1463 crypto_params.output_buffer.type = crypto_params.input_buffer.type;
1464 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1465 crypto_params.output_buffer.size = crypto_params.input_buffer.size;
1466 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001467 input_buffer.buf_data = (uint8_t*)crypto_params.output_buffer.addr;
1468 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001469 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001470 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001471 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001472 input_buffer.buf_size = crypto_params.output_buffer.size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001473 }
Yahui Han1fbf3292021-11-08 18:17:19 +08001474 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001475 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001476 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
Wentao MA270dc0f2022-08-23 13:17:26 +08001477 input_buffer.buf_data = dec_bufs.buf_data;
1478 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1479 input_buffer.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001480 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001481rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001482 if (player->drop_ts == DVR_TRUE) {
1483 //need drop ts data when seek occur.we need read next loop,drop this ts data
1484 goto_rewrite = DVR_FALSE;
1485 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001486 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001487 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001488 player->drop_ts = DVR_FALSE;
Wentao MA63c6cba2022-09-20 10:14:29 +08001489 pthread_mutex_unlock(&player->segment_lock);
1490 DVR_PB_INFO("----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001491 continue;
1492 }
hualing chen21a40372021-10-29 11:07:26 +08001493
1494 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001495 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001496 //used for printf first write data time.
1497 //to check change channel kpi.
1498 if (first_write == 0) {
1499 first_write++;
Wentao MA270dc0f2022-08-23 13:17:26 +08001500 DVR_PB_INFO("----first write ts data");
hualing chenb9a02922021-12-14 11:29:47 +08001501 }
1502
Wentao MA270dc0f2022-08-23 13:17:26 +08001503 ret = AmTsPlayer_writeData(player->handle, &input_buffer, write_timeout_ms);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001504 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001505 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001506 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001507 real_read = 0;
1508 write_success++;
shenghui.gengbec6a462023-01-12 15:21:02 +08001509 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001510check0:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001511 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001512 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001513 break;
1514 }
hualing chend241c7a2021-06-22 13:34:27 +08001515 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001516 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001517 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001518 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001519 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1520 goto check0;
1521 }
1522 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001523 //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 +08001524 } else {
Wentao MA804bab12022-11-29 10:01:26 +08001525 pthread_mutex_unlock(&player->segment_lock);
wentao.ma4ee43022022-12-14 13:22:57 +08001526 DVR_PB_DEBUG("write time out write_success:%d buf_size:%d systime:%u",
1527 write_success, input_buffer.buf_size, _dvr_time_getClock());
hualing chena540a7e2020-03-27 16:44:05 +08001528 write_success = 0;
shenghui.gengbec6a462023-01-12 15:21:02 +08001529 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001530check1:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001531 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001532 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001533 break;
1534 }
hualing chend241c7a2021-06-22 13:34:27 +08001535 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001536 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001537 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001538 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001539 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1540 goto check1;
1541 }
1542 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001543 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001544 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001545 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001546 if (!player->is_running) {
Wentao MA96f68962022-06-15 19:45:35 +08001547 DVR_PB_INFO("playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001548 break;
1549 }
hualing chen2aba4022020-03-02 13:49:55 +08001550 goto_rewrite = DVR_TRUE;
1551 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001552 }
1553 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001554end:
Wentao MA96f68962022-06-15 19:45:35 +08001555 DVR_PB_INFO("playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001556 free(buf);
1557 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001558 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001559}
1560
1561
hualing chen040df222020-01-17 13:35:02 +08001562static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001563{
hualing chen040df222020-01-17 13:35:02 +08001564 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001565
1566 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001567 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001568 return DVR_FAILURE;
1569 }
Wentao MA96f68962022-06-15 19:45:35 +08001570 DVR_PB_INFO("start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001571 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001572 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001573 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001574 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001575 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001576 if (rc < 0)
1577 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001578 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001579}
1580
1581
hualing chen040df222020-01-17 13:35:02 +08001582static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001583{
hualing chen040df222020-01-17 13:35:02 +08001584 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001585
1586 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001587 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001588 return DVR_FAILURE;
1589 }
1590
Wentao MA96f68962022-06-15 19:45:35 +08001591 DVR_PB_INFO("stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001592 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001593 {
1594 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001595 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001596 pthread_join(player->playback_thread, NULL);
1597 }
Wentao MAf35c3882023-04-17 12:36:19 +08001598 if (player->segment_handle) {
1599 segment_close(player->segment_handle);
1600 player->segment_handle = NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001601 }
Wentao MA96f68962022-06-15 19:45:35 +08001602 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001603 return 0;
1604}
1605
hualing chen1679f812021-11-08 15:17:46 +08001606static int getFakePid()
1607{
wentao ma7d642782022-10-23 18:26:16 -07001608 return dvr_prop_read_int("vendor.tv.dtv.fake_pid",0xffff);
hualing chen1679f812021-11-08 15:17:46 +08001609}
1610
1611void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1612
1613 DVR_ASSERT(handle);
1614 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1615 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001616 DVR_PB_INFO("player is NULL");
hualing chen1679f812021-11-08 15:17:46 +08001617 return ;
1618 }
1619 if (player->need_seek_start == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001620 DVR_PB_INFO("player need_seek_start is false");
hualing chen1679f812021-11-08 15:17:46 +08001621 return ;
1622 }
1623
hualing chena5f03222021-12-02 11:22:35 +08001624 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001625 player->need_seek_start = DVR_FALSE;
1626 }
Wentao MA96f68962022-06-15 19:45:35 +08001627 DVR_PB_INFO("player player->need_seek_start=%d", player->need_seek_start);
hualing chen1679f812021-11-08 15:17:46 +08001628}
1629
hualing chenb31a6c62020-01-13 17:27:00 +08001630/**\brief Open an dvr palyback
1631 * \param[out] p_handle dvr playback addr
1632 * \param[in] params dvr playback open parameters
1633 * \retval DVR_SUCCESS On success
1634 * \return Error code
1635 */
hualing chen040df222020-01-17 13:35:02 +08001636int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001637
hualing chen040df222020-01-17 13:35:02 +08001638 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001639 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001640
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001641 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
wentao.maa22bc852022-10-13 12:18:06 +08001642 DVR_RETURN_IF_FALSE(player);
hualing chenb31a6c62020-01-13 17:27:00 +08001643
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001644 dvr_mutex_init(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001645 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001646 pthread_condattr_init(&cattr);
1647 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1648 pthread_cond_init(&player->cond, &cattr);
1649 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001650
hualing chen5cbe1a62020-02-10 16:36:36 +08001651 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001652 INIT_LIST_HEAD(&player->segment_list);
1653 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1654 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001655 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001656 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00001657 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen86e7d482020-01-16 15:13:33 +08001658 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001659 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001660 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001661
hualing chen86e7d482020-01-16 15:13:33 +08001662 //store open params
hualing chen040df222020-01-17 13:35:02 +08001663 player->openParams.dmx_dev_id = params->dmx_dev_id;
1664 player->openParams.block_size = params->block_size;
Wentao MA96f68962022-06-15 19:45:35 +08001665 DVR_PB_INFO("playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001666 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001667 player->openParams.event_fn = params->event_fn;
1668 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001669 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001670 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001671
hualing chen5cbe1a62020-02-10 16:36:36 +08001672 player->has_pids = params->has_pids;
1673
hualing chen2aba4022020-03-02 13:49:55 +08001674 player->handle = params->player_handle ;
shenghui.gengbec6a462023-01-12 15:21:02 +08001675 player->control_speed_enable = params->control_speed_enable;
hualing chen6e4bfa52020-03-13 14:37:11 +08001676
1677 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1678 //for test get callback
1679 if (0 && player->player_callback_func == NULL) {
1680 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1681 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
Wentao MA96f68962022-06-15 19:45:35 +08001682 DVR_PB_INFO("playback open get callback[%p][%p][%p][%p]",
hualing chen03fd4942021-07-15 15:56:41 +08001683 player->player_callback_func,
1684 player->player_callback_userdata,
1685 _dvr_tsplayer_callback_test,
1686 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001687 }
1688 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001689
hualing chen86e7d482020-01-16 15:13:33 +08001690 //init has audio and video
1691 player->has_video = DVR_FALSE;
1692 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001693 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001694 player->last_segment_id = 0LL;
1695 player->segment_is_open = DVR_FALSE;
Wentao MA5629ad82022-08-24 10:03:02 +08001696 player->audio_presentation_id = -1;
hualing chenb31a6c62020-01-13 17:27:00 +08001697
hualing chen5cbe1a62020-02-10 16:36:36 +08001698 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001699 player->fffb_current = 0;
1700 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001701 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001702 //seek time
1703 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001704 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001705
Yahui Han1fbf3292021-11-08 18:17:19 +08001706 //allocate cryptor if have clearkey
1707 if (params->keylen > 0) {
1708 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +08001709 (uint8_t *)params->cleariv,
1710 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +08001711 if (!player->cryptor) {
Wentao MA96f68962022-06-15 19:45:35 +08001712 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +08001713 }
1714 } else {
1715 player->cryptor = NULL;
1716 }
1717
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001718 //init secure stuff
1719 player->dec_func = NULL;
1720 player->dec_userdata = NULL;
1721 player->is_secure_mode = 0;
1722 player->secure_buffer = NULL;
1723 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001724 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001725
hualing chen4b7c15d2020-04-07 16:13:48 +08001726 player->fffb_play = DVR_FALSE;
1727
1728 player->last_send_time_id = UINT64_MAX;
1729 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001730 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001731
hualing chend241c7a2021-06-22 13:34:27 +08001732 //speed con init
shenghui.gengbec6a462023-01-12 15:21:02 +08001733 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001734 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001735 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001736 player->con_spe.sys_dur = 0;
1737 player->con_spe.sys_sta = 0;
1738 }
1739
hualing chen03fd4942021-07-15 15:56:41 +08001740 //limit info
1741 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001742 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001743 //need seek to start pos
1744 player->first_start_time = 0;
Wentao MA01de0e62022-01-10 18:48:23 +08001745 player->first_start_id = UINT64_MAX;
Wentao MAa0b9c002022-11-10 17:47:27 +08001746 player->delay_is_effective = DVR_FALSE;
hualing chen8a657f32021-08-30 13:12:49 +08001747 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001748 //fake_pid init
1749 player->fake_pid = getFakePid();
hualing chen86e7d482020-01-16 15:13:33 +08001750 *p_handle = player;
1751 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001752}
1753
1754/**\brief Close an dvr palyback
1755 * \param[in] handle playback handle
1756 * \retval DVR_SUCCESS On success
1757 * \return Error code
1758 */
hualing chen040df222020-01-17 13:35:02 +08001759int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001760
hualing chen86e7d482020-01-16 15:13:33 +08001761 DVR_ASSERT(handle);
Wentao MA96f68962022-06-15 19:45:35 +08001762 DVR_PB_INFO(":into");
hualing chen040df222020-01-17 13:35:02 +08001763 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001764 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001765 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001766 return DVR_FAILURE;
1767 }
1768
hualing chencc91e1c2020-02-28 13:26:17 +08001769 if (player->state != DVR_PLAYBACK_STATE_STOP)
1770 {
Wentao MA96f68962022-06-15 19:45:35 +08001771 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001772 if (player->cryptor) {
1773 am_crypt_des_close(player->cryptor);
1774 player->cryptor = NULL;
1775 }
hualing chencc91e1c2020-02-28 13:26:17 +08001776 dvr_playback_stop(handle, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08001777 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
hualing chenb96aa2c2020-04-15 14:13:53 +08001778 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001779 DVR_PB_INFO(":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001780 }
Wentao MA96f68962022-06-15 19:45:35 +08001781 DVR_PB_INFO(":into");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001782 dvr_mutex_destroy(&player->lock);
Zhiqiang Hanc9513462022-06-21 09:55:23 +08001783 pthread_mutex_destroy(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001784 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001785
1786 if (player) {
1787 free(player);
hualing chen040df222020-01-17 13:35:02 +08001788 }
Wentao MA96f68962022-06-15 19:45:35 +08001789 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001790 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001791}
1792
Wentao MA270dc0f2022-08-23 13:17:26 +08001793/**\brief Start play audio and video, used start audio api and start video api
hualing chenb31a6c62020-01-13 17:27:00 +08001794 * \param[in] handle playback handle
1795 * \param[in] params audio playback params,contains fmt and pid...
1796 * \retval DVR_SUCCESS On success
1797 * \return Error code
1798 */
hualing chen040df222020-01-17 13:35:02 +08001799int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1800 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA270dc0f2022-08-23 13:17:26 +08001801 am_tsplayer_video_params video_params;
1802 am_tsplayer_audio_params audio_params;
1803 am_tsplayer_audio_params ad_params;
hualing chena540a7e2020-03-27 16:44:05 +08001804
Wentao MA270dc0f2022-08-23 13:17:26 +08001805 memset(&video_params, 0, sizeof(video_params));
1806 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001807
hualing chena540a7e2020-03-27 16:44:05 +08001808 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001809 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001810 return DVR_FAILURE;
1811 }
hualing chencc91e1c2020-02-28 13:26:17 +08001812 uint64_t segment_id = player->cur_segment_id;
Wentao MA96f68962022-06-15 19:45:35 +08001813 DVR_PB_INFO("[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001814
hualing chena540a7e2020-03-27 16:44:05 +08001815 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001816 //can used start api to resume playback
1817 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1818 return dvr_playback_resume(handle);
1819 }
hualing chen87072a82020-03-12 16:20:12 +08001820 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001821 //if flag is paused and not decode first frame. if user resume, we need
hualing chen9b434f02020-06-10 15:06:54 +08001822 //clear flag and set trickmode none
1823 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001824 DVR_PB_INFO("[%p]clear pause live flag and clear trick mode", handle);
hualing chen9b434f02020-06-10 15:06:54 +08001825 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1826 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1827 }
Wentao MA96f68962022-06-15 19:45:35 +08001828 DVR_PB_INFO("stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001829 return DVR_SUCCESS;
1830 }
hualing chen86e7d482020-01-16 15:13:33 +08001831 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001832 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001833 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08001834 DVR_PB_INFO("lock flag:0x%x", flag);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001835 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001836 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08001837 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08001838 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
1839 //audio and video pids are all invalid, return error.
1840 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 +08001841 dvr_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001842 DVR_Play_Notify_t notify;
1843 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1844 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1845 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1846 notify.info.transition_failed_data.segment_id = segment_id;
1847 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001848 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001849 return -1;
1850 }
hualing chen31140872020-03-25 12:29:26 +08001851
hualing chencc91e1c2020-02-28 13:26:17 +08001852 {
Wentao MA270dc0f2022-08-23 13:17:26 +08001853 if (VALID_PID(video_params.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001854 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001855 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001856 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001857 DVR_PB_INFO("set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001858 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1859 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001860 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
Wentao MA96f68962022-06-15 19:45:35 +08001861 DVR_PB_INFO("set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001862 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001863 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001864 DVR_PB_INFO("set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001865 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001866 }
hualing chena93bbbc2020-12-22 17:23:42 +08001867 AmTsPlayer_showVideo(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08001868 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08001869 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001870 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001871 }
hualing chena540a7e2020-03-27 16:44:05 +08001872
Wentao MA270dc0f2022-08-23 13:17:26 +08001873 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 +08001874 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001875 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1876 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1877 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001878 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001879 } else {
1880 player->cmd.last_cmd = player->cmd.cur_cmd;
1881 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001882 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001883 //set fast play
Wentao MA96f68962022-06-15 19:45:35 +08001884 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08001885 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001886 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08001887 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08001888 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08001889 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08001890 dvr_playback_change_seek_state(handle, ad_params.pid);
1891 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08001892 AmTsPlayer_enableADMix(player->handle);
1893 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001894 if (VALID_PID(audio_params.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001895 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08001896 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08001897 dvr_playback_change_seek_state(handle, audio_params.pid);
1898 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08001899 if (player->audio_presentation_id > -1) {
1900 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
1901 }
hualing chen969fe7b2021-05-26 15:13:17 +08001902 AmTsPlayer_startAudioDecoding(player->handle);
1903 }
hualing chen31140872020-03-25 12:29:26 +08001904 }
hualing chencc91e1c2020-02-28 13:26:17 +08001905 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001906 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001907 }
hualing chen86e7d482020-01-16 15:13:33 +08001908 }
hualing chen43a89bc2022-01-19 14:31:20 +08001909#ifdef AVSYNC_USED_PCR
1910 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001911 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08001912 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
1913 }
1914#endif
Wentao MA96f68962022-06-15 19:45:35 +08001915 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001916 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001917 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001918 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001919}
hualing chen040df222020-01-17 13:35:02 +08001920/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001921 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001922 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001923 * \retval DVR_SUCCESS On success
1924 * \return Error code
1925 */
hualing chen040df222020-01-17 13:35:02 +08001926int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1927 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa22bc852022-10-13 12:18:06 +08001928 DVR_RETURN_IF_FALSE(player);
hualing chena540a7e2020-03-27 16:44:05 +08001929
Wentao MA96f68962022-06-15 19:45:35 +08001930 DVR_PB_INFO("add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001931 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001932
hualing chen040df222020-01-17 13:35:02 +08001933 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
wentao.maa22bc852022-10-13 12:18:06 +08001934 DVR_RETURN_IF_FALSE(segment);
hualing chen040df222020-01-17 13:35:02 +08001935 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001936
Wentao MA270dc0f2022-08-23 13:17:26 +08001937 //not memcpy chunk info.
hualing chen040df222020-01-17 13:35:02 +08001938 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001939 //cp location
hualing chen040df222020-01-17 13:35:02 +08001940 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001941
Wentao MA96f68962022-06-15 19:45:35 +08001942 DVR_PB_INFO("add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001943 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001944
1945 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001946 segment->pids.video.pid = info->pids.video.pid;
1947 segment->pids.video.format = info->pids.video.format;
1948 segment->pids.video.type = info->pids.video.type;
1949
hualing chen2aba4022020-03-02 13:49:55 +08001950 segment->pids.audio.pid = info->pids.audio.pid;
1951 segment->pids.audio.format = info->pids.audio.format;
1952 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001953
hualing chen2aba4022020-03-02 13:49:55 +08001954 segment->pids.ad.pid = info->pids.ad.pid;
1955 segment->pids.ad.format = info->pids.ad.format;
1956 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001957
1958 segment->pids.pcr.pid = info->pids.pcr.pid;
1959
Wentao MA96f68962022-06-15 19:45:35 +08001960 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 +08001961 dvr_mutex_lock(&player->lock);
wentao.maa22bc852022-10-13 12:18:06 +08001962 list_add_tail(segment, &player->segment_list);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001963 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001964 DVR_PB_DEBUG("unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001965
hualing chen5cbe1a62020-02-10 16:36:36 +08001966 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001967}
hualing chen040df222020-01-17 13:35:02 +08001968/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001969 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001970 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001971 * \retval DVR_SUCCESS On success
1972 * \return Error code
1973 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001974int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001975 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001976 DVR_PB_INFO("remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001977 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001978 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001979 return DVR_FAILURE;
1980 }
1981
hualing chencc91e1c2020-02-28 13:26:17 +08001982 if (segment_id == player->cur_segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08001983 DVR_PB_INFO("not support remove current segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001984 return DVR_FAILURE;
1985 }
Wentao MA96f68962022-06-15 19:45:35 +08001986 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001987 dvr_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001988 DVR_PlaybackSegmentInfo_t *segment = NULL;
1989 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1990 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001991 {
hualing chen040df222020-01-17 13:35:02 +08001992 if (segment->segment_id == segment_id) {
1993 list_del(&segment->head);
1994 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001995 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001996 }
hualing chen86e7d482020-01-16 15:13:33 +08001997 }
Wentao MA96f68962022-06-15 19:45:35 +08001998 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001999 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002000
2001 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002002}
hualing chen040df222020-01-17 13:35:02 +08002003/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08002004 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08002005 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08002006 * \retval DVR_SUCCESS On success
2007 * \return Error code
2008 */
hualing chen040df222020-01-17 13:35:02 +08002009int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002010 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08002011 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08002012 DVR_PB_INFO("update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08002013 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002014 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002015 return DVR_FAILURE;
2016 }
Wentao MA292380e2022-12-14 14:46:19 +08002017 if (player->vendor != DVR_PLAYBACK_VENDOR_DEF) {
2018 DVR_PB_INFO("In case of vendor Amlogic/Amazon, do not control AV display");
hualing chenf43b8ba2020-07-28 13:11:42 +08002019 return DVR_SUCCESS;
2020 }
hualing chena540a7e2020-03-27 16:44:05 +08002021
hualing chen040df222020-01-17 13:35:02 +08002022 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002023 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002024 dvr_mutex_lock(&player->lock);
wentao.mafd5283f2022-10-14 09:51:13 +08002025 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002026 // prefetch() here incurring self_assign is used to avoid some compiling
2027 // warnings.
2028 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002029 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002030 {
hualing chen040df222020-01-17 13:35:02 +08002031 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08002032 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08002033 }
hualing chen86e7d482020-01-16 15:13:33 +08002034 // if encramble to free, only set flag and return;
2035
2036 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08002037 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002038 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
2039 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08002040 //disable display, mute
Wentao MA96f68962022-06-15 19:45:35 +08002041 DVR_PB_INFO("mute av");
hualing chen2aba4022020-03-02 13:49:55 +08002042 AmTsPlayer_hideVideo(player->handle);
2043 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002044 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
2045 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002046 //enable display, unmute
Wentao MA96f68962022-06-15 19:45:35 +08002047 DVR_PB_INFO("unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08002048 AmTsPlayer_showVideo(player->handle);
2049 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002050 } else {
2051 //do nothing
2052 }
2053 } else {
2054 //do nothing
2055 }
2056 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08002057 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08002058 }
Wentao MA96f68962022-06-15 19:45:35 +08002059 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002060 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002061 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002062}
2063
2064
Wentao MA6dcdc342023-01-30 17:03:19 +08002065static 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 +08002066 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08002067 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08002068 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08002069
Wentao MA6dcdc342023-01-30 17:03:19 +08002070 if (player == NULL) {
2071 DVR_PB_INFO("player is NULL");
2072 return DVR_FAILURE;
2073 }
2074
hualing chen275379e2021-06-15 17:57:21 +08002075 if (type == 0) {
2076 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08002077 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08002078 } else if (type == 1) {
2079 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08002080 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08002081 } else if (type == 2) {
2082 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08002083 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08002084 } else {
2085 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08002086 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08002087 }
2088
Wentao MA6dcdc342023-01-30 17:03:19 +08002089 if (type == 1 && VALID_PID(set_pid.pid) && player->cmd.state == DVR_PLAYBACK_STATE_START
2090 && player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
2091 // Here we mute audio no matter it is displayable or not in starting phase of a playback.
2092 // Audio will be unmuted shortly on receiving first frame event.
2093 AmTsPlayer_setAudioMute(player->handle,1,1);
hualing chena540a7e2020-03-27 16:44:05 +08002094 }
Wentao MA6dcdc342023-01-30 17:03:19 +08002095
hualing chen86e7d482020-01-16 15:13:33 +08002096 if (now_pid.pid == set_pid.pid) {
2097 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08002098 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08002099 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08002100 if (VALID_PID(now_pid.pid)) {
2101 //stop now stream
2102 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002103 //stop video
hualing chenc70a8df2020-05-12 19:23:11 +08002104 if (player->has_video == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002105 DVR_PB_INFO("stop video");
hualing chenc70a8df2020-05-12 19:23:11 +08002106 AmTsPlayer_stopVideoDecoding(player->handle);
2107 player->has_video = DVR_FALSE;
2108 }
hualing chen86e7d482020-01-16 15:13:33 +08002109 } else if (type == 1) {
2110 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002111 if (player->has_audio == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002112 DVR_PB_INFO("stop audio");
hualing chenc70a8df2020-05-12 19:23:11 +08002113 AmTsPlayer_stopAudioDecoding(player->handle);
2114 player->has_audio = DVR_FALSE;
2115 }
hualing chen86e7d482020-01-16 15:13:33 +08002116 } else if (type == 2) {
2117 //stop sub audio
Wentao MA96f68962022-06-15 19:45:35 +08002118 DVR_PB_INFO("stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002119 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002120 } else if (type == 3) {
2121 //pcr
2122 }
2123 }
2124 if (VALID_PID(set_pid.pid)) {
2125 //start
2126 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002127 //start video
2128 am_tsplayer_video_params video_params;
2129 video_params.pid = set_pid.pid;
2130 video_params.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002131 player->has_video = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002132 DVR_PB_INFO("start video pid[%d]fmt[%d]",video_params.pid, video_params.codectype);
2133 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen2aba4022020-03-02 13:49:55 +08002134 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002135 //playback_device_video_start(player->handle,&video_params);
hualing chen86e7d482020-01-16 15:13:33 +08002136 } else if (type == 1) {
2137 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002138 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002139 if (VALID_PID(set_pids.ad.pid)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002140 am_tsplayer_audio_params ad_params;
2141 ad_params.pid = set_pids.ad.pid;
2142 ad_params.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2143 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",ad_params.pid, ad_params.codectype);
2144 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen275379e2021-06-15 17:57:21 +08002145 AmTsPlayer_enableADMix(player->handle);
2146 }
2147
Wentao MA270dc0f2022-08-23 13:17:26 +08002148 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002149
Wentao MA270dc0f2022-08-23 13:17:26 +08002150 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002151
Wentao MA270dc0f2022-08-23 13:17:26 +08002152 audio_params.pid = set_pid.pid;
2153 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002154 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002155 DVR_PB_INFO("start audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2156 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002157 if (player->audio_presentation_id > -1) {
2158 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2159 }
Wentao MA6dcdc342023-01-30 17:03:19 +08002160
hualing chenc70a8df2020-05-12 19:23:11 +08002161 AmTsPlayer_startAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002162 //playback_device_audio_start(player->handle,&audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002163 }
hualing chen86e7d482020-01-16 15:13:33 +08002164 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002165 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002166 if (set_pids.audio.pid == now_pids.audio.pid) {
2167 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002168 DVR_PB_INFO("stop audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002169 AmTsPlayer_stopAudioDecoding(player->handle);
2170 }
Wentao MA270dc0f2022-08-23 13:17:26 +08002171 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002172
Wentao MA270dc0f2022-08-23 13:17:26 +08002173 memset(&audio_params, 0, sizeof(audio_params));
2174 audio_params.pid = set_pid.pid;
2175 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002176 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002177 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2178 AmTsPlayer_setADParams(player->handle, &audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002179 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002180
2181 if (set_pids.audio.pid == now_pids.audio.pid) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002182 am_tsplayer_audio_params audio_params;
hualing chen99508642021-10-18 15:41:17 +08002183
Wentao MA270dc0f2022-08-23 13:17:26 +08002184 memset(&audio_params, 0, sizeof(audio_params));
hualing chen99508642021-10-18 15:41:17 +08002185
Wentao MA270dc0f2022-08-23 13:17:26 +08002186 audio_params.pid = set_pids.audio.pid;
2187 audio_params.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
hualing chen99508642021-10-18 15:41:17 +08002188 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002189 DVR_PB_INFO("restart audio when start ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002190 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002191 if (player->audio_presentation_id > -1) {
2192 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2193 }
hualing chen99508642021-10-18 15:41:17 +08002194 AmTsPlayer_startAudioDecoding(player->handle);
2195 }
hualing chenc70a8df2020-05-12 19:23:11 +08002196 }
hualing chen86e7d482020-01-16 15:13:33 +08002197 } else if (type == 3) {
2198 //pcr
Wentao MA96f68962022-06-15 19:45:35 +08002199 DVR_PB_INFO("start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002200 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002201 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002202 //audio and video all close
2203 if (!player->has_audio && !player->has_video) {
Wentao MA907b6432022-08-01 06:23:08 +00002204 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen5cbe1a62020-02-10 16:36:36 +08002205 }
hualing chen43a89bc2022-01-19 14:31:20 +08002206 } else if (type == 2) {
2207 //case disable ad
Wentao MA96f68962022-06-15 19:45:35 +08002208 DVR_PB_INFO("restart audio when stop ad");
hualing chen43a89bc2022-01-19 14:31:20 +08002209 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
Wentao MA6d045b32022-02-18 18:47:25 +08002210 if (VALID_PID(now_pids.audio.pid)) {
2211 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002212 DVR_PB_INFO("stop audio when stop ad pid [0x%x]", now_pids.audio.pid);
Wentao MA6d045b32022-02-18 18:47:25 +08002213 AmTsPlayer_stopAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002214 am_tsplayer_audio_params audio_params;
hualing chen43a89bc2022-01-19 14:31:20 +08002215
Wentao MA270dc0f2022-08-23 13:17:26 +08002216 memset(&audio_params, 0, sizeof(audio_params));
hualing chen43a89bc2022-01-19 14:31:20 +08002217
Wentao MA270dc0f2022-08-23 13:17:26 +08002218 audio_params.pid = now_pids.audio.pid;
2219 audio_params.codectype= _dvr_convert_stream_fmt(now_pids.audio.format, DVR_TRUE);
Wentao MA6d045b32022-02-18 18:47:25 +08002220 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002221 DVR_PB_INFO("restart audio when stop ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002222 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002223 if (player->audio_presentation_id > -1) {
2224 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2225 }
Wentao MA6d045b32022-02-18 18:47:25 +08002226 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen43a89bc2022-01-19 14:31:20 +08002227 }
Wentao MA6d045b32022-02-18 18:47:25 +08002228 }
hualing chen86e7d482020-01-16 15:13:33 +08002229 }
2230 }
2231 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002232}
hualing chena5f03222021-12-02 11:22:35 +08002233/**\brief dvr play back only update segment pids info
2234 * only update pid info not to start stop codec.
2235 * \param[in] handle playback handle
2236 * \param[in] segment_id need updated pids segment id
2237 * \param[in] p_pids need updated pids
2238 * \retval DVR_SUCCESS On success
2239 * \return Error code
2240 */
2241int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2242 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2243 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002244 DVR_PB_INFO("player is NULL");
hualing chena5f03222021-12-02 11:22:35 +08002245 return DVR_FAILURE;
2246 }
2247
2248 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002249 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002250 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002251 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 +08002252 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002253 // prefetch() here incurring self_assign is used to avoid some compiling
2254 // warnings.
2255 // coverity[self_assign]
hualing chena5f03222021-12-02 11:22:35 +08002256 list_for_each_entry(segment, &player->segment_list, head)
2257 {
2258 if (segment->segment_id == segment_id) {
2259 if (player->cur_segment_id == segment_id) {
2260 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002261 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chena5f03222021-12-02 11:22:35 +08002262 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002263 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002264 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002265 return 0;
2266 }
2267 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2268 }
2269 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002270 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002271 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002272 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002273 break;
2274 }
2275 }
Wentao MA96f68962022-06-15 19:45:35 +08002276 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002277 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002278 return DVR_SUCCESS;
2279}
2280
hualing chen5cbe1a62020-02-10 16:36:36 +08002281/**\brief dvr play back update segment pids
2282 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002283 * add pid stream and stop remove pid stream.
2284 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002285 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002286 * \retval DVR_SUCCESS On success
2287 * \return Error code
2288 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002289int dvr_playback_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
hualing chen040df222020-01-17 13:35:02 +08002290 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002291 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002292 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002293 return DVR_FAILURE;
2294 }
2295
hualing chen040df222020-01-17 13:35:02 +08002296 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002297 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002298 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002299 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 +08002300
wentao.mafd5283f2022-10-14 09:51:13 +08002301 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002302 // prefetch() here incurring self_assign is used to avoid some compiling
2303 // warnings.
2304 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002305 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002306 {
hualing chen040df222020-01-17 13:35:02 +08002307 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002308
2309 if (player->cur_segment_id == segment_id) {
2310 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002311 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002312 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002313 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002314 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002315 return 0;
2316 }
2317
2318 //if segment is on going segment,we need stop start stream
2319 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA96f68962022-06-15 19:45:35 +08002320 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002321 dvr_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002322 if (segment->pids.audio.pid != p_pids->audio.pid &&
2323 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002324 //not used this to seek to start pos.we will
Wentao MA9a164002022-08-29 11:20:24 +08002325 //add update only api. if need seek to start
hualing chena5f03222021-12-02 11:22:35 +08002326 //pos, we will call only update api and used seek api
2327 //to start and stop av codec
2328 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002329 player->need_seek_start = DVR_FALSE;
2330 pthread_mutex_lock(&player->segment_lock);
2331 player->drop_ts = DVR_TRUE;
2332 player->ts_cache_len = 0;
2333 if (player->first_start_time > 0)
2334 player->first_start_time = player->first_start_time - 1;
Wentao MAf35c3882023-04-17 12:36:19 +08002335 segment_seek(player->segment_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002336 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 +08002337 pthread_mutex_unlock(&player->segment_lock);
2338 }
2339 }
hualing chen1679f812021-11-08 15:17:46 +08002340 //check video pids, stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002341 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
hualing chen1679f812021-11-08 15:17:46 +08002342 //check sub audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002343 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
hualing chen1679f812021-11-08 15:17:46 +08002344 //check audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002345 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
hualing chen1679f812021-11-08 15:17:46 +08002346 //check pcr pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002347 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
hualing chen1679f812021-11-08 15:17:46 +08002348
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002349 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002350 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2351 //if state is pause, we need process at resume api. we only record change info
2352 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2353 int a_cmd = DVR_PLAYBACK_CMD_NONE;
Zhiqiang Han83923642023-11-03 12:06:48 +08002354
2355 #define CHECK_IF_NEED_RESTART(_now, _next, _cmd, _v_cmd) \
2356 if (VALID_PID(_now) && VALID_PID(_next) && (_now) != (_next)) \
2357 (_cmd) = (_v_cmd);
2358
2359 #define CHECK_IF_NEED_STOP(_now, _next, _cmd, _v_cmd) \
2360 if (VALID_PID(_now) && !VALID_PID(_next)) \
2361 (_cmd) = (_v_cmd);
2362
2363 #define CHECK_IF_NEED_START(_now, _next, _cmd, _v_cmd) \
2364 if (!VALID_PID(_now) && VALID_PID(_next)) \
2365 (_cmd) = (_v_cmd);
2366
2367 CHECK_IF_NEED_RESTART(segment->pids.video.pid, p_pids->video.pid, v_cmd, DVR_PLAYBACK_CMD_V_RESTART);
2368 CHECK_IF_NEED_STOP(segment->pids.video.pid, p_pids->video.pid, v_cmd, DVR_PLAYBACK_CMD_V_STOP);
2369 CHECK_IF_NEED_START(segment->pids.video.pid, p_pids->video.pid, v_cmd, DVR_PLAYBACK_CMD_V_START);
2370
2371 CHECK_IF_NEED_RESTART(segment->pids.audio.pid, p_pids->audio.pid, a_cmd, DVR_PLAYBACK_CMD_A_RESTART);
2372 CHECK_IF_NEED_STOP(segment->pids.audio.pid, p_pids->audio.pid, a_cmd, DVR_PLAYBACK_CMD_A_STOP);
2373 CHECK_IF_NEED_START(segment->pids.audio.pid, p_pids->audio.pid, a_cmd, DVR_PLAYBACK_CMD_A_START);
Zhiqiang Han400e2a12023-10-23 09:12:32 +08002374
2375 /*process the ad, if main audio exists, but no action*/
2376 if (a_cmd == DVR_PLAYBACK_CMD_NONE && VALID_PID(p_pids->audio.pid)) {
2377
Zhiqiang Han83923642023-11-03 12:06:48 +08002378 CHECK_IF_NEED_RESTART(segment->pids.ad.pid, p_pids->ad.pid, a_cmd, DVR_PLAYBACK_CMD_A_RESTART);
2379 CHECK_IF_NEED_STOP(segment->pids.ad.pid, p_pids->ad.pid, a_cmd, DVR_PLAYBACK_CMD_A_RESTART);
2380 CHECK_IF_NEED_START(segment->pids.ad.pid, p_pids->ad.pid, a_cmd, DVR_PLAYBACK_CMD_A_RESTART);
Zhiqiang Han400e2a12023-10-23 09:12:32 +08002381
2382 }
2383
Zhiqiang Han83923642023-11-03 12:06:48 +08002384 DVR_PB_INFO("%s, v_cmd[%#x] a_cmd[%#x]", __func__, v_cmd, a_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002385
Zhiqiang Han83923642023-11-03 12:06:48 +08002386 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
2387 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_NONE) {
2388 /*another cmd coming in pause mode, should check and merge with last cmd*/
2389 player->cmd.cur_cmd |= a_cmd | v_cmd;
2390 } else {
2391 player->cmd.cur_cmd = a_cmd | v_cmd;
hualing chen5cbe1a62020-02-10 16:36:36 +08002392 }
Zhiqiang Han83923642023-11-03 12:06:48 +08002393 player->cmd.last_cmd = DVR_PLAYBACK_CMD_PAUSE;
2394
2395 DVR_PB_INFO("%s, last_cmd[%#x] cur_cmd[%#x]", __func__, player->cmd.last_cmd, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002396 }
Zhiqiang Han83923642023-11-03 12:06:48 +08002397
hualing chene10666f2020-04-14 13:58:37 +08002398 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002399 }
hualing chen86e7d482020-01-16 15:13:33 +08002400 //save pids info
Zhiqiang Han83923642023-11-03 12:06:48 +08002401 DVR_PB_INFO(":vpid :%d -> %d", segment->pids.video.pid, p_pids->video.pid);
2402 DVR_PB_INFO(":apid :%d -> %d", segment->pids.audio.pid, p_pids->audio.pid);
2403 DVR_PB_INFO(":adpid :%d -> %d", segment->pids.ad.pid, p_pids->ad.pid);
hualing chen040df222020-01-17 13:35:02 +08002404 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +08002405 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002406 }
hualing chen86e7d482020-01-16 15:13:33 +08002407 }
Wentao MA96f68962022-06-15 19:45:35 +08002408 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002409 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002410 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002411}
2412/**\brief Stop play, will stop video and audio
2413 * \param[in] handle playback handle
2414 * \param[in] clear is clear last frame
2415 * \retval DVR_SUCCESS On success
2416 * \return Error code
2417 */
hualing chen040df222020-01-17 13:35:02 +08002418int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2419 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002420 DVR_UNUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002421 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002422 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002423 return DVR_FAILURE;
2424 }
Zhiqiang Han1f279702024-03-18 13:55:56 +08002425
hualing chen87072a82020-03-12 16:20:12 +08002426 _stop_playback_thread(handle);
Zhiqiang Han1f279702024-03-18 13:55:56 +08002427
2428 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2429 DVR_PB_INFO(":playback is stoped");
2430 return DVR_SUCCESS;
2431 }
2432
Wentao MA96f68962022-06-15 19:45:35 +08002433 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002434 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002435 DVR_PB_INFO(":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002436 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002437 if (player->has_video) {
2438 AmTsPlayer_resumeVideoDecoding(player->handle);
2439 }
2440 if (player->has_audio) {
2441 AmTsPlayer_resumeAudioDecoding(player->handle);
2442 }
2443 if (player->has_video) {
2444 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002445 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002446 AmTsPlayer_stopVideoDecoding(player->handle);
2447 }
2448 if (player->has_audio) {
2449 player->has_audio = DVR_FALSE;
2450 AmTsPlayer_stopAudioDecoding(player->handle);
2451 }
hualing chendf118dd2020-05-21 15:49:11 +08002452 if (player->has_ad_audio) {
2453 player->has_ad_audio =DVR_FALSE;
2454 AmTsPlayer_disableADMix(player->handle);
2455 }
hualing chen266b9502020-04-04 17:39:39 +08002456
hualing chen86e7d482020-01-16 15:13:33 +08002457 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002458 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2459 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002460 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen87072a82020-03-12 16:20:12 +08002461 player->cur_segment_id = UINT64_MAX;
2462 player->segment_is_open = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08002463 DVR_PB_DEBUG("unlock");
2464 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002465 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002466 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002467}
2468/**\brief Start play audio
2469 * \param[in] handle playback handle
2470 * \param[in] params audio playback params,contains fmt and pid...
2471 * \retval DVR_SUCCESS On success
2472 * \return Error code
2473 */
hualing chen2aba4022020-03-02 13:49:55 +08002474
Wentao MA270dc0f2022-08-23 13:17:26 +08002475int 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 +08002476 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002477
2478 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002479 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002480 return DVR_FAILURE;
2481 }
hualing chen86e7d482020-01-16 15:13:33 +08002482 _start_playback_thread(handle);
2483 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002484 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002485 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002486
Wentao MA270dc0f2022-08-23 13:17:26 +08002487 if (VALID_PID(ad_param->pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08002488 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002489 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002490 AmTsPlayer_setADParams(player->handle, ad_param);
hualing chendf118dd2020-05-21 15:49:11 +08002491 AmTsPlayer_enableADMix(player->handle);
2492 }
hualing chen969fe7b2021-05-26 15:13:17 +08002493 if (VALID_PID(param->pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08002494 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08002495 player->has_audio = DVR_TRUE;
2496 AmTsPlayer_setAudioParams(player->handle, param);
Wentao MA5629ad82022-08-24 10:03:02 +08002497 if (player->audio_presentation_id > -1) {
2498 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2499 }
hualing chen969fe7b2021-05-26 15:13:17 +08002500 AmTsPlayer_startAudioDecoding(player->handle);
2501 }
hualing chendf118dd2020-05-21 15:49:11 +08002502
hualing chen86e7d482020-01-16 15:13:33 +08002503 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002504 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen040df222020-01-17 13:35:02 +08002505 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002506 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002507 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002508 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002509 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002510}
2511/**\brief Stop play audio
2512 * \param[in] handle playback handle
2513 * \retval DVR_SUCCESS On success
2514 * \return Error code
2515 */
hualing chen040df222020-01-17 13:35:02 +08002516int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2517 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002518
2519 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002520 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002521 return DVR_FAILURE;
2522 }
2523
hualing chen2aba4022020-03-02 13:49:55 +08002524 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002525 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002526 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002527 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002528 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002529 _stop_playback_thread(handle);
2530 } else {
2531 //do nothing.video is playing
2532 }
Wentao MA96f68962022-06-15 19:45:35 +08002533 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002534 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002535
hualing chenf00cdc82020-06-10 14:23:35 +08002536 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002537 player->has_audio = DVR_FALSE;
2538 AmTsPlayer_stopAudioDecoding(player->handle);
2539 }
hualing chen87072a82020-03-12 16:20:12 +08002540
hualing chendf118dd2020-05-21 15:49:11 +08002541 if (player->has_ad_audio) {
2542 player->has_ad_audio =DVR_FALSE;
2543 AmTsPlayer_disableADMix(player->handle);
2544 }
2545
hualing chen87072a82020-03-12 16:20:12 +08002546 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002547 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002548
Wentao MA96f68962022-06-15 19:45:35 +08002549 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002550 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002551 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002552}
2553/**\brief Start play video
2554 * \param[in] handle playback handle
2555 * \param[in] params video playback params,contains fmt and pid...
2556 * \retval DVR_SUCCESS On success
2557 * \return Error code
2558 */
hualing chen2aba4022020-03-02 13:49:55 +08002559int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002560 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002561
2562 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002563 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002564 return DVR_FAILURE;
2565 }
2566
hualing chen86e7d482020-01-16 15:13:33 +08002567 _start_playback_thread(handle);
2568 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002569 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002570 dvr_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002571 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002572 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002573 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002574 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002575
2576 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002577 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002578 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08002579 DVR_PB_INFO("settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002580 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2581 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002582 }
2583 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002584 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen040df222020-01-17 13:35:02 +08002585 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002586 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002587 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002588 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002589 return DVR_SUCCESS;
2590}
2591/**\brief Stop play video
2592 * \param[in] handle playback handle
2593 * \retval DVR_SUCCESS On success
2594 * \return Error code
2595 */
hualing chen040df222020-01-17 13:35:02 +08002596int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2597 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002598
2599 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002600 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002601 return DVR_FAILURE;
2602 }
2603
hualing chen86e7d482020-01-16 15:13:33 +08002604 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002605 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002606 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002607 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002608 _stop_playback_thread(handle);
2609 } else {
2610 //do nothing.audio is playing
2611 }
hualing chen7a56cba2020-04-14 14:09:27 +08002612
Wentao MA96f68962022-06-15 19:45:35 +08002613 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002614 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002615
hualing chen87072a82020-03-12 16:20:12 +08002616 player->has_video = DVR_FALSE;
2617
2618 AmTsPlayer_stopVideoDecoding(player->handle);
2619 //playback_device_video_stop(player->handle);
2620
2621 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002622 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002623
Wentao MA96f68962022-06-15 19:45:35 +08002624 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002625 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002626 return DVR_SUCCESS;
2627}
2628/**\brief Pause play
2629 * \param[in] handle playback handle
2630 * \param[in] flush whether its internal buffers should be flushed
2631 * \retval DVR_SUCCESS On success
2632 * \return Error code
2633 */
hualing chen040df222020-01-17 13:35:02 +08002634int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2635 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002636 DVR_UNUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002637 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002638 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002639 return DVR_FAILURE;
2640 }
hualing chenf00cdc82020-06-10 14:23:35 +08002641 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
Wentao MA96f68962022-06-15 19:45:35 +08002642 DVR_PB_INFO("player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002643 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002644 }
Wentao MA96f68962022-06-15 19:45:35 +08002645 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002646 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002647 DVR_PB_DEBUG("get lock");
hualing chen266b9502020-04-04 17:39:39 +08002648 if (player->has_video)
2649 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002650 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002651 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002652
2653 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002654 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2655 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2656 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002657 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002658 } else {
2659 player->cmd.last_cmd = player->cmd.cur_cmd;
2660 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2661 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002662 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002663 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002664 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002665 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002666
hualing chen86e7d482020-01-16 15:13:33 +08002667 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002668}
2669
hualing chen5cbe1a62020-02-10 16:36:36 +08002670//not add lock
2671static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2672{
2673 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2674
hualing chena540a7e2020-03-27 16:44:05 +08002675 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002676 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002677 return DVR_FAILURE;
2678 }
2679
hualing chen5cbe1a62020-02-10 16:36:36 +08002680 //get video params and audio params
Wentao MA96f68962022-06-15 19:45:35 +08002681 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002682 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08002683 am_tsplayer_video_params video_params;
2684 am_tsplayer_audio_params audio_params;
2685 am_tsplayer_audio_params ad_params;
hualing chencc91e1c2020-02-28 13:26:17 +08002686 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002687
Wentao MA270dc0f2022-08-23 13:17:26 +08002688 memset(&video_params, 0, sizeof(video_params));
2689 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002690
Wentao MA270dc0f2022-08-23 13:17:26 +08002691 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
Zhiqiang Han83923642023-11-03 12:06:48 +08002692 DVR_PB_INFO("unlock, _dvr_cmd: %#x", cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002693 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002694
Zhiqiang Han83923642023-11-03 12:06:48 +08002695 if (DVR_PLAYBACK_CMD_IS_V_RESTART(cmd) && DVR_PLAYBACK_CMD_IS_A_RESTART(cmd)) {
2696
2697 DVR_PB_INFO("do_cmd av_restart");
2698 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
2699
2700 } else if (cmd == DVR_PLAYBACK_CMD_FF || cmd == DVR_PLAYBACK_CMD_FB) {
2701
2702 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
2703
2704 } else if (cmd == DVR_PLAYBACK_CMD_START || cmd == DVR_PLAYBACK_CMD_STOP) {
2705
2706 //nop
2707
2708 } else {
2709
2710 if (DVR_PLAYBACK_CMD_IS_A_STOP(cmd)) {
2711 DVR_PB_INFO("do_cmd a_stop");
2712 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2713 }
2714
2715 if (DVR_PLAYBACK_CMD_IS_V_STOP(cmd)) {
2716 DVR_PB_INFO("do_cmd v_stop");
hualing chen2aba4022020-03-02 13:49:55 +08002717 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Zhiqiang Han83923642023-11-03 12:06:48 +08002718 }
2719
2720 if (DVR_PLAYBACK_CMD_IS_V_START(cmd)) {
2721 DVR_PB_INFO("do_cmd v_start");
Wentao MA270dc0f2022-08-23 13:17:26 +08002722 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
Zhiqiang Han83923642023-11-03 12:06:48 +08002723 }
2724
2725 if (DVR_PLAYBACK_CMD_IS_A_START(cmd)) {
2726 DVR_PB_INFO("do_cmd a_start");
Wentao MA270dc0f2022-08-23 13:17:26 +08002727 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
Zhiqiang Han83923642023-11-03 12:06:48 +08002728 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002729 }
Zhiqiang Han83923642023-11-03 12:06:48 +08002730
hualing chen5cbe1a62020-02-10 16:36:36 +08002731 return DVR_SUCCESS;
2732}
2733
2734/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002735 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002736 * \retval DVR_SUCCESS On success
2737 * \return Error code
2738 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002739int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2740 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002741 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002742 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002743 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002744 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002745 return DVR_FAILURE;
2746 }
2747
hualing chena991aa82021-08-16 10:21:15 +08002748 if (dvr_playback_check_limit(handle)) {
2749 //get id and pos to check if we can seek to this pos
Wentao MA96f68962022-06-15 19:45:35 +08002750 DVR_PB_INFO("player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002751 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2752 if (segmentid != player->cur_segment_id ||
2753 (segmentid == player->cur_segment_id &&
2754 pos > _dvr_get_cur_time(handle))) {
2755 //first to seek new pos and to resume
Wentao MA96f68962022-06-15 19:45:35 +08002756 DVR_PB_INFO("seek new pos and to resume");
hualing chena991aa82021-08-16 10:21:15 +08002757 dvr_playback_seek(handle, segmentid, pos);
2758 }
hualing chen7ea70a72021-09-09 11:25:13 +08002759 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002760 DVR_PB_INFO("player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002761 }
hualing chena991aa82021-08-16 10:21:15 +08002762
hualing chen5cbe1a62020-02-10 16:36:36 +08002763 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08002764 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002765 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002766 player->first_frame = 0;
2767 if (player->has_video)
2768 AmTsPlayer_pauseVideoDecoding(player->handle);
2769 if (player->has_audio)
2770 AmTsPlayer_pauseAudioDecoding(player->handle);
2771
hualing chen266b9502020-04-04 17:39:39 +08002772 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002773 DVR_PB_INFO("dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002774 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2775 AmTsPlayer_resumeVideoDecoding(player->handle);
2776 }
2777 if (player->has_audio) {
2778 AmTsPlayer_resumeAudioDecoding(player->handle);
2779 }
2780 //check is has audio param,if has audio .we need start audio,
2781 //we will stop audio when ff fb, if reach end, we will pause.so we need
2782 //start audio when resume play
2783
Wentao MA270dc0f2022-08-23 13:17:26 +08002784 am_tsplayer_video_params video_params;
2785 am_tsplayer_audio_params audio_params;
2786 am_tsplayer_audio_params ad_params;
hualing chen266b9502020-04-04 17:39:39 +08002787 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002788
Wentao MA270dc0f2022-08-23 13:17:26 +08002789 memset(&video_params, 0, sizeof(video_params));
2790 memset(&audio_params, 0, sizeof(audio_params));
2791 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
hualing chen266b9502020-04-04 17:39:39 +08002792 //valid audio pid, start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002793 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 +08002794 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002795 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002796 dvr_playback_change_seek_state(handle, ad_params.pid);
2797 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen969fe7b2021-05-26 15:13:17 +08002798 AmTsPlayer_enableADMix(player->handle);
2799 }
2800
Wentao MA270dc0f2022-08-23 13:17:26 +08002801 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 +08002802 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002803 dvr_playback_change_seek_state(handle, audio_params.pid);
2804 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002805 if (player->audio_presentation_id > -1) {
2806 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2807 }
hualing chen266b9502020-04-04 17:39:39 +08002808 AmTsPlayer_startAudioDecoding(player->handle);
2809 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08002810 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 +08002811 }
hualing chendf118dd2020-05-21 15:49:11 +08002812
hualing chen87072a82020-03-12 16:20:12 +08002813 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2814 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2815 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002816 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002817 } else {
2818 player->cmd.last_cmd = player->cmd.cur_cmd;
2819 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2820 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002821 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002822 }
Wentao MA96f68962022-06-15 19:45:35 +08002823 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002824 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002825 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
Wentao MA96f68962022-06-15 19:45:35 +08002826 DVR_PB_INFO("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002827 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002828 player->first_frame = 0;
2829 if (player->has_video)
2830 AmTsPlayer_pauseVideoDecoding(player->handle);
2831 if (player->has_audio)
2832 AmTsPlayer_pauseAudioDecoding(player->handle);
2833
Zhiqiang Hane82b61f2023-12-27 16:05:05 +08002834 DVR_PB_INFO("set start state cur cmd[%d]", player->cmd.cur_cmd);
2835 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2836 _dvr_cmd(handle, player->cmd.cur_cmd);
2837
hualing chene41f4372020-06-06 16:29:17 +08002838 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002839 DVR_PB_INFO("dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002840 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002841 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002842 }
hualing chen041c4092020-04-05 15:11:50 +08002843 if (player->has_audio)
2844 AmTsPlayer_resumeAudioDecoding(player->handle);
Zhiqiang Hane82b61f2023-12-27 16:05:05 +08002845
hualing chend1686e52022-01-05 17:10:42 +08002846 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002847 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002848 DVR_PB_INFO("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002849 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002850 } else {
2851 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2852 {
Wentao MA96f68962022-06-15 19:45:35 +08002853 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002854 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002855 player->first_frame = 0;
2856 if (player->has_video)
2857 AmTsPlayer_pauseVideoDecoding(player->handle);
2858 if (player->has_audio)
2859 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002860 //clear flag
Wentao MA96f68962022-06-15 19:45:35 +08002861 DVR_PB_INFO("clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002862 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2863 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002864 if (player->has_video) {
2865 AmTsPlayer_resumeVideoDecoding(player->handle);
2866 }
2867 if (player->has_audio)
2868 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002869 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002870 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002871 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002872 }
2873 return DVR_SUCCESS;
2874}
2875
hualing chena540a7e2020-03-27 16:44:05 +08002876static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2877
2878 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2879 DVR_PlaybackSegmentInfo_t *segment = NULL;
2880 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2881 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2882
wentao.mafd5283f2022-10-14 09:51:13 +08002883 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002884 // prefetch() here incurring self_assign is used to avoid some compiling
2885 // warnings.
2886 // coverity[self_assign]
hualing chena540a7e2020-03-27 16:44:05 +08002887 list_for_each_entry(segment, &player->segment_list, head)
2888 {
2889 if (segment->segment_id == segment_id) {
2890 cur_segment = segment;
2891 }
2892 if (segment->segment_id == set_seg_id) {
2893 set_segment = segment;
2894 }
2895 if (cur_segment != NULL && set_segment != NULL) {
2896 break;
2897 }
2898 }
2899 if (cur_segment == NULL || set_segment == NULL) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002900 DVR_PB_INFO("set segment or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002901 return DVR_TRUE;
2902 }
2903 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2904 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2905 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2906 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
Wentao MA96f68962022-06-15 19:45:35 +08002907 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 +08002908 return DVR_TRUE;
2909 }
Wentao MA96f68962022-06-15 19:45:35 +08002910 DVR_PB_INFO("play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002911 return DVR_FALSE;
2912}
2913
hualing chen03fd4942021-07-15 15:56:41 +08002914/**\brief set limit
2915 * \param[in] handle playback handle
2916 * \param[in] rec start time ms
2917 * \param[in] rec limit time ms
2918 * \retval DVR_SUCCESS On success
2919 * \return Error code
2920 */
hualing chen7ea70a72021-09-09 11:25:13 +08002921int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08002922{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2923
2924 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002925 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08002926 return DVR_FAILURE;
2927 }
hualing chen7ea70a72021-09-09 11:25:13 +08002928 _dvr_getClock_sec();
Wentao MA96f68962022-06-15 19:45:35 +08002929 DVR_PB_INFO("lock time %lu limit: %u player->state:%d", time, limit, player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002930 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002931 player->rec_start = time;
2932 player->limit = limit;
Wentao MA96f68962022-06-15 19:45:35 +08002933 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002934 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002935 return DVR_SUCCESS;
2936}
2937
hualing chen5cbe1a62020-02-10 16:36:36 +08002938/**\brief seek
2939 * \param[in] handle playback handle
2940 * \param[in] time_offset time offset base cur segment
2941 * \retval DVR_SUCCESS On success
2942 * \return Error code
2943 */
hualing chencc91e1c2020-02-28 13:26:17 +08002944int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002945 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002946 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08002947 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002948 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002949 return DVR_FAILURE;
2950 }
2951
Wentao MA96f68962022-06-15 19:45:35 +08002952 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 +08002953 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002954
hualing chena540a7e2020-03-27 16:44:05 +08002955 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
Wentao MA96f68962022-06-15 19:45:35 +08002956 DVR_PB_INFO("player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002957
hualing chen5cbe1a62020-02-10 16:36:36 +08002958 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08002959 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002960 if (ret ==DVR_FAILURE) {
wentao.maa210e5e2022-10-12 16:10:03 +08002961 DVR_PB_ERROR("unlock seek error at open segment");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002962 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002963 return DVR_FAILURE;
2964 }
2965 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
Wentao MAf35c3882023-04-17 12:36:19 +08002966 if (segment_ongoing(player->segment_handle) == DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08002967 DVR_PB_INFO("is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002968 time_offset = _dvr_get_end_time(handle);
2969 } else {
wentao.maa210e5e2022-10-12 16:10:03 +08002970 DVR_PB_ERROR("is not ongoing segment when seek end, return failure");
Zhiqiang Han447cff02022-12-15 11:13:41 +08002971 dvr_mutex_unlock(&player->lock);
wentao.maa210e5e2022-10-12 16:10:03 +08002972 return DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08002973 }
2974 }
2975
Wentao MA96f68962022-06-15 19:45:35 +08002976 DVR_PB_INFO("seek open id[%lld]flag[0x%x] time_offset %u",
hualing chen03fd4942021-07-15 15:56:41 +08002977 player->cur_segment.segment_id,
2978 player->cur_segment.flags,
2979 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08002980 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002981 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2982 //forward playback.not seek end of file
2983 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2984 //default -2000ms
2985 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2986 }
hualing chen86e7d482020-01-16 15:13:33 +08002987 }
Wentao MA01de0e62022-01-10 18:48:23 +08002988 // Seek can be regarded as a new playback, so keep the start segment_id for it also
hualing chen8a657f32021-08-30 13:12:49 +08002989 if (player->need_seek_start == DVR_TRUE) {
2990 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
Wentao MA01de0e62022-01-10 18:48:23 +08002991 player->first_start_id = player->cur_segment.segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08002992 }
hualing chen2aba4022020-03-02 13:49:55 +08002993 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002994 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002995 player->ts_cache_len = 0;
Wentao MAf35c3882023-04-17 12:36:19 +08002996 int offset = segment_seek(player->segment_handle, (uint64_t)time_offset, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002997 DVR_PB_ERROR("seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08002998 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002999 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08003000
hualing chen2aba4022020-03-02 13:49:55 +08003001 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08003002
3003 player->last_send_time_id = UINT64_MAX;
Wentao MA270dc0f2022-08-23 13:17:26 +08003004 player->last_segment_total = 0LL;
hualing chen03fd4942021-07-15 15:56:41 +08003005 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08003006 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08003007 player->fffb_current = _dvr_time_getClock();
3008 player->fffb_start = player->fffb_current;
3009 player->fffb_start_pcr = _dvr_get_cur_time(handle);
3010 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08003011 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08003012 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003013 //only seek file,not start
Wentao MA96f68962022-06-15 19:45:35 +08003014 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003015 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003016 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08003017 }
hualing chen86e7d482020-01-16 15:13:33 +08003018 //stop play
Wentao MA96f68962022-06-15 19:45:35 +08003019 DVR_PB_ERROR("seek stop play, not inject data has video[%d]audio[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003020 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08003021
hualing chen266b9502020-04-04 17:39:39 +08003022 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08003023 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003024 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003025 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003026 }
3027
hualing chen40dd5462021-11-26 19:56:20 +08003028
hualing chen266b9502020-04-04 17:39:39 +08003029 if (player->has_audio) {
3030 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003031 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003032 }
hualing chendf118dd2020-05-21 15:49:11 +08003033 if (player->has_ad_audio) {
3034 player->has_ad_audio =DVR_FALSE;
3035 AmTsPlayer_disableADMix(player->handle);
3036 }
3037
hualing chen86e7d482020-01-16 15:13:33 +08003038 //start play
Wentao MA270dc0f2022-08-23 13:17:26 +08003039 am_tsplayer_video_params video_params;
3040 am_tsplayer_audio_params audio_params;
3041 am_tsplayer_audio_params ad_params;
hualing chenb31a6c62020-01-13 17:27:00 +08003042
Wentao MA270dc0f2022-08-23 13:17:26 +08003043 memset(&video_params, 0, sizeof(video_params));
3044 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003045
hualing chen040df222020-01-17 13:35:02 +08003046 player->cur_segment_id = segment_id;
3047
3048 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08003049 //get segment info and audio video pid fmt ;
Wentao MA270dc0f2022-08-23 13:17:26 +08003050 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08003051 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003052 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chena5f03222021-12-02 11:22:35 +08003053 //audio and video pid is all invalid, return error.
Wentao MA270dc0f2022-08-23 13:17:26 +08003054 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 +08003055 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08003056 return -1;
3057 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003058 DVR_PB_ERROR("seek start[0x%x]", video_params.pid);
hualing chen86e7d482020-01-16 15:13:33 +08003059 //add
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003060 int v_restarted = 0;
3061 int a_restarted = 0;
hualing chen040df222020-01-17 13:35:02 +08003062 if (sync == DVR_PLAYBACK_SYNC) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003063 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003064 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08003065 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08003066 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08003067 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08003068 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003069 //if is pause state. we need set trick mode.
Wentao MA96f68962022-06-15 19:45:35 +08003070 DVR_PB_INFO("seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003071 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08003072 }
Wentao MA96f68962022-06-15 19:45:35 +08003073 DVR_PB_INFO("start video");
Wentao MA270dc0f2022-08-23 13:17:26 +08003074 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003075 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003076 AmTsPlayer_startVideoDecoding(player->handle);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003077 v_restarted = 1;
hualing chene41f4372020-06-06 16:29:17 +08003078 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
3079 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
3080 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
3081 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
3082 AmTsPlayer_stopFast(player->handle);
3083 }
hualing chen266b9502020-04-04 17:39:39 +08003084 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08003085 } else {
3086 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08003087 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003088 if (VALID_PID(ad_params.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08003089 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003090 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003091 dvr_playback_change_seek_state(handle, ad_params.pid);
3092 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003093 AmTsPlayer_enableADMix(player->handle);
3094 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003095 if (VALID_PID(audio_params.pid) && player->speed == 1.0) {
Wentao MA96f68962022-06-15 19:45:35 +08003096 DVR_PB_INFO("start audio seek");
Wentao MA270dc0f2022-08-23 13:17:26 +08003097 dvr_playback_change_seek_state(handle, audio_params.pid);
3098 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003099 if (player->audio_presentation_id > -1) {
3100 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3101 }
hualing chen969fe7b2021-05-26 15:13:17 +08003102 AmTsPlayer_startAudioDecoding(player->handle);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003103 a_restarted = 1;
hualing chen969fe7b2021-05-26 15:13:17 +08003104 player->has_audio = DVR_TRUE;
3105 }
hualing chen43a89bc2022-01-19 14:31:20 +08003106#ifdef AVSYNC_USED_PCR
3107 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003108 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003109 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3110 }
3111#endif
hualing chen86e7d482020-01-16 15:13:33 +08003112 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003113 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Zhiqiang Han83923642023-11-03 12:06:48 +08003114
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003115 if (v_restarted) {
Zhiqiang Han83923642023-11-03 12:06:48 +08003116 DVR_PLAYBACK_CMD_RESET_V(player->cmd.cur_cmd);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003117 }
3118 if (a_restarted) {
Zhiqiang Han83923642023-11-03 12:06:48 +08003119 DVR_PLAYBACK_CMD_RESET_A(player->cmd.cur_cmd);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003120 }
Zhiqiang Han83923642023-11-03 12:06:48 +08003121
hualing chen2aba4022020-03-02 13:49:55 +08003122 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00003123 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
Wentao MA270dc0f2022-08-23 13:17:26 +08003124 if (VALID_PID(audio_params.pid) || VALID_PID(video_params.pid))
hualing chena5f03222021-12-02 11:22:35 +08003125 player->seek_pause = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08003126 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 +08003127 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
Wentao MA16f870e2022-09-09 11:00:22 +08003128 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chen31140872020-03-25 12:29:26 +08003129 player->speed > 1.0f||
3130 player->speed <= -1.0f) {
Wentao MA96f68962022-06-15 19:45:35 +08003131 DVR_PB_INFO("not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003132 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003133 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003134 DVR_PB_INFO("set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003135 player->cmd.last_cmd = player->cmd.cur_cmd;
3136 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3137 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003138 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen2aba4022020-03-02 13:49:55 +08003139 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003140 player->last_send_time_id = UINT64_MAX;
Wentao MA96f68962022-06-15 19:45:35 +08003141 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003142 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003143
3144 return DVR_SUCCESS;
3145}
hualing chen5cbe1a62020-02-10 16:36:36 +08003146
Wentao MAac5ea062022-08-11 11:44:27 +08003147// Get current playback time position of the ongoing segment.
3148// Notice the return value may be negative. This is because previous segment's
3149// data cached in demux buffer need to be considered.
hualing chen5cbe1a62020-02-10 16:36:36 +08003150static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3151 //get cur time of segment
3152 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003153
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003154 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003155 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003156 return DVR_FAILURE;
3157 }
3158
Wentao MA270dc0f2022-08-23 13:17:26 +08003159 int64_t cache = 0;//default es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003160 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003161 loff_t pos = segment_tell_position(player->segment_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003162 uint64_t cur = 0;
3163 if (player->ts_cache_len > 0 && pos < 0) {
3164 //this case is open new segment end,but cache data is last segment.
3165 //we need used last segment len to send play time.
3166 cur = 0;
3167 } else {
Wentao MAf35c3882023-04-17 12:36:19 +08003168 cur = segment_tell_position_time(player->segment_handle, pos);
hualing chena5f03222021-12-02 11:22:35 +08003169 }
hualing chen21a40372021-10-29 11:07:26 +08003170 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003171 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08003172 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 +08003173 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3174 cache = 0;
3175 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003176 int cur_time = (int)(cur > cache ? cur - cache : 0);
3177 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003178}
3179
Wentao MAac5ea062022-08-11 11:44:27 +08003180// Get current playback time position of the ongoing segment.
3181// Notice the return value may be negative. This is because previous segment's
3182// data cached in demux buffer need to be considered.
hualing chen969fe7b2021-05-26 15:13:17 +08003183static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3184 //get cur time of segment
3185 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA804bab12022-11-29 10:01:26 +08003186 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MAf35c3882023-04-17 12:36:19 +08003187 DVR_RETURN_IF_FALSE(player->segment_handle != NULL);
hualing chen969fe7b2021-05-26 15:13:17 +08003188
hualing chen969fe7b2021-05-26 15:13:17 +08003189 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003190 const loff_t pos = segment_tell_position(player->segment_handle);
3191 const uint64_t cur = segment_tell_position_time(player->segment_handle, pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003192 pthread_mutex_unlock(&player->segment_lock);
Wentao MA01de0e62022-01-10 18:48:23 +08003193
Wentao MA804bab12022-11-29 10:01:26 +08003194 int cache = 0;
3195 get_effective_tsplayer_delay_time(player, &cache);
Wentao MA01de0e62022-01-10 18:48:23 +08003196
hualing chen969fe7b2021-05-26 15:13:17 +08003197 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3198 cache = 0;
3199 }
Wentao MA804bab12022-11-29 10:01:26 +08003200
Wentao MA3e2dc452022-12-20 11:17:16 +08003201 int cur_time = (int)(cur - cache);
Wentao MA804bab12022-11-29 10:01:26 +08003202 *id = player->cur_segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003203
Wentao MA3e2dc452022-12-20 11:17:16 +08003204 if (*id == 0 && cur_time<0) {
3205 cur_time = 0;
3206 }
3207
Wentao MA80179512022-11-03 12:20:03 +08003208 DVR_PB_INFO("***get playback slider position within segment. segment_id [%lld],"
wentao.ma4ee43022022-12-14 13:22:57 +08003209 " segment_slider_pos[%7d ms] = segment_read_pos[%7lld ms] - tsplayer_cache_len[%5ld ms],"
Wentao MA80179512022-11-03 12:20:03 +08003210 " last id [%lld] pos [%lld]",
3211 player->cur_segment_id,cur_time,cur,cache,player->last_send_time_id,pos);
Wentao MA804bab12022-11-29 10:01:26 +08003212
hualing chen969fe7b2021-05-26 15:13:17 +08003213 return cur_time;
3214}
3215
hualing chencc91e1c2020-02-28 13:26:17 +08003216//get current segment current pcr time of read pos
3217static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3218 //get cur time of segment
3219 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAf35c3882023-04-17 12:36:19 +08003220 DVR_RETURN_IF_FALSE(player != NULL);
3221 DVR_RETURN_IF_FALSE(player->segment_handle != NULL);
hualing chena540a7e2020-03-27 16:44:05 +08003222
3223 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003224 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003225 return DVR_FAILURE;
3226 }
3227
hualing chen2aba4022020-03-02 13:49:55 +08003228 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003229 uint64_t end = segment_tell_total_time(player->segment_handle);
hualing chen2aba4022020-03-02 13:49:55 +08003230 pthread_mutex_unlock(&player->segment_lock);
3231 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003232}
3233
hualing chen03fd4942021-07-15 15:56:41 +08003234DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3235{
3236 //check is set limit info
3237 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3238
3239 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003240 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003241 return DVR_FALSE;
3242 }
3243 if (player->rec_start > 0 || player->limit > 0) {
3244 return DVR_TRUE;
3245 }
3246 return DVR_FALSE;
3247}
3248
3249/**\brief set DVR playback calculate expired time len
3250 * \param[in] handle, DVR playback session handle
3251 * \return DVR_SUCCESS on success
3252 * \return error code on failure
3253 */
hualing chen7ea70a72021-09-09 11:25:13 +08003254uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003255{
3256 //calculate expired time to play
3257 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003258 uint32_t cur_time;
3259 uint32_t tmp_time;
3260 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003261 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003262 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003263 return expired;
3264 }
hualing chen7ea70a72021-09-09 11:25:13 +08003265 if (player->rec_start == 0 || player->limit == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003266 DVR_PB_INFO("rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003267 return expired;
3268 }
3269 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003270 cur_time = _dvr_getClock_sec();
3271 if ((cur_time - player->rec_start) > player->limit) {
3272 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3273 expired = *(int*)&tmp_time;
Wentao MA96f68962022-06-15 19:45:35 +08003274 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 +08003275 cur_time,
3276 player->rec_start,
3277 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003278 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3279 }
hualing chen03fd4942021-07-15 15:56:41 +08003280 return expired;
3281}
3282
3283/**\brief set DVR playback obsolete time
3284 * \param[in] handle, DVR playback session handle
3285 * \param[in] obsolete, obsolete len
3286 * \return DVR_SUCCESS on success
3287 * \return error code on failure
3288 */
3289int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3290{
3291 int expired = 0;
3292 //calculate expired time to play
3293 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3294
3295 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003296 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003297 return DVR_FALSE;
3298 }
3299 //get system time
Wentao MA96f68962022-06-15 19:45:35 +08003300 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003301 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003302 player->obsolete = obsolete;
Wentao MA96f68962022-06-15 19:45:35 +08003303 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003304 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003305 return expired;
3306}
3307
3308/**\brief update DVR playback newest segment duration
3309 * \param[in] handle, DVR playback session handle
3310 * \param[in] segmentid, newest segment id
3311 * \param[in] dur dur time ms
3312 * \return DVR_SUCCESS on success
3313 * \return error code on failure
3314 */
3315int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3316uint64_t segmentid, int dur)
3317{
3318 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3319 DVR_PlaybackSegmentInfo_t *segment;
3320 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3321
3322 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003323 DVR_PB_INFO(" player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003324 return DVR_FAILURE;
3325 }
3326 //update the newest segment duration on timeshift mode
wentao.mafd5283f2022-10-14 09:51:13 +08003327 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003328 // prefetch() here incurring self_assign is used to avoid some compiling
3329 // warnings.
3330 // coverity[self_assign]
hualing chen03fd4942021-07-15 15:56:41 +08003331 list_for_each_entry(segment, &player->segment_list, head)
3332 {
3333 if (segment->segment_id == segmentid) {
3334 segment->duration = dur;
3335 break;
3336 }
3337 pre_segment = segment;
3338 }
3339
3340 return DVR_SUCCESS;
3341}
3342
hualing chen7ea70a72021-09-09 11:25:13 +08003343static uint32_t dvr_playback_calculate_last_valid_segment(
3344 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003345{
hualing chen7ea70a72021-09-09 11:25:13 +08003346 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003347 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003348 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003349 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003350 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003351 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3352
3353 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003354 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003355 return DVR_FAILURE;
3356 }
3357 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003358 if (expired == 0) {
3359 *segmentid = player->cur_segment_id;
3360 *pos = 0;
3361 return DVR_SUCCESS;
3362 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003363 DVR_PlaybackSegmentInfo_t *p_seg;
wentao.mafd5283f2022-10-14 09:51:13 +08003364 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003365 // prefetch() here incurring self_assign is used to avoid some compiling
3366 // warnings.
3367 // coverity[self_assign]
Wentao MA270dc0f2022-08-23 13:17:26 +08003368 list_for_each_entry_reverse(p_seg, &player->segment_list, head) {
3369 segment_id = p_seg->segment_id;
hualing chen03fd4942021-07-15 15:56:41 +08003370
Wentao MA270dc0f2022-08-23 13:17:26 +08003371 if ((player->obsolete + pre_off + p_seg->duration) > expired)
hualing chen03fd4942021-07-15 15:56:41 +08003372 break;
3373
Wentao MA270dc0f2022-08-23 13:17:26 +08003374 last_segment_id = p_seg->segment_id;
3375 pre_off += p_seg->duration;
hualing chen03fd4942021-07-15 15:56:41 +08003376 }
3377
3378 if (last_segment_id == segment_id) {
3379 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3380 off = expired;
3381 } else if (player->obsolete >= expired) {
3382 off = 0;
3383 } else {
3384 off = expired - pre_off - player->obsolete;
3385 }
3386 *segmentid = segment_id;
3387 *pos = off;
3388 return DVR_SUCCESS;
3389}
3390
hualing chen4b7c15d2020-04-07 16:13:48 +08003391#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003392//start replay
3393static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3394
3395 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3396 //calculate pcr seek time
3397 int t_diff = 0;
3398 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003399 uint64_t segmentid = 0;
3400 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003401 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003402 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003403 return DVR_FAILURE;
3404 }
3405
hualing chen5cbe1a62020-02-10 16:36:36 +08003406 if (player->fffb_start == -1) {
3407 //set fffb start time ms
3408 player->fffb_start = _dvr_time_getClock();
3409 player->fffb_current = player->fffb_start;
3410 //get segment current time pos
3411 player->fffb_start_pcr = _dvr_get_cur_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003412 DVR_PB_INFO("calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
hualing chen03fd4942021-07-15 15:56:41 +08003413 player->fffb_start_pcr, player->speed);
hualing chene41f4372020-06-06 16:29:17 +08003414 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003415 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003416 } else {
3417 player->fffb_current = _dvr_time_getClock();
3418 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003419 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003420 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003421 if (seek_time <= 0) {
3422 //need seek to pre one segment
3423 seek_time = 0;
3424 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003425 //seek segment pos
Wentao MAf35c3882023-04-17 12:36:19 +08003426 if (player->segment_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003427 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003428 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003429 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3430 //set seek time to 0;
Wentao MA96f68962022-06-15 19:45:35 +08003431 DVR_PB_INFO("segment seek to 0 at fb mode [%d]id[%lld]",
hualing chen03fd4942021-07-15 15:56:41 +08003432 seek_time,
3433 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003434 seek_time = 0;
3435 }
hualing chen03fd4942021-07-15 15:56:41 +08003436 if (IS_FB(player->speed)
3437 && dvr_playback_check_limit(handle)) {
3438 //fb case.check expired time
3439 //get id and pos to check if we can seek to this pos
3440 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3441 //case cur id < segment id
3442 if (player->cur_segment_id < segmentid) {
3443 //expired ts data is player,return error
3444 //
3445 pthread_mutex_unlock(&player->segment_lock);
3446 return 0;
3447 } else if (player->cur_segment_id == segmentid) {
3448 //id is same,compare seek pos
3449 if (seek_time < pos) {
3450 //expired ts data is player,return error
3451 //
3452 pthread_mutex_unlock(&player->segment_lock);
3453 return 0;
3454 }
3455 }
3456 //case can play
3457 }
Wentao MAf35c3882023-04-17 12:36:19 +08003458 if (segment_seek(player->segment_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
hualing chen041c4092020-04-05 15:11:50 +08003459 seek_time = 0;
3460 }
hualing chen2aba4022020-03-02 13:49:55 +08003461 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003462 } else {
3463 //
Wentao MA96f68962022-06-15 19:45:35 +08003464 DVR_PB_INFO("segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003465 }
Wentao MA96f68962022-06-15 19:45:35 +08003466 DVR_PB_INFO("calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003467 seek_time,
3468 player->speed,
3469 player->cur_segment_id,
3470 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003471 }
hualing chen2aba4022020-03-02 13:49:55 +08003472 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003473}
3474
3475
3476//start replay
3477static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3478 //
3479 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003480
3481 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003482 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003483 return DVR_FAILURE;
3484 }
3485
hualing chen5cbe1a62020-02-10 16:36:36 +08003486 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003487 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08003488 DVR_PB_INFO("fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003489 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003490 AmTsPlayer_stopVideoDecoding(player->handle);
3491 }
3492 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003493 DVR_PB_INFO("fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003494 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003495 AmTsPlayer_stopAudioDecoding(player->handle);
3496 }
hualing chendf118dd2020-05-21 15:49:11 +08003497 if (player->has_ad_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003498 DVR_PB_INFO("fffb stop audio");
hualing chendf118dd2020-05-21 15:49:11 +08003499 player->has_ad_audio =DVR_FALSE;
3500 AmTsPlayer_disableADMix(player->handle);
3501 }
hualing chen2aba4022020-03-02 13:49:55 +08003502
hualing chen5cbe1a62020-02-10 16:36:36 +08003503 //start video and audio
3504
Wentao MA270dc0f2022-08-23 13:17:26 +08003505 am_tsplayer_video_params video_params;
3506 am_tsplayer_audio_params audio_params;
3507 am_tsplayer_audio_params ad_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003508
Wentao MA270dc0f2022-08-23 13:17:26 +08003509 memset(&video_params, 0, sizeof(video_params));
3510 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003511
hualing chen87072a82020-03-12 16:20:12 +08003512 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003513
3514 //get segment info and audio video pid fmt ;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003515 //dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08003516 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003517 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003518 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
3519 //audio and video pids are all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003520 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003521 return -1;
3522 }
3523
Wentao MA270dc0f2022-08-23 13:17:26 +08003524 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003525 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003526 DVR_PB_INFO("fffb start video");
3527 //DVR_PB_INFO("fffb start video and save last frame");
hualing chen0888c032020-12-18 17:54:57 +08003528 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003529 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003530 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
Wentao MA270dc0f2022-08-23 13:17:26 +08003531 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003532 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003533 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003534 //playback_device_video_start(player->handle , &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003535 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003536 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003537 }
hualing chen31140872020-03-25 12:29:26 +08003538 //fffb mode need stop fast;
Wentao MA96f68962022-06-15 19:45:35 +08003539 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003540 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003541 return 0;
3542}
3543
3544static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3545 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003546 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003547 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003548 return DVR_FAILURE;
3549 }
3550
3551 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003552 DVR_PB_INFO("lock speed [%f]", player->speed);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003553 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003554
hualing chen2aba4022020-03-02 13:49:55 +08003555 int seek_time = _dvr_playback_calculate_seekpos(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003556 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 +08003557
hualing chen87072a82020-03-12 16:20:12 +08003558 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3559 //seek time set 0
3560 seek_time = 0;
3561 }
hualing chen041c4092020-04-05 15:11:50 +08003562 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003563 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3564 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003565 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
wentao.ma4ee43022022-12-14 13:22:57 +08003566
3567 // An fffb_replay is required here to help finish the last FB play
3568 // at beginning position of a recording. In addition to function
3569 // correctness, another benefit is that after play, demux buffer
3570 // is cleared due to stopVideoDecoding invocation in the process.
3571 // The following resume operation will not be affected by the invalid
3572 // cache length.
3573 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
3574 _dvr_playback_fffb_replay(handle);
3575
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003576 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003577 DVR_PB_DEBUG("unlock");
Wentao MAfae6ce82023-12-29 17:55:55 +08003578#ifdef FOR_OTT_49490
Wentao MA75775d22023-09-25 16:53:24 +08003579 DVR_PlaybackSpeed_t normal_speed = {PLAYBACK_SPEED_X1,0};
3580 DVR_PB_INFO("Change to normal speed due to FB reaching beginning");
3581 dvr_playback_set_speed((DVR_PlaybackHandle_t)player,normal_speed);
Wentao MA9e31f692023-09-26 17:42:18 +08003582
3583 {
3584 DVR_Play_Notify_t notify;
3585 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
3586 notify.event = DVR_PLAYBACK_EVENT_TIMESHIFT_FR_REACHED_BEGIN;
3587 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, notify.event, &notify, 0);
3588 }
Wentao MA75775d22023-09-25 16:53:24 +08003589#else
Wentao MA9e31f692023-09-26 17:42:18 +08003590 DVR_PB_INFO("Change to pause due to FB reaching beginning");
hualing chen87072a82020-03-12 16:20:12 +08003591 dvr_playback_pause(handle, DVR_FALSE);
Wentao MA75775d22023-09-25 16:53:24 +08003592#endif
Wentao MA9e31f692023-09-26 17:42:18 +08003593 {
3594 //send event here and pause
3595 DVR_Play_Notify_t notify;
3596 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
3597 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
3598 //get play statue not here
3599 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
3600 DVR_PB_INFO("*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
3601 }
hualing chen2aba4022020-03-02 13:49:55 +08003602 return DVR_SUCCESS;
3603 }
hualing chen2932d372020-04-29 13:44:00 +08003604 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003605 _dvr_init_fffb_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003606 DVR_PB_INFO("*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003607 }
3608 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003609 _dvr_playback_fffb_replay(handle);
3610
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003611 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003612 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003613
hualing chen5cbe1a62020-02-10 16:36:36 +08003614 return DVR_SUCCESS;
3615}
3616
hualing chen87072a82020-03-12 16:20:12 +08003617//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003618static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003619 //
3620 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003621
3622 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003623 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003624 return DVR_FAILURE;
3625 }
3626
hualing chen5cbe1a62020-02-10 16:36:36 +08003627 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003628 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003629 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003630 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003631 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003632 }
3633
3634 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003635 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003636 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003637 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003638 //start video and audio
3639
Wentao MA270dc0f2022-08-23 13:17:26 +08003640 am_tsplayer_video_params video_params;
3641 am_tsplayer_audio_params audio_params;
3642 am_tsplayer_audio_params ad_params;
hualing chen87072a82020-03-12 16:20:12 +08003643 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003644
Wentao MA270dc0f2022-08-23 13:17:26 +08003645 memset(&video_params, 0, sizeof(video_params));
3646 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003647
hualing chen5cbe1a62020-02-10 16:36:36 +08003648 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08003649 DVR_PB_INFO("into");
Wentao MA270dc0f2022-08-23 13:17:26 +08003650 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003651 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003652 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003653 //audio and video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003654 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003655 return -1;
3656 }
3657
Wentao MA270dc0f2022-08-23 13:17:26 +08003658 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003659 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003660 if (trick == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003661 DVR_PB_INFO("settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003662 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003663 }
hualing chen266b9502020-04-04 17:39:39 +08003664 else {
hualing chen2aba4022020-03-02 13:49:55 +08003665 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003666 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003667 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003668 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003669 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003670 }
hualing chena540a7e2020-03-27 16:44:05 +08003671
3672 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
Wentao MA96f68962022-06-15 19:45:35 +08003673 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08003674 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003675 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003676 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08003677 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08003678 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003679 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003680 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003681 AmTsPlayer_enableADMix(player->handle);
3682 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003683 if (VALID_PID(audio_params.pid)) {
hualing chen969fe7b2021-05-26 15:13:17 +08003684 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003685 DVR_PB_INFO("start audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003686 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003687 if (player->audio_presentation_id > -1) {
3688 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3689 }
hualing chen969fe7b2021-05-26 15:13:17 +08003690 AmTsPlayer_startAudioDecoding(player->handle);
3691 }
hualing chendf118dd2020-05-21 15:49:11 +08003692
Wentao MA96f68962022-06-15 19:45:35 +08003693 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003694 AmTsPlayer_stopFast(player->handle);
3695 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3696 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3697 }
hualing chen43a89bc2022-01-19 14:31:20 +08003698#ifdef AVSYNC_USED_PCR
3699 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003700 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003701 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3702 }
3703#endif
hualing chen2aba4022020-03-02 13:49:55 +08003704 player->cmd.last_cmd = player->cmd.cur_cmd;
3705 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003706 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003707 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen5cbe1a62020-02-10 16:36:36 +08003708 return 0;
3709}
3710
3711
hualing chenb31a6c62020-01-13 17:27:00 +08003712/**\brief Set play speed
3713 * \param[in] handle playback handle
3714 * \param[in] speed playback speed
3715 * \retval DVR_SUCCESS On success
3716 * \return Error code
3717 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003718int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3719
3720 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003721
3722 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003723 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003724 return DVR_FAILURE;
3725 }
3726
hualing chena540a7e2020-03-27 16:44:05 +08003727 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08003728 DVR_PB_INFO(" func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003729 return DVR_FAILURE;
3730 }
hualing chenf00cdc82020-06-10 14:23:35 +08003731 if (speed.speed.speed == player->cmd.speed.speed.speed) {
Wentao MA96f68962022-06-15 19:45:35 +08003732 DVR_PB_INFO(" func: eq speed [%d]", speed.speed.speed);
hualing chenf00cdc82020-06-10 14:23:35 +08003733 return DVR_SUCCESS;
3734 }
Wentao MA96f68962022-06-15 19:45:35 +08003735 DVR_PB_INFO("lock func: speed [%d]", speed.speed.speed);
hualing chen1679f812021-11-08 15:17:46 +08003736
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003737 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003738 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3739 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3740 player->cmd.last_cmd = player->cmd.cur_cmd;
3741 }
hualing chene41f4372020-06-06 16:29:17 +08003742
hualing chen31140872020-03-25 12:29:26 +08003743 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003744 IS_KERNEL_SPEED(speed.speed.speed) ) {
3745 //case 1. not start play.only set speed
3746 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3747 //only set speed.and return;
3748 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3749 player->cmd.speed.speed = speed.speed;
3750 player->speed = (float)speed.speed.speed/(float)100;
3751 player->fffb_play = DVR_FALSE;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003752 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003753 DVR_PB_DEBUG("unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003754 return DVR_SUCCESS;
3755 }
3756 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003757 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3758 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003759 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003760 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3761 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003762 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003763 AmTsPlayer_stopFast(player->handle);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003764 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003765 DVR_PB_DEBUG("unlock ---\r\n");
Wentao MA270dc0f2022-08-23 13:17:26 +08003766 _dvr_cmd(handle, DVR_PLAYBACK_CMD_A_START);
Wentao MA96f68962022-06-15 19:45:35 +08003767 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003768 dvr_mutex_lock(&player->lock);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003769 } else {
3770 //set play speed and if audio is start, stop audio.
3771 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003772 DVR_PB_INFO("fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003773 AmTsPlayer_stopAudioDecoding(player->handle);
3774 player->has_audio = DVR_FALSE;
3775 }
Wentao MA96f68962022-06-15 19:45:35 +08003776 DVR_PB_INFO("start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003777 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003778 }
hualing chenbcada022020-04-22 14:27:01 +08003779 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003780 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003781 player->cmd.speed.speed = speed.speed;
3782 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA96f68962022-06-15 19:45:35 +08003783 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003784 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003785 return DVR_SUCCESS;
3786 }
hualing chen31140872020-03-25 12:29:26 +08003787 //case 3 fffb mode
3788 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3789 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3790 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003791 DVR_PB_INFO("set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003792 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003793 player->cmd.speed.speed = speed.speed;
3794 player->speed = (float)speed.speed.speed/(float)100;
3795 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003796 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003797 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003798 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003799 return DVR_SUCCESS;
3800 }
3801 }
3802 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003803 IS_KERNEL_SPEED(speed.speed.speed)) {
3804 //case 1. cur speed is kernel support speed,set kernel speed.
3805 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003806 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003807 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3808 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003809 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003810 AmTsPlayer_stopFast(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003811 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003812 } else {
3813 //set play speed and if audio is start, stop audio.
3814 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003815 DVR_PB_INFO("fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003816 AmTsPlayer_stopAudioDecoding(player->handle);
3817 player->has_audio = DVR_FALSE;
3818 }
Wentao MA96f68962022-06-15 19:45:35 +08003819 DVR_PB_INFO("start fast");
hualing chenf00cdc82020-06-10 14:23:35 +08003820 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003821 }
hualing chena540a7e2020-03-27 16:44:05 +08003822 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003823 player->cmd.speed.speed = speed.speed;
3824 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003825 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003826 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003827 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003828 return DVR_SUCCESS;
3829 }
3830 //case 2 fffb mode
3831 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3832 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3833 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003834 DVR_PB_INFO("set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003835 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003836 player->cmd.speed.speed = speed.speed;
3837 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA270dc0f2022-08-23 13:17:26 +08003838 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
hualing chenbcada022020-04-22 14:27:01 +08003839 player->fffb_play = DVR_FALSE;
Zhiqiang Han68ba6bc2024-04-02 15:02:34 +08003840
3841 /*paused in fffb and set speed(>0), resume the playback*/
3842 dvr_playback_resume(player);
3843
Wentao MA96f68962022-06-15 19:45:35 +08003844 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003845 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003846 return DVR_SUCCESS;
3847 }
hualing chen31140872020-03-25 12:29:26 +08003848 }
hualing chena540a7e2020-03-27 16:44:05 +08003849 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3850 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003851 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003852 } else {
hualing chen31140872020-03-25 12:29:26 +08003853 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003854 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3855 else
3856 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003857 player->fffb_play = DVR_TRUE;
3858 }
3859 DVR_Bool_t init_last_time = DVR_FALSE;
3860 if (player->speed > 0.0f && speed.speed.speed < 0) {
3861 init_last_time = DVR_TRUE;
3862 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3863 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003864 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003865 player->cmd.speed.mode = speed.mode;
3866 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003867 player->speed = (float)speed.speed.speed/(float)100;
3868 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003869 _dvr_init_fffb_t(handle);
3870 if (init_last_time == DVR_TRUE)
3871 player->last_send_time_id = UINT64_MAX;
3872
hualing chen87072a82020-03-12 16:20:12 +08003873 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003874 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3875 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003876 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003877 DVR_PB_INFO("set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003878 _dvr_playback_replay(handle, DVR_FALSE);
3879 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3880 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003881 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
Wentao MA96f68962022-06-15 19:45:35 +08003882 DVR_PB_INFO("set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003883 }
Wentao MA96f68962022-06-15 19:45:35 +08003884 DVR_PB_INFO("unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003885 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003886 return DVR_SUCCESS;
3887}
hualing chen2932d372020-04-29 13:44:00 +08003888
hualing chenb31a6c62020-01-13 17:27:00 +08003889/**\brief Get playback status
3890 * \param[in] handle playback handle
3891 * \param[out] p_status playback status
3892 * \retval DVR_SUCCESS On success
3893 * \return Error code
3894 */
hualing chen2932d372020-04-29 13:44:00 +08003895static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3896 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003897//
3898 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003899 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003900 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003901 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003902 return DVR_FAILURE;
3903 }
hualing chen1679f812021-11-08 15:17:46 +08003904 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003905 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003906 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003907 }
3908
hualing chen5cbe1a62020-02-10 16:36:36 +08003909 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003910 //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 +08003911 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3912 player->state == DVR_PLAYBACK_STATE_START) {
3913 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3914 }
hualing chen041c4092020-04-05 15:11:50 +08003915
hualing chencc91e1c2020-02-28 13:26:17 +08003916 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003917 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003918
shenghui.gengbec6a462023-01-12 15:21:02 +08003919 if (player->control_speed_enable == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08003920 if (player->con_spe.ply_sta == 0) {
wentao.mafdba9a02023-01-17 16:43:26 +08003921 DVR_PB_INFO("player dur[%d] sta[%d] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08003922 player->con_spe.ply_dur,
3923 player->con_spe.ply_sta,
3924 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003925 player->con_spe.ply_sta = p_status->time_cur;
3926 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3927 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
wentao.mafdba9a02023-01-17 16:43:26 +08003928 DVR_PB_INFO("player dur[%d] sta[%d] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003929 player->con_spe.ply_dur,
3930 player->con_spe.ply_sta,
3931 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003932 player->con_spe.ply_sta = p_status->time_cur;
3933 }
3934
3935 if (player->con_spe.sys_sta == 0) {
3936 player->con_spe.sys_sta = _dvr_time_getClock();
3937 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3938 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3939 player->con_spe.sys_sta = _dvr_time_getClock();
3940 }
3941 }
3942
hualing chen4b7c15d2020-04-07 16:13:48 +08003943 if (player->last_send_time_id == UINT64_MAX) {
3944 player->last_send_time_id = player->cur_segment_id;
3945 player->last_cur_time = p_status->time_cur;
3946 }
3947 if (player->last_send_time_id == player->cur_segment_id) {
Wentao MA80179512022-11-03 12:20:03 +08003948 if (player->speed > 1.0f ) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003949 //ff
3950 if (p_status->time_cur < player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08003951 DVR_PB_INFO("get ff time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003952 player->last_cur_time,
3953 p_status->time_cur,
3954 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08003955 p_status->time_cur = player->last_cur_time;
3956 } else {
3957 player->last_cur_time = p_status->time_cur;
3958 }
hualing chene41f4372020-06-06 16:29:17 +08003959 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003960 //fb
3961 if (p_status->time_cur > player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08003962 DVR_PB_INFO("get fb time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003963 player->last_cur_time,
3964 p_status->time_cur,
3965 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08003966 p_status->time_cur = player->last_cur_time;
3967 } else {
3968 player->last_cur_time = p_status->time_cur;
3969 }
3970 }
hualing chend241c7a2021-06-22 13:34:27 +08003971 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003972 player->last_cur_time = p_status->time_cur;
3973 }
hualing chen969fe7b2021-05-26 15:13:17 +08003974 player->last_send_time_id = segment_id;
3975 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003976
hualing chen5cbe1a62020-02-10 16:36:36 +08003977 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003978 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003979 p_status->flags = player->cur_segment.flags;
Wentao MA96f68962022-06-15 19:45:35 +08003980 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 +08003981 _dvr_playback_state_toString(player->state),
3982 _dvr_playback_state_toString(p_status->state),
3983 p_status->time_cur, p_status->time_end,
3984 p_status->segment_id,player->play_flag,
3985 player->speed,
3986 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08003987 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003988 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003989 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003990 }
hualing chen2932d372020-04-29 13:44:00 +08003991 return DVR_SUCCESS;
3992}
3993
3994
3995/**\brief Get playback status
3996 * \param[in] handle playback handle
3997 * \param[out] p_status playback status
3998 * \retval DVR_SUCCESS On success
3999 * \return Error code
4000 */
4001int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
4002 DVR_PlaybackStatus_t *p_status) {
4003//
4004 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4005
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004006 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
4007
hualing chen2932d372020-04-29 13:44:00 +08004008 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004009 DVR_PB_INFO("player is NULL");
hualing chen2932d372020-04-29 13:44:00 +08004010 return DVR_FAILURE;
4011 }
Wentao MA96f68962022-06-15 19:45:35 +08004012 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004013 dvr_mutex_lock(&player->lock);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004014 if (!player->has_video && !player->has_audio)
4015 p_status->time_cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08004016 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004017 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08004018
hualing chenb31a6c62020-01-13 17:27:00 +08004019 return DVR_SUCCESS;
4020}
4021
hualing chen040df222020-01-17 13:35:02 +08004022void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
4023 if (segment != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004024 DVR_PB_INFO("segment id: %lld", segment->segment_id);
4025 DVR_PB_INFO("segment flag: %d", segment->flags);
4026 DVR_PB_INFO("segment location: [%s]", segment->location);
4027 DVR_PB_INFO("segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
4028 DVR_PB_INFO("segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
4029 DVR_PB_INFO("segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
4030 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 +08004031 }
hualing chenb31a6c62020-01-13 17:27:00 +08004032}
4033
hualing chen5cbe1a62020-02-10 16:36:36 +08004034int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004035 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08004036
hualing chena540a7e2020-03-27 16:44:05 +08004037 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004038 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004039 return DVR_FAILURE;
4040 }
4041
hualing chen040df222020-01-17 13:35:02 +08004042 DVR_PlaybackSegmentInfo_t *segment;
wentao.mafd5283f2022-10-14 09:51:13 +08004043 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08004044 // prefetch() here incurring self_assign is used to avoid some compiling
4045 // warnings.
4046 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08004047 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08004048 {
Wentao MA07d3d742022-09-06 09:58:05 +08004049 if (segment->segment_id == segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004050 _dvr_dump_segment(segment);
Wentao MA07d3d742022-09-06 09:58:05 +08004051 break;
hualing chen86e7d482020-01-16 15:13:33 +08004052 }
4053 }
4054 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08004055}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004056
pengfei.liu27cc4ec2020-04-03 16:28:16 +08004057int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004058{
4059 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4060 DVR_RETURN_IF_FALSE(player);
4061 DVR_RETURN_IF_FALSE(func);
4062
Wentao MA96f68962022-06-15 19:45:35 +08004063 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004064 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004065
4066 player->dec_func = func;
4067 player->dec_userdata = userdata;
4068
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004069 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004070 DVR_PB_INFO("out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004071 return DVR_SUCCESS;
4072}
4073
4074int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
4075{
4076 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4077 DVR_RETURN_IF_FALSE(player);
4078 DVR_RETURN_IF_FALSE(p_secure_buf);
4079 DVR_RETURN_IF_FALSE(len);
4080
Wentao MA96f68962022-06-15 19:45:35 +08004081 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004082 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004083
4084 player->is_secure_mode = 1;
4085 player->secure_buffer = p_secure_buf;
4086 player->secure_buffer_size = len;
4087
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004088 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004089 DVR_PB_INFO("out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004090 return DVR_SUCCESS;
4091}
Wentao MA5629ad82022-08-24 10:03:02 +08004092
4093int dvr_playback_set_ac4_preselection_id(DVR_PlaybackHandle_t handle, int presel_id)
4094{
4095 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa210e5e2022-10-12 16:10:03 +08004096 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MA5629ad82022-08-24 10:03:02 +08004097
4098 player->audio_presentation_id = presel_id;
4099 am_tsplayer_result ret = AmTsPlayer_setParams(player->handle,
4100 AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &presel_id);
4101 DVR_RETURN_IF_FALSE(ret == AM_TSPLAYER_OK);
4102
4103 return DVR_SUCCESS;
4104}
Wentao MAa0b9c002022-11-10 17:47:27 +08004105
4106// This function ensures a valid TsPlayer delay time is provided or else it
4107// returns DVR_FAILURE. It is designed to workaround a weakness of
4108// AmTsPlayer_getDelayTime at starting phase of a playback in a short period
4109// of 20ms or less. During the said period, getDelayTime does NOT work as
4110// expect to return real delay length because demux isn't actually running
4111// to provide valid pts to TsPlayer.
Wentao MA804bab12022-11-29 10:01:26 +08004112static int get_effective_tsplayer_delay_time(DVR_Playback_t* play, int *time)
Wentao MAa0b9c002022-11-10 17:47:27 +08004113{
4114 int64_t delay=0;
4115 uint64_t pts_a=0;
4116 uint64_t pts_v=0;
4117
Wentao MA804bab12022-11-29 10:01:26 +08004118 DVR_RETURN_IF_FALSE(play != NULL);
4119 DVR_RETURN_IF_FALSE(play->handle != NULL);
Wentao MAa0b9c002022-11-10 17:47:27 +08004120
Wentao MA804bab12022-11-29 10:01:26 +08004121 AmTsPlayer_getDelayTime(play->handle, &delay);
4122 // In scambled stream situation, the returned TsPlayer delay time is
4123 // invalid and dirty. An additional time check agaginst 15 minutes (900s)
4124 // is introduced to insure such error condition is handled properly.
4125 DVR_RETURN_IF_FALSE((delay >= 0) && (delay <= 900*1000));
Wentao MAa0b9c002022-11-10 17:47:27 +08004126
Wentao MA804bab12022-11-29 10:01:26 +08004127 if (play->delay_is_effective) {
4128 *time = (int)delay;
Wentao MAa0b9c002022-11-10 17:47:27 +08004129 return DVR_SUCCESS;
4130 } else if (delay > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004131 *time = (int)delay;
4132 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004133 return DVR_SUCCESS;
4134 }
4135
Wentao MA804bab12022-11-29 10:01:26 +08004136 AmTsPlayer_getPts(play->handle, TS_STREAM_AUDIO, &pts_a);
4137 AmTsPlayer_getPts(play->handle, TS_STREAM_VIDEO, &pts_v);
Wentao MAa0b9c002022-11-10 17:47:27 +08004138 if ((int64_t)pts_a > 0 || (int64_t)pts_v > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004139 *time = (int)delay;
4140 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004141 return DVR_SUCCESS;
4142 }
4143
4144 return DVR_FAILURE;
4145}
4146