blob: e732fd045902dcb3d1d8c7335584cd3be15defb7 [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 MA75775d22023-09-25 16:53:24 +080043//#define FOR_SKYWORTH_FETCH_RDK
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
326 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800327 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800328 return DVR_FAILURE;
329 }
330
hualing chen86e7d482020-01-16 15:13:33 +0800331 struct timespec ts;
332 clock_gettime(CLOCK_MONOTONIC, &ts);
333 //ms为毫秒,换算成秒
334 ts.tv_sec += ms/1000;
335 //在outtime的基础上,增加ms毫秒
336 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
337 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
338 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
339 //us的值有可能超过1秒,
340 ts.tv_sec += us / 1000000;
341 us = us % 1000000;
342 ts.tv_nsec = us * 1000;//换算成纳秒
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800343
344 int val = dvr_mutex_save(&player->lock);
345 pthread_cond_timedwait(&player->cond, &player->lock.lock, &ts);
346 dvr_mutex_restore(&player->lock, val);
hualing chen86e7d482020-01-16 15:13:33 +0800347 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800348}
Wentao MA804bab12022-11-29 10:01:26 +0800349
hualing chenb31a6c62020-01-13 17:27:00 +0800350//send signal
hualing chen040df222020-01-17 13:35:02 +0800351static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800352{
hualing chen87072a82020-03-12 16:20:12 +0800353 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800354
355 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800356 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800357 return DVR_FAILURE;
358 }
Wentao MA96f68962022-06-15 19:45:35 +0800359 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800360 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800361 pthread_cond_signal(&player->cond);
Wentao MA96f68962022-06-15 19:45:35 +0800362 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800363 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800364 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800365}
366
hualing chen2932d372020-04-29 13:44:00 +0800367//send playback event, need check is need lock first
368static 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 +0800369
370 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800371
372 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800373 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800374 return DVR_FAILURE;
375 }
376
hualing chencc91e1c2020-02-28 13:26:17 +0800377 switch (evt) {
378 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800379 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800380 break;
381 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
382 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800383 DVR_PB_INFO("trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800384 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800385 break;
386 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
387 break;
388 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
389 break;
390 case DVR_PLAYBACK_EVENT_NO_KEY:
391 break;
392 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800393 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800394 DVR_PB_INFO("reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800395 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800396 break;
397 case DVR_PLAYBACK_EVENT_REACHED_END:
398 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800399 DVR_PB_INFO("reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800400 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800401 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800402 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800403 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800404 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800405 default:
406 break;
407 }
408 if (player->openParams.event_fn != NULL)
409 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800410 return DVR_SUCCESS;
411}
hualing chen2932d372020-04-29 13:44:00 +0800412static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800413{
414 DVR_Play_Notify_t notify;
415 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
416 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
417 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800418 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800419 return DVR_SUCCESS;
420}
421
hualing chen2932d372020-04-29 13:44:00 +0800422static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800423{
424 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800425
Wentao MA16f870e2022-09-09 11:00:22 +0800426 if (player == NULL) {
427 DVR_PB_ERROR("player is NULL");
428 return DVR_FAILURE;
429 }
hualing chene3797f02021-01-13 14:53:28 +0800430 if (player->openParams.is_notify_time == DVR_FALSE) {
shenghui.gengbec6a462023-01-12 15:21:02 +0800431 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800432 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800433 }
hualing chena540a7e2020-03-27 16:44:05 +0800434
hualing chen03fd4942021-07-15 15:56:41 +0800435 if (player->send_time == 0) {
shenghui.gengbec6a462023-01-12 15:21:02 +0800436 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800437 player->send_time = _dvr_time_getClock() + 500;
438 else
439 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800440 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen56c0a162022-01-27 17:01:50 +0800441 if ((player->send_time - _dvr_time_getClock()) > 1000) {
442 player->send_time = _dvr_time_getClock() + 500;
Wentao MA96f68962022-06-15 19:45:35 +0800443 DVR_PB_INFO("player send time occur system time changed!!!!!");
hualing chen56c0a162022-01-27 17:01:50 +0800444 } else {
445 return DVR_SUCCESS;
446 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800447 }
shenghui.gengbec6a462023-01-12 15:21:02 +0800448 if (player->control_speed_enable == 0)
hualing chend241c7a2021-06-22 13:34:27 +0800449 player->send_time = _dvr_time_getClock() + 500;
450 else
451 player->send_time = _dvr_time_getClock() + 20;
452
hualing chen6e4bfa52020-03-13 14:37:11 +0800453 DVR_Play_Notify_t notify;
454 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
455 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
456 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800457 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800458 return DVR_SUCCESS;
459}
460
hualing chen4b7c15d2020-04-07 16:13:48 +0800461static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
462 DVR_Playback_t *player = (DVR_Playback_t *) handle;
463 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800464 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800465 player->fffb_current = player->fffb_start;
466 //get segment current time pos
467 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800468 player->next_fffb_time = _dvr_time_getClock();
469
470 return DVR_SUCCESS;
471}
472
hualing chen2aba4022020-03-02 13:49:55 +0800473static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
474 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800475 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800476 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800477 player->fffb_current = player->fffb_start;
478 //get segment current time pos
479 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800480
hualing chen2aba4022020-03-02 13:49:55 +0800481 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800482 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800483 return DVR_SUCCESS;
484}
hualing chencc91e1c2020-02-28 13:26:17 +0800485//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800486static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
487
488 DVR_Playback_t *player = (DVR_Playback_t *) handle;
489 DVR_PlaybackSegmentInfo_t *segment;
490 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
491
hualing chena540a7e2020-03-27 16:44:05 +0800492 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800493 DVR_PB_INFO(" player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800494 return DVR_FAILURE;
495 }
496
hualing chen87072a82020-03-12 16:20:12 +0800497 int found = 0;
498 int found_eq_id = 0;
wentao.mafd5283f2022-10-14 09:51:13 +0800499 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800500 // prefetch() here incurring self_assign is used to avoid some compiling
501 // warnings.
502 // coverity[self_assign]
hualing chen87072a82020-03-12 16:20:12 +0800503 list_for_each_entry(segment, &player->segment_list, head)
504 {
505 if (player->segment_is_open == DVR_FALSE) {
506 //get first segment from list, case segment is not open
507 if (!IS_FB(player->speed))
508 found = 1;
509 } else if (segment->segment_id == segmentid) {
510 //find cur segment, we need get next one
511 found_eq_id = 1;
512 if (!IS_FB(player->speed)) {
513 found = 1;
514 continue;
515 } else {
516 //if is fb mode.we need used pre segment
517 if (pre_segment != NULL) {
518 found = 1;
519 } else {
520 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800521 DVR_PB_INFO("not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800522 return DVR_FAILURE;
523 }
524 }
525 }
526 if (found == 1) {
527 found = 2;
528 break;
529 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800530 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800531 }
532 if (found != 2) {
533 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800534 DVR_PB_INFO("not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800535 return DVR_FAILURE;
536 }
Wentao MA96f68962022-06-15 19:45:35 +0800537 DVR_PB_INFO("found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800538 return DVR_SUCCESS;
539}
540
541//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800542static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800543
hualing chen040df222020-01-17 13:35:02 +0800544 DVR_Playback_t *player = (DVR_Playback_t *) handle;
545 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800546 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800547 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800548 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800549 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800550 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800551 return DVR_FAILURE;
552 }
553
hualing chen03fd4942021-07-15 15:56:41 +0800554 if (IS_FB(player->speed)
555 && dvr_playback_check_limit(handle)) {
556 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
557 //case cur id < segment id
558 if (player->cur_segment_id <= segmentid) {
559 //expired ts data is player,return error
Wentao MA96f68962022-06-15 19:45:35 +0800560 DVR_PB_INFO("reach start segment ,return error");
hualing chen03fd4942021-07-15 15:56:41 +0800561 return DVR_FAILURE;
562 }
Wentao MA96f68962022-06-15 19:45:35 +0800563 DVR_PB_INFO("has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800564 }
565
hualing chen86e7d482020-01-16 15:13:33 +0800566 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800567 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800568
wentao.mafd5283f2022-10-14 09:51:13 +0800569 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800570 // prefetch() here incurring self_assign is used to avoid some compiling
571 // warnings.
572 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +0800573 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800574 {
hualing chencc91e1c2020-02-28 13:26:17 +0800575 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800576 //get first segment from list, case segment is not open
577 if (!IS_FB(player->speed))
578 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800579 } else if (segment->segment_id == player->cur_segment_id) {
580 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800581 found_eq_id = 1;
582 if (!IS_FB(player->speed)) {
583 found = 1;
584 continue;
585 } else {
586 //if is fb mode.we need used pre segment
587 if (pre_segment != NULL) {
588 found = 1;
589 } else {
590 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800591 DVR_PB_INFO("not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800592 return DVR_FAILURE;
593 }
594 }
hualing chen86e7d482020-01-16 15:13:33 +0800595 }
596 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800597 if (IS_FB(player->speed)) {
598 //used pre segment
599 segment = pre_segment;
600 }
hualing chencc91e1c2020-02-28 13:26:17 +0800601 //save segment info
602 player->last_segment_id = player->cur_segment_id;
Wentao MAf35c3882023-04-17 12:36:19 +0800603 if (player->segment_handle) {
604 player->last_segment_total = segment_tell_total_time(player->segment_handle);
605 }
hualing chen87072a82020-03-12 16:20:12 +0800606 player->last_segment.segment_id = player->cur_segment.segment_id;
607 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800608 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
609 //pids
610 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
611
hualing chen5cbe1a62020-02-10 16:36:36 +0800612 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800613 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800614 player->cur_segment_id = segment->segment_id;
615 player->cur_segment.segment_id = segment->segment_id;
616 player->cur_segment.flags = segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800617 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 +0800618 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800619 //pids
hualing chen040df222020-01-17 13:35:02 +0800620 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800621 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800622 break;
hualing chen86e7d482020-01-16 15:13:33 +0800623 }
hualing chen2aba4022020-03-02 13:49:55 +0800624 pre_segment = segment;
625 }
626 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
627 //used the last one segment to open
628 //get segment info
629 player->segment_is_open = DVR_TRUE;
630 player->cur_segment_id = pre_segment->segment_id;
631 player->cur_segment.segment_id = pre_segment->segment_id;
632 player->cur_segment.flags = pre_segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800633 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 +0800634 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
635 //pids
636 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
637 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800638 }
639 if (found != 2) {
640 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800641 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800642 }
643 return DVR_SUCCESS;
644}
hualing chen040df222020-01-17 13:35:02 +0800645//open next segment to play,if reach list end return errro.
646static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800647{
hualing chen040df222020-01-17 13:35:02 +0800648 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800649 Segment_OpenParams_t params;
650 int ret = DVR_SUCCESS;
651
hualing chena540a7e2020-03-27 16:44:05 +0800652 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800653 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800654 return DVR_FAILURE;
655 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800656 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800657retry:
hualing chena540a7e2020-03-27 16:44:05 +0800658 ret = _dvr_get_next_segmentId(handle);
659 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800660 DVR_PB_INFO("not found segment info");
hualing chen4b7c15d2020-04-07 16:13:48 +0800661 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800662 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800663 }
664
Wentao MAf35c3882023-04-17 12:36:19 +0800665 if (player->segment_handle != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800666 DVR_PB_INFO("close segment");
Wentao MAf35c3882023-04-17 12:36:19 +0800667 segment_close(player->segment_handle);
668 player->segment_handle = NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800669 }
670
Wentao MA4d85ff32022-09-23 11:36:18 +0800671 memset((void*)&params,0,sizeof(params));
Wentao MA270dc0f2022-08-23 13:17:26 +0800672 //cp current segment path to location
hualing chen5cbe1a62020-02-10 16:36:36 +0800673 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800674 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800675 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800676 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 +0800677
Wentao MAf35c3882023-04-17 12:36:19 +0800678 ret = segment_open(&params, &(player->segment_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800679 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800680 DVR_PB_INFO("open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800681 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800682 }
Wentao MA01de0e62022-01-10 18:48:23 +0800683 // Keep the start segment_id when the first segment_open is called during a playback
684 if (player->first_start_id == UINT64_MAX) {
685 player->first_start_id = player->cur_segment.segment_id;
686 }
hualing chen87072a82020-03-12 16:20:12 +0800687 pthread_mutex_unlock(&player->segment_lock);
688 int total = _dvr_get_end_time( handle);
689 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800690 if (IS_FB(player->speed)) {
691 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800692 player->ts_cache_len = 0;
Wentao MAf35c3882023-04-17 12:36:19 +0800693 segment_seek(player->segment_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +0800694 DVR_PB_INFO("seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800695 }
hualing chen87072a82020-03-12 16:20:12 +0800696 player->dur = total;
wentao.mafdba9a02023-01-17 16:43:26 +0800697 player->con_spe.ply_dur = 0;
698 player->con_spe.ply_sta = 0;
699 player->con_spe.sys_dur = 0;
700 player->con_spe.sys_sta = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800701 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +0800702 DVR_PB_INFO("next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800703 return ret;
704}
705
hualing chen5cbe1a62020-02-10 16:36:36 +0800706//open next segment to play,if reach list end return errro.
707static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
708{
709 DVR_Playback_t *player = (DVR_Playback_t *) handle;
710 Segment_OpenParams_t params;
711 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800712 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800713 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800714 return DVR_FAILURE;
715 }
hualing chencc91e1c2020-02-28 13:26:17 +0800716 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800717 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800718 }
hualing chencc91e1c2020-02-28 13:26:17 +0800719 uint64_t id = segment_id;
Wentao MA07d3d742022-09-06 09:58:05 +0800720 DVR_PB_INFO("start finding segment[%lld] info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800721 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800722
723 DVR_PlaybackSegmentInfo_t *segment;
724
725 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800726
wentao.mafd5283f2022-10-14 09:51:13 +0800727 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800728 // prefetch() here incurring self_assign is used to avoid some compiling
729 // warnings.
730 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800731 list_for_each_entry(segment, &player->segment_list, head)
732 {
Wentao MA96f68962022-06-15 19:45:35 +0800733 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 +0800734 if (segment->segment_id == segment_id) {
735 found = 1;
736 }
737 if (found == 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800738 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 +0800739 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800740 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800741 player->cur_segment_id = segment->segment_id;
742 player->cur_segment.segment_id = segment->segment_id;
743 player->cur_segment.flags = segment->flags;
Wentao MAe88ad702022-09-02 10:35:00 +0800744 const int len = strlen(segment->location);
745 if (len >= DVR_MAX_LOCATION_SIZE || len <= 0) {
746 DVR_PB_ERROR("Invalid segment.location length %d",len);
747 pthread_mutex_unlock(&player->segment_lock);
748 return DVR_FAILURE;
749 }
750 strncpy(player->cur_segment.location, segment->location, len+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800751 //pids
752 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +0800753 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 +0800754 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800755 }
756 }
hualing chencc91e1c2020-02-28 13:26:17 +0800757 if (found == 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800758 DVR_PB_INFO("not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800759 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800760 return DVR_FAILURE;
761 }
Wentao MA4d85ff32022-09-23 11:36:18 +0800762 memset((void*)&params,0,sizeof(params));
Wentao MAe88ad702022-09-02 10:35:00 +0800763
764 const int len2 = strlen(player->cur_segment.location);
765 if (len2 >= DVR_MAX_LOCATION_SIZE || len2 <= 0) {
766 DVR_PB_ERROR("Invalid cur_segment.location length %d",len2);
767 pthread_mutex_unlock(&player->segment_lock);
768 return DVR_FAILURE;
769 }
770 strncpy(params.location, player->cur_segment.location, len2+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800771 params.segment_id = (uint64_t)player->cur_segment.segment_id;
772 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800773 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 +0800774 if (player->segment_handle != NULL) {
775 segment_close(player->segment_handle);
776 player->segment_handle = NULL;
hualing chen2aba4022020-03-02 13:49:55 +0800777 }
Wentao MAf35c3882023-04-17 12:36:19 +0800778 ret = segment_open(&params, &(player->segment_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800779 if (ret == DVR_FAILURE) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800780 DVR_PB_INFO("segment open error");
hualing chen4b7c15d2020-04-07 16:13:48 +0800781 }
Wentao MA01de0e62022-01-10 18:48:23 +0800782 // Keep the start segment_id when the first segment_open is called during a playback
783 if (player->first_start_id == UINT64_MAX) {
784 player->first_start_id = player->cur_segment.segment_id;
785 }
hualing chen2aba4022020-03-02 13:49:55 +0800786 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800787 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800788
Wentao MA96f68962022-06-15 19:45:35 +0800789 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 +0800790 return ret;
791}
792
793
794//get play info by segment id
795static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
796 uint64_t segment_id,
Wentao MA270dc0f2022-08-23 13:17:26 +0800797 am_tsplayer_video_params *video_param,
798 am_tsplayer_audio_params *audio_param, am_tsplayer_audio_params *ad_param) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800799
800 DVR_Playback_t *player = (DVR_Playback_t *) handle;
801 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800802 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800803 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800804 return DVR_FAILURE;
805 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800806
807 int found = 0;
808
wentao.mafd5283f2022-10-14 09:51:13 +0800809 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800810 // prefetch() here incurring self_assign is used to avoid some compiling
811 // warnings.
812 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800813 list_for_each_entry(segment, &player->segment_list, head)
814 {
hualing chen87072a82020-03-12 16:20:12 +0800815 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800816 //get first segment from list
817 found = 1;
818 }
819 if (segment->segment_id == segment_id) {
820 found = 1;
821 }
822 if (found == 1) {
823 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800824 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800825 player->cur_segment_id = segment->segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800826 player->cur_segment.segment_id = segment->segment_id;
827 player->cur_segment.flags = segment->flags;
828 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800829 player->cur_segment.pids.video.pid = segment->pids.video.pid;
830 player->cur_segment.pids.video.format = segment->pids.video.format;
831 player->cur_segment.pids.video.type = segment->pids.video.type;
832 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
833 player->cur_segment.pids.audio.format = segment->pids.audio.format;
834 player->cur_segment.pids.audio.type = segment->pids.audio.type;
835 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
836 player->cur_segment.pids.ad.format = segment->pids.ad.format;
837 player->cur_segment.pids.ad.type = segment->pids.ad.type;
838 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800839 //
Wentao MA270dc0f2022-08-23 13:17:26 +0800840 video_param->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
841 video_param->pid = segment->pids.video.pid;
842 audio_param->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
843 audio_param->pid = segment->pids.audio.pid;
844 ad_param->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
845 ad_param->pid =segment->pids.ad.pid;
Wentao MA804bab12022-11-29 10:01:26 +0800846 DVR_PB_DEBUG("get_playinfo, segment_id:%lld, vpid[0x%x], apid[0x%x], vfmt[%d], afmt[%d]",
847 player->cur_segment_id, video_param->pid, audio_param->pid,
848 video_param->codectype, audio_param->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800849 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800850 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800851 }
852 }
hualing chencc91e1c2020-02-28 13:26:17 +0800853 if (found != 2) {
854 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800855 DVR_PB_INFO("get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800856 return DVR_FAILURE;
857 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800858
859 return DVR_SUCCESS;
860}
hualing chencc91e1c2020-02-28 13:26:17 +0800861static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
862 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800863 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800864 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800865 return DVR_FAILURE;
866 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800867
hualing chencc91e1c2020-02-28 13:26:17 +0800868 //compare cur segment
869 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
870 {
871 //check video pids, stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800872 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800873 //check sub audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800874 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800875 //check audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800876 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 1);
Wentao MA96f68962022-06-15 19:45:35 +0800877 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 +0800878 //check pcr pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +0800879 _do_handle_pid_update(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800880 }
hualing chena540a7e2020-03-27 16:44:05 +0800881 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800882}
hualing chen5cbe1a62020-02-10 16:36:36 +0800883
hualing chend241c7a2021-06-22 13:34:27 +0800884static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
885{
886 DVR_Playback_t *player = (DVR_Playback_t *) handle;
887 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800888 DVR_PB_INFO("player is NULL");
hualing chend241c7a2021-06-22 13:34:27 +0800889 return DVR_TRUE;
890 }
hualing chend241c7a2021-06-22 13:34:27 +0800891
wentao.mafdba9a02023-01-17 16:43:26 +0800892 DVR_PB_INFO(":play speed: %f ply dur: %d sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800893 player->speed,
894 player->con_spe.ply_dur,
895 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800896
897 if (player->speed != 1.0f)
898 return DVR_TRUE;
899
900 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800901 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800902 return DVR_FALSE;
903
904 return DVR_TRUE;
905}
906
hualing chencc91e1c2020-02-28 13:26:17 +0800907static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
908{
909 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800910 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800911 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800912 return DVR_FAILURE;
913 }
Wentao MA292380e2022-12-14 14:46:19 +0800914 if (player->vendor != DVR_PLAYBACK_VENDOR_DEF) {
915 DVR_PB_INFO("In case of vendor Amlogic/Amazon, do not control AV display");
hualing chenf43b8ba2020-07-28 13:11:42 +0800916 return DVR_SUCCESS;
917 }
Wentao MA96f68962022-06-15 19:45:35 +0800918 DVR_PB_INFO("flag[0x%x]id[%lld]last[0x%x][%llu]",
hualing chen03fd4942021-07-15 15:56:41 +0800919 player->cur_segment.flags,
920 player->cur_segment.segment_id,
921 player->last_segment.flags,
922 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800923 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
924 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800925 //enable display
Wentao MA96f68962022-06-15 19:45:35 +0800926 DVR_PB_INFO("unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800927 AmTsPlayer_showVideo(player->handle);
928 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800929 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
930 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800931 //disable display
Wentao MA96f68962022-06-15 19:45:35 +0800932 DVR_PB_INFO("mute");
hualing chen2aba4022020-03-02 13:49:55 +0800933 AmTsPlayer_hideVideo(player->handle);
934 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800935 }
936 return DVR_SUCCESS;
937}
hualing chene3797f02021-01-13 14:53:28 +0800938/*
Wentao MA270dc0f2022-08-23 13:17:26 +0800939if decode success first time.
940success: return true
hualing chene3797f02021-01-13 14:53:28 +0800941fail: return false
942*/
Wentao MA270dc0f2022-08-23 13:17:26 +0800943static DVR_Bool_t _dvr_pauselive_decode_success(DVR_PlaybackHandle_t handle) {
hualing chena540a7e2020-03-27 16:44:05 +0800944 DVR_Playback_t *player = (DVR_Playback_t *) handle;
945 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800946 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800947 return DVR_TRUE;
948 }
hualing chene3797f02021-01-13 14:53:28 +0800949 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800950 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800951 } else {
952 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800953 }
954}
hualing chen86e7d482020-01-16 15:13:33 +0800955static void* _dvr_playback_thread(void *arg)
956{
hualing chen040df222020-01-17 13:35:02 +0800957 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800958 //int need_open_segment = 1;
Wentao MA270dc0f2022-08-23 13:17:26 +0800959 am_tsplayer_input_buffer input_buffer;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800960 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800961 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800962
hualing chen39628212020-05-14 10:35:13 +0800963 #define MAX_REACHEND_TIMEOUT (3000)
964 int reach_end_timeout = 0;//ms
965 int cache_time = 0;
hualing chen40dd5462021-11-26 19:56:20 +0800966 int check_no_data_time = 4;
hualing chen040df222020-01-17 13:35:02 +0800967 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800968 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +0800969 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800970 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800971 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800972 DVR_Bool_t goto_rewrite = DVR_FALSE;
wentao ma7d642782022-10-23 18:26:16 -0700973 int read = 0;
yinming ding0ce94922021-09-08 15:09:15 +0800974
Wentao MA361eaac2023-03-21 13:12:28 +0800975 prctl(PR_SET_NAME,"DvrPlayback");
976
wentao ma7d642782022-10-23 18:26:16 -0700977 const uint64_t write_timeout_ms = (uint64_t)dvr_prop_read_int("vendor.tv.libdvr.writetm",50);
978 const int timeout = dvr_prop_read_int("vendor.tv.libdvr.waittm",200);
hualing chen56c0a162022-01-27 17:01:50 +0800979
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800980 if (player->is_secure_mode) {
981 if (dec_buf_size > player->secure_buffer_size) {
Wentao MA96f68962022-06-15 19:45:35 +0800982 DVR_PB_INFO("playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800983 return NULL;
984 }
985 }
wentao.maa210e5e2022-10-12 16:10:03 +0800986
987 uint8_t *buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800988 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +0800989 DVR_PB_INFO("Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800990 return NULL;
991 }
Wentao MA270dc0f2022-08-23 13:17:26 +0800992 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
993 input_buffer.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800994
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800995 dec_bufs.buf_data = malloc(dec_buf_size);
996 if (!dec_bufs.buf_data) {
Wentao MA96f68962022-06-15 19:45:35 +0800997 DVR_PB_INFO("Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800998 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800999 return NULL;
1000 }
1001 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1002 dec_bufs.buf_size = dec_buf_size;
1003
hualing chencc91e1c2020-02-28 13:26:17 +08001004 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001005 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1006 }
hualing chen86e7d482020-01-16 15:13:33 +08001007
hualing chen86e7d482020-01-16 15:13:33 +08001008 if (ret != DVR_SUCCESS) {
1009 if (buf != NULL) {
1010 free(buf);
hualing chen86e7d482020-01-16 15:13:33 +08001011 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001012 free(dec_bufs.buf_data);
Wentao MA96f68962022-06-15 19:45:35 +08001013 DVR_PB_INFO("get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001014 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001015 }
Wentao MA96f68962022-06-15 19:45:35 +08001016 DVR_PB_INFO("--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001017 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001018 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1019 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1020 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1021 player->first_trans_ok = DVR_TRUE;
1022 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1023 }
hualing chencc91e1c2020-02-28 13:26:17 +08001024 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001025 //set video show
1026 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001027 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1028 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001029 int trick_stat = 0;
1030 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001031
hualing chen86e7d482020-01-16 15:13:33 +08001032 //check trick stat
Wentao MA96f68962022-06-15 19:45:35 +08001033 //DVR_PB_INFO("lock check_no_data_time:%d", check_no_data_time);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001034 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001035
Wentao MA907b6432022-08-01 06:23:08 +00001036 {
Wentao MA9a164002022-08-29 11:20:24 +08001037 static struct timespec _prev_ts={0,0};
Wentao MA907b6432022-08-01 06:23:08 +00001038 struct timespec _nowts,_diffts;
1039 clock_gettime(CLOCK_MONOTONIC, &_nowts);
Wentao MA9a164002022-08-29 11:20:24 +08001040 clock_timespec_subtract(&_nowts,&_prev_ts,&_diffts);
Wentao MA907b6432022-08-01 06:23:08 +00001041 if (_diffts.tv_sec>0) {
1042 char _logbuf[512]={0};
1043 char* _pbuf=_logbuf;
1044 int _nchar=0;
1045 DVR_PlaybackSegmentInfo_t* _segment;
wentao.mafd5283f2022-10-14 09:51:13 +08001046 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08001047 // prefetch() here incurring self_assign is used to avoid some compiling
1048 // warnings.
1049 // coverity[self_assign]
Wentao MA907b6432022-08-01 06:23:08 +00001050 list_for_each_entry(_segment, &player->segment_list, head) {
1051 if (player->cur_segment_id == _segment->segment_id) {
Wentao MAf35c3882023-04-17 12:36:19 +08001052 int seg_size = segment_get_cur_segment_size(player->segment_handle);
1053 int read_ptr = segment_tell_position(player->segment_handle);
Wentao MA907b6432022-08-01 06:23:08 +00001054 float progress = -1.0f;
Wentao MA9a164002022-08-29 11:20:24 +08001055 if (seg_size>0) {
1056 progress = (float)read_ptr*100/seg_size;
Wentao MA907b6432022-08-01 06:23:08 +00001057 }
Wentao MA4d85ff32022-09-23 11:36:18 +08001058 _nchar=sprintf(_pbuf,"%lld(%.1f%%), ",_segment->segment_id,progress);
Wentao MA907b6432022-08-01 06:23:08 +00001059 } else {
1060 _nchar=sprintf(_pbuf,"%lld, ",_segment->segment_id);
1061 }
1062 if (_nchar<0) {
1063 break;
1064 }
1065 _pbuf+=_nchar;
1066 if (_pbuf-_logbuf+10 >= sizeof(_logbuf)) {
1067 sprintf(_pbuf,"...");
1068 break;
1069 }
1070 }
Wentao MA9a164002022-08-29 11:20:24 +08001071 DVR_PB_INFO("clk: %08u, seg_list: %s",_nowts.tv_sec,_logbuf);
1072 _prev_ts=_nowts;
Wentao MA907b6432022-08-01 06:23:08 +00001073 }
1074 }
1075
hualing chen2aba4022020-03-02 13:49:55 +08001076 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1077 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001078 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001079 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001080 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001081 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001082 {
hualing chen2aba4022020-03-02 13:49:55 +08001083 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1084 if (trick_stat > 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001085 DVR_PB_INFO("trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001086 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001087 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 +08001088 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001089 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001090 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001091 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
Wentao MA270dc0f2022-08-23 13:17:26 +08001092 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_V_START
1093 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_A_START
hualing chen2aba4022020-03-02 13:49:55 +08001094 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
Wentao MA96f68962022-06-15 19:45:35 +08001095 DVR_PB_INFO("pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001096 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001097 //need change to pause state
1098 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1099 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00001100 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08001101 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001102 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001103 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001104 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001105 AmTsPlayer_pauseVideoDecoding(player->handle);
1106 AmTsPlayer_pauseAudioDecoding(player->handle);
Wentao MA6dcdc342023-01-30 17:03:19 +08001107
1108 // Audio is unmuted here, for it was muted before receiving first frame event.
1109 if (player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
1110 AmTsPlayer_setAudioMute(player->handle,0,0);
1111 }
hualing chen2bd8a7a2020-04-02 11:31:03 +08001112 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001113 DVR_PB_INFO("clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001114 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001115 }
1116 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1117 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001118 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001119 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001120 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001121 DVR_PB_INFO("fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001122 player->speed,
1123 player->fffb_current,
1124 _dvr_time_getClock(),
1125 _dvr_playback_state_toString(player->state),
1126 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001127 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001128 //dvr_mutex_unlock(&player->lock);
1129 //dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001130 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001131 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001132 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001133 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001134 } else if (_dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001135 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 +08001136 player->speed,
1137 player->fffb_current,
1138 _dvr_time_getClock(),
1139 _dvr_playback_state_toString(player->state),
1140 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001141 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001142 //dvr_mutex_unlock(&player->lock);
1143 //dvr_mutex_lock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001144 AmTsPlayer_pauseVideoDecoding(player->handle);
1145 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001146 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001147 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001148 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001149 }
Wentao MA96f68962022-06-15 19:45:35 +08001150 DVR_PB_INFO("fffb play-------speed[%f][%d][%d][%s][%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001151 player->speed,
1152 goto_rewrite,
1153 real_read,
1154 _dvr_playback_state_toString(player->state),
1155 player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001156 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001157 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001158 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1159 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001160 DVR_PB_INFO("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001161 dvr_mutex_unlock(&player->lock);
1162
hualing chen2aba4022020-03-02 13:49:55 +08001163 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001164 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001165 dvr_mutex_lock(&player->lock);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001166 player->fffb_play = DVR_FALSE;
hualing chen1ffd85b2021-08-16 15:18:43 +08001167 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1168 //on pause state,user seek to new pos,we need pause and wait
1169 //user to resume
Wentao MA96f68962022-06-15 19:45:35 +08001170 DVR_PB_INFO("pause, when got first frame event when user seek end");
hualing chen1ffd85b2021-08-16 15:18:43 +08001171 player->first_frame = 0;
1172 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1173 AmTsPlayer_pauseVideoDecoding(player->handle);
1174 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001175 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001176 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001177 //for first into fffb when reset speed
1178 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1179 _dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001180 DVR_PB_INFO("fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001181 player->speed,
1182 player->fffb_current,
1183 _dvr_time_getClock(),
1184 _dvr_playback_state_toString(player->state),
1185 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001186 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001187 //dvr_mutex_unlock(&player->lock);
1188 //dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001189 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001190 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001191 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001192 continue;
1193 }
Wentao MA96f68962022-06-15 19:45:35 +08001194 DVR_PB_INFO("fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001195 player->speed,
1196 goto_rewrite,
1197 real_read,
1198 _dvr_playback_state_toString(player->state),
1199 player->cmd.cur_cmd,
1200 player->fffb_play);
Wentao MA96f68962022-06-15 19:45:35 +08001201 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001202 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001203 goto_rewrite = DVR_FALSE;
1204 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001205 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001206 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001207 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1208 player->first_frame = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001209 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001210 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001211 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001212 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001213 }
hualing chenb31a6c62020-01-13 17:27:00 +08001214 }
hualing chen86e7d482020-01-16 15:13:33 +08001215
hualing chen30423862021-04-16 14:39:12 +08001216 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1217 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001218 //check is need send time send end
Wentao MA96f68962022-06-15 19:45:35 +08001219 DVR_PB_INFO("pause, continue");
1220 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001221 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001222 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001223 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001224 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001225 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001226 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001227 continue;
1228 }
hualing chen266b9502020-04-04 17:39:39 +08001229 //when seek action is done. we need drop write timeout data.
1230 if (player->drop_ts == DVR_TRUE) {
1231 goto_rewrite = DVR_FALSE;
1232 real_read = 0;
1233 player->drop_ts = DVR_FALSE;
1234 }
hualing chen2aba4022020-03-02 13:49:55 +08001235 if (goto_rewrite == DVR_TRUE) {
1236 goto_rewrite = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001237 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001238 dvr_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001239 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Wentao MA96f68962022-06-15 19:45:35 +08001240 //DVR_PB_INFO("rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001241 goto rewrite;
1242 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001243 //.check is need send time send end
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001244 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001245 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001246 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001247 pthread_mutex_lock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001248 //DVR_PB_INFO("start read");
Wentao MAf35c3882023-04-17 12:36:19 +08001249 read = segment_read(player->segment_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001250 real_read = real_read + read;
1251 player->ts_cache_len = real_read;
Wentao MA96f68962022-06-15 19:45:35 +08001252 //DVR_PB_INFO("start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001253 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001254 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001255 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001256 if (read < 0 && errno == EIO) {
1257 //EIO ERROR, EXIT THRAD
Wentao MA96f68962022-06-15 19:45:35 +08001258 DVR_PB_INFO("read error.EIO error, exit thread");
hualing chenb5cd42e2020-04-15 17:03:34 +08001259 DVR_Play_Notify_t notify;
1260 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1261 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001262 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001263 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001264 goto end;
1265 } else if (read < 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001266 DVR_PB_INFO("read error.:%d EIO:%d", errno, EIO);
hualing chenb5cd42e2020-04-15 17:03:34 +08001267 }
hualing chen87072a82020-03-12 16:20:12 +08001268 //if on fb mode and read file end , we need calculate pos to retry read.
1269 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001270 DVR_PB_INFO("recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
hualing chen03fd4942021-07-15 15:56:41 +08001271 read,
1272 real_read,
1273 buf_len,
1274 player->speed,
1275 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001276 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001277 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001278 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001279 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001280 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001281 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001282 continue;
1283 }
Wentao MA96f68962022-06-15 19:45:35 +08001284 //DVR_PB_INFO("read ts [%d]buf_len[%d]speed[%f]real_read:%d", read, buf_len, player->speed, real_read);
hualing chen86e7d482020-01-16 15:13:33 +08001285 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001286 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001287 #define MIN_CACHE_TIME (3000)
Wentao MA804bab12022-11-29 10:01:26 +08001288 int delay = 0;
1289 get_effective_tsplayer_delay_time(player,&delay);
hualing chene3797f02021-01-13 14:53:28 +08001290 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
Wentao MA804bab12022-11-29 10:01:26 +08001291 if (delay > MIN_CACHE_TIME) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001292 //dvr_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001293 /*if cache time > 20s , we think get time is error,*/
Wentao MA804bab12022-11-29 10:01:26 +08001294 if (delay - MIN_CACHE_TIME > 20 * 1000) {
1295 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 +08001296 }
hualing chene41f4372020-06-06 16:29:17 +08001297 }
hualing chen969fe7b2021-05-26 15:13:17 +08001298
hualing chen040df222020-01-17 13:35:02 +08001299 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001300 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001301 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001302
Wentao MA804bab12022-11-29 10:01:26 +08001303 get_effective_tsplayer_delay_time(player,&delay);
hualing chen1679f812021-11-08 15:17:46 +08001304 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1305 player->noData++;
Wentao MA96f68962022-06-15 19:45:35 +08001306 DVR_PB_INFO("playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001307 if (player->noData == check_no_data_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001308 DVR_PB_INFO("playback send nodata event nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001309 //send event here and pause
1310 DVR_Play_Notify_t notify;
1311 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1312 notify.event = DVR_PLAYBACK_EVENT_NODATA;
Wentao MA96f68962022-06-15 19:45:35 +08001313 DVR_PB_INFO("send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001314 //get play statue not here
1315 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1316 }
1317 }
Wentao MAa0b9c002022-11-10 17:47:27 +08001318
1319 DVR_Bool_t cond1 = (ret != DVR_SUCCESS);
1320 DVR_Bool_t cond2 = (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON);
1321 DVR_Bool_t cond3 = (delay <= MIN_TSPLAYER_DELAY_TIME);
1322 DVR_Bool_t cond4 = (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF);
1323 DVR_Bool_t cond5 = (player->delay_is_effective == DVR_TRUE);
1324 DVR_Bool_t cond6 = (reach_end_timeout >= MAX_REACHEND_TIMEOUT);
1325 if ((cond1 && cond2 && (cond3 || cond4) && cond5) || cond6) {
1326 DVR_PB_INFO("REACHED_END conditions: cond1:%d, cond2:%d, (cond3:%d, cond4:%d),"
1327 " cond5:%d, cond6:%d. delay:%d, reach_end_timeout:%d",
1328 (int)cond1,(int)cond2,(int)cond3,(int)cond4,(int)cond5,(int)cond6,
1329 delay,reach_end_timeout);
Wentao MA804bab12022-11-29 10:01:26 +08001330 DVR_Play_Notify_t notify;
1331 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1332 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1333 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
1334 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
1335 dvr_mutex_lock(&player->lock);
1336 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1337 dvr_mutex_unlock(&player->lock);
1338 continue;
1339 } else if (ret != DVR_SUCCESS) {
1340 DVR_PB_INFO("delay:%d pauselive:%d", delay, _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player));
1341 dvr_mutex_lock(&player->lock);
1342 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1343 dvr_mutex_unlock(&player->lock);
1344
1345 get_effective_tsplayer_delay_time(player,&delay);
1346 //not send event and pause,sleep and go to next time to recheck
1347 if (delay < cache_time) {
1348 //delay time is changed and then has data to play, so not start timeout
1349 reach_end_timeout = 0;
1350 } else {
1351 reach_end_timeout = reach_end_timeout + timeout;
1352 }
1353 cache_time = delay;
1354 continue;
1355 }
hualing chen39628212020-05-14 10:35:13 +08001356 reach_end_timeout = 0;
1357 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001358 //change next segment success case
1359 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001360 dvr_mutex_lock(&player->lock);
hualing chen40dd5462021-11-26 19:56:20 +08001361 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001362 DVR_PB_INFO("_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001363 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1364 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001365 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08001366 read = segment_read(player->segment_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001367 real_read = real_read + read;
1368 player->ts_cache_len = real_read;
1369 pthread_mutex_unlock(&player->segment_lock);
1370
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001371 dvr_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001372 }//read len 0 check end
Wentao MA92a14892023-09-12 18:54:47 +08001373
1374#ifdef FOR_SKYWORTH_FETCH_RDK
1375 if (player->openParams.is_timeshift == DVR_TRUE && player->speed >= FF_SPEED)
1376 {
1377 DVR_PlaybackSegmentInfo_t *newest_segment
1378 = list_last_entry(&player->segment_list, DVR_PlaybackSegmentInfo_t, head);
1379 DVR_Bool_t cond1 = (player->cur_segment_id == newest_segment->segment_id);
1380 int32_t time_end = _dvr_get_end_time((DVR_PlaybackHandle_t)player);
1381 uint64_t cur_seg_id = 0;
1382 int32_t time_cur = _dvr_get_play_cur_time((DVR_PlaybackHandle_t)player, &cur_seg_id);
1383 DVR_Bool_t cond2 = (cur_seg_id == player->cur_segment_id && time_end - time_cur < 1000);
1384 if (cond1 && cond2)
1385 {
1386 DVR_PlaybackSpeed_t normal_speed = {PLAYBACK_SPEED_X1,0};
1387 DVR_PB_INFO("Change to normal speed due to FF reaching end");
1388 dvr_playback_set_speed((DVR_PlaybackHandle_t)player,normal_speed);
Wentao MA9e31f692023-09-26 17:42:18 +08001389
1390 DVR_Play_Notify_t notify;
1391 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1392 notify.event = DVR_PLAYBACK_EVENT_TIMESHIFT_FF_REACHED_END;
1393 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, notify.event, &notify, 0);
Wentao MA92a14892023-09-12 18:54:47 +08001394 }
1395 }
1396#endif
1397
hualing chen40dd5462021-11-26 19:56:20 +08001398 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001399 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001400 DVR_PB_INFO("playback send data event resume[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001401 //send event here and pause
1402 DVR_Play_Notify_t notify;
1403 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1404 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
Wentao MA96f68962022-06-15 19:45:35 +08001405 DVR_PB_INFO("----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001406 //get play statue not here
1407 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001408 }
hualing chen39628212020-05-14 10:35:13 +08001409 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001410 //real_read = real_read + read;
Wentao MA270dc0f2022-08-23 13:17:26 +08001411 input_buffer.buf_size = real_read;
1412 input_buffer.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001413
Wentao MA270dc0f2022-08-23 13:17:26 +08001414 //check read data len,if len < 0, we need continue
1415 if (input_buffer.buf_size <= 0 || input_buffer.buf_data == NULL) {
1416 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 +08001417 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001418 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001419 player->ts_cache_len = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001420 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001421 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001422 }
hualing chen266b9502020-04-04 17:39:39 +08001423 //if need write whole block size, we need check read buf len is eq block size.
Wentao MAa0b9c002022-11-10 17:47:27 +08001424 if (b_writed_whole_block == DVR_TRUE
1425 && (player->has_video || player->dec_func || player->cryptor)) {
hualing chen266b9502020-04-04 17:39:39 +08001426 //buf_len is block size value.
1427 if (real_read < buf_len) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001428 //continue to read data from file
Wentao MA96f68962022-06-15 19:45:35 +08001429 DVR_PB_INFO("read buf len[%d] is < block size [%d]", real_read, buf_len);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001430 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001431 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1432 dvr_mutex_unlock(&player->lock);
1433 DVR_PB_INFO("read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001434 continue;
1435 } else if (real_read > buf_len) {
Wentao MA96f68962022-06-15 19:45:35 +08001436 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 +08001437 }
1438 }
1439
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001440 if (player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001441 DVR_CryptoParams_t crypto_params;
1442
1443 memset(&crypto_params, 0, sizeof(crypto_params));
1444 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1445 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1446 crypto_params.segment_id = player->cur_segment.segment_id;
Wentao MAf35c3882023-04-17 12:36:19 +08001447 crypto_params.offset = segment_tell_position(player->segment_handle) - input_buffer.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001448 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
Wentao MA96f68962022-06-15 19:45:35 +08001449 DVR_PB_INFO("offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001450 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1451 crypto_params.input_buffer.addr = (size_t)buf;
1452 crypto_params.input_buffer.size = real_read;
1453
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001454 if (player->is_secure_mode) {
1455 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1456 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1457 crypto_params.output_buffer.size = dec_buf_size;
1458 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001459 input_buffer.buf_data = player->secure_buffer;
1460 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001461 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001462 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001463 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001464 input_buffer.buf_size = crypto_params.output_size;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001465 } else { // only for NAGRA
1466 crypto_params.output_buffer.type = crypto_params.input_buffer.type;
1467 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1468 crypto_params.output_buffer.size = crypto_params.input_buffer.size;
1469 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001470 input_buffer.buf_data = (uint8_t*)crypto_params.output_buffer.addr;
1471 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001472 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001473 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001474 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001475 input_buffer.buf_size = crypto_params.output_buffer.size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001476 }
Yahui Han1fbf3292021-11-08 18:17:19 +08001477 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001478 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001479 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
Wentao MA270dc0f2022-08-23 13:17:26 +08001480 input_buffer.buf_data = dec_bufs.buf_data;
1481 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1482 input_buffer.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001483 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001484rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001485 if (player->drop_ts == DVR_TRUE) {
1486 //need drop ts data when seek occur.we need read next loop,drop this ts data
1487 goto_rewrite = DVR_FALSE;
1488 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001489 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001490 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001491 player->drop_ts = DVR_FALSE;
Wentao MA63c6cba2022-09-20 10:14:29 +08001492 pthread_mutex_unlock(&player->segment_lock);
1493 DVR_PB_INFO("----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001494 continue;
1495 }
hualing chen21a40372021-10-29 11:07:26 +08001496
1497 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001498 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001499 //used for printf first write data time.
1500 //to check change channel kpi.
1501 if (first_write == 0) {
1502 first_write++;
Wentao MA270dc0f2022-08-23 13:17:26 +08001503 DVR_PB_INFO("----first write ts data");
hualing chenb9a02922021-12-14 11:29:47 +08001504 }
1505
Wentao MA270dc0f2022-08-23 13:17:26 +08001506 ret = AmTsPlayer_writeData(player->handle, &input_buffer, write_timeout_ms);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001507 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001508 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001509 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001510 real_read = 0;
1511 write_success++;
shenghui.gengbec6a462023-01-12 15:21:02 +08001512 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001513check0:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001514 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001515 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001516 break;
1517 }
hualing chend241c7a2021-06-22 13:34:27 +08001518 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001519 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001520 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001521 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001522 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1523 goto check0;
1524 }
1525 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001526 //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 +08001527 } else {
Wentao MA804bab12022-11-29 10:01:26 +08001528 pthread_mutex_unlock(&player->segment_lock);
wentao.ma4ee43022022-12-14 13:22:57 +08001529 DVR_PB_DEBUG("write time out write_success:%d buf_size:%d systime:%u",
1530 write_success, input_buffer.buf_size, _dvr_time_getClock());
hualing chena540a7e2020-03-27 16:44:05 +08001531 write_success = 0;
shenghui.gengbec6a462023-01-12 15:21:02 +08001532 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001533check1:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001534 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001535 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001536 break;
1537 }
hualing chend241c7a2021-06-22 13:34:27 +08001538 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001539 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001540 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001541 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001542 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1543 goto check1;
1544 }
1545 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001546 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001547 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001548 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001549 if (!player->is_running) {
Wentao MA96f68962022-06-15 19:45:35 +08001550 DVR_PB_INFO("playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001551 break;
1552 }
hualing chen2aba4022020-03-02 13:49:55 +08001553 goto_rewrite = DVR_TRUE;
1554 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001555 }
1556 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001557end:
Wentao MA96f68962022-06-15 19:45:35 +08001558 DVR_PB_INFO("playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001559 free(buf);
1560 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001561 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001562}
1563
1564
hualing chen040df222020-01-17 13:35:02 +08001565static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001566{
hualing chen040df222020-01-17 13:35:02 +08001567 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001568
1569 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001570 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001571 return DVR_FAILURE;
1572 }
Wentao MA96f68962022-06-15 19:45:35 +08001573 DVR_PB_INFO("start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001574 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001575 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001576 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001577 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001578 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001579 if (rc < 0)
1580 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001581 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001582}
1583
1584
hualing chen040df222020-01-17 13:35:02 +08001585static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001586{
hualing chen040df222020-01-17 13:35:02 +08001587 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001588
1589 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001590 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001591 return DVR_FAILURE;
1592 }
1593
Wentao MA96f68962022-06-15 19:45:35 +08001594 DVR_PB_INFO("stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001595 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001596 {
1597 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001598 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001599 pthread_join(player->playback_thread, NULL);
1600 }
Wentao MAf35c3882023-04-17 12:36:19 +08001601 if (player->segment_handle) {
1602 segment_close(player->segment_handle);
1603 player->segment_handle = NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001604 }
Wentao MA96f68962022-06-15 19:45:35 +08001605 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001606 return 0;
1607}
1608
hualing chen1679f812021-11-08 15:17:46 +08001609static int getFakePid()
1610{
wentao ma7d642782022-10-23 18:26:16 -07001611 return dvr_prop_read_int("vendor.tv.dtv.fake_pid",0xffff);
hualing chen1679f812021-11-08 15:17:46 +08001612}
1613
1614void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1615
1616 DVR_ASSERT(handle);
1617 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1618 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001619 DVR_PB_INFO("player is NULL");
hualing chen1679f812021-11-08 15:17:46 +08001620 return ;
1621 }
1622 if (player->need_seek_start == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001623 DVR_PB_INFO("player need_seek_start is false");
hualing chen1679f812021-11-08 15:17:46 +08001624 return ;
1625 }
1626
hualing chena5f03222021-12-02 11:22:35 +08001627 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001628 player->need_seek_start = DVR_FALSE;
1629 }
Wentao MA96f68962022-06-15 19:45:35 +08001630 DVR_PB_INFO("player player->need_seek_start=%d", player->need_seek_start);
hualing chen1679f812021-11-08 15:17:46 +08001631}
1632
hualing chenb31a6c62020-01-13 17:27:00 +08001633/**\brief Open an dvr palyback
1634 * \param[out] p_handle dvr playback addr
1635 * \param[in] params dvr playback open parameters
1636 * \retval DVR_SUCCESS On success
1637 * \return Error code
1638 */
hualing chen040df222020-01-17 13:35:02 +08001639int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001640
hualing chen040df222020-01-17 13:35:02 +08001641 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001642 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001643
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001644 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
wentao.maa22bc852022-10-13 12:18:06 +08001645 DVR_RETURN_IF_FALSE(player);
hualing chenb31a6c62020-01-13 17:27:00 +08001646
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001647 dvr_mutex_init(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001648 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001649 pthread_condattr_init(&cattr);
1650 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1651 pthread_cond_init(&player->cond, &cattr);
1652 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001653
hualing chen5cbe1a62020-02-10 16:36:36 +08001654 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001655 INIT_LIST_HEAD(&player->segment_list);
1656 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1657 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001658 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001659 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00001660 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen86e7d482020-01-16 15:13:33 +08001661 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001662 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001663 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001664
hualing chen86e7d482020-01-16 15:13:33 +08001665 //store open params
hualing chen040df222020-01-17 13:35:02 +08001666 player->openParams.dmx_dev_id = params->dmx_dev_id;
1667 player->openParams.block_size = params->block_size;
Wentao MA96f68962022-06-15 19:45:35 +08001668 DVR_PB_INFO("playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001669 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001670 player->openParams.event_fn = params->event_fn;
1671 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001672 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001673 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001674
hualing chen5cbe1a62020-02-10 16:36:36 +08001675 player->has_pids = params->has_pids;
1676
hualing chen2aba4022020-03-02 13:49:55 +08001677 player->handle = params->player_handle ;
shenghui.gengbec6a462023-01-12 15:21:02 +08001678 player->control_speed_enable = params->control_speed_enable;
hualing chen6e4bfa52020-03-13 14:37:11 +08001679
1680 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1681 //for test get callback
1682 if (0 && player->player_callback_func == NULL) {
1683 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1684 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
Wentao MA96f68962022-06-15 19:45:35 +08001685 DVR_PB_INFO("playback open get callback[%p][%p][%p][%p]",
hualing chen03fd4942021-07-15 15:56:41 +08001686 player->player_callback_func,
1687 player->player_callback_userdata,
1688 _dvr_tsplayer_callback_test,
1689 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001690 }
1691 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001692
hualing chen86e7d482020-01-16 15:13:33 +08001693 //init has audio and video
1694 player->has_video = DVR_FALSE;
1695 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001696 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001697 player->last_segment_id = 0LL;
1698 player->segment_is_open = DVR_FALSE;
Wentao MA5629ad82022-08-24 10:03:02 +08001699 player->audio_presentation_id = -1;
hualing chenb31a6c62020-01-13 17:27:00 +08001700
hualing chen5cbe1a62020-02-10 16:36:36 +08001701 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001702 player->fffb_current = 0;
1703 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001704 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001705 //seek time
1706 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001707 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001708
Yahui Han1fbf3292021-11-08 18:17:19 +08001709 //allocate cryptor if have clearkey
1710 if (params->keylen > 0) {
1711 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +08001712 (uint8_t *)params->cleariv,
1713 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +08001714 if (!player->cryptor) {
Wentao MA96f68962022-06-15 19:45:35 +08001715 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +08001716 }
1717 } else {
1718 player->cryptor = NULL;
1719 }
1720
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001721 //init secure stuff
1722 player->dec_func = NULL;
1723 player->dec_userdata = NULL;
1724 player->is_secure_mode = 0;
1725 player->secure_buffer = NULL;
1726 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001727 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001728
hualing chen4b7c15d2020-04-07 16:13:48 +08001729 player->fffb_play = DVR_FALSE;
1730
1731 player->last_send_time_id = UINT64_MAX;
1732 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001733 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001734
hualing chend241c7a2021-06-22 13:34:27 +08001735 //speed con init
shenghui.gengbec6a462023-01-12 15:21:02 +08001736 if (player->control_speed_enable == 1) {
hualing chend241c7a2021-06-22 13:34:27 +08001737 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001738 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001739 player->con_spe.sys_dur = 0;
1740 player->con_spe.sys_sta = 0;
1741 }
1742
hualing chen03fd4942021-07-15 15:56:41 +08001743 //limit info
1744 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001745 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001746 //need seek to start pos
1747 player->first_start_time = 0;
Wentao MA01de0e62022-01-10 18:48:23 +08001748 player->first_start_id = UINT64_MAX;
Wentao MAa0b9c002022-11-10 17:47:27 +08001749 player->delay_is_effective = DVR_FALSE;
hualing chen8a657f32021-08-30 13:12:49 +08001750 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001751 //fake_pid init
1752 player->fake_pid = getFakePid();
hualing chen86e7d482020-01-16 15:13:33 +08001753 *p_handle = player;
1754 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001755}
1756
1757/**\brief Close an dvr palyback
1758 * \param[in] handle playback handle
1759 * \retval DVR_SUCCESS On success
1760 * \return Error code
1761 */
hualing chen040df222020-01-17 13:35:02 +08001762int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001763
hualing chen86e7d482020-01-16 15:13:33 +08001764 DVR_ASSERT(handle);
Wentao MA96f68962022-06-15 19:45:35 +08001765 DVR_PB_INFO(":into");
hualing chen040df222020-01-17 13:35:02 +08001766 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001767 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001768 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001769 return DVR_FAILURE;
1770 }
1771
hualing chencc91e1c2020-02-28 13:26:17 +08001772 if (player->state != DVR_PLAYBACK_STATE_STOP)
1773 {
Wentao MA96f68962022-06-15 19:45:35 +08001774 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001775 if (player->cryptor) {
1776 am_crypt_des_close(player->cryptor);
1777 player->cryptor = NULL;
1778 }
hualing chencc91e1c2020-02-28 13:26:17 +08001779 dvr_playback_stop(handle, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08001780 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
hualing chenb96aa2c2020-04-15 14:13:53 +08001781 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001782 DVR_PB_INFO(":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001783 }
Wentao MA96f68962022-06-15 19:45:35 +08001784 DVR_PB_INFO(":into");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001785 dvr_mutex_destroy(&player->lock);
Zhiqiang Hanc9513462022-06-21 09:55:23 +08001786 pthread_mutex_destroy(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001787 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001788
1789 if (player) {
1790 free(player);
hualing chen040df222020-01-17 13:35:02 +08001791 }
Wentao MA96f68962022-06-15 19:45:35 +08001792 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001793 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001794}
1795
Wentao MA270dc0f2022-08-23 13:17:26 +08001796/**\brief Start play audio and video, used start audio api and start video api
hualing chenb31a6c62020-01-13 17:27:00 +08001797 * \param[in] handle playback handle
1798 * \param[in] params audio playback params,contains fmt and pid...
1799 * \retval DVR_SUCCESS On success
1800 * \return Error code
1801 */
hualing chen040df222020-01-17 13:35:02 +08001802int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1803 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA270dc0f2022-08-23 13:17:26 +08001804 am_tsplayer_video_params video_params;
1805 am_tsplayer_audio_params audio_params;
1806 am_tsplayer_audio_params ad_params;
hualing chena540a7e2020-03-27 16:44:05 +08001807
Wentao MA270dc0f2022-08-23 13:17:26 +08001808 memset(&video_params, 0, sizeof(video_params));
1809 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001810
hualing chena540a7e2020-03-27 16:44:05 +08001811 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001812 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001813 return DVR_FAILURE;
1814 }
hualing chencc91e1c2020-02-28 13:26:17 +08001815 uint64_t segment_id = player->cur_segment_id;
Wentao MA96f68962022-06-15 19:45:35 +08001816 DVR_PB_INFO("[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001817
hualing chena540a7e2020-03-27 16:44:05 +08001818 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001819 //can used start api to resume playback
1820 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1821 return dvr_playback_resume(handle);
1822 }
hualing chen87072a82020-03-12 16:20:12 +08001823 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001824 //if flag is paused and not decode first frame. if user resume, we need
hualing chen9b434f02020-06-10 15:06:54 +08001825 //clear flag and set trickmode none
1826 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001827 DVR_PB_INFO("[%p]clear pause live flag and clear trick mode", handle);
hualing chen9b434f02020-06-10 15:06:54 +08001828 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1829 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1830 }
Wentao MA96f68962022-06-15 19:45:35 +08001831 DVR_PB_INFO("stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001832 return DVR_SUCCESS;
1833 }
hualing chen86e7d482020-01-16 15:13:33 +08001834 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001835 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001836 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08001837 DVR_PB_INFO("lock flag:0x%x", flag);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001838 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001839 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08001840 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08001841 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
1842 //audio and video pids are all invalid, return error.
1843 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 +08001844 dvr_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001845 DVR_Play_Notify_t notify;
1846 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1847 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1848 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1849 notify.info.transition_failed_data.segment_id = segment_id;
1850 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001851 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001852 return -1;
1853 }
hualing chen31140872020-03-25 12:29:26 +08001854
hualing chencc91e1c2020-02-28 13:26:17 +08001855 {
Wentao MA270dc0f2022-08-23 13:17:26 +08001856 if (VALID_PID(video_params.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001857 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001858 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001859 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001860 DVR_PB_INFO("set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001861 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1862 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001863 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
Wentao MA96f68962022-06-15 19:45:35 +08001864 DVR_PB_INFO("set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001865 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001866 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001867 DVR_PB_INFO("set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001868 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001869 }
hualing chena93bbbc2020-12-22 17:23:42 +08001870 AmTsPlayer_showVideo(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08001871 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08001872 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001873 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001874 }
hualing chena540a7e2020-03-27 16:44:05 +08001875
Wentao MA270dc0f2022-08-23 13:17:26 +08001876 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 +08001877 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001878 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1879 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1880 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001881 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001882 } else {
1883 player->cmd.last_cmd = player->cmd.cur_cmd;
1884 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001885 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001886 //set fast play
Wentao MA96f68962022-06-15 19:45:35 +08001887 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08001888 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001889 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08001890 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08001891 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08001892 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08001893 dvr_playback_change_seek_state(handle, ad_params.pid);
1894 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08001895 AmTsPlayer_enableADMix(player->handle);
1896 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001897 if (VALID_PID(audio_params.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001898 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08001899 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08001900 dvr_playback_change_seek_state(handle, audio_params.pid);
1901 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08001902 if (player->audio_presentation_id > -1) {
1903 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
1904 }
hualing chen969fe7b2021-05-26 15:13:17 +08001905 AmTsPlayer_startAudioDecoding(player->handle);
1906 }
hualing chen31140872020-03-25 12:29:26 +08001907 }
hualing chencc91e1c2020-02-28 13:26:17 +08001908 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001909 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001910 }
hualing chen86e7d482020-01-16 15:13:33 +08001911 }
hualing chen43a89bc2022-01-19 14:31:20 +08001912#ifdef AVSYNC_USED_PCR
1913 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001914 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08001915 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
1916 }
1917#endif
Wentao MA96f68962022-06-15 19:45:35 +08001918 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001919 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001920 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001921 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001922}
hualing chen040df222020-01-17 13:35:02 +08001923/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001924 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001925 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001926 * \retval DVR_SUCCESS On success
1927 * \return Error code
1928 */
hualing chen040df222020-01-17 13:35:02 +08001929int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1930 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa22bc852022-10-13 12:18:06 +08001931 DVR_RETURN_IF_FALSE(player);
hualing chena540a7e2020-03-27 16:44:05 +08001932
Wentao MA96f68962022-06-15 19:45:35 +08001933 DVR_PB_INFO("add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001934 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001935
hualing chen040df222020-01-17 13:35:02 +08001936 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
wentao.maa22bc852022-10-13 12:18:06 +08001937 DVR_RETURN_IF_FALSE(segment);
hualing chen040df222020-01-17 13:35:02 +08001938 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001939
Wentao MA270dc0f2022-08-23 13:17:26 +08001940 //not memcpy chunk info.
hualing chen040df222020-01-17 13:35:02 +08001941 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001942 //cp location
hualing chen040df222020-01-17 13:35:02 +08001943 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001944
Wentao MA96f68962022-06-15 19:45:35 +08001945 DVR_PB_INFO("add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001946 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001947
1948 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001949 segment->pids.video.pid = info->pids.video.pid;
1950 segment->pids.video.format = info->pids.video.format;
1951 segment->pids.video.type = info->pids.video.type;
1952
hualing chen2aba4022020-03-02 13:49:55 +08001953 segment->pids.audio.pid = info->pids.audio.pid;
1954 segment->pids.audio.format = info->pids.audio.format;
1955 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001956
hualing chen2aba4022020-03-02 13:49:55 +08001957 segment->pids.ad.pid = info->pids.ad.pid;
1958 segment->pids.ad.format = info->pids.ad.format;
1959 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001960
1961 segment->pids.pcr.pid = info->pids.pcr.pid;
1962
Wentao MA96f68962022-06-15 19:45:35 +08001963 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 +08001964 dvr_mutex_lock(&player->lock);
wentao.maa22bc852022-10-13 12:18:06 +08001965 list_add_tail(segment, &player->segment_list);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001966 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001967 DVR_PB_DEBUG("unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001968
hualing chen5cbe1a62020-02-10 16:36:36 +08001969 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001970}
hualing chen040df222020-01-17 13:35:02 +08001971/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001972 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001973 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001974 * \retval DVR_SUCCESS On success
1975 * \return Error code
1976 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001977int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001978 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001979 DVR_PB_INFO("remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001980 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001981 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001982 return DVR_FAILURE;
1983 }
1984
hualing chencc91e1c2020-02-28 13:26:17 +08001985 if (segment_id == player->cur_segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08001986 DVR_PB_INFO("not support remove current segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001987 return DVR_FAILURE;
1988 }
Wentao MA96f68962022-06-15 19:45:35 +08001989 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001990 dvr_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001991 DVR_PlaybackSegmentInfo_t *segment = NULL;
1992 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1993 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001994 {
hualing chen040df222020-01-17 13:35:02 +08001995 if (segment->segment_id == segment_id) {
1996 list_del(&segment->head);
1997 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001998 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001999 }
hualing chen86e7d482020-01-16 15:13:33 +08002000 }
Wentao MA96f68962022-06-15 19:45:35 +08002001 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002002 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002003
2004 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002005}
hualing chen040df222020-01-17 13:35:02 +08002006/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08002007 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08002008 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08002009 * \retval DVR_SUCCESS On success
2010 * \return Error code
2011 */
hualing chen040df222020-01-17 13:35:02 +08002012int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002013 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08002014 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08002015 DVR_PB_INFO("update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08002016 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002017 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002018 return DVR_FAILURE;
2019 }
Wentao MA292380e2022-12-14 14:46:19 +08002020 if (player->vendor != DVR_PLAYBACK_VENDOR_DEF) {
2021 DVR_PB_INFO("In case of vendor Amlogic/Amazon, do not control AV display");
hualing chenf43b8ba2020-07-28 13:11:42 +08002022 return DVR_SUCCESS;
2023 }
hualing chena540a7e2020-03-27 16:44:05 +08002024
hualing chen040df222020-01-17 13:35:02 +08002025 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002026 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002027 dvr_mutex_lock(&player->lock);
wentao.mafd5283f2022-10-14 09:51:13 +08002028 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002029 // prefetch() here incurring self_assign is used to avoid some compiling
2030 // warnings.
2031 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002032 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002033 {
hualing chen040df222020-01-17 13:35:02 +08002034 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08002035 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08002036 }
hualing chen86e7d482020-01-16 15:13:33 +08002037 // if encramble to free, only set flag and return;
2038
2039 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08002040 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002041 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
2042 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08002043 //disable display, mute
Wentao MA96f68962022-06-15 19:45:35 +08002044 DVR_PB_INFO("mute av");
hualing chen2aba4022020-03-02 13:49:55 +08002045 AmTsPlayer_hideVideo(player->handle);
2046 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002047 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
2048 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002049 //enable display, unmute
Wentao MA96f68962022-06-15 19:45:35 +08002050 DVR_PB_INFO("unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08002051 AmTsPlayer_showVideo(player->handle);
2052 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002053 } else {
2054 //do nothing
2055 }
2056 } else {
2057 //do nothing
2058 }
2059 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08002060 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08002061 }
Wentao MA96f68962022-06-15 19:45:35 +08002062 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002063 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002064 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002065}
2066
2067
Wentao MA6dcdc342023-01-30 17:03:19 +08002068static 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 +08002069 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08002070 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08002071 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08002072
Wentao MA6dcdc342023-01-30 17:03:19 +08002073 if (player == NULL) {
2074 DVR_PB_INFO("player is NULL");
2075 return DVR_FAILURE;
2076 }
2077
hualing chen275379e2021-06-15 17:57:21 +08002078 if (type == 0) {
2079 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08002080 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08002081 } else if (type == 1) {
2082 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08002083 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08002084 } else if (type == 2) {
2085 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08002086 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08002087 } else {
2088 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08002089 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08002090 }
2091
Wentao MA6dcdc342023-01-30 17:03:19 +08002092 if (type == 1 && VALID_PID(set_pid.pid) && player->cmd.state == DVR_PLAYBACK_STATE_START
2093 && player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
2094 // Here we mute audio no matter it is displayable or not in starting phase of a playback.
2095 // Audio will be unmuted shortly on receiving first frame event.
2096 AmTsPlayer_setAudioMute(player->handle,1,1);
hualing chena540a7e2020-03-27 16:44:05 +08002097 }
Wentao MA6dcdc342023-01-30 17:03:19 +08002098
hualing chen86e7d482020-01-16 15:13:33 +08002099 if (now_pid.pid == set_pid.pid) {
2100 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08002101 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08002102 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08002103 if (VALID_PID(now_pid.pid)) {
2104 //stop now stream
2105 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002106 //stop video
hualing chenc70a8df2020-05-12 19:23:11 +08002107 if (player->has_video == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002108 DVR_PB_INFO("stop video");
hualing chenc70a8df2020-05-12 19:23:11 +08002109 AmTsPlayer_stopVideoDecoding(player->handle);
2110 player->has_video = DVR_FALSE;
2111 }
hualing chen86e7d482020-01-16 15:13:33 +08002112 } else if (type == 1) {
2113 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002114 if (player->has_audio == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002115 DVR_PB_INFO("stop audio");
hualing chenc70a8df2020-05-12 19:23:11 +08002116 AmTsPlayer_stopAudioDecoding(player->handle);
2117 player->has_audio = DVR_FALSE;
2118 }
hualing chen86e7d482020-01-16 15:13:33 +08002119 } else if (type == 2) {
2120 //stop sub audio
Wentao MA96f68962022-06-15 19:45:35 +08002121 DVR_PB_INFO("stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002122 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002123 } else if (type == 3) {
2124 //pcr
2125 }
2126 }
2127 if (VALID_PID(set_pid.pid)) {
2128 //start
2129 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002130 //start video
2131 am_tsplayer_video_params video_params;
2132 video_params.pid = set_pid.pid;
2133 video_params.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002134 player->has_video = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002135 DVR_PB_INFO("start video pid[%d]fmt[%d]",video_params.pid, video_params.codectype);
2136 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen2aba4022020-03-02 13:49:55 +08002137 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002138 //playback_device_video_start(player->handle,&video_params);
hualing chen86e7d482020-01-16 15:13:33 +08002139 } else if (type == 1) {
2140 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002141 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002142 if (VALID_PID(set_pids.ad.pid)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002143 am_tsplayer_audio_params ad_params;
2144 ad_params.pid = set_pids.ad.pid;
2145 ad_params.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2146 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",ad_params.pid, ad_params.codectype);
2147 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen275379e2021-06-15 17:57:21 +08002148 AmTsPlayer_enableADMix(player->handle);
2149 }
2150
Wentao MA270dc0f2022-08-23 13:17:26 +08002151 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002152
Wentao MA270dc0f2022-08-23 13:17:26 +08002153 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002154
Wentao MA270dc0f2022-08-23 13:17:26 +08002155 audio_params.pid = set_pid.pid;
2156 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002157 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002158 DVR_PB_INFO("start audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2159 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002160 if (player->audio_presentation_id > -1) {
2161 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2162 }
Wentao MA6dcdc342023-01-30 17:03:19 +08002163
hualing chenc70a8df2020-05-12 19:23:11 +08002164 AmTsPlayer_startAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002165 //playback_device_audio_start(player->handle,&audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002166 }
hualing chen86e7d482020-01-16 15:13:33 +08002167 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002168 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002169 if (set_pids.audio.pid == now_pids.audio.pid) {
2170 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002171 DVR_PB_INFO("stop audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002172 AmTsPlayer_stopAudioDecoding(player->handle);
2173 }
Wentao MA270dc0f2022-08-23 13:17:26 +08002174 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002175
Wentao MA270dc0f2022-08-23 13:17:26 +08002176 memset(&audio_params, 0, sizeof(audio_params));
2177 audio_params.pid = set_pid.pid;
2178 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002179 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002180 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2181 AmTsPlayer_setADParams(player->handle, &audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002182 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002183
2184 if (set_pids.audio.pid == now_pids.audio.pid) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002185 am_tsplayer_audio_params audio_params;
hualing chen99508642021-10-18 15:41:17 +08002186
Wentao MA270dc0f2022-08-23 13:17:26 +08002187 memset(&audio_params, 0, sizeof(audio_params));
hualing chen99508642021-10-18 15:41:17 +08002188
Wentao MA270dc0f2022-08-23 13:17:26 +08002189 audio_params.pid = set_pids.audio.pid;
2190 audio_params.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
hualing chen99508642021-10-18 15:41:17 +08002191 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002192 DVR_PB_INFO("restart audio when start ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002193 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002194 if (player->audio_presentation_id > -1) {
2195 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2196 }
hualing chen99508642021-10-18 15:41:17 +08002197 AmTsPlayer_startAudioDecoding(player->handle);
2198 }
hualing chenc70a8df2020-05-12 19:23:11 +08002199 }
hualing chen86e7d482020-01-16 15:13:33 +08002200 } else if (type == 3) {
2201 //pcr
Wentao MA96f68962022-06-15 19:45:35 +08002202 DVR_PB_INFO("start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002203 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002204 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002205 //audio and video all close
2206 if (!player->has_audio && !player->has_video) {
Wentao MA907b6432022-08-01 06:23:08 +00002207 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen5cbe1a62020-02-10 16:36:36 +08002208 }
hualing chen43a89bc2022-01-19 14:31:20 +08002209 } else if (type == 2) {
2210 //case disable ad
Wentao MA96f68962022-06-15 19:45:35 +08002211 DVR_PB_INFO("restart audio when stop ad");
hualing chen43a89bc2022-01-19 14:31:20 +08002212 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
Wentao MA6d045b32022-02-18 18:47:25 +08002213 if (VALID_PID(now_pids.audio.pid)) {
2214 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002215 DVR_PB_INFO("stop audio when stop ad pid [0x%x]", now_pids.audio.pid);
Wentao MA6d045b32022-02-18 18:47:25 +08002216 AmTsPlayer_stopAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002217 am_tsplayer_audio_params audio_params;
hualing chen43a89bc2022-01-19 14:31:20 +08002218
Wentao MA270dc0f2022-08-23 13:17:26 +08002219 memset(&audio_params, 0, sizeof(audio_params));
hualing chen43a89bc2022-01-19 14:31:20 +08002220
Wentao MA270dc0f2022-08-23 13:17:26 +08002221 audio_params.pid = now_pids.audio.pid;
2222 audio_params.codectype= _dvr_convert_stream_fmt(now_pids.audio.format, DVR_TRUE);
Wentao MA6d045b32022-02-18 18:47:25 +08002223 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002224 DVR_PB_INFO("restart audio when stop ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002225 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002226 if (player->audio_presentation_id > -1) {
2227 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2228 }
Wentao MA6d045b32022-02-18 18:47:25 +08002229 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen43a89bc2022-01-19 14:31:20 +08002230 }
Wentao MA6d045b32022-02-18 18:47:25 +08002231 }
hualing chen86e7d482020-01-16 15:13:33 +08002232 }
2233 }
2234 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002235}
hualing chena5f03222021-12-02 11:22:35 +08002236/**\brief dvr play back only update segment pids info
2237 * only update pid info not to start stop codec.
2238 * \param[in] handle playback handle
2239 * \param[in] segment_id need updated pids segment id
2240 * \param[in] p_pids need updated pids
2241 * \retval DVR_SUCCESS On success
2242 * \return Error code
2243 */
2244int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2245 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2246 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002247 DVR_PB_INFO("player is NULL");
hualing chena5f03222021-12-02 11:22:35 +08002248 return DVR_FAILURE;
2249 }
2250
2251 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002252 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002253 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002254 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 +08002255 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002256 // prefetch() here incurring self_assign is used to avoid some compiling
2257 // warnings.
2258 // coverity[self_assign]
hualing chena5f03222021-12-02 11:22:35 +08002259 list_for_each_entry(segment, &player->segment_list, head)
2260 {
2261 if (segment->segment_id == segment_id) {
2262 if (player->cur_segment_id == segment_id) {
2263 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002264 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chena5f03222021-12-02 11:22:35 +08002265 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002266 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002267 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002268 return 0;
2269 }
2270 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2271 }
2272 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002273 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002274 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002275 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002276 break;
2277 }
2278 }
Wentao MA96f68962022-06-15 19:45:35 +08002279 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002280 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002281 return DVR_SUCCESS;
2282}
2283
hualing chen5cbe1a62020-02-10 16:36:36 +08002284/**\brief dvr play back update segment pids
2285 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002286 * add pid stream and stop remove pid stream.
2287 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002288 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002289 * \retval DVR_SUCCESS On success
2290 * \return Error code
2291 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002292int 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 +08002293 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002294 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002295 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002296 return DVR_FAILURE;
2297 }
2298
hualing chen040df222020-01-17 13:35:02 +08002299 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002300 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002301 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002302 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 +08002303
wentao.mafd5283f2022-10-14 09:51:13 +08002304 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002305 // prefetch() here incurring self_assign is used to avoid some compiling
2306 // warnings.
2307 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002308 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002309 {
hualing chen040df222020-01-17 13:35:02 +08002310 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002311
2312 if (player->cur_segment_id == segment_id) {
2313 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002314 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002315 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002316 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002317 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002318 return 0;
2319 }
2320
2321 //if segment is on going segment,we need stop start stream
2322 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA96f68962022-06-15 19:45:35 +08002323 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002324 dvr_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002325 if (segment->pids.audio.pid != p_pids->audio.pid &&
2326 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002327 //not used this to seek to start pos.we will
Wentao MA9a164002022-08-29 11:20:24 +08002328 //add update only api. if need seek to start
hualing chena5f03222021-12-02 11:22:35 +08002329 //pos, we will call only update api and used seek api
2330 //to start and stop av codec
2331 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002332 player->need_seek_start = DVR_FALSE;
2333 pthread_mutex_lock(&player->segment_lock);
2334 player->drop_ts = DVR_TRUE;
2335 player->ts_cache_len = 0;
2336 if (player->first_start_time > 0)
2337 player->first_start_time = player->first_start_time - 1;
Wentao MAf35c3882023-04-17 12:36:19 +08002338 segment_seek(player->segment_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002339 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 +08002340 pthread_mutex_unlock(&player->segment_lock);
2341 }
2342 }
hualing chen1679f812021-11-08 15:17:46 +08002343 //check video pids, stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002344 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
hualing chen1679f812021-11-08 15:17:46 +08002345 //check sub audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002346 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
hualing chen1679f812021-11-08 15:17:46 +08002347 //check audio pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002348 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
hualing chen1679f812021-11-08 15:17:46 +08002349 //check pcr pids stop or restart
Wentao MA6dcdc342023-01-30 17:03:19 +08002350 _do_handle_pid_update((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
hualing chen1679f812021-11-08 15:17:46 +08002351
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002352 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002353 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2354 //if state is pause, we need process at resume api. we only record change info
2355 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2356 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2357 if (VALID_PID(segment->pids.video.pid)
2358 && VALID_PID(p_pids->video.pid)
2359 && segment->pids.video.pid != p_pids->video.pid) {
2360 //restart video
Wentao MA270dc0f2022-08-23 13:17:26 +08002361 v_cmd = DVR_PLAYBACK_CMD_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002362 }
2363 if (!VALID_PID(segment->pids.video.pid)
2364 && VALID_PID(p_pids->video.pid)
2365 && segment->pids.video.pid != p_pids->video.pid) {
2366 //start video
Wentao MA270dc0f2022-08-23 13:17:26 +08002367 v_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002368 }
2369 if (VALID_PID(segment->pids.video.pid)
2370 && !VALID_PID(p_pids->video.pid)
2371 && segment->pids.video.pid != p_pids->video.pid) {
2372 //stop video
Wentao MA270dc0f2022-08-23 13:17:26 +08002373 v_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002374 }
2375 if (VALID_PID(segment->pids.audio.pid)
2376 && VALID_PID(p_pids->audio.pid)
2377 && segment->pids.audio.pid != p_pids->audio.pid) {
2378 //restart audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002379 a_cmd = DVR_PLAYBACK_CMD_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002380 }
2381 if (!VALID_PID(segment->pids.audio.pid)
2382 && VALID_PID(p_pids->audio.pid)
2383 && segment->pids.audio.pid != p_pids->audio.pid) {
2384 //start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002385 a_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002386 }
2387 if (VALID_PID(segment->pids.audio.pid)
2388 && !VALID_PID(p_pids->audio.pid)
2389 && segment->pids.audio.pid != p_pids->audio.pid) {
2390 //stop audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002391 a_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002392 }
Zhiqiang Han400e2a12023-10-23 09:12:32 +08002393
2394 /*process the ad, if main audio exists, but no action*/
2395 if (a_cmd == DVR_PLAYBACK_CMD_NONE && VALID_PID(p_pids->audio.pid)) {
2396
2397 if (VALID_PID(segment->pids.ad.pid)
2398 && VALID_PID(p_pids->ad.pid)
2399 && segment->pids.ad.pid != p_pids->ad.pid) {
2400 //changed
2401 a_cmd = DVR_PLAYBACK_CMD_A_RESTART;
2402 }
2403 if (VALID_PID(segment->pids.ad.pid)
2404 && !VALID_PID(p_pids->ad.pid)
2405 && segment->pids.ad.pid != p_pids->ad.pid) {
2406 //to stop
2407 a_cmd = DVR_PLAYBACK_CMD_A_RESTART;
2408 }
2409 if (!VALID_PID(segment->pids.ad.pid)
2410 && VALID_PID(p_pids->ad.pid)
2411 && segment->pids.ad.pid != p_pids->ad.pid) {
2412 //to start
2413 a_cmd = DVR_PLAYBACK_CMD_A_RESTART;
2414 }
2415
2416 }
2417
hualing chen5cbe1a62020-02-10 16:36:36 +08002418 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2419 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2420 //do nothing
2421 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2422 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2423 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2424 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2425 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2426 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002427 if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2428 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002429 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002430 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
2431 }else if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2432 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002433 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002434 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002435 } else {
2436 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002437 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002438 }
2439
Wentao MA270dc0f2022-08-23 13:17:26 +08002440 if (v_cmd == DVR_PLAYBACK_CMD_V_START
2441 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002442 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002443 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START_A_RESTART;
2444 } else if (v_cmd == DVR_PLAYBACK_CMD_V_START
2445 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002446 //not occur this case
2447 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2448 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2449 } else {
2450 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002451 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002452 }
2453
Wentao MA270dc0f2022-08-23 13:17:26 +08002454 if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2455 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002456 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002457 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_START;
2458 } else if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2459 && a_cmd == DVR_PLAYBACK_CMD_A_RESTART) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002460 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002461 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002462 } else {
2463 //not occur this case
2464 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2465 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2466 }
2467 }
2468 }
hualing chene10666f2020-04-14 13:58:37 +08002469 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002470 }
hualing chen86e7d482020-01-16 15:13:33 +08002471 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002472 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002473 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002474 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002475 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002476 }
hualing chen86e7d482020-01-16 15:13:33 +08002477 }
Wentao MA96f68962022-06-15 19:45:35 +08002478 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002479 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002480 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002481}
2482/**\brief Stop play, will stop video and audio
2483 * \param[in] handle playback handle
2484 * \param[in] clear is clear last frame
2485 * \retval DVR_SUCCESS On success
2486 * \return Error code
2487 */
hualing chen040df222020-01-17 13:35:02 +08002488int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2489 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002490 DVR_UNUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002491 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002492 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002493 return DVR_FAILURE;
2494 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002495 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002496 DVR_PB_INFO(":playback is stoped");
hualing chenb96aa2c2020-04-15 14:13:53 +08002497 return DVR_SUCCESS;
2498 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002499 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002500 DVR_PB_INFO(":playback is stoped");
Ke Gong3c0caba2020-04-21 22:58:18 -07002501 return DVR_SUCCESS;
2502 }
hualing chen87072a82020-03-12 16:20:12 +08002503 _stop_playback_thread(handle);
Wentao MA96f68962022-06-15 19:45:35 +08002504 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002505 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002506 DVR_PB_INFO(":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002507 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002508 if (player->has_video) {
2509 AmTsPlayer_resumeVideoDecoding(player->handle);
2510 }
2511 if (player->has_audio) {
2512 AmTsPlayer_resumeAudioDecoding(player->handle);
2513 }
2514 if (player->has_video) {
2515 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002516 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002517 AmTsPlayer_stopVideoDecoding(player->handle);
2518 }
2519 if (player->has_audio) {
2520 player->has_audio = DVR_FALSE;
2521 AmTsPlayer_stopAudioDecoding(player->handle);
2522 }
hualing chendf118dd2020-05-21 15:49:11 +08002523 if (player->has_ad_audio) {
2524 player->has_ad_audio =DVR_FALSE;
2525 AmTsPlayer_disableADMix(player->handle);
2526 }
hualing chen266b9502020-04-04 17:39:39 +08002527
hualing chen86e7d482020-01-16 15:13:33 +08002528 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002529 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2530 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002531 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen87072a82020-03-12 16:20:12 +08002532 player->cur_segment_id = UINT64_MAX;
2533 player->segment_is_open = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08002534 DVR_PB_DEBUG("unlock");
2535 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002536 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002537 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002538}
2539/**\brief Start play audio
2540 * \param[in] handle playback handle
2541 * \param[in] params audio playback params,contains fmt and pid...
2542 * \retval DVR_SUCCESS On success
2543 * \return Error code
2544 */
hualing chen2aba4022020-03-02 13:49:55 +08002545
Wentao MA270dc0f2022-08-23 13:17:26 +08002546int 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 +08002547 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002548
2549 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002550 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002551 return DVR_FAILURE;
2552 }
hualing chen86e7d482020-01-16 15:13:33 +08002553 _start_playback_thread(handle);
2554 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002555 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002556 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002557
Wentao MA270dc0f2022-08-23 13:17:26 +08002558 if (VALID_PID(ad_param->pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08002559 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002560 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002561 AmTsPlayer_setADParams(player->handle, ad_param);
hualing chendf118dd2020-05-21 15:49:11 +08002562 AmTsPlayer_enableADMix(player->handle);
2563 }
hualing chen969fe7b2021-05-26 15:13:17 +08002564 if (VALID_PID(param->pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08002565 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08002566 player->has_audio = DVR_TRUE;
2567 AmTsPlayer_setAudioParams(player->handle, param);
Wentao MA5629ad82022-08-24 10:03:02 +08002568 if (player->audio_presentation_id > -1) {
2569 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2570 }
hualing chen969fe7b2021-05-26 15:13:17 +08002571 AmTsPlayer_startAudioDecoding(player->handle);
2572 }
hualing chendf118dd2020-05-21 15:49:11 +08002573
hualing chen86e7d482020-01-16 15:13:33 +08002574 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002575 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen040df222020-01-17 13:35:02 +08002576 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002577 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002578 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002579 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002580 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002581}
2582/**\brief Stop play audio
2583 * \param[in] handle playback handle
2584 * \retval DVR_SUCCESS On success
2585 * \return Error code
2586 */
hualing chen040df222020-01-17 13:35:02 +08002587int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2588 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002589
2590 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002591 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002592 return DVR_FAILURE;
2593 }
2594
hualing chen2aba4022020-03-02 13:49:55 +08002595 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002596 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002597 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002598 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002599 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002600 _stop_playback_thread(handle);
2601 } else {
2602 //do nothing.video is playing
2603 }
Wentao MA96f68962022-06-15 19:45:35 +08002604 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002605 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002606
hualing chenf00cdc82020-06-10 14:23:35 +08002607 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002608 player->has_audio = DVR_FALSE;
2609 AmTsPlayer_stopAudioDecoding(player->handle);
2610 }
hualing chen87072a82020-03-12 16:20:12 +08002611
hualing chendf118dd2020-05-21 15:49:11 +08002612 if (player->has_ad_audio) {
2613 player->has_ad_audio =DVR_FALSE;
2614 AmTsPlayer_disableADMix(player->handle);
2615 }
2616
hualing chen87072a82020-03-12 16:20:12 +08002617 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002618 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002619
Wentao MA96f68962022-06-15 19:45:35 +08002620 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002621 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002622 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002623}
2624/**\brief Start play video
2625 * \param[in] handle playback handle
2626 * \param[in] params video playback params,contains fmt and pid...
2627 * \retval DVR_SUCCESS On success
2628 * \return Error code
2629 */
hualing chen2aba4022020-03-02 13:49:55 +08002630int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002631 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002632
2633 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002634 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002635 return DVR_FAILURE;
2636 }
2637
hualing chen86e7d482020-01-16 15:13:33 +08002638 _start_playback_thread(handle);
2639 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002640 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002641 dvr_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002642 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002643 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002644 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002645 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002646
2647 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002648 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002649 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08002650 DVR_PB_INFO("settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002651 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2652 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002653 }
2654 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002655 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen040df222020-01-17 13:35:02 +08002656 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002657 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002658 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002659 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002660 return DVR_SUCCESS;
2661}
2662/**\brief Stop play video
2663 * \param[in] handle playback handle
2664 * \retval DVR_SUCCESS On success
2665 * \return Error code
2666 */
hualing chen040df222020-01-17 13:35:02 +08002667int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2668 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002669
2670 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002671 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002672 return DVR_FAILURE;
2673 }
2674
hualing chen86e7d482020-01-16 15:13:33 +08002675 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002676 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002677 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002678 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002679 _stop_playback_thread(handle);
2680 } else {
2681 //do nothing.audio is playing
2682 }
hualing chen7a56cba2020-04-14 14:09:27 +08002683
Wentao MA96f68962022-06-15 19:45:35 +08002684 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002685 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002686
hualing chen87072a82020-03-12 16:20:12 +08002687 player->has_video = DVR_FALSE;
2688
2689 AmTsPlayer_stopVideoDecoding(player->handle);
2690 //playback_device_video_stop(player->handle);
2691
2692 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002693 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002694
Wentao MA96f68962022-06-15 19:45:35 +08002695 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002696 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002697 return DVR_SUCCESS;
2698}
2699/**\brief Pause play
2700 * \param[in] handle playback handle
2701 * \param[in] flush whether its internal buffers should be flushed
2702 * \retval DVR_SUCCESS On success
2703 * \return Error code
2704 */
hualing chen040df222020-01-17 13:35:02 +08002705int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2706 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002707 DVR_UNUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002708 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002709 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002710 return DVR_FAILURE;
2711 }
hualing chenf00cdc82020-06-10 14:23:35 +08002712 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
Wentao MA96f68962022-06-15 19:45:35 +08002713 DVR_PB_INFO("player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002714 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002715 }
Wentao MA96f68962022-06-15 19:45:35 +08002716 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002717 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002718 DVR_PB_DEBUG("get lock");
hualing chen266b9502020-04-04 17:39:39 +08002719 if (player->has_video)
2720 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002721 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002722 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002723
2724 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002725 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2726 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2727 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002728 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002729 } else {
2730 player->cmd.last_cmd = player->cmd.cur_cmd;
2731 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2732 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002733 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002734 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002735 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002736 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002737
hualing chen86e7d482020-01-16 15:13:33 +08002738 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002739}
2740
hualing chen5cbe1a62020-02-10 16:36:36 +08002741//not add lock
2742static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2743{
2744 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2745
hualing chena540a7e2020-03-27 16:44:05 +08002746 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002747 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002748 return DVR_FAILURE;
2749 }
2750
hualing chen5cbe1a62020-02-10 16:36:36 +08002751 //get video params and audio params
Wentao MA96f68962022-06-15 19:45:35 +08002752 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002753 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08002754 am_tsplayer_video_params video_params;
2755 am_tsplayer_audio_params audio_params;
2756 am_tsplayer_audio_params ad_params;
hualing chencc91e1c2020-02-28 13:26:17 +08002757 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002758
Wentao MA270dc0f2022-08-23 13:17:26 +08002759 memset(&video_params, 0, sizeof(video_params));
2760 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002761
Wentao MA270dc0f2022-08-23 13:17:26 +08002762 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
Wentao MA96f68962022-06-15 19:45:35 +08002763 DVR_PB_INFO("unlock cmd: %d", cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002764 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002765
2766 switch (cmd) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002767 case DVR_PLAYBACK_CMD_AV_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002768 //av restart
Wentao MA270dc0f2022-08-23 13:17:26 +08002769 DVR_PB_INFO("do_cmd av_restart");
hualing chen87072a82020-03-12 16:20:12 +08002770 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002771 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002772 case DVR_PLAYBACK_CMD_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002773 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002774 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002775 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002776 case DVR_PLAYBACK_CMD_V_START:
2777 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002778 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002779 case DVR_PLAYBACK_CMD_V_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002780 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002781 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002782 case DVR_PLAYBACK_CMD_A_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002783 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002784 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002785 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002786 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002787 case DVR_PLAYBACK_CMD_A_START:
2788 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002789 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002790 case DVR_PLAYBACK_CMD_A_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002791 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002792 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002793 case DVR_PLAYBACK_CMD_A_STOP_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002794 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2795 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002796 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002797 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002798 case DVR_PLAYBACK_CMD_A_STOP_V_START:
hualing chen2aba4022020-03-02 13:49:55 +08002799 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002800 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002801 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002802 case DVR_PLAYBACK_CMD_V_STOP_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002803 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2804 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002805 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002806 break;
2807 case DVR_PLAYBACK_CMD_STOP:
2808 break;
2809 case DVR_PLAYBACK_CMD_START:
2810 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002811 case DVR_PLAYBACK_CMD_A_START_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002812 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002813 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2814 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002815 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002816 case DVR_PLAYBACK_CMD_V_START_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002817 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002818 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2819 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002820 break;
2821 case DVR_PLAYBACK_CMD_FF:
2822 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002823 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002824 break;
2825 default:
2826 break;
2827 }
2828 return DVR_SUCCESS;
2829}
2830
2831/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002832 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002833 * \retval DVR_SUCCESS On success
2834 * \return Error code
2835 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002836int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2837 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002838 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002839 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002840 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002841 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002842 return DVR_FAILURE;
2843 }
2844
hualing chena991aa82021-08-16 10:21:15 +08002845 if (dvr_playback_check_limit(handle)) {
2846 //get id and pos to check if we can seek to this pos
Wentao MA96f68962022-06-15 19:45:35 +08002847 DVR_PB_INFO("player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002848 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2849 if (segmentid != player->cur_segment_id ||
2850 (segmentid == player->cur_segment_id &&
2851 pos > _dvr_get_cur_time(handle))) {
2852 //first to seek new pos and to resume
Wentao MA96f68962022-06-15 19:45:35 +08002853 DVR_PB_INFO("seek new pos and to resume");
hualing chena991aa82021-08-16 10:21:15 +08002854 dvr_playback_seek(handle, segmentid, pos);
2855 }
hualing chen7ea70a72021-09-09 11:25:13 +08002856 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002857 DVR_PB_INFO("player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002858 }
hualing chena991aa82021-08-16 10:21:15 +08002859
hualing chen5cbe1a62020-02-10 16:36:36 +08002860 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08002861 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002862 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002863 player->first_frame = 0;
2864 if (player->has_video)
2865 AmTsPlayer_pauseVideoDecoding(player->handle);
2866 if (player->has_audio)
2867 AmTsPlayer_pauseAudioDecoding(player->handle);
2868
hualing chen266b9502020-04-04 17:39:39 +08002869 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002870 DVR_PB_INFO("dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002871 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2872 AmTsPlayer_resumeVideoDecoding(player->handle);
2873 }
2874 if (player->has_audio) {
2875 AmTsPlayer_resumeAudioDecoding(player->handle);
2876 }
2877 //check is has audio param,if has audio .we need start audio,
2878 //we will stop audio when ff fb, if reach end, we will pause.so we need
2879 //start audio when resume play
2880
Wentao MA270dc0f2022-08-23 13:17:26 +08002881 am_tsplayer_video_params video_params;
2882 am_tsplayer_audio_params audio_params;
2883 am_tsplayer_audio_params ad_params;
hualing chen266b9502020-04-04 17:39:39 +08002884 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002885
Wentao MA270dc0f2022-08-23 13:17:26 +08002886 memset(&video_params, 0, sizeof(video_params));
2887 memset(&audio_params, 0, sizeof(audio_params));
2888 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
hualing chen266b9502020-04-04 17:39:39 +08002889 //valid audio pid, start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002890 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 +08002891 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002892 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002893 dvr_playback_change_seek_state(handle, ad_params.pid);
2894 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen969fe7b2021-05-26 15:13:17 +08002895 AmTsPlayer_enableADMix(player->handle);
2896 }
2897
Wentao MA270dc0f2022-08-23 13:17:26 +08002898 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 +08002899 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002900 dvr_playback_change_seek_state(handle, audio_params.pid);
2901 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002902 if (player->audio_presentation_id > -1) {
2903 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2904 }
hualing chen266b9502020-04-04 17:39:39 +08002905 AmTsPlayer_startAudioDecoding(player->handle);
2906 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08002907 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 +08002908 }
hualing chendf118dd2020-05-21 15:49:11 +08002909
hualing chen87072a82020-03-12 16:20:12 +08002910 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2911 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2912 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002913 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002914 } else {
2915 player->cmd.last_cmd = player->cmd.cur_cmd;
2916 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2917 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002918 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002919 }
Wentao MA96f68962022-06-15 19:45:35 +08002920 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002921 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002922 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
Wentao MA96f68962022-06-15 19:45:35 +08002923 DVR_PB_INFO("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002924 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002925 player->first_frame = 0;
2926 if (player->has_video)
2927 AmTsPlayer_pauseVideoDecoding(player->handle);
2928 if (player->has_audio)
2929 AmTsPlayer_pauseAudioDecoding(player->handle);
2930
hualing chene41f4372020-06-06 16:29:17 +08002931 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002932 DVR_PB_INFO("dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002933 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002934 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002935 }
hualing chen041c4092020-04-05 15:11:50 +08002936 if (player->has_audio)
2937 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002938 DVR_PB_INFO("set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen9811b212020-10-29 11:21:44 +08002939 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2940 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chend1686e52022-01-05 17:10:42 +08002941 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002942 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002943 DVR_PB_INFO("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002944 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002945 } else {
2946 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2947 {
Wentao MA96f68962022-06-15 19:45:35 +08002948 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002949 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002950 player->first_frame = 0;
2951 if (player->has_video)
2952 AmTsPlayer_pauseVideoDecoding(player->handle);
2953 if (player->has_audio)
2954 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002955 //clear flag
Wentao MA96f68962022-06-15 19:45:35 +08002956 DVR_PB_INFO("clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002957 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2958 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002959 if (player->has_video) {
2960 AmTsPlayer_resumeVideoDecoding(player->handle);
2961 }
2962 if (player->has_audio)
2963 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002964 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002965 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002966 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002967 }
2968 return DVR_SUCCESS;
2969}
2970
hualing chena540a7e2020-03-27 16:44:05 +08002971static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2972
2973 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2974 DVR_PlaybackSegmentInfo_t *segment = NULL;
2975 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2976 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2977
wentao.mafd5283f2022-10-14 09:51:13 +08002978 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002979 // prefetch() here incurring self_assign is used to avoid some compiling
2980 // warnings.
2981 // coverity[self_assign]
hualing chena540a7e2020-03-27 16:44:05 +08002982 list_for_each_entry(segment, &player->segment_list, head)
2983 {
2984 if (segment->segment_id == segment_id) {
2985 cur_segment = segment;
2986 }
2987 if (segment->segment_id == set_seg_id) {
2988 set_segment = segment;
2989 }
2990 if (cur_segment != NULL && set_segment != NULL) {
2991 break;
2992 }
2993 }
2994 if (cur_segment == NULL || set_segment == NULL) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002995 DVR_PB_INFO("set segment or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002996 return DVR_TRUE;
2997 }
2998 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2999 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
3000 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
3001 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
Wentao MA96f68962022-06-15 19:45:35 +08003002 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 +08003003 return DVR_TRUE;
3004 }
Wentao MA96f68962022-06-15 19:45:35 +08003005 DVR_PB_INFO("play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08003006 return DVR_FALSE;
3007}
3008
hualing chen03fd4942021-07-15 15:56:41 +08003009/**\brief set limit
3010 * \param[in] handle playback handle
3011 * \param[in] rec start time ms
3012 * \param[in] rec limit time ms
3013 * \retval DVR_SUCCESS On success
3014 * \return Error code
3015 */
hualing chen7ea70a72021-09-09 11:25:13 +08003016int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08003017{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
3018
3019 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003020 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003021 return DVR_FAILURE;
3022 }
hualing chen7ea70a72021-09-09 11:25:13 +08003023 _dvr_getClock_sec();
Wentao MA96f68962022-06-15 19:45:35 +08003024 DVR_PB_INFO("lock time %lu limit: %u player->state:%d", time, limit, player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003025 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003026 player->rec_start = time;
3027 player->limit = limit;
Wentao MA96f68962022-06-15 19:45:35 +08003028 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003029 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003030 return DVR_SUCCESS;
3031}
3032
hualing chen5cbe1a62020-02-10 16:36:36 +08003033/**\brief seek
3034 * \param[in] handle playback handle
3035 * \param[in] time_offset time offset base cur segment
3036 * \retval DVR_SUCCESS On success
3037 * \return Error code
3038 */
hualing chencc91e1c2020-02-28 13:26:17 +08003039int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08003040 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08003041 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08003042 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003043 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003044 return DVR_FAILURE;
3045 }
3046
Wentao MA96f68962022-06-15 19:45:35 +08003047 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 +08003048 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003049
hualing chena540a7e2020-03-27 16:44:05 +08003050 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
Wentao MA96f68962022-06-15 19:45:35 +08003051 DVR_PB_INFO("player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08003052
hualing chen5cbe1a62020-02-10 16:36:36 +08003053 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08003054 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08003055 if (ret ==DVR_FAILURE) {
wentao.maa210e5e2022-10-12 16:10:03 +08003056 DVR_PB_ERROR("unlock seek error at open segment");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003057 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003058 return DVR_FAILURE;
3059 }
3060 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
Wentao MAf35c3882023-04-17 12:36:19 +08003061 if (segment_ongoing(player->segment_handle) == DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08003062 DVR_PB_INFO("is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08003063 time_offset = _dvr_get_end_time(handle);
3064 } else {
wentao.maa210e5e2022-10-12 16:10:03 +08003065 DVR_PB_ERROR("is not ongoing segment when seek end, return failure");
Zhiqiang Han447cff02022-12-15 11:13:41 +08003066 dvr_mutex_unlock(&player->lock);
wentao.maa210e5e2022-10-12 16:10:03 +08003067 return DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08003068 }
3069 }
3070
Wentao MA96f68962022-06-15 19:45:35 +08003071 DVR_PB_INFO("seek open id[%lld]flag[0x%x] time_offset %u",
hualing chen03fd4942021-07-15 15:56:41 +08003072 player->cur_segment.segment_id,
3073 player->cur_segment.flags,
3074 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08003075 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08003076 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3077 //forward playback.not seek end of file
3078 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
3079 //default -2000ms
3080 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
3081 }
hualing chen86e7d482020-01-16 15:13:33 +08003082 }
Wentao MA01de0e62022-01-10 18:48:23 +08003083 // Seek can be regarded as a new playback, so keep the start segment_id for it also
hualing chen8a657f32021-08-30 13:12:49 +08003084 if (player->need_seek_start == DVR_TRUE) {
3085 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
Wentao MA01de0e62022-01-10 18:48:23 +08003086 player->first_start_id = player->cur_segment.segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003087 }
hualing chen2aba4022020-03-02 13:49:55 +08003088 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08003089 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08003090 player->ts_cache_len = 0;
Wentao MAf35c3882023-04-17 12:36:19 +08003091 int offset = segment_seek(player->segment_handle, (uint64_t)time_offset, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08003092 DVR_PB_ERROR("seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08003093 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08003094 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08003095
hualing chen2aba4022020-03-02 13:49:55 +08003096 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08003097
3098 player->last_send_time_id = UINT64_MAX;
Wentao MA270dc0f2022-08-23 13:17:26 +08003099 player->last_segment_total = 0LL;
hualing chen03fd4942021-07-15 15:56:41 +08003100 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08003101 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08003102 player->fffb_current = _dvr_time_getClock();
3103 player->fffb_start = player->fffb_current;
3104 player->fffb_start_pcr = _dvr_get_cur_time(handle);
3105 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08003106 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08003107 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003108 //only seek file,not start
Wentao MA96f68962022-06-15 19:45:35 +08003109 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003110 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003111 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08003112 }
hualing chen86e7d482020-01-16 15:13:33 +08003113 //stop play
Wentao MA96f68962022-06-15 19:45:35 +08003114 DVR_PB_ERROR("seek stop play, not inject data has video[%d]audio[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003115 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08003116
hualing chen266b9502020-04-04 17:39:39 +08003117 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08003118 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003119 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003120 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003121 }
3122
hualing chen40dd5462021-11-26 19:56:20 +08003123
hualing chen266b9502020-04-04 17:39:39 +08003124 if (player->has_audio) {
3125 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003126 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003127 }
hualing chendf118dd2020-05-21 15:49:11 +08003128 if (player->has_ad_audio) {
3129 player->has_ad_audio =DVR_FALSE;
3130 AmTsPlayer_disableADMix(player->handle);
3131 }
3132
hualing chen86e7d482020-01-16 15:13:33 +08003133 //start play
Wentao MA270dc0f2022-08-23 13:17:26 +08003134 am_tsplayer_video_params video_params;
3135 am_tsplayer_audio_params audio_params;
3136 am_tsplayer_audio_params ad_params;
hualing chenb31a6c62020-01-13 17:27:00 +08003137
Wentao MA270dc0f2022-08-23 13:17:26 +08003138 memset(&video_params, 0, sizeof(video_params));
3139 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003140
hualing chen040df222020-01-17 13:35:02 +08003141 player->cur_segment_id = segment_id;
3142
3143 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08003144 //get segment info and audio video pid fmt ;
Wentao MA270dc0f2022-08-23 13:17:26 +08003145 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08003146 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003147 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chena5f03222021-12-02 11:22:35 +08003148 //audio and video pid is all invalid, return error.
Wentao MA270dc0f2022-08-23 13:17:26 +08003149 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 +08003150 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08003151 return -1;
3152 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003153 DVR_PB_ERROR("seek start[0x%x]", video_params.pid);
hualing chen86e7d482020-01-16 15:13:33 +08003154 //add
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003155 int v_restarted = 0;
3156 int a_restarted = 0;
hualing chen040df222020-01-17 13:35:02 +08003157 if (sync == DVR_PLAYBACK_SYNC) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003158 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003159 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08003160 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08003161 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08003162 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08003163 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003164 //if is pause state. we need set trick mode.
Wentao MA96f68962022-06-15 19:45:35 +08003165 DVR_PB_INFO("seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003166 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08003167 }
Wentao MA96f68962022-06-15 19:45:35 +08003168 DVR_PB_INFO("start video");
Wentao MA270dc0f2022-08-23 13:17:26 +08003169 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003170 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003171 AmTsPlayer_startVideoDecoding(player->handle);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003172 v_restarted = 1;
hualing chene41f4372020-06-06 16:29:17 +08003173 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
3174 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
3175 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
3176 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
3177 AmTsPlayer_stopFast(player->handle);
3178 }
hualing chen266b9502020-04-04 17:39:39 +08003179 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08003180 } else {
3181 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08003182 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003183 if (VALID_PID(ad_params.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08003184 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003185 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003186 dvr_playback_change_seek_state(handle, ad_params.pid);
3187 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003188 AmTsPlayer_enableADMix(player->handle);
3189 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003190 if (VALID_PID(audio_params.pid) && player->speed == 1.0) {
Wentao MA96f68962022-06-15 19:45:35 +08003191 DVR_PB_INFO("start audio seek");
Wentao MA270dc0f2022-08-23 13:17:26 +08003192 dvr_playback_change_seek_state(handle, audio_params.pid);
3193 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003194 if (player->audio_presentation_id > -1) {
3195 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3196 }
hualing chen969fe7b2021-05-26 15:13:17 +08003197 AmTsPlayer_startAudioDecoding(player->handle);
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003198 a_restarted = 1;
hualing chen969fe7b2021-05-26 15:13:17 +08003199 player->has_audio = DVR_TRUE;
3200 }
hualing chen43a89bc2022-01-19 14:31:20 +08003201#ifdef AVSYNC_USED_PCR
3202 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003203 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003204 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3205 }
3206#endif
hualing chen86e7d482020-01-16 15:13:33 +08003207 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003208 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Zhiqiang Hand48afcd2023-04-03 18:26:27 +08003209 if (v_restarted) {
3210 switch (player->cmd.cur_cmd) {
3211 case DVR_PLAYBACK_CMD_V_RESTART:
3212 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_NONE;
3213 break;
3214 case DVR_PLAYBACK_CMD_A_STOP_V_RESTART:
3215 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
3216 break;
3217 case DVR_PLAYBACK_CMD_A_START_V_RESTART:
3218 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
3219 break;
3220 case DVR_PLAYBACK_CMD_AV_RESTART:
3221 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_RESTART;
3222 break;
3223 default:
3224 break;
3225 }
3226 }
3227 if (a_restarted) {
3228 switch (player->cmd.cur_cmd) {
3229 case DVR_PLAYBACK_CMD_A_RESTART:
3230 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_NONE;
3231 break;
3232 case DVR_PLAYBACK_CMD_V_STOP_A_RESTART:
3233 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
3234 break;
3235 case DVR_PLAYBACK_CMD_V_START_A_RESTART:
3236 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
3237 break;
3238 case DVR_PLAYBACK_CMD_AV_RESTART:
3239 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_RESTART;
3240 break;
3241 default:
3242 break;
3243 }
3244 }
hualing chen2aba4022020-03-02 13:49:55 +08003245 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00003246 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
Wentao MA270dc0f2022-08-23 13:17:26 +08003247 if (VALID_PID(audio_params.pid) || VALID_PID(video_params.pid))
hualing chena5f03222021-12-02 11:22:35 +08003248 player->seek_pause = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08003249 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 +08003250 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
Wentao MA16f870e2022-09-09 11:00:22 +08003251 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chen31140872020-03-25 12:29:26 +08003252 player->speed > 1.0f||
3253 player->speed <= -1.0f) {
Wentao MA96f68962022-06-15 19:45:35 +08003254 DVR_PB_INFO("not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003255 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003256 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003257 DVR_PB_INFO("set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003258 player->cmd.last_cmd = player->cmd.cur_cmd;
3259 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3260 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003261 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen2aba4022020-03-02 13:49:55 +08003262 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003263 player->last_send_time_id = UINT64_MAX;
Wentao MA96f68962022-06-15 19:45:35 +08003264 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003265 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003266
3267 return DVR_SUCCESS;
3268}
hualing chen5cbe1a62020-02-10 16:36:36 +08003269
Wentao MAac5ea062022-08-11 11:44:27 +08003270// Get current playback time position of the ongoing segment.
3271// Notice the return value may be negative. This is because previous segment's
3272// data cached in demux buffer need to be considered.
hualing chen5cbe1a62020-02-10 16:36:36 +08003273static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3274 //get cur time of segment
3275 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003276
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003277 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003278 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003279 return DVR_FAILURE;
3280 }
3281
Wentao MA270dc0f2022-08-23 13:17:26 +08003282 int64_t cache = 0;//default es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003283 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003284 loff_t pos = segment_tell_position(player->segment_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003285 uint64_t cur = 0;
3286 if (player->ts_cache_len > 0 && pos < 0) {
3287 //this case is open new segment end,but cache data is last segment.
3288 //we need used last segment len to send play time.
3289 cur = 0;
3290 } else {
Wentao MAf35c3882023-04-17 12:36:19 +08003291 cur = segment_tell_position_time(player->segment_handle, pos);
hualing chena5f03222021-12-02 11:22:35 +08003292 }
hualing chen21a40372021-10-29 11:07:26 +08003293 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003294 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08003295 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 +08003296 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3297 cache = 0;
3298 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003299 int cur_time = (int)(cur > cache ? cur - cache : 0);
3300 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003301}
3302
Wentao MAac5ea062022-08-11 11:44:27 +08003303// Get current playback time position of the ongoing segment.
3304// Notice the return value may be negative. This is because previous segment's
3305// data cached in demux buffer need to be considered.
hualing chen969fe7b2021-05-26 15:13:17 +08003306static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3307 //get cur time of segment
3308 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA804bab12022-11-29 10:01:26 +08003309 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MAf35c3882023-04-17 12:36:19 +08003310 DVR_RETURN_IF_FALSE(player->segment_handle != NULL);
hualing chen969fe7b2021-05-26 15:13:17 +08003311
hualing chen969fe7b2021-05-26 15:13:17 +08003312 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003313 const loff_t pos = segment_tell_position(player->segment_handle);
3314 const uint64_t cur = segment_tell_position_time(player->segment_handle, pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003315 pthread_mutex_unlock(&player->segment_lock);
Wentao MA01de0e62022-01-10 18:48:23 +08003316
Wentao MA804bab12022-11-29 10:01:26 +08003317 int cache = 0;
3318 get_effective_tsplayer_delay_time(player, &cache);
Wentao MA01de0e62022-01-10 18:48:23 +08003319
hualing chen969fe7b2021-05-26 15:13:17 +08003320 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3321 cache = 0;
3322 }
Wentao MA804bab12022-11-29 10:01:26 +08003323
Wentao MA3e2dc452022-12-20 11:17:16 +08003324 int cur_time = (int)(cur - cache);
Wentao MA804bab12022-11-29 10:01:26 +08003325 *id = player->cur_segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003326
Wentao MA3e2dc452022-12-20 11:17:16 +08003327 if (*id == 0 && cur_time<0) {
3328 cur_time = 0;
3329 }
3330
Wentao MA80179512022-11-03 12:20:03 +08003331 DVR_PB_INFO("***get playback slider position within segment. segment_id [%lld],"
wentao.ma4ee43022022-12-14 13:22:57 +08003332 " segment_slider_pos[%7d ms] = segment_read_pos[%7lld ms] - tsplayer_cache_len[%5ld ms],"
Wentao MA80179512022-11-03 12:20:03 +08003333 " last id [%lld] pos [%lld]",
3334 player->cur_segment_id,cur_time,cur,cache,player->last_send_time_id,pos);
Wentao MA804bab12022-11-29 10:01:26 +08003335
hualing chen969fe7b2021-05-26 15:13:17 +08003336 return cur_time;
3337}
3338
hualing chencc91e1c2020-02-28 13:26:17 +08003339//get current segment current pcr time of read pos
3340static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3341 //get cur time of segment
3342 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAf35c3882023-04-17 12:36:19 +08003343 DVR_RETURN_IF_FALSE(player != NULL);
3344 DVR_RETURN_IF_FALSE(player->segment_handle != NULL);
hualing chena540a7e2020-03-27 16:44:05 +08003345
3346 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003347 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003348 return DVR_FAILURE;
3349 }
3350
hualing chen2aba4022020-03-02 13:49:55 +08003351 pthread_mutex_lock(&player->segment_lock);
Wentao MAf35c3882023-04-17 12:36:19 +08003352 uint64_t end = segment_tell_total_time(player->segment_handle);
hualing chen2aba4022020-03-02 13:49:55 +08003353 pthread_mutex_unlock(&player->segment_lock);
3354 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003355}
3356
hualing chen03fd4942021-07-15 15:56:41 +08003357DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3358{
3359 //check is set limit info
3360 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3361
3362 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003363 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003364 return DVR_FALSE;
3365 }
3366 if (player->rec_start > 0 || player->limit > 0) {
3367 return DVR_TRUE;
3368 }
3369 return DVR_FALSE;
3370}
3371
3372/**\brief set DVR playback calculate expired time len
3373 * \param[in] handle, DVR playback session handle
3374 * \return DVR_SUCCESS on success
3375 * \return error code on failure
3376 */
hualing chen7ea70a72021-09-09 11:25:13 +08003377uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003378{
3379 //calculate expired time to play
3380 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003381 uint32_t cur_time;
3382 uint32_t tmp_time;
3383 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003384 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003385 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003386 return expired;
3387 }
hualing chen7ea70a72021-09-09 11:25:13 +08003388 if (player->rec_start == 0 || player->limit == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003389 DVR_PB_INFO("rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003390 return expired;
3391 }
3392 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003393 cur_time = _dvr_getClock_sec();
3394 if ((cur_time - player->rec_start) > player->limit) {
3395 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3396 expired = *(int*)&tmp_time;
Wentao MA96f68962022-06-15 19:45:35 +08003397 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 +08003398 cur_time,
3399 player->rec_start,
3400 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003401 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3402 }
hualing chen03fd4942021-07-15 15:56:41 +08003403 return expired;
3404}
3405
3406/**\brief set DVR playback obsolete time
3407 * \param[in] handle, DVR playback session handle
3408 * \param[in] obsolete, obsolete len
3409 * \return DVR_SUCCESS on success
3410 * \return error code on failure
3411 */
3412int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3413{
3414 int expired = 0;
3415 //calculate expired time to play
3416 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3417
3418 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003419 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003420 return DVR_FALSE;
3421 }
3422 //get system time
Wentao MA96f68962022-06-15 19:45:35 +08003423 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003424 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003425 player->obsolete = obsolete;
Wentao MA96f68962022-06-15 19:45:35 +08003426 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003427 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003428 return expired;
3429}
3430
3431/**\brief update DVR playback newest segment duration
3432 * \param[in] handle, DVR playback session handle
3433 * \param[in] segmentid, newest segment id
3434 * \param[in] dur dur time ms
3435 * \return DVR_SUCCESS on success
3436 * \return error code on failure
3437 */
3438int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3439uint64_t segmentid, int dur)
3440{
3441 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3442 DVR_PlaybackSegmentInfo_t *segment;
3443 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3444
3445 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003446 DVR_PB_INFO(" player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003447 return DVR_FAILURE;
3448 }
3449 //update the newest segment duration on timeshift mode
wentao.mafd5283f2022-10-14 09:51:13 +08003450 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003451 // prefetch() here incurring self_assign is used to avoid some compiling
3452 // warnings.
3453 // coverity[self_assign]
hualing chen03fd4942021-07-15 15:56:41 +08003454 list_for_each_entry(segment, &player->segment_list, head)
3455 {
3456 if (segment->segment_id == segmentid) {
3457 segment->duration = dur;
3458 break;
3459 }
3460 pre_segment = segment;
3461 }
3462
3463 return DVR_SUCCESS;
3464}
3465
hualing chen7ea70a72021-09-09 11:25:13 +08003466static uint32_t dvr_playback_calculate_last_valid_segment(
3467 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003468{
hualing chen7ea70a72021-09-09 11:25:13 +08003469 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003470 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003471 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003472 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003473 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003474 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3475
3476 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003477 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003478 return DVR_FAILURE;
3479 }
3480 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003481 if (expired == 0) {
3482 *segmentid = player->cur_segment_id;
3483 *pos = 0;
3484 return DVR_SUCCESS;
3485 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003486 DVR_PlaybackSegmentInfo_t *p_seg;
wentao.mafd5283f2022-10-14 09:51:13 +08003487 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003488 // prefetch() here incurring self_assign is used to avoid some compiling
3489 // warnings.
3490 // coverity[self_assign]
Wentao MA270dc0f2022-08-23 13:17:26 +08003491 list_for_each_entry_reverse(p_seg, &player->segment_list, head) {
3492 segment_id = p_seg->segment_id;
hualing chen03fd4942021-07-15 15:56:41 +08003493
Wentao MA270dc0f2022-08-23 13:17:26 +08003494 if ((player->obsolete + pre_off + p_seg->duration) > expired)
hualing chen03fd4942021-07-15 15:56:41 +08003495 break;
3496
Wentao MA270dc0f2022-08-23 13:17:26 +08003497 last_segment_id = p_seg->segment_id;
3498 pre_off += p_seg->duration;
hualing chen03fd4942021-07-15 15:56:41 +08003499 }
3500
3501 if (last_segment_id == segment_id) {
3502 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3503 off = expired;
3504 } else if (player->obsolete >= expired) {
3505 off = 0;
3506 } else {
3507 off = expired - pre_off - player->obsolete;
3508 }
3509 *segmentid = segment_id;
3510 *pos = off;
3511 return DVR_SUCCESS;
3512}
3513
hualing chen4b7c15d2020-04-07 16:13:48 +08003514#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003515//start replay
3516static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3517
3518 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3519 //calculate pcr seek time
3520 int t_diff = 0;
3521 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003522 uint64_t segmentid = 0;
3523 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003524 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003525 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003526 return DVR_FAILURE;
3527 }
3528
hualing chen5cbe1a62020-02-10 16:36:36 +08003529 if (player->fffb_start == -1) {
3530 //set fffb start time ms
3531 player->fffb_start = _dvr_time_getClock();
3532 player->fffb_current = player->fffb_start;
3533 //get segment current time pos
3534 player->fffb_start_pcr = _dvr_get_cur_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003535 DVR_PB_INFO("calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
hualing chen03fd4942021-07-15 15:56:41 +08003536 player->fffb_start_pcr, player->speed);
hualing chene41f4372020-06-06 16:29:17 +08003537 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003538 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003539 } else {
3540 player->fffb_current = _dvr_time_getClock();
3541 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003542 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003543 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003544 if (seek_time <= 0) {
3545 //need seek to pre one segment
3546 seek_time = 0;
3547 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003548 //seek segment pos
Wentao MAf35c3882023-04-17 12:36:19 +08003549 if (player->segment_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003550 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003551 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003552 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3553 //set seek time to 0;
Wentao MA96f68962022-06-15 19:45:35 +08003554 DVR_PB_INFO("segment seek to 0 at fb mode [%d]id[%lld]",
hualing chen03fd4942021-07-15 15:56:41 +08003555 seek_time,
3556 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003557 seek_time = 0;
3558 }
hualing chen03fd4942021-07-15 15:56:41 +08003559 if (IS_FB(player->speed)
3560 && dvr_playback_check_limit(handle)) {
3561 //fb case.check expired time
3562 //get id and pos to check if we can seek to this pos
3563 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3564 //case cur id < segment id
3565 if (player->cur_segment_id < segmentid) {
3566 //expired ts data is player,return error
3567 //
3568 pthread_mutex_unlock(&player->segment_lock);
3569 return 0;
3570 } else if (player->cur_segment_id == segmentid) {
3571 //id is same,compare seek pos
3572 if (seek_time < pos) {
3573 //expired ts data is player,return error
3574 //
3575 pthread_mutex_unlock(&player->segment_lock);
3576 return 0;
3577 }
3578 }
3579 //case can play
3580 }
Wentao MAf35c3882023-04-17 12:36:19 +08003581 if (segment_seek(player->segment_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
hualing chen041c4092020-04-05 15:11:50 +08003582 seek_time = 0;
3583 }
hualing chen2aba4022020-03-02 13:49:55 +08003584 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003585 } else {
3586 //
Wentao MA96f68962022-06-15 19:45:35 +08003587 DVR_PB_INFO("segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003588 }
Wentao MA96f68962022-06-15 19:45:35 +08003589 DVR_PB_INFO("calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003590 seek_time,
3591 player->speed,
3592 player->cur_segment_id,
3593 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003594 }
hualing chen2aba4022020-03-02 13:49:55 +08003595 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003596}
3597
3598
3599//start replay
3600static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3601 //
3602 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003603
3604 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003605 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003606 return DVR_FAILURE;
3607 }
3608
hualing chen5cbe1a62020-02-10 16:36:36 +08003609 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003610 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08003611 DVR_PB_INFO("fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003612 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003613 AmTsPlayer_stopVideoDecoding(player->handle);
3614 }
3615 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003616 DVR_PB_INFO("fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003617 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003618 AmTsPlayer_stopAudioDecoding(player->handle);
3619 }
hualing chendf118dd2020-05-21 15:49:11 +08003620 if (player->has_ad_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003621 DVR_PB_INFO("fffb stop audio");
hualing chendf118dd2020-05-21 15:49:11 +08003622 player->has_ad_audio =DVR_FALSE;
3623 AmTsPlayer_disableADMix(player->handle);
3624 }
hualing chen2aba4022020-03-02 13:49:55 +08003625
hualing chen5cbe1a62020-02-10 16:36:36 +08003626 //start video and audio
3627
Wentao MA270dc0f2022-08-23 13:17:26 +08003628 am_tsplayer_video_params video_params;
3629 am_tsplayer_audio_params audio_params;
3630 am_tsplayer_audio_params ad_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003631
Wentao MA270dc0f2022-08-23 13:17:26 +08003632 memset(&video_params, 0, sizeof(video_params));
3633 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003634
hualing chen87072a82020-03-12 16:20:12 +08003635 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003636
3637 //get segment info and audio video pid fmt ;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003638 //dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08003639 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003640 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003641 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
3642 //audio and video pids are all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003643 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003644 return -1;
3645 }
3646
Wentao MA270dc0f2022-08-23 13:17:26 +08003647 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003648 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003649 DVR_PB_INFO("fffb start video");
3650 //DVR_PB_INFO("fffb start video and save last frame");
hualing chen0888c032020-12-18 17:54:57 +08003651 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003652 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003653 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
Wentao MA270dc0f2022-08-23 13:17:26 +08003654 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003655 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003656 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003657 //playback_device_video_start(player->handle , &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003658 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003659 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003660 }
hualing chen31140872020-03-25 12:29:26 +08003661 //fffb mode need stop fast;
Wentao MA96f68962022-06-15 19:45:35 +08003662 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003663 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003664 return 0;
3665}
3666
3667static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3668 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003669 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003670 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003671 return DVR_FAILURE;
3672 }
3673
3674 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003675 DVR_PB_INFO("lock speed [%f]", player->speed);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003676 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003677
hualing chen2aba4022020-03-02 13:49:55 +08003678 int seek_time = _dvr_playback_calculate_seekpos(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003679 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 +08003680
hualing chen87072a82020-03-12 16:20:12 +08003681 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3682 //seek time set 0
3683 seek_time = 0;
3684 }
hualing chen041c4092020-04-05 15:11:50 +08003685 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003686 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3687 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003688 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
wentao.ma4ee43022022-12-14 13:22:57 +08003689
3690 // An fffb_replay is required here to help finish the last FB play
3691 // at beginning position of a recording. In addition to function
3692 // correctness, another benefit is that after play, demux buffer
3693 // is cleared due to stopVideoDecoding invocation in the process.
3694 // The following resume operation will not be affected by the invalid
3695 // cache length.
3696 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
3697 _dvr_playback_fffb_replay(handle);
3698
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003699 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003700 DVR_PB_DEBUG("unlock");
Wentao MA75775d22023-09-25 16:53:24 +08003701#ifdef FOR_SKYWORTH_FETCH_RDK
3702 DVR_PlaybackSpeed_t normal_speed = {PLAYBACK_SPEED_X1,0};
3703 DVR_PB_INFO("Change to normal speed due to FB reaching beginning");
3704 dvr_playback_set_speed((DVR_PlaybackHandle_t)player,normal_speed);
Wentao MA9e31f692023-09-26 17:42:18 +08003705
3706 {
3707 DVR_Play_Notify_t notify;
3708 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
3709 notify.event = DVR_PLAYBACK_EVENT_TIMESHIFT_FR_REACHED_BEGIN;
3710 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, notify.event, &notify, 0);
3711 }
Wentao MA75775d22023-09-25 16:53:24 +08003712#else
Wentao MA9e31f692023-09-26 17:42:18 +08003713 DVR_PB_INFO("Change to pause due to FB reaching beginning");
hualing chen87072a82020-03-12 16:20:12 +08003714 dvr_playback_pause(handle, DVR_FALSE);
Wentao MA75775d22023-09-25 16:53:24 +08003715#endif
Wentao MA9e31f692023-09-26 17:42:18 +08003716 {
3717 //send event here and pause
3718 DVR_Play_Notify_t notify;
3719 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
3720 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
3721 //get play statue not here
3722 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
3723 DVR_PB_INFO("*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
3724 }
hualing chen2aba4022020-03-02 13:49:55 +08003725 return DVR_SUCCESS;
3726 }
hualing chen2932d372020-04-29 13:44:00 +08003727 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003728 _dvr_init_fffb_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003729 DVR_PB_INFO("*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003730 }
3731 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003732 _dvr_playback_fffb_replay(handle);
3733
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003734 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003735 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003736
hualing chen5cbe1a62020-02-10 16:36:36 +08003737 return DVR_SUCCESS;
3738}
3739
hualing chen87072a82020-03-12 16:20:12 +08003740//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003741static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003742 //
3743 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003744
3745 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003746 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003747 return DVR_FAILURE;
3748 }
3749
hualing chen5cbe1a62020-02-10 16:36:36 +08003750 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003751 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003752 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003753 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003754 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003755 }
3756
3757 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003758 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003759 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003760 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003761 //start video and audio
3762
Wentao MA270dc0f2022-08-23 13:17:26 +08003763 am_tsplayer_video_params video_params;
3764 am_tsplayer_audio_params audio_params;
3765 am_tsplayer_audio_params ad_params;
hualing chen87072a82020-03-12 16:20:12 +08003766 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003767
Wentao MA270dc0f2022-08-23 13:17:26 +08003768 memset(&video_params, 0, sizeof(video_params));
3769 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003770
hualing chen5cbe1a62020-02-10 16:36:36 +08003771 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08003772 DVR_PB_INFO("into");
Wentao MA270dc0f2022-08-23 13:17:26 +08003773 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003774 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003775 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003776 //audio and video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003777 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003778 return -1;
3779 }
3780
Wentao MA270dc0f2022-08-23 13:17:26 +08003781 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003782 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003783 if (trick == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003784 DVR_PB_INFO("settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003785 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003786 }
hualing chen266b9502020-04-04 17:39:39 +08003787 else {
hualing chen2aba4022020-03-02 13:49:55 +08003788 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003789 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003790 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003791 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003792 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003793 }
hualing chena540a7e2020-03-27 16:44:05 +08003794
3795 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
Wentao MA96f68962022-06-15 19:45:35 +08003796 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08003797 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003798 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003799 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08003800 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08003801 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003802 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003803 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003804 AmTsPlayer_enableADMix(player->handle);
3805 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003806 if (VALID_PID(audio_params.pid)) {
hualing chen969fe7b2021-05-26 15:13:17 +08003807 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003808 DVR_PB_INFO("start audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003809 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003810 if (player->audio_presentation_id > -1) {
3811 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3812 }
hualing chen969fe7b2021-05-26 15:13:17 +08003813 AmTsPlayer_startAudioDecoding(player->handle);
3814 }
hualing chendf118dd2020-05-21 15:49:11 +08003815
Wentao MA96f68962022-06-15 19:45:35 +08003816 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003817 AmTsPlayer_stopFast(player->handle);
3818 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3819 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3820 }
hualing chen43a89bc2022-01-19 14:31:20 +08003821#ifdef AVSYNC_USED_PCR
3822 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003823 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003824 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3825 }
3826#endif
hualing chen2aba4022020-03-02 13:49:55 +08003827 player->cmd.last_cmd = player->cmd.cur_cmd;
3828 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003829 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003830 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen5cbe1a62020-02-10 16:36:36 +08003831 return 0;
3832}
3833
3834
hualing chenb31a6c62020-01-13 17:27:00 +08003835/**\brief Set play speed
3836 * \param[in] handle playback handle
3837 * \param[in] speed playback speed
3838 * \retval DVR_SUCCESS On success
3839 * \return Error code
3840 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003841int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3842
3843 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003844
3845 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003846 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003847 return DVR_FAILURE;
3848 }
3849
hualing chena540a7e2020-03-27 16:44:05 +08003850 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08003851 DVR_PB_INFO(" func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003852 return DVR_FAILURE;
3853 }
hualing chenf00cdc82020-06-10 14:23:35 +08003854 if (speed.speed.speed == player->cmd.speed.speed.speed) {
Wentao MA96f68962022-06-15 19:45:35 +08003855 DVR_PB_INFO(" func: eq speed [%d]", speed.speed.speed);
hualing chenf00cdc82020-06-10 14:23:35 +08003856 return DVR_SUCCESS;
3857 }
Wentao MA96f68962022-06-15 19:45:35 +08003858 DVR_PB_INFO("lock func: speed [%d]", speed.speed.speed);
hualing chen1679f812021-11-08 15:17:46 +08003859
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003860 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003861 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3862 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3863 player->cmd.last_cmd = player->cmd.cur_cmd;
3864 }
hualing chene41f4372020-06-06 16:29:17 +08003865
hualing chen31140872020-03-25 12:29:26 +08003866 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003867 IS_KERNEL_SPEED(speed.speed.speed) ) {
3868 //case 1. not start play.only set speed
3869 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3870 //only set speed.and return;
3871 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3872 player->cmd.speed.speed = speed.speed;
3873 player->speed = (float)speed.speed.speed/(float)100;
3874 player->fffb_play = DVR_FALSE;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003875 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003876 DVR_PB_DEBUG("unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003877 return DVR_SUCCESS;
3878 }
3879 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003880 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3881 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003882 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003883 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3884 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003885 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003886 AmTsPlayer_stopFast(player->handle);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003887 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003888 DVR_PB_DEBUG("unlock ---\r\n");
Wentao MA270dc0f2022-08-23 13:17:26 +08003889 _dvr_cmd(handle, DVR_PLAYBACK_CMD_A_START);
Wentao MA96f68962022-06-15 19:45:35 +08003890 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003891 dvr_mutex_lock(&player->lock);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003892 } else {
3893 //set play speed and if audio is start, stop audio.
3894 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003895 DVR_PB_INFO("fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003896 AmTsPlayer_stopAudioDecoding(player->handle);
3897 player->has_audio = DVR_FALSE;
3898 }
Wentao MA96f68962022-06-15 19:45:35 +08003899 DVR_PB_INFO("start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003900 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003901 }
hualing chenbcada022020-04-22 14:27:01 +08003902 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003903 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003904 player->cmd.speed.speed = speed.speed;
3905 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA96f68962022-06-15 19:45:35 +08003906 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003907 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003908 return DVR_SUCCESS;
3909 }
hualing chen31140872020-03-25 12:29:26 +08003910 //case 3 fffb mode
3911 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3912 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3913 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003914 DVR_PB_INFO("set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003915 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003916 player->cmd.speed.speed = speed.speed;
3917 player->speed = (float)speed.speed.speed/(float)100;
3918 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003919 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003920 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003921 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003922 return DVR_SUCCESS;
3923 }
3924 }
3925 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003926 IS_KERNEL_SPEED(speed.speed.speed)) {
3927 //case 1. cur speed is kernel support speed,set kernel speed.
3928 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003929 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003930 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3931 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003932 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003933 AmTsPlayer_stopFast(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003934 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003935 } else {
3936 //set play speed and if audio is start, stop audio.
3937 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003938 DVR_PB_INFO("fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003939 AmTsPlayer_stopAudioDecoding(player->handle);
3940 player->has_audio = DVR_FALSE;
3941 }
Wentao MA96f68962022-06-15 19:45:35 +08003942 DVR_PB_INFO("start fast");
hualing chenf00cdc82020-06-10 14:23:35 +08003943 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003944 }
hualing chena540a7e2020-03-27 16:44:05 +08003945 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003946 player->cmd.speed.speed = speed.speed;
3947 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003948 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003949 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003950 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003951 return DVR_SUCCESS;
3952 }
3953 //case 2 fffb mode
3954 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3955 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3956 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003957 DVR_PB_INFO("set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003958 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003959 player->cmd.speed.speed = speed.speed;
3960 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA270dc0f2022-08-23 13:17:26 +08003961 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
hualing chenbcada022020-04-22 14:27:01 +08003962 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003963 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003964 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003965 return DVR_SUCCESS;
3966 }
hualing chen31140872020-03-25 12:29:26 +08003967 }
hualing chena540a7e2020-03-27 16:44:05 +08003968 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3969 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003970 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003971 } else {
hualing chen31140872020-03-25 12:29:26 +08003972 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003973 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3974 else
3975 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003976 player->fffb_play = DVR_TRUE;
3977 }
3978 DVR_Bool_t init_last_time = DVR_FALSE;
3979 if (player->speed > 0.0f && speed.speed.speed < 0) {
3980 init_last_time = DVR_TRUE;
3981 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3982 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003983 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003984 player->cmd.speed.mode = speed.mode;
3985 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003986 player->speed = (float)speed.speed.speed/(float)100;
3987 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003988 _dvr_init_fffb_t(handle);
3989 if (init_last_time == DVR_TRUE)
3990 player->last_send_time_id = UINT64_MAX;
3991
hualing chen87072a82020-03-12 16:20:12 +08003992 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003993 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3994 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003995 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003996 DVR_PB_INFO("set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003997 _dvr_playback_replay(handle, DVR_FALSE);
3998 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3999 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08004000 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
Wentao MA96f68962022-06-15 19:45:35 +08004001 DVR_PB_INFO("set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08004002 }
Wentao MA96f68962022-06-15 19:45:35 +08004003 DVR_PB_INFO("unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004004 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08004005 return DVR_SUCCESS;
4006}
hualing chen2932d372020-04-29 13:44:00 +08004007
hualing chenb31a6c62020-01-13 17:27:00 +08004008/**\brief Get playback status
4009 * \param[in] handle playback handle
4010 * \param[out] p_status playback status
4011 * \retval DVR_SUCCESS On success
4012 * \return Error code
4013 */
hualing chen2932d372020-04-29 13:44:00 +08004014static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
4015 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08004016//
4017 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08004018 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08004019 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004020 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004021 return DVR_FAILURE;
4022 }
hualing chen1679f812021-11-08 15:17:46 +08004023 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08004024 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004025 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08004026 }
4027
hualing chen5cbe1a62020-02-10 16:36:36 +08004028 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08004029 //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 +08004030 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
4031 player->state == DVR_PLAYBACK_STATE_START) {
4032 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
4033 }
hualing chen041c4092020-04-05 15:11:50 +08004034
hualing chencc91e1c2020-02-28 13:26:17 +08004035 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08004036 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08004037
shenghui.gengbec6a462023-01-12 15:21:02 +08004038 if (player->control_speed_enable == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08004039 if (player->con_spe.ply_sta == 0) {
wentao.mafdba9a02023-01-17 16:43:26 +08004040 DVR_PB_INFO("player dur[%d] sta[%d] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08004041 player->con_spe.ply_dur,
4042 player->con_spe.ply_sta,
4043 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08004044 player->con_spe.ply_sta = p_status->time_cur;
4045 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
4046 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
wentao.mafdba9a02023-01-17 16:43:26 +08004047 DVR_PB_INFO("player dur[%d] sta[%d] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004048 player->con_spe.ply_dur,
4049 player->con_spe.ply_sta,
4050 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08004051 player->con_spe.ply_sta = p_status->time_cur;
4052 }
4053
4054 if (player->con_spe.sys_sta == 0) {
4055 player->con_spe.sys_sta = _dvr_time_getClock();
4056 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
4057 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
4058 player->con_spe.sys_sta = _dvr_time_getClock();
4059 }
4060 }
4061
hualing chen4b7c15d2020-04-07 16:13:48 +08004062 if (player->last_send_time_id == UINT64_MAX) {
4063 player->last_send_time_id = player->cur_segment_id;
4064 player->last_cur_time = p_status->time_cur;
4065 }
4066 if (player->last_send_time_id == player->cur_segment_id) {
Wentao MA80179512022-11-03 12:20:03 +08004067 if (player->speed > 1.0f ) {
hualing chen4b7c15d2020-04-07 16:13:48 +08004068 //ff
4069 if (p_status->time_cur < player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004070 DVR_PB_INFO("get ff time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004071 player->last_cur_time,
4072 p_status->time_cur,
4073 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08004074 p_status->time_cur = player->last_cur_time;
4075 } else {
4076 player->last_cur_time = p_status->time_cur;
4077 }
hualing chene41f4372020-06-06 16:29:17 +08004078 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08004079 //fb
4080 if (p_status->time_cur > player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004081 DVR_PB_INFO("get fb time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004082 player->last_cur_time,
4083 p_status->time_cur,
4084 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08004085 p_status->time_cur = player->last_cur_time;
4086 } else {
4087 player->last_cur_time = p_status->time_cur;
4088 }
4089 }
hualing chend241c7a2021-06-22 13:34:27 +08004090 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08004091 player->last_cur_time = p_status->time_cur;
4092 }
hualing chen969fe7b2021-05-26 15:13:17 +08004093 player->last_send_time_id = segment_id;
4094 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08004095
hualing chen5cbe1a62020-02-10 16:36:36 +08004096 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08004097 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08004098 p_status->flags = player->cur_segment.flags;
Wentao MA96f68962022-06-15 19:45:35 +08004099 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 +08004100 _dvr_playback_state_toString(player->state),
4101 _dvr_playback_state_toString(p_status->state),
4102 p_status->time_cur, p_status->time_end,
4103 p_status->segment_id,player->play_flag,
4104 player->speed,
4105 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08004106 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08004107 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004108 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08004109 }
hualing chen2932d372020-04-29 13:44:00 +08004110 return DVR_SUCCESS;
4111}
4112
4113
4114/**\brief Get playback status
4115 * \param[in] handle playback handle
4116 * \param[out] p_status playback status
4117 * \retval DVR_SUCCESS On success
4118 * \return Error code
4119 */
4120int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
4121 DVR_PlaybackStatus_t *p_status) {
4122//
4123 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4124
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004125 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
4126
hualing chen2932d372020-04-29 13:44:00 +08004127 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004128 DVR_PB_INFO("player is NULL");
hualing chen2932d372020-04-29 13:44:00 +08004129 return DVR_FAILURE;
4130 }
Wentao MA96f68962022-06-15 19:45:35 +08004131 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004132 dvr_mutex_lock(&player->lock);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004133 if (!player->has_video && !player->has_audio)
4134 p_status->time_cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08004135 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004136 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08004137
hualing chenb31a6c62020-01-13 17:27:00 +08004138 return DVR_SUCCESS;
4139}
4140
hualing chen040df222020-01-17 13:35:02 +08004141void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
4142 if (segment != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004143 DVR_PB_INFO("segment id: %lld", segment->segment_id);
4144 DVR_PB_INFO("segment flag: %d", segment->flags);
4145 DVR_PB_INFO("segment location: [%s]", segment->location);
4146 DVR_PB_INFO("segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
4147 DVR_PB_INFO("segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
4148 DVR_PB_INFO("segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
4149 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 +08004150 }
hualing chenb31a6c62020-01-13 17:27:00 +08004151}
4152
hualing chen5cbe1a62020-02-10 16:36:36 +08004153int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004154 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08004155
hualing chena540a7e2020-03-27 16:44:05 +08004156 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004157 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004158 return DVR_FAILURE;
4159 }
4160
hualing chen040df222020-01-17 13:35:02 +08004161 DVR_PlaybackSegmentInfo_t *segment;
wentao.mafd5283f2022-10-14 09:51:13 +08004162 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08004163 // prefetch() here incurring self_assign is used to avoid some compiling
4164 // warnings.
4165 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08004166 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08004167 {
Wentao MA07d3d742022-09-06 09:58:05 +08004168 if (segment->segment_id == segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004169 _dvr_dump_segment(segment);
Wentao MA07d3d742022-09-06 09:58:05 +08004170 break;
hualing chen86e7d482020-01-16 15:13:33 +08004171 }
4172 }
4173 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08004174}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004175
pengfei.liu27cc4ec2020-04-03 16:28:16 +08004176int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004177{
4178 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4179 DVR_RETURN_IF_FALSE(player);
4180 DVR_RETURN_IF_FALSE(func);
4181
Wentao MA96f68962022-06-15 19:45:35 +08004182 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004183 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004184
4185 player->dec_func = func;
4186 player->dec_userdata = userdata;
4187
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004188 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004189 DVR_PB_INFO("out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004190 return DVR_SUCCESS;
4191}
4192
4193int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
4194{
4195 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4196 DVR_RETURN_IF_FALSE(player);
4197 DVR_RETURN_IF_FALSE(p_secure_buf);
4198 DVR_RETURN_IF_FALSE(len);
4199
Wentao MA96f68962022-06-15 19:45:35 +08004200 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004201 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004202
4203 player->is_secure_mode = 1;
4204 player->secure_buffer = p_secure_buf;
4205 player->secure_buffer_size = len;
4206
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004207 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004208 DVR_PB_INFO("out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004209 return DVR_SUCCESS;
4210}
Wentao MA5629ad82022-08-24 10:03:02 +08004211
4212int dvr_playback_set_ac4_preselection_id(DVR_PlaybackHandle_t handle, int presel_id)
4213{
4214 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa210e5e2022-10-12 16:10:03 +08004215 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MA5629ad82022-08-24 10:03:02 +08004216
4217 player->audio_presentation_id = presel_id;
4218 am_tsplayer_result ret = AmTsPlayer_setParams(player->handle,
4219 AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &presel_id);
4220 DVR_RETURN_IF_FALSE(ret == AM_TSPLAYER_OK);
4221
4222 return DVR_SUCCESS;
4223}
Wentao MAa0b9c002022-11-10 17:47:27 +08004224
4225// This function ensures a valid TsPlayer delay time is provided or else it
4226// returns DVR_FAILURE. It is designed to workaround a weakness of
4227// AmTsPlayer_getDelayTime at starting phase of a playback in a short period
4228// of 20ms or less. During the said period, getDelayTime does NOT work as
4229// expect to return real delay length because demux isn't actually running
4230// to provide valid pts to TsPlayer.
Wentao MA804bab12022-11-29 10:01:26 +08004231static int get_effective_tsplayer_delay_time(DVR_Playback_t* play, int *time)
Wentao MAa0b9c002022-11-10 17:47:27 +08004232{
4233 int64_t delay=0;
4234 uint64_t pts_a=0;
4235 uint64_t pts_v=0;
4236
Wentao MA804bab12022-11-29 10:01:26 +08004237 DVR_RETURN_IF_FALSE(play != NULL);
4238 DVR_RETURN_IF_FALSE(play->handle != NULL);
Wentao MAa0b9c002022-11-10 17:47:27 +08004239
Wentao MA804bab12022-11-29 10:01:26 +08004240 AmTsPlayer_getDelayTime(play->handle, &delay);
4241 // In scambled stream situation, the returned TsPlayer delay time is
4242 // invalid and dirty. An additional time check agaginst 15 minutes (900s)
4243 // is introduced to insure such error condition is handled properly.
4244 DVR_RETURN_IF_FALSE((delay >= 0) && (delay <= 900*1000));
Wentao MAa0b9c002022-11-10 17:47:27 +08004245
Wentao MA804bab12022-11-29 10:01:26 +08004246 if (play->delay_is_effective) {
4247 *time = (int)delay;
Wentao MAa0b9c002022-11-10 17:47:27 +08004248 return DVR_SUCCESS;
4249 } else if (delay > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004250 *time = (int)delay;
4251 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004252 return DVR_SUCCESS;
4253 }
4254
Wentao MA804bab12022-11-29 10:01:26 +08004255 AmTsPlayer_getPts(play->handle, TS_STREAM_AUDIO, &pts_a);
4256 AmTsPlayer_getPts(play->handle, TS_STREAM_VIDEO, &pts_v);
Wentao MAa0b9c002022-11-10 17:47:27 +08004257 if ((int64_t)pts_a > 0 || (int64_t)pts_v > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004258 *time = (int)delay;
4259 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004260 return DVR_SUCCESS;
4261 }
4262
4263 return DVR_FAILURE;
4264}
4265