blob: b50f8aa231c27703a0d1bccce0302057118897c3 [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <poll.h>
11#include <errno.h>
12#include <signal.h>
13#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080014#include <errno.h>
hualing chen03fd4942021-07-15 15:56:41 +080015#include "dvr_utils.h"
16#include "dvr_types.h"
hualing chenb31a6c62020-01-13 17:27:00 +080017#include "dvr_playback.h"
Yahui Han1fbf3292021-11-08 18:17:19 +080018#include "am_crypt.h"
hualing chenb31a6c62020-01-13 17:27:00 +080019
Wentao MA96f68962022-06-15 19:45:35 +080020#define PB_LOG_TAG "libdvr-playback"
21#define DVR_PB_DEBUG(...) DVR_LOG_PRINT(LOG_LV_DEBUG, PB_LOG_TAG, __VA_ARGS__)
22#define DVR_PB_INFO(...) DVR_LOG_PRINT(LOG_LV_INFO, PB_LOG_TAG, __VA_ARGS__)
23#define DVR_PB_WARN(...) DVR_LOG_PRINT(LOG_LV_WARN, PB_LOG_TAG, __VA_ARGS__)
24#define DVR_PB_ERROR(...) DVR_LOG_PRINT(LOG_LV_ERROR, PB_LOG_TAG, __VA_ARGS__)
25#define DVR_PB_FATAL(...) DVR_LOG_PRINT(LOG_LV_FATAL, PB_LOG_TAG, __VA_ARGS__)
hualing chena540a7e2020-03-27 16:44:05 +080026
hualing chenb31a6c62020-01-13 17:27:00 +080027#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080028
hualing chend241c7a2021-06-22 13:34:27 +080029#define CONTROL_SPEED_ENABLE 0
hualing chena540a7e2020-03-27 16:44:05 +080030
31#define FF_SPEED (2.0f)
32#define FB_SPEED (-1.0f)
33#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080034#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080035
36#define IS_KERNEL_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_X1) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
37#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
38
Wentao MA907b6432022-08-01 06:23:08 +000039#define DVR_PLAYER_CHANGE_STATE(player,newstate)\
40 DVR_PB_INFO("%s:%d player %p changes state from %s to %s",__func__,__LINE__,\
41 player,_dvr_playback_state_toString(player->state),_dvr_playback_state_toString(newstate));\
42 player->state=newstate;
43
hualing chenb31a6c62020-01-13 17:27:00 +080044
hualing chenb5cd42e2020-04-15 17:03:34 +080045#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080046#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080047//if tsplayer delay time < 200 and no data can read, we will pause
48#define MIN_TSPLAYER_DELAY_TIME (200)
49
hualing chen041c4092020-04-05 15:11:50 +080050#define MAX_CACHE_TIME (30000)
hualing chen43a89bc2022-01-19 14:31:20 +080051//used pcr to control avsync,default not used
52//#define AVSYNC_USED_PCR 1
hualing chena540a7e2020-03-27 16:44:05 +080053static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080054//
55static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chen99508642021-10-18 15:41:17 +080056static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_PlaybackPids_t now_pids, DVR_PlaybackPids_t pids, int type);
hualing chencc91e1c2020-02-28 13:26:17 +080057static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
58static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080059static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080060static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080061static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
62 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080063static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen7ea70a72021-09-09 11:25:13 +080064static uint32_t dvr_playback_calculate_last_valid_segment(
65 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos);
Wentao MA804bab12022-11-29 10:01:26 +080066static int get_effective_tsplayer_delay_time(DVR_Playback_t* playback, int *time);
hualing chen87072a82020-03-12 16:20:12 +080067
hualing chenbcada022020-04-22 14:27:01 +080068
hualing chena5f03222021-12-02 11:22:35 +080069
hualing chenbcada022020-04-22 14:27:01 +080070static char* _cmd_toString(int cmd)
71{
72
73 char *string[DVR_PLAYBACK_CMD_NONE+1]={
74 "start",
75 "stop",
Wentao MA270dc0f2022-08-23 13:17:26 +080076 "v_start",
77 "a_start",
78 "v_stop",
79 "a_stop",
80 "v_restart",
81 "a_restart",
82 "av_restart",
83 "v_stop_a_start",
84 "a_stop_v_start",
85 "v_stop_a_restart",
86 "a_stop_v_restart",
87 "v_start_a_restart",
88 "a_start_v_restart",
hualing chenbcada022020-04-22 14:27:01 +080089 "pause",
90 "resume",
91 "seek",
92 "ff",
93 "fb",
94 "NONE"
95 };
96
97 if (cmd > DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +080098 return "unknown";
hualing chenbcada022020-04-22 14:27:01 +080099 } else {
100 return string[cmd];
101 }
102}
103
104
Wentao MA907b6432022-08-01 06:23:08 +0000105static char* _dvr_playback_state_toString(int state)
hualing chen6d24aa92020-03-23 18:43:47 +0800106{
Wentao MA907b6432022-08-01 06:23:08 +0000107 char *strings[5]={
108 "START",
109 "STOP",
110 "PAUSE",
111 "FF",
112 "FB",
hualing chen6d24aa92020-03-23 18:43:47 +0800113 };
114
Wentao MA907b6432022-08-01 06:23:08 +0000115 if (state >= 5 || state < 0) {
116 return "UNKNOWN";
hualing chen6d24aa92020-03-23 18:43:47 +0800117 }
Wentao MA907b6432022-08-01 06:23:08 +0000118 return strings[state];
hualing chen6d24aa92020-03-23 18:43:47 +0800119}
hualing chena540a7e2020-03-27 16:44:05 +0800120
121static DVR_Bool_t _dvr_support_speed(int speed) {
122
123 DVR_Bool_t ret = DVR_FALSE;
124
125 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800126 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800127 case PLAYBACK_SPEED_FBX2:
128 case PLAYBACK_SPEED_FBX4:
129 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800130 case PLAYBACK_SPEED_FBX16:
131 case PLAYBACK_SPEED_FBX12:
132 case PLAYBACK_SPEED_FBX32:
133 case PLAYBACK_SPEED_FBX48:
134 case PLAYBACK_SPEED_FBX64:
135 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800136 case PLAYBACK_SPEED_S2:
137 case PLAYBACK_SPEED_S4:
138 case PLAYBACK_SPEED_S8:
139 case PLAYBACK_SPEED_X1:
140 case PLAYBACK_SPEED_X2:
141 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800142 case PLAYBACK_SPEED_X3:
143 case PLAYBACK_SPEED_X5:
144 case PLAYBACK_SPEED_X6:
145 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800146 case PLAYBACK_SPEED_X8:
147 case PLAYBACK_SPEED_X12:
148 case PLAYBACK_SPEED_X16:
149 case PLAYBACK_SPEED_X32:
150 case PLAYBACK_SPEED_X48:
151 case PLAYBACK_SPEED_X64:
152 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800153 ret = DVR_TRUE;
154 break;
155 default:
Wentao MA96f68962022-06-15 19:45:35 +0800156 DVR_PB_INFO("not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800157 break;
158 }
159 return ret;
160}
Wentao MA907b6432022-08-01 06:23:08 +0000161
hualing chen6e4bfa52020-03-13 14:37:11 +0800162void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
163{
Wentao MA96f68962022-06-15 19:45:35 +0800164 DVR_PB_INFO("in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800165 DVR_Playback_t *player = NULL;
166 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800167 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800168 DVR_PB_INFO("play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800169 }
170 switch (event->type) {
171 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
172 {
Wentao MA96f68962022-06-15 19:45:35 +0800173 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800174 event->event.video_format.frame_width,
175 event->event.video_format.frame_height,
176 event->event.video_format.frame_rate);
177 break;
178 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800179 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
180 {
Wentao MA16f870e2022-09-09 11:00:22 +0800181 if (player == NULL) {
182 DVR_PB_WARN("player is null at line %d",__LINE__);
183 break;
184 }
Wentao MA96f68962022-06-15 19:45:35 +0800185 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800186 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800187 break;
188 }
189 default:
190 break;
191 }
192}
Wentao MA804bab12022-11-29 10:01:26 +0800193
hualing chen2aba4022020-03-02 13:49:55 +0800194void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
195{
Wentao MA804bab12022-11-29 10:01:26 +0800196 DVR_Playback_t *play = (DVR_Playback_t*)user_data;
197 if (play == NULL) {
198 DVR_PB_WARN("play is invalid in %s",__func__);
199 return;
hualing chen6e4bfa52020-03-13 14:37:11 +0800200 }
hualing chen2aba4022020-03-02 13:49:55 +0800201 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800202 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
Wentao MA804bab12022-11-29 10:01:26 +0800203 DVR_PB_INFO("Received AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME");
204 if (play->first_trans_ok == DVR_FALSE) {
205 play->first_trans_ok = DVR_TRUE;
206 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)play, DVR_FALSE);
207 }
208 play->first_frame = 1;
209 play->seek_pause = DVR_FALSE;
210 break;
hualing chen487ae6d2020-07-22 10:34:11 +0800211 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
Wentao MA804bab12022-11-29 10:01:26 +0800212 DVR_PB_INFO("Received AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO");
213 if (play->first_trans_ok == DVR_FALSE && play->has_video == DVR_FALSE) {
214 play->first_trans_ok = DVR_TRUE;
215 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)play, DVR_FALSE);
216 }
217 if (play->has_video == DVR_FALSE) {
218 play->first_frame = 1;
219 play->seek_pause = DVR_FALSE;
220 }
hualing chen487ae6d2020-07-22 10:34:11 +0800221 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800222 default:
223 break;
224 }
Wentao MA804bab12022-11-29 10:01:26 +0800225 if (play->player_callback_func == NULL) {
226 DVR_PB_WARN("play callback function %p is invalid",play->player_callback_func);
227 return;
hualing chen2aba4022020-03-02 13:49:55 +0800228 }
Wentao MA804bab12022-11-29 10:01:26 +0800229 play->player_callback_func(play->player_callback_userdata, event);
hualing chen2aba4022020-03-02 13:49:55 +0800230}
hualing chencc91e1c2020-02-28 13:26:17 +0800231
hualing chen5cbe1a62020-02-10 16:36:36 +0800232//convert video and audio fmt
233static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
234 int format = 0;
235 if (is_audio == DVR_FALSE) {
236 //for video fmt
237 switch (fmt)
238 {
239 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800240 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800241 break;
242 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800243 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800244 break;
245 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800246 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800247 break;
248 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800249 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800250 break;
hualing chena540a7e2020-03-27 16:44:05 +0800251 case DVR_VIDEO_FORMAT_VP9:
252 format = AV_VIDEO_CODEC_VP9;
253 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800254 }
255 } else {
256 //for audio fmt
257 switch (fmt)
258 {
259 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800260 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800261 break;
262 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800263 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800264 break;
265 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800266 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800267 break;
268 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800269 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800270 break;
hualing chena540a7e2020-03-27 16:44:05 +0800271 case DVR_AUDIO_FORMAT_AAC:
272 format = AV_AUDIO_CODEC_AAC;
273 break;
274 case DVR_AUDIO_FORMAT_LATM:
275 format = AV_AUDIO_CODEC_LATM;
276 break;
277 case DVR_AUDIO_FORMAT_PCM:
278 format = AV_AUDIO_CODEC_PCM;
279 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800280 case DVR_AUDIO_FORMAT_AC4:
281 format = AV_AUDIO_CODEC_AC4;
282 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800283 }
284 }
285 return format;
286}
hualing chen040df222020-01-17 13:35:02 +0800287static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800288{
hualing chen040df222020-01-17 13:35:02 +0800289 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800290
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800291 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800292 return -1;
293
hualing chena540a7e2020-03-27 16:44:05 +0800294 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800295}
hualing chena540a7e2020-03-27 16:44:05 +0800296
hualing chen7ea70a72021-09-09 11:25:13 +0800297
298//get sys time sec
299static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800300{
301 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800302 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800303 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800304 s = (uint32_t)(ts.tv_sec);
Wentao MA96f68962022-06-15 19:45:35 +0800305 DVR_PB_INFO("n:%u", s);
hualing chen7ea70a72021-09-09 11:25:13 +0800306 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800307}
hualing chen86e7d482020-01-16 15:13:33 +0800308
hualing chen7ea70a72021-09-09 11:25:13 +0800309//get sys time ms
310static uint32_t _dvr_time_getClock(void)
311{
312 struct timespec ts;
313 uint32_t ms;
314 clock_gettime(CLOCK_REALTIME, &ts);
315 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
316 return ms;
317}
hualing chenb31a6c62020-01-13 17:27:00 +0800318
Wentao MA270dc0f2022-08-23 13:17:26 +0800319//timeout wait signal
hualing chen040df222020-01-17 13:35:02 +0800320static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800321{
hualing chen040df222020-01-17 13:35:02 +0800322 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800323
hualing chena540a7e2020-03-27 16:44:05 +0800324
325 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800326 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800327 return DVR_FAILURE;
328 }
329
hualing chen86e7d482020-01-16 15:13:33 +0800330 struct timespec ts;
331 clock_gettime(CLOCK_MONOTONIC, &ts);
332 //ms为毫秒,换算成秒
333 ts.tv_sec += ms/1000;
334 //在outtime的基础上,增加ms毫秒
335 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
336 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
337 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
338 //us的值有可能超过1秒,
339 ts.tv_sec += us / 1000000;
340 us = us % 1000000;
341 ts.tv_nsec = us * 1000;//换算成纳秒
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800342
343 int val = dvr_mutex_save(&player->lock);
344 pthread_cond_timedwait(&player->cond, &player->lock.lock, &ts);
345 dvr_mutex_restore(&player->lock, val);
hualing chen86e7d482020-01-16 15:13:33 +0800346 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800347}
Wentao MA804bab12022-11-29 10:01:26 +0800348
hualing chenb31a6c62020-01-13 17:27:00 +0800349//send signal
hualing chen040df222020-01-17 13:35:02 +0800350static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800351{
hualing chen87072a82020-03-12 16:20:12 +0800352 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800353
354 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800355 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800356 return DVR_FAILURE;
357 }
Wentao MA96f68962022-06-15 19:45:35 +0800358 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800359 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800360 pthread_cond_signal(&player->cond);
Wentao MA96f68962022-06-15 19:45:35 +0800361 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800362 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800363 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800364}
365
hualing chen2932d372020-04-29 13:44:00 +0800366//send playback event, need check is need lock first
367static 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 +0800368
369 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800370
371 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800372 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800373 return DVR_FAILURE;
374 }
375
hualing chencc91e1c2020-02-28 13:26:17 +0800376 switch (evt) {
377 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800378 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800379 break;
380 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
381 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800382 DVR_PB_INFO("trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800383 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800384 break;
385 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
386 break;
387 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
388 break;
389 case DVR_PLAYBACK_EVENT_NO_KEY:
390 break;
391 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800392 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800393 DVR_PB_INFO("reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800394 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800395 break;
396 case DVR_PLAYBACK_EVENT_REACHED_END:
397 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800398 DVR_PB_INFO("reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800399 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800400 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800401 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800402 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800403 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800404 default:
405 break;
406 }
407 if (player->openParams.event_fn != NULL)
408 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800409 return DVR_SUCCESS;
410}
hualing chen2932d372020-04-29 13:44:00 +0800411static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800412{
413 DVR_Play_Notify_t notify;
414 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
415 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
416 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800417 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800418 return DVR_SUCCESS;
419}
420
hualing chen2932d372020-04-29 13:44:00 +0800421static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800422{
423 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800424
Wentao MA16f870e2022-09-09 11:00:22 +0800425 if (player == NULL) {
426 DVR_PB_ERROR("player is NULL");
427 return DVR_FAILURE;
428 }
hualing chene3797f02021-01-13 14:53:28 +0800429 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800430 if (CONTROL_SPEED_ENABLE == 0)
431 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800432 }
hualing chena540a7e2020-03-27 16:44:05 +0800433
hualing chen03fd4942021-07-15 15:56:41 +0800434 if (player->send_time == 0) {
hualing chend241c7a2021-06-22 13:34:27 +0800435 if (CONTROL_SPEED_ENABLE == 0)
436 player->send_time = _dvr_time_getClock() + 500;
437 else
438 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800439 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen56c0a162022-01-27 17:01:50 +0800440 if ((player->send_time - _dvr_time_getClock()) > 1000) {
441 player->send_time = _dvr_time_getClock() + 500;
Wentao MA96f68962022-06-15 19:45:35 +0800442 DVR_PB_INFO("player send time occur system time changed!!!!!");
hualing chen56c0a162022-01-27 17:01:50 +0800443 } else {
444 return DVR_SUCCESS;
445 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800446 }
hualing chend241c7a2021-06-22 13:34:27 +0800447 if (CONTROL_SPEED_ENABLE == 0)
448 player->send_time = _dvr_time_getClock() + 500;
449 else
450 player->send_time = _dvr_time_getClock() + 20;
451
hualing chen6e4bfa52020-03-13 14:37:11 +0800452 DVR_Play_Notify_t notify;
453 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
454 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
455 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800456 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800457 return DVR_SUCCESS;
458}
459
hualing chencc91e1c2020-02-28 13:26:17 +0800460//check is ongoing segment
461static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
462
463 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800464
465 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800466 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800467 return DVR_FAILURE;
468 }
wentao.maa210e5e2022-10-12 16:10:03 +0800469 int ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800470 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800471 return DVR_FALSE;
472 }
hualing chencc91e1c2020-02-28 13:26:17 +0800473 return DVR_TRUE;
474}
hualing chen4b7c15d2020-04-07 16:13:48 +0800475
476
477static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
478 DVR_Playback_t *player = (DVR_Playback_t *) handle;
479 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800480 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800481 player->fffb_current = player->fffb_start;
482 //get segment current time pos
483 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800484 player->next_fffb_time = _dvr_time_getClock();
485
486 return DVR_SUCCESS;
487}
488
hualing chen2aba4022020-03-02 13:49:55 +0800489static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
490 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800491 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800492 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800493 player->fffb_current = player->fffb_start;
494 //get segment current time pos
495 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800496
hualing chen2aba4022020-03-02 13:49:55 +0800497 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800498 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800499 return DVR_SUCCESS;
500}
hualing chencc91e1c2020-02-28 13:26:17 +0800501//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800502static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
503
504 DVR_Playback_t *player = (DVR_Playback_t *) handle;
505 DVR_PlaybackSegmentInfo_t *segment;
506 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
507
hualing chena540a7e2020-03-27 16:44:05 +0800508 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800509 DVR_PB_INFO(" player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800510 return DVR_FAILURE;
511 }
512
hualing chen87072a82020-03-12 16:20:12 +0800513 int found = 0;
514 int found_eq_id = 0;
wentao.mafd5283f2022-10-14 09:51:13 +0800515 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800516 // prefetch() here incurring self_assign is used to avoid some compiling
517 // warnings.
518 // coverity[self_assign]
hualing chen87072a82020-03-12 16:20:12 +0800519 list_for_each_entry(segment, &player->segment_list, head)
520 {
521 if (player->segment_is_open == DVR_FALSE) {
522 //get first segment from list, case segment is not open
523 if (!IS_FB(player->speed))
524 found = 1;
525 } else if (segment->segment_id == segmentid) {
526 //find cur segment, we need get next one
527 found_eq_id = 1;
528 if (!IS_FB(player->speed)) {
529 found = 1;
530 continue;
531 } else {
532 //if is fb mode.we need used pre segment
533 if (pre_segment != NULL) {
534 found = 1;
535 } else {
536 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800537 DVR_PB_INFO("not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800538 return DVR_FAILURE;
539 }
540 }
541 }
542 if (found == 1) {
543 found = 2;
544 break;
545 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800546 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800547 }
548 if (found != 2) {
549 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800550 DVR_PB_INFO("not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800551 return DVR_FAILURE;
552 }
Wentao MA96f68962022-06-15 19:45:35 +0800553 DVR_PB_INFO("found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800554 return DVR_SUCCESS;
555}
556
557//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800558static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800559
hualing chen040df222020-01-17 13:35:02 +0800560 DVR_Playback_t *player = (DVR_Playback_t *) handle;
561 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800562 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800563 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800564 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800565 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800566 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800567 return DVR_FAILURE;
568 }
569
hualing chen03fd4942021-07-15 15:56:41 +0800570 if (IS_FB(player->speed)
571 && dvr_playback_check_limit(handle)) {
572 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
573 //case cur id < segment id
574 if (player->cur_segment_id <= segmentid) {
575 //expired ts data is player,return error
Wentao MA96f68962022-06-15 19:45:35 +0800576 DVR_PB_INFO("reach start segment ,return error");
hualing chen03fd4942021-07-15 15:56:41 +0800577 return DVR_FAILURE;
578 }
Wentao MA96f68962022-06-15 19:45:35 +0800579 DVR_PB_INFO("has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800580 }
581
hualing chen86e7d482020-01-16 15:13:33 +0800582 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800583 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800584
wentao.mafd5283f2022-10-14 09:51:13 +0800585 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800586 // prefetch() here incurring self_assign is used to avoid some compiling
587 // warnings.
588 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +0800589 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800590 {
hualing chencc91e1c2020-02-28 13:26:17 +0800591 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800592 //get first segment from list, case segment is not open
593 if (!IS_FB(player->speed))
594 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800595 } else if (segment->segment_id == player->cur_segment_id) {
596 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800597 found_eq_id = 1;
598 if (!IS_FB(player->speed)) {
599 found = 1;
600 continue;
601 } else {
602 //if is fb mode.we need used pre segment
603 if (pre_segment != NULL) {
604 found = 1;
605 } else {
606 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800607 DVR_PB_INFO("not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800608 return DVR_FAILURE;
609 }
610 }
hualing chen86e7d482020-01-16 15:13:33 +0800611 }
612 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800613 if (IS_FB(player->speed)) {
614 //used pre segment
615 segment = pre_segment;
616 }
hualing chencc91e1c2020-02-28 13:26:17 +0800617 //save segment info
618 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800619 if (player->r_handle)
Wentao MA270dc0f2022-08-23 13:17:26 +0800620 player->last_segment_total = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800621 player->last_segment.segment_id = player->cur_segment.segment_id;
622 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800623 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
624 //pids
625 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
626
hualing chen5cbe1a62020-02-10 16:36:36 +0800627 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800628 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800629 player->cur_segment_id = segment->segment_id;
630 player->cur_segment.segment_id = segment->segment_id;
631 player->cur_segment.flags = segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800632 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 +0800633 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800634 //pids
hualing chen040df222020-01-17 13:35:02 +0800635 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800636 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800637 break;
hualing chen86e7d482020-01-16 15:13:33 +0800638 }
hualing chen2aba4022020-03-02 13:49:55 +0800639 pre_segment = segment;
640 }
641 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
642 //used the last one segment to open
643 //get segment info
644 player->segment_is_open = DVR_TRUE;
645 player->cur_segment_id = pre_segment->segment_id;
646 player->cur_segment.segment_id = pre_segment->segment_id;
647 player->cur_segment.flags = pre_segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800648 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 +0800649 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
650 //pids
651 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
652 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800653 }
654 if (found != 2) {
655 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800656 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800657 }
658 return DVR_SUCCESS;
659}
hualing chen040df222020-01-17 13:35:02 +0800660//open next segment to play,if reach list end return errro.
661static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800662{
hualing chen040df222020-01-17 13:35:02 +0800663 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800664 Segment_OpenParams_t params;
665 int ret = DVR_SUCCESS;
666
hualing chena540a7e2020-03-27 16:44:05 +0800667 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800668 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800669 return DVR_FAILURE;
670 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800671 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800672retry:
hualing chena540a7e2020-03-27 16:44:05 +0800673 ret = _dvr_get_next_segmentId(handle);
674 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800675 DVR_PB_INFO("not found segment info");
hualing chen4b7c15d2020-04-07 16:13:48 +0800676 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800677 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800678 }
679
680 if (player->r_handle != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800681 DVR_PB_INFO("close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800682 segment_close(player->r_handle);
683 player->r_handle = NULL;
684 }
685
Wentao MA4d85ff32022-09-23 11:36:18 +0800686 memset((void*)&params,0,sizeof(params));
Wentao MA270dc0f2022-08-23 13:17:26 +0800687 //cp current segment path to location
hualing chen5cbe1a62020-02-10 16:36:36 +0800688 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800689 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800690 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800691 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 +0800692
hualing chen86e7d482020-01-16 15:13:33 +0800693 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800694 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800695 DVR_PB_INFO("open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800696 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800697 }
Wentao MA01de0e62022-01-10 18:48:23 +0800698 // Keep the start segment_id when the first segment_open is called during a playback
699 if (player->first_start_id == UINT64_MAX) {
700 player->first_start_id = player->cur_segment.segment_id;
701 }
hualing chen87072a82020-03-12 16:20:12 +0800702 pthread_mutex_unlock(&player->segment_lock);
703 int total = _dvr_get_end_time( handle);
704 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800705 if (IS_FB(player->speed)) {
706 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800707 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800708 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +0800709 DVR_PB_INFO("seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800710 }
hualing chen87072a82020-03-12 16:20:12 +0800711 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800712 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +0800713 DVR_PB_INFO("next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800714 return ret;
715}
716
hualing chen5cbe1a62020-02-10 16:36:36 +0800717//open next segment to play,if reach list end return errro.
718static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
719{
720 DVR_Playback_t *player = (DVR_Playback_t *) handle;
721 Segment_OpenParams_t params;
722 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800723 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800724 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800725 return DVR_FAILURE;
726 }
hualing chencc91e1c2020-02-28 13:26:17 +0800727 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800728 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800729 }
hualing chencc91e1c2020-02-28 13:26:17 +0800730 uint64_t id = segment_id;
Wentao MA07d3d742022-09-06 09:58:05 +0800731 DVR_PB_INFO("start finding segment[%lld] info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800732 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800733
734 DVR_PlaybackSegmentInfo_t *segment;
735
736 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800737
wentao.mafd5283f2022-10-14 09:51:13 +0800738 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800739 // prefetch() here incurring self_assign is used to avoid some compiling
740 // warnings.
741 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800742 list_for_each_entry(segment, &player->segment_list, head)
743 {
Wentao MA96f68962022-06-15 19:45:35 +0800744 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 +0800745 if (segment->segment_id == segment_id) {
746 found = 1;
747 }
748 if (found == 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800749 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 +0800750 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800751 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800752 player->cur_segment_id = segment->segment_id;
753 player->cur_segment.segment_id = segment->segment_id;
754 player->cur_segment.flags = segment->flags;
Wentao MAe88ad702022-09-02 10:35:00 +0800755 const int len = strlen(segment->location);
756 if (len >= DVR_MAX_LOCATION_SIZE || len <= 0) {
757 DVR_PB_ERROR("Invalid segment.location length %d",len);
758 pthread_mutex_unlock(&player->segment_lock);
759 return DVR_FAILURE;
760 }
761 strncpy(player->cur_segment.location, segment->location, len+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800762 //pids
763 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +0800764 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 +0800765 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800766 }
767 }
hualing chencc91e1c2020-02-28 13:26:17 +0800768 if (found == 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800769 DVR_PB_INFO("not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800770 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800771 return DVR_FAILURE;
772 }
Wentao MA4d85ff32022-09-23 11:36:18 +0800773 memset((void*)&params,0,sizeof(params));
Wentao MAe88ad702022-09-02 10:35:00 +0800774
775 const int len2 = strlen(player->cur_segment.location);
776 if (len2 >= DVR_MAX_LOCATION_SIZE || len2 <= 0) {
777 DVR_PB_ERROR("Invalid cur_segment.location length %d",len2);
778 pthread_mutex_unlock(&player->segment_lock);
779 return DVR_FAILURE;
780 }
781 strncpy(params.location, player->cur_segment.location, len2+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800782 params.segment_id = (uint64_t)player->cur_segment.segment_id;
783 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800784 DVR_PB_INFO("open segment location[%s][%lld]cur flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen2aba4022020-03-02 13:49:55 +0800785 if (player->r_handle != NULL) {
786 segment_close(player->r_handle);
787 player->r_handle = NULL;
788 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800789 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800790 if (ret == DVR_FAILURE) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800791 DVR_PB_INFO("segment open error");
hualing chen4b7c15d2020-04-07 16:13:48 +0800792 }
Wentao MA01de0e62022-01-10 18:48:23 +0800793 // Keep the start segment_id when the first segment_open is called during a playback
794 if (player->first_start_id == UINT64_MAX) {
795 player->first_start_id = player->cur_segment.segment_id;
796 }
hualing chen2aba4022020-03-02 13:49:55 +0800797 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800798 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800799
Wentao MA96f68962022-06-15 19:45:35 +0800800 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 +0800801 return ret;
802}
803
804
805//get play info by segment id
806static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
807 uint64_t segment_id,
Wentao MA270dc0f2022-08-23 13:17:26 +0800808 am_tsplayer_video_params *video_param,
809 am_tsplayer_audio_params *audio_param, am_tsplayer_audio_params *ad_param) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800810
811 DVR_Playback_t *player = (DVR_Playback_t *) handle;
812 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800813 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800814 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800815 return DVR_FAILURE;
816 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800817
818 int found = 0;
819
wentao.mafd5283f2022-10-14 09:51:13 +0800820 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +0800821 // prefetch() here incurring self_assign is used to avoid some compiling
822 // warnings.
823 // coverity[self_assign]
hualing chen5cbe1a62020-02-10 16:36:36 +0800824 list_for_each_entry(segment, &player->segment_list, head)
825 {
hualing chen87072a82020-03-12 16:20:12 +0800826 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800827 //get first segment from list
828 found = 1;
829 }
830 if (segment->segment_id == segment_id) {
831 found = 1;
832 }
833 if (found == 1) {
834 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800835 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800836 player->cur_segment_id = segment->segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800837 player->cur_segment.segment_id = segment->segment_id;
838 player->cur_segment.flags = segment->flags;
839 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800840 player->cur_segment.pids.video.pid = segment->pids.video.pid;
841 player->cur_segment.pids.video.format = segment->pids.video.format;
842 player->cur_segment.pids.video.type = segment->pids.video.type;
843 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
844 player->cur_segment.pids.audio.format = segment->pids.audio.format;
845 player->cur_segment.pids.audio.type = segment->pids.audio.type;
846 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
847 player->cur_segment.pids.ad.format = segment->pids.ad.format;
848 player->cur_segment.pids.ad.type = segment->pids.ad.type;
849 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800850 //
Wentao MA270dc0f2022-08-23 13:17:26 +0800851 video_param->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
852 video_param->pid = segment->pids.video.pid;
853 audio_param->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
854 audio_param->pid = segment->pids.audio.pid;
855 ad_param->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
856 ad_param->pid =segment->pids.ad.pid;
Wentao MA804bab12022-11-29 10:01:26 +0800857 DVR_PB_DEBUG("get_playinfo, segment_id:%lld, vpid[0x%x], apid[0x%x], vfmt[%d], afmt[%d]",
858 player->cur_segment_id, video_param->pid, audio_param->pid,
859 video_param->codectype, audio_param->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800860 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800861 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800862 }
863 }
hualing chencc91e1c2020-02-28 13:26:17 +0800864 if (found != 2) {
865 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800866 DVR_PB_INFO("get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800867 return DVR_FAILURE;
868 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800869
870 return DVR_SUCCESS;
871}
hualing chencc91e1c2020-02-28 13:26:17 +0800872static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
873 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800874 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800875 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800876 return DVR_FAILURE;
877 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800878
hualing chencc91e1c2020-02-28 13:26:17 +0800879 //compare cur segment
880 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
881 {
882 //check video pids, stop or restart
hualing chen99508642021-10-18 15:41:17 +0800883 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800884 //check sub audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800885 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800886 //check audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800887 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 1);
Wentao MA96f68962022-06-15 19:45:35 +0800888 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 +0800889 //check pcr pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800890 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800891 }
hualing chena540a7e2020-03-27 16:44:05 +0800892 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800893}
hualing chen5cbe1a62020-02-10 16:36:36 +0800894
hualing chend241c7a2021-06-22 13:34:27 +0800895static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
896{
897 DVR_Playback_t *player = (DVR_Playback_t *) handle;
898 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800899 DVR_PB_INFO("player is NULL");
hualing chend241c7a2021-06-22 13:34:27 +0800900 return DVR_TRUE;
901 }
hualing chend241c7a2021-06-22 13:34:27 +0800902
Wentao MA96f68962022-06-15 19:45:35 +0800903 DVR_PB_INFO(":play speed: %f ply dur: %u sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800904 player->speed,
905 player->con_spe.ply_dur,
906 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800907
908 if (player->speed != 1.0f)
909 return DVR_TRUE;
910
911 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800912 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800913 return DVR_FALSE;
914
915 return DVR_TRUE;
916}
917
hualing chencc91e1c2020-02-28 13:26:17 +0800918static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
919{
920 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800921 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800922 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800923 return DVR_FAILURE;
924 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800925 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
Wentao MA96f68962022-06-15 19:45:35 +0800926 DVR_PB_INFO("vendor is amlogic. no used segment flag to hide or show av");
hualing chenf43b8ba2020-07-28 13:11:42 +0800927 return DVR_SUCCESS;
928 }
Wentao MA96f68962022-06-15 19:45:35 +0800929 DVR_PB_INFO("flag[0x%x]id[%lld]last[0x%x][%llu]",
hualing chen03fd4942021-07-15 15:56:41 +0800930 player->cur_segment.flags,
931 player->cur_segment.segment_id,
932 player->last_segment.flags,
933 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800934 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
935 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800936 //enable display
Wentao MA96f68962022-06-15 19:45:35 +0800937 DVR_PB_INFO("unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800938 AmTsPlayer_showVideo(player->handle);
939 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800940 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
941 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800942 //disable display
Wentao MA96f68962022-06-15 19:45:35 +0800943 DVR_PB_INFO("mute");
hualing chen2aba4022020-03-02 13:49:55 +0800944 AmTsPlayer_hideVideo(player->handle);
945 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800946 }
947 return DVR_SUCCESS;
948}
hualing chene3797f02021-01-13 14:53:28 +0800949/*
Wentao MA270dc0f2022-08-23 13:17:26 +0800950if decode success first time.
951success: return true
hualing chene3797f02021-01-13 14:53:28 +0800952fail: return false
953*/
Wentao MA270dc0f2022-08-23 13:17:26 +0800954static DVR_Bool_t _dvr_pauselive_decode_success(DVR_PlaybackHandle_t handle) {
hualing chena540a7e2020-03-27 16:44:05 +0800955 DVR_Playback_t *player = (DVR_Playback_t *) handle;
956 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800957 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800958 return DVR_TRUE;
959 }
hualing chene3797f02021-01-13 14:53:28 +0800960 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800961 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800962 } else {
963 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800964 }
965}
hualing chen86e7d482020-01-16 15:13:33 +0800966static void* _dvr_playback_thread(void *arg)
967{
hualing chen040df222020-01-17 13:35:02 +0800968 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800969 //int need_open_segment = 1;
Wentao MA270dc0f2022-08-23 13:17:26 +0800970 am_tsplayer_input_buffer input_buffer;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800971 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800972 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800973
hualing chen39628212020-05-14 10:35:13 +0800974 #define MAX_REACHEND_TIMEOUT (3000)
975 int reach_end_timeout = 0;//ms
976 int cache_time = 0;
hualing chen40dd5462021-11-26 19:56:20 +0800977 int check_no_data_time = 4;
hualing chen040df222020-01-17 13:35:02 +0800978 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800979 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +0800980 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800981 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800982 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800983 DVR_Bool_t goto_rewrite = DVR_FALSE;
wentao ma7d642782022-10-23 18:26:16 -0700984 int read = 0;
yinming ding0ce94922021-09-08 15:09:15 +0800985
wentao ma7d642782022-10-23 18:26:16 -0700986 const uint64_t write_timeout_ms = (uint64_t)dvr_prop_read_int("vendor.tv.libdvr.writetm",50);
987 const int timeout = dvr_prop_read_int("vendor.tv.libdvr.waittm",200);
hualing chen56c0a162022-01-27 17:01:50 +0800988
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800989 if (player->is_secure_mode) {
990 if (dec_buf_size > player->secure_buffer_size) {
Wentao MA96f68962022-06-15 19:45:35 +0800991 DVR_PB_INFO("playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800992 return NULL;
993 }
994 }
wentao.maa210e5e2022-10-12 16:10:03 +0800995
996 uint8_t *buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800997 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +0800998 DVR_PB_INFO("Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800999 return NULL;
1000 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001001 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1002 input_buffer.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001003
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001004 dec_bufs.buf_data = malloc(dec_buf_size);
1005 if (!dec_bufs.buf_data) {
Wentao MA96f68962022-06-15 19:45:35 +08001006 DVR_PB_INFO("Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +08001007 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001008 return NULL;
1009 }
1010 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1011 dec_bufs.buf_size = dec_buf_size;
1012
hualing chencc91e1c2020-02-28 13:26:17 +08001013 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001014 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1015 }
hualing chen86e7d482020-01-16 15:13:33 +08001016
hualing chen86e7d482020-01-16 15:13:33 +08001017 if (ret != DVR_SUCCESS) {
1018 if (buf != NULL) {
1019 free(buf);
hualing chen86e7d482020-01-16 15:13:33 +08001020 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001021 free(dec_bufs.buf_data);
Wentao MA96f68962022-06-15 19:45:35 +08001022 DVR_PB_INFO("get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001023 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001024 }
Wentao MA96f68962022-06-15 19:45:35 +08001025 DVR_PB_INFO("--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001026 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001027 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1028 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1029 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1030 player->first_trans_ok = DVR_TRUE;
1031 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1032 }
hualing chencc91e1c2020-02-28 13:26:17 +08001033 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001034 //set video show
1035 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001036 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1037 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001038 int trick_stat = 0;
1039 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001040
hualing chen86e7d482020-01-16 15:13:33 +08001041 //check trick stat
Wentao MA96f68962022-06-15 19:45:35 +08001042 //DVR_PB_INFO("lock check_no_data_time:%d", check_no_data_time);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001043 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001044
Wentao MA907b6432022-08-01 06:23:08 +00001045 {
Wentao MA9a164002022-08-29 11:20:24 +08001046 static struct timespec _prev_ts={0,0};
Wentao MA907b6432022-08-01 06:23:08 +00001047 struct timespec _nowts,_diffts;
1048 clock_gettime(CLOCK_MONOTONIC, &_nowts);
Wentao MA9a164002022-08-29 11:20:24 +08001049 clock_timespec_subtract(&_nowts,&_prev_ts,&_diffts);
Wentao MA907b6432022-08-01 06:23:08 +00001050 if (_diffts.tv_sec>0) {
1051 char _logbuf[512]={0};
1052 char* _pbuf=_logbuf;
1053 int _nchar=0;
1054 DVR_PlaybackSegmentInfo_t* _segment;
wentao.mafd5283f2022-10-14 09:51:13 +08001055 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08001056 // prefetch() here incurring self_assign is used to avoid some compiling
1057 // warnings.
1058 // coverity[self_assign]
Wentao MA907b6432022-08-01 06:23:08 +00001059 list_for_each_entry(_segment, &player->segment_list, head) {
1060 if (player->cur_segment_id == _segment->segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08001061 int seg_size = segment_get_cur_segment_size(player->r_handle);
1062 int read_ptr = segment_tell_position(player->r_handle);
Wentao MA907b6432022-08-01 06:23:08 +00001063 float progress = -1.0f;
Wentao MA9a164002022-08-29 11:20:24 +08001064 if (seg_size>0) {
1065 progress = (float)read_ptr*100/seg_size;
Wentao MA907b6432022-08-01 06:23:08 +00001066 }
Wentao MA4d85ff32022-09-23 11:36:18 +08001067 _nchar=sprintf(_pbuf,"%lld(%.1f%%), ",_segment->segment_id,progress);
Wentao MA907b6432022-08-01 06:23:08 +00001068 } else {
1069 _nchar=sprintf(_pbuf,"%lld, ",_segment->segment_id);
1070 }
1071 if (_nchar<0) {
1072 break;
1073 }
1074 _pbuf+=_nchar;
1075 if (_pbuf-_logbuf+10 >= sizeof(_logbuf)) {
1076 sprintf(_pbuf,"...");
1077 break;
1078 }
1079 }
Wentao MA9a164002022-08-29 11:20:24 +08001080 DVR_PB_INFO("clk: %08u, seg_list: %s",_nowts.tv_sec,_logbuf);
1081 _prev_ts=_nowts;
Wentao MA907b6432022-08-01 06:23:08 +00001082 }
1083 }
1084
hualing chen2aba4022020-03-02 13:49:55 +08001085 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1086 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001087 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001088 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001089 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001090 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001091 {
hualing chen2aba4022020-03-02 13:49:55 +08001092 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1093 if (trick_stat > 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001094 DVR_PB_INFO("trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001095 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001096 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 +08001097 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001098 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001099 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001100 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
Wentao MA270dc0f2022-08-23 13:17:26 +08001101 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_V_START
1102 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_A_START
hualing chen2aba4022020-03-02 13:49:55 +08001103 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
Wentao MA96f68962022-06-15 19:45:35 +08001104 DVR_PB_INFO("pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001105 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001106 //need change to pause state
1107 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1108 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00001109 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08001110 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001111 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001112 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001113 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001114 AmTsPlayer_pauseVideoDecoding(player->handle);
1115 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001116 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001117 DVR_PB_INFO("clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001118 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001119 }
1120 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1121 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001122 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001123 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001124 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001125 DVR_PB_INFO("fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001126 player->speed,
1127 player->fffb_current,
1128 _dvr_time_getClock(),
1129 _dvr_playback_state_toString(player->state),
1130 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001131 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001132 //dvr_mutex_unlock(&player->lock);
1133 //dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001134 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001135 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001136 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001137 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001138 } else if (_dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001139 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 +08001140 player->speed,
1141 player->fffb_current,
1142 _dvr_time_getClock(),
1143 _dvr_playback_state_toString(player->state),
1144 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001145 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001146 //dvr_mutex_unlock(&player->lock);
1147 //dvr_mutex_lock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001148 AmTsPlayer_pauseVideoDecoding(player->handle);
1149 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001150 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001151 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001152 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001153 }
Wentao MA96f68962022-06-15 19:45:35 +08001154 DVR_PB_INFO("fffb play-------speed[%f][%d][%d][%s][%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001155 player->speed,
1156 goto_rewrite,
1157 real_read,
1158 _dvr_playback_state_toString(player->state),
1159 player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001160 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001161 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001162 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1163 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001164 DVR_PB_INFO("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001165 dvr_mutex_unlock(&player->lock);
1166
hualing chen2aba4022020-03-02 13:49:55 +08001167 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001168 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001169 dvr_mutex_lock(&player->lock);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001170 player->fffb_play = DVR_FALSE;
hualing chen1ffd85b2021-08-16 15:18:43 +08001171 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1172 //on pause state,user seek to new pos,we need pause and wait
1173 //user to resume
Wentao MA96f68962022-06-15 19:45:35 +08001174 DVR_PB_INFO("pause, when got first frame event when user seek end");
hualing chen1ffd85b2021-08-16 15:18:43 +08001175 player->first_frame = 0;
1176 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1177 AmTsPlayer_pauseVideoDecoding(player->handle);
1178 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001179 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001180 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001181 //for first into fffb when reset speed
1182 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1183 _dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001184 DVR_PB_INFO("fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001185 player->speed,
1186 player->fffb_current,
1187 _dvr_time_getClock(),
1188 _dvr_playback_state_toString(player->state),
1189 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001190 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001191 //dvr_mutex_unlock(&player->lock);
1192 //dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001193 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001194 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001195 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001196 continue;
1197 }
Wentao MA96f68962022-06-15 19:45:35 +08001198 DVR_PB_INFO("fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001199 player->speed,
1200 goto_rewrite,
1201 real_read,
1202 _dvr_playback_state_toString(player->state),
1203 player->cmd.cur_cmd,
1204 player->fffb_play);
Wentao MA96f68962022-06-15 19:45:35 +08001205 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001206 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001207 goto_rewrite = DVR_FALSE;
1208 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001209 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001210 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001211 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1212 player->first_frame = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001213 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001214 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001215 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001216 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001217 }
hualing chenb31a6c62020-01-13 17:27:00 +08001218 }
hualing chen86e7d482020-01-16 15:13:33 +08001219
hualing chen30423862021-04-16 14:39:12 +08001220 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1221 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001222 //check is need send time send end
Wentao MA96f68962022-06-15 19:45:35 +08001223 DVR_PB_INFO("pause, continue");
1224 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001225 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001226 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001227 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001228 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001229 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001230 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001231 continue;
1232 }
hualing chen266b9502020-04-04 17:39:39 +08001233 //when seek action is done. we need drop write timeout data.
1234 if (player->drop_ts == DVR_TRUE) {
1235 goto_rewrite = DVR_FALSE;
1236 real_read = 0;
1237 player->drop_ts = DVR_FALSE;
1238 }
hualing chen2aba4022020-03-02 13:49:55 +08001239 if (goto_rewrite == DVR_TRUE) {
1240 goto_rewrite = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001241 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001242 dvr_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001243 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Wentao MA96f68962022-06-15 19:45:35 +08001244 //DVR_PB_INFO("rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001245 goto rewrite;
1246 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001247 //.check is need send time send end
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001248 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001249 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001250 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001251 pthread_mutex_lock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001252 //DVR_PB_INFO("start read");
Wentao MA9628de82022-09-13 14:19:37 +08001253 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001254 real_read = real_read + read;
1255 player->ts_cache_len = real_read;
Wentao MA96f68962022-06-15 19:45:35 +08001256 //DVR_PB_INFO("start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001257 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001258 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001259 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001260 if (read < 0 && errno == EIO) {
1261 //EIO ERROR, EXIT THRAD
Wentao MA96f68962022-06-15 19:45:35 +08001262 DVR_PB_INFO("read error.EIO error, exit thread");
hualing chenb5cd42e2020-04-15 17:03:34 +08001263 DVR_Play_Notify_t notify;
1264 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1265 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001266 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001267 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001268 goto end;
1269 } else if (read < 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001270 DVR_PB_INFO("read error.:%d EIO:%d", errno, EIO);
hualing chenb5cd42e2020-04-15 17:03:34 +08001271 }
hualing chen87072a82020-03-12 16:20:12 +08001272 //if on fb mode and read file end , we need calculate pos to retry read.
1273 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001274 DVR_PB_INFO("recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
hualing chen03fd4942021-07-15 15:56:41 +08001275 read,
1276 real_read,
1277 buf_len,
1278 player->speed,
1279 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001280 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001281 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001282 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001283 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001284 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001285 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001286 continue;
1287 }
Wentao MA96f68962022-06-15 19:45:35 +08001288 //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 +08001289 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001290 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001291 #define MIN_CACHE_TIME (3000)
Wentao MA804bab12022-11-29 10:01:26 +08001292 int delay = 0;
1293 get_effective_tsplayer_delay_time(player,&delay);
hualing chene3797f02021-01-13 14:53:28 +08001294 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
Wentao MA804bab12022-11-29 10:01:26 +08001295 if (delay > MIN_CACHE_TIME) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001296 //dvr_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001297 /*if cache time > 20s , we think get time is error,*/
Wentao MA804bab12022-11-29 10:01:26 +08001298 if (delay - MIN_CACHE_TIME > 20 * 1000) {
1299 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 +08001300 }
hualing chene41f4372020-06-06 16:29:17 +08001301 }
hualing chen969fe7b2021-05-26 15:13:17 +08001302
hualing chen040df222020-01-17 13:35:02 +08001303 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001304 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001305 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001306
Wentao MA804bab12022-11-29 10:01:26 +08001307 get_effective_tsplayer_delay_time(player,&delay);
hualing chen1679f812021-11-08 15:17:46 +08001308 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1309 player->noData++;
Wentao MA96f68962022-06-15 19:45:35 +08001310 DVR_PB_INFO("playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001311 if (player->noData == check_no_data_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001312 DVR_PB_INFO("playback send nodata event nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001313 //send event here and pause
1314 DVR_Play_Notify_t notify;
1315 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1316 notify.event = DVR_PLAYBACK_EVENT_NODATA;
Wentao MA96f68962022-06-15 19:45:35 +08001317 DVR_PB_INFO("send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001318 //get play statue not here
1319 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1320 }
1321 }
Wentao MAa0b9c002022-11-10 17:47:27 +08001322
1323 DVR_Bool_t cond1 = (ret != DVR_SUCCESS);
1324 DVR_Bool_t cond2 = (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON);
1325 DVR_Bool_t cond3 = (delay <= MIN_TSPLAYER_DELAY_TIME);
1326 DVR_Bool_t cond4 = (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF);
1327 DVR_Bool_t cond5 = (player->delay_is_effective == DVR_TRUE);
1328 DVR_Bool_t cond6 = (reach_end_timeout >= MAX_REACHEND_TIMEOUT);
1329 if ((cond1 && cond2 && (cond3 || cond4) && cond5) || cond6) {
1330 DVR_PB_INFO("REACHED_END conditions: cond1:%d, cond2:%d, (cond3:%d, cond4:%d),"
1331 " cond5:%d, cond6:%d. delay:%d, reach_end_timeout:%d",
1332 (int)cond1,(int)cond2,(int)cond3,(int)cond4,(int)cond5,(int)cond6,
1333 delay,reach_end_timeout);
Wentao MA804bab12022-11-29 10:01:26 +08001334 DVR_Play_Notify_t notify;
1335 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1336 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1337 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
1338 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
1339 dvr_mutex_lock(&player->lock);
1340 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1341 dvr_mutex_unlock(&player->lock);
1342 continue;
1343 } else if (ret != DVR_SUCCESS) {
1344 DVR_PB_INFO("delay:%d pauselive:%d", delay, _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player));
1345 dvr_mutex_lock(&player->lock);
1346 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1347 dvr_mutex_unlock(&player->lock);
1348
1349 get_effective_tsplayer_delay_time(player,&delay);
1350 //not send event and pause,sleep and go to next time to recheck
1351 if (delay < cache_time) {
1352 //delay time is changed and then has data to play, so not start timeout
1353 reach_end_timeout = 0;
1354 } else {
1355 reach_end_timeout = reach_end_timeout + timeout;
1356 }
1357 cache_time = delay;
1358 continue;
1359 }
hualing chen39628212020-05-14 10:35:13 +08001360 reach_end_timeout = 0;
1361 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001362 //change next segment success case
1363 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001364 dvr_mutex_lock(&player->lock);
hualing chen40dd5462021-11-26 19:56:20 +08001365 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001366 DVR_PB_INFO("_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001367 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1368 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001369 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001370 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001371 real_read = real_read + read;
1372 player->ts_cache_len = real_read;
1373 pthread_mutex_unlock(&player->segment_lock);
1374
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001375 dvr_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001376 }//read len 0 check end
hualing chen40dd5462021-11-26 19:56:20 +08001377 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001378 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001379 DVR_PB_INFO("playback send data event resume[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001380 //send event here and pause
1381 DVR_Play_Notify_t notify;
1382 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1383 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
Wentao MA96f68962022-06-15 19:45:35 +08001384 DVR_PB_INFO("----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001385 //get play statue not here
1386 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001387 }
hualing chen39628212020-05-14 10:35:13 +08001388 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001389 //real_read = real_read + read;
Wentao MA270dc0f2022-08-23 13:17:26 +08001390 input_buffer.buf_size = real_read;
1391 input_buffer.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001392
Wentao MA270dc0f2022-08-23 13:17:26 +08001393 //check read data len,if len < 0, we need continue
1394 if (input_buffer.buf_size <= 0 || input_buffer.buf_data == NULL) {
1395 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 +08001396 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001397 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001398 player->ts_cache_len = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001399 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001400 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001401 }
hualing chen266b9502020-04-04 17:39:39 +08001402 //if need write whole block size, we need check read buf len is eq block size.
Wentao MAa0b9c002022-11-10 17:47:27 +08001403 if (b_writed_whole_block == DVR_TRUE
1404 && (player->has_video || player->dec_func || player->cryptor)) {
hualing chen266b9502020-04-04 17:39:39 +08001405 //buf_len is block size value.
1406 if (real_read < buf_len) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001407 //continue to read data from file
Wentao MA96f68962022-06-15 19:45:35 +08001408 DVR_PB_INFO("read buf len[%d] is < block size [%d]", real_read, buf_len);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001409 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001410 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1411 dvr_mutex_unlock(&player->lock);
1412 DVR_PB_INFO("read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001413 continue;
1414 } else if (real_read > buf_len) {
Wentao MA96f68962022-06-15 19:45:35 +08001415 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 +08001416 }
1417 }
1418
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001419 if (player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001420 DVR_CryptoParams_t crypto_params;
1421
1422 memset(&crypto_params, 0, sizeof(crypto_params));
1423 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1424 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1425 crypto_params.segment_id = player->cur_segment.segment_id;
Wentao MA270dc0f2022-08-23 13:17:26 +08001426 crypto_params.offset = segment_tell_position(player->r_handle) - input_buffer.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001427 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
Wentao MA96f68962022-06-15 19:45:35 +08001428 DVR_PB_INFO("offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001429 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1430 crypto_params.input_buffer.addr = (size_t)buf;
1431 crypto_params.input_buffer.size = real_read;
1432
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001433 if (player->is_secure_mode) {
1434 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1435 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1436 crypto_params.output_buffer.size = dec_buf_size;
1437 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001438 input_buffer.buf_data = player->secure_buffer;
1439 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001440 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001441 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001442 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001443 input_buffer.buf_size = crypto_params.output_size;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001444 } else { // only for NAGRA
1445 crypto_params.output_buffer.type = crypto_params.input_buffer.type;
1446 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1447 crypto_params.output_buffer.size = crypto_params.input_buffer.size;
1448 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001449 input_buffer.buf_data = (uint8_t*)crypto_params.output_buffer.addr;
1450 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001451 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001452 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001453 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001454 input_buffer.buf_size = crypto_params.output_buffer.size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001455 }
Yahui Han1fbf3292021-11-08 18:17:19 +08001456 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001457 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001458 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
Wentao MA270dc0f2022-08-23 13:17:26 +08001459 input_buffer.buf_data = dec_bufs.buf_data;
1460 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1461 input_buffer.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001462 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001463rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001464 if (player->drop_ts == DVR_TRUE) {
1465 //need drop ts data when seek occur.we need read next loop,drop this ts data
1466 goto_rewrite = DVR_FALSE;
1467 real_read = 0;
Wentao MA63c6cba2022-09-20 10:14:29 +08001468 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001469 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001470 player->drop_ts = DVR_FALSE;
Wentao MA63c6cba2022-09-20 10:14:29 +08001471 pthread_mutex_unlock(&player->segment_lock);
1472 DVR_PB_INFO("----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001473 continue;
1474 }
hualing chen21a40372021-10-29 11:07:26 +08001475
1476 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001477 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001478 //used for printf first write data time.
1479 //to check change channel kpi.
1480 if (first_write == 0) {
1481 first_write++;
Wentao MA270dc0f2022-08-23 13:17:26 +08001482 DVR_PB_INFO("----first write ts data");
hualing chenb9a02922021-12-14 11:29:47 +08001483 }
1484
Wentao MA270dc0f2022-08-23 13:17:26 +08001485 ret = AmTsPlayer_writeData(player->handle, &input_buffer, write_timeout_ms);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001486 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001487 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001488 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001489 real_read = 0;
1490 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001491 if (CONTROL_SPEED_ENABLE == 1) {
1492check0:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001493 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001494 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001495 break;
1496 }
hualing chend241c7a2021-06-22 13:34:27 +08001497 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001498 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001499 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001500 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001501 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1502 goto check0;
1503 }
1504 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001505 //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 +08001506 } else {
Wentao MA804bab12022-11-29 10:01:26 +08001507 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001508 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001509 if (CONTROL_SPEED_ENABLE == 1) {
1510check1:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001511 if (!player->is_running) {
Yahui Han28c66ed2022-09-08 10:32:33 +08001512 //DVR_PB_DEBUG(1, "playback thread exit");
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001513 break;
1514 }
hualing chend241c7a2021-06-22 13:34:27 +08001515 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001516 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001517 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001518 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001519 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1520 goto check1;
1521 }
1522 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001523 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001524 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001525 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001526 if (!player->is_running) {
Wentao MA96f68962022-06-15 19:45:35 +08001527 DVR_PB_INFO("playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001528 break;
1529 }
hualing chen2aba4022020-03-02 13:49:55 +08001530 goto_rewrite = DVR_TRUE;
1531 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001532 }
1533 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001534end:
Wentao MA96f68962022-06-15 19:45:35 +08001535 DVR_PB_INFO("playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001536 free(buf);
1537 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001538 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001539}
1540
1541
hualing chen040df222020-01-17 13:35:02 +08001542static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001543{
hualing chen040df222020-01-17 13:35:02 +08001544 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001545
1546 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001547 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001548 return DVR_FAILURE;
1549 }
Wentao MA96f68962022-06-15 19:45:35 +08001550 DVR_PB_INFO("start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001551 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001552 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001553 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001554 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001555 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001556 if (rc < 0)
1557 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001558 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001559}
1560
1561
hualing chen040df222020-01-17 13:35:02 +08001562static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001563{
hualing chen040df222020-01-17 13:35:02 +08001564 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001565
1566 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001567 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001568 return DVR_FAILURE;
1569 }
1570
Wentao MA96f68962022-06-15 19:45:35 +08001571 DVR_PB_INFO("stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001572 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001573 {
1574 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001575 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001576 pthread_join(player->playback_thread, NULL);
1577 }
1578 if (player->r_handle) {
1579 segment_close(player->r_handle);
1580 player->r_handle = NULL;
1581 }
Wentao MA96f68962022-06-15 19:45:35 +08001582 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001583 return 0;
1584}
1585
hualing chen1679f812021-11-08 15:17:46 +08001586static int getFakePid()
1587{
wentao ma7d642782022-10-23 18:26:16 -07001588 return dvr_prop_read_int("vendor.tv.dtv.fake_pid",0xffff);
hualing chen1679f812021-11-08 15:17:46 +08001589}
1590
1591void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1592
1593 DVR_ASSERT(handle);
1594 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1595 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001596 DVR_PB_INFO("player is NULL");
hualing chen1679f812021-11-08 15:17:46 +08001597 return ;
1598 }
1599 if (player->need_seek_start == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001600 DVR_PB_INFO("player need_seek_start is false");
hualing chen1679f812021-11-08 15:17:46 +08001601 return ;
1602 }
1603
hualing chena5f03222021-12-02 11:22:35 +08001604 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001605 player->need_seek_start = DVR_FALSE;
1606 }
Wentao MA96f68962022-06-15 19:45:35 +08001607 DVR_PB_INFO("player player->need_seek_start=%d", player->need_seek_start);
hualing chen1679f812021-11-08 15:17:46 +08001608}
1609
hualing chenb31a6c62020-01-13 17:27:00 +08001610/**\brief Open an dvr palyback
1611 * \param[out] p_handle dvr playback addr
1612 * \param[in] params dvr playback open parameters
1613 * \retval DVR_SUCCESS On success
1614 * \return Error code
1615 */
hualing chen040df222020-01-17 13:35:02 +08001616int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001617
hualing chen040df222020-01-17 13:35:02 +08001618 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001619 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001620
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001621 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
wentao.maa22bc852022-10-13 12:18:06 +08001622 DVR_RETURN_IF_FALSE(player);
hualing chenb31a6c62020-01-13 17:27:00 +08001623
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001624 dvr_mutex_init(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001625 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001626 pthread_condattr_init(&cattr);
1627 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1628 pthread_cond_init(&player->cond, &cattr);
1629 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001630
hualing chen5cbe1a62020-02-10 16:36:36 +08001631 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001632 INIT_LIST_HEAD(&player->segment_list);
1633 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1634 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001635 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001636 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00001637 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen86e7d482020-01-16 15:13:33 +08001638 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001639 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001640 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001641
hualing chen86e7d482020-01-16 15:13:33 +08001642 //store open params
hualing chen040df222020-01-17 13:35:02 +08001643 player->openParams.dmx_dev_id = params->dmx_dev_id;
1644 player->openParams.block_size = params->block_size;
Wentao MA96f68962022-06-15 19:45:35 +08001645 DVR_PB_INFO("playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001646 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001647 player->openParams.event_fn = params->event_fn;
1648 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001649 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001650 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001651
hualing chen5cbe1a62020-02-10 16:36:36 +08001652 player->has_pids = params->has_pids;
1653
hualing chen2aba4022020-03-02 13:49:55 +08001654 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001655
1656 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1657 //for test get callback
1658 if (0 && player->player_callback_func == NULL) {
1659 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1660 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
Wentao MA96f68962022-06-15 19:45:35 +08001661 DVR_PB_INFO("playback open get callback[%p][%p][%p][%p]",
hualing chen03fd4942021-07-15 15:56:41 +08001662 player->player_callback_func,
1663 player->player_callback_userdata,
1664 _dvr_tsplayer_callback_test,
1665 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001666 }
1667 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001668
hualing chen86e7d482020-01-16 15:13:33 +08001669 //init has audio and video
1670 player->has_video = DVR_FALSE;
1671 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001672 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001673 player->last_segment_id = 0LL;
1674 player->segment_is_open = DVR_FALSE;
Wentao MA5629ad82022-08-24 10:03:02 +08001675 player->audio_presentation_id = -1;
hualing chenb31a6c62020-01-13 17:27:00 +08001676
hualing chen5cbe1a62020-02-10 16:36:36 +08001677 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001678 player->fffb_current = 0;
1679 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001680 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001681 //seek time
1682 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001683 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001684
Yahui Han1fbf3292021-11-08 18:17:19 +08001685 //allocate cryptor if have clearkey
1686 if (params->keylen > 0) {
1687 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +08001688 (uint8_t *)params->cleariv,
1689 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +08001690 if (!player->cryptor) {
Wentao MA96f68962022-06-15 19:45:35 +08001691 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +08001692 }
1693 } else {
1694 player->cryptor = NULL;
1695 }
1696
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001697 //init secure stuff
1698 player->dec_func = NULL;
1699 player->dec_userdata = NULL;
1700 player->is_secure_mode = 0;
1701 player->secure_buffer = NULL;
1702 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001703 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001704
hualing chen4b7c15d2020-04-07 16:13:48 +08001705 player->fffb_play = DVR_FALSE;
1706
1707 player->last_send_time_id = UINT64_MAX;
1708 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001709 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001710
hualing chend241c7a2021-06-22 13:34:27 +08001711 //speed con init
1712 if (CONTROL_SPEED_ENABLE == 1) {
1713 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001714 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001715 player->con_spe.sys_dur = 0;
1716 player->con_spe.sys_sta = 0;
1717 }
1718
hualing chen03fd4942021-07-15 15:56:41 +08001719 //limit info
1720 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001721 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001722 //need seek to start pos
1723 player->first_start_time = 0;
Wentao MA01de0e62022-01-10 18:48:23 +08001724 player->first_start_id = UINT64_MAX;
Wentao MAa0b9c002022-11-10 17:47:27 +08001725 player->delay_is_effective = DVR_FALSE;
hualing chen8a657f32021-08-30 13:12:49 +08001726 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001727 //fake_pid init
1728 player->fake_pid = getFakePid();
hualing chen86e7d482020-01-16 15:13:33 +08001729 *p_handle = player;
1730 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001731}
1732
1733/**\brief Close an dvr palyback
1734 * \param[in] handle playback handle
1735 * \retval DVR_SUCCESS On success
1736 * \return Error code
1737 */
hualing chen040df222020-01-17 13:35:02 +08001738int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001739
hualing chen86e7d482020-01-16 15:13:33 +08001740 DVR_ASSERT(handle);
Wentao MA96f68962022-06-15 19:45:35 +08001741 DVR_PB_INFO(":into");
hualing chen040df222020-01-17 13:35:02 +08001742 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001743 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001744 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001745 return DVR_FAILURE;
1746 }
1747
hualing chencc91e1c2020-02-28 13:26:17 +08001748 if (player->state != DVR_PLAYBACK_STATE_STOP)
1749 {
Wentao MA96f68962022-06-15 19:45:35 +08001750 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001751 if (player->cryptor) {
1752 am_crypt_des_close(player->cryptor);
1753 player->cryptor = NULL;
1754 }
hualing chencc91e1c2020-02-28 13:26:17 +08001755 dvr_playback_stop(handle, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08001756 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
hualing chenb96aa2c2020-04-15 14:13:53 +08001757 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001758 DVR_PB_INFO(":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001759 }
Wentao MA96f68962022-06-15 19:45:35 +08001760 DVR_PB_INFO(":into");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001761 dvr_mutex_destroy(&player->lock);
Zhiqiang Hanc9513462022-06-21 09:55:23 +08001762 pthread_mutex_destroy(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001763 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001764
1765 if (player) {
1766 free(player);
hualing chen040df222020-01-17 13:35:02 +08001767 }
Wentao MA96f68962022-06-15 19:45:35 +08001768 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001769 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001770}
1771
Wentao MA270dc0f2022-08-23 13:17:26 +08001772/**\brief Start play audio and video, used start audio api and start video api
hualing chenb31a6c62020-01-13 17:27:00 +08001773 * \param[in] handle playback handle
1774 * \param[in] params audio playback params,contains fmt and pid...
1775 * \retval DVR_SUCCESS On success
1776 * \return Error code
1777 */
hualing chen040df222020-01-17 13:35:02 +08001778int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1779 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA270dc0f2022-08-23 13:17:26 +08001780 am_tsplayer_video_params video_params;
1781 am_tsplayer_audio_params audio_params;
1782 am_tsplayer_audio_params ad_params;
hualing chena540a7e2020-03-27 16:44:05 +08001783
Wentao MA270dc0f2022-08-23 13:17:26 +08001784 memset(&video_params, 0, sizeof(video_params));
1785 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001786
hualing chena540a7e2020-03-27 16:44:05 +08001787 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001788 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001789 return DVR_FAILURE;
1790 }
hualing chencc91e1c2020-02-28 13:26:17 +08001791 uint64_t segment_id = player->cur_segment_id;
Wentao MA96f68962022-06-15 19:45:35 +08001792 DVR_PB_INFO("[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001793
hualing chena540a7e2020-03-27 16:44:05 +08001794 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001795 //can used start api to resume playback
1796 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1797 return dvr_playback_resume(handle);
1798 }
hualing chen87072a82020-03-12 16:20:12 +08001799 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001800 //if flag is paused and not decode first frame. if user resume, we need
hualing chen9b434f02020-06-10 15:06:54 +08001801 //clear flag and set trickmode none
1802 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001803 DVR_PB_INFO("[%p]clear pause live flag and clear trick mode", handle);
hualing chen9b434f02020-06-10 15:06:54 +08001804 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1805 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1806 }
Wentao MA96f68962022-06-15 19:45:35 +08001807 DVR_PB_INFO("stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001808 return DVR_SUCCESS;
1809 }
hualing chen86e7d482020-01-16 15:13:33 +08001810 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001811 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001812 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08001813 DVR_PB_INFO("lock flag:0x%x", flag);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001814 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001815 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08001816 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08001817 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
1818 //audio and video pids are all invalid, return error.
1819 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 +08001820 dvr_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001821 DVR_Play_Notify_t notify;
1822 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1823 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1824 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1825 notify.info.transition_failed_data.segment_id = segment_id;
1826 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001827 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001828 return -1;
1829 }
hualing chen31140872020-03-25 12:29:26 +08001830
hualing chencc91e1c2020-02-28 13:26:17 +08001831 {
Wentao MA270dc0f2022-08-23 13:17:26 +08001832 if (VALID_PID(video_params.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001833 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001834 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001835 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001836 DVR_PB_INFO("set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001837 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1838 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001839 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
Wentao MA96f68962022-06-15 19:45:35 +08001840 DVR_PB_INFO("set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001841 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001842 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001843 DVR_PB_INFO("set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001844 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001845 }
hualing chena93bbbc2020-12-22 17:23:42 +08001846 AmTsPlayer_showVideo(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08001847 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08001848 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001849 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001850 }
hualing chena540a7e2020-03-27 16:44:05 +08001851
Wentao MA270dc0f2022-08-23 13:17:26 +08001852 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 +08001853 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001854 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1855 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1856 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001857 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001858 } else {
1859 player->cmd.last_cmd = player->cmd.cur_cmd;
1860 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001861 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001862 //set fast play
Wentao MA96f68962022-06-15 19:45:35 +08001863 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08001864 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001865 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08001866 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08001867 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08001868 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08001869 dvr_playback_change_seek_state(handle, ad_params.pid);
1870 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08001871 AmTsPlayer_enableADMix(player->handle);
1872 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001873 if (VALID_PID(audio_params.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001874 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08001875 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08001876 dvr_playback_change_seek_state(handle, audio_params.pid);
1877 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08001878 if (player->audio_presentation_id > -1) {
1879 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
1880 }
hualing chen969fe7b2021-05-26 15:13:17 +08001881 AmTsPlayer_startAudioDecoding(player->handle);
1882 }
hualing chen31140872020-03-25 12:29:26 +08001883 }
hualing chencc91e1c2020-02-28 13:26:17 +08001884 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001885 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001886 }
hualing chen86e7d482020-01-16 15:13:33 +08001887 }
hualing chen43a89bc2022-01-19 14:31:20 +08001888#ifdef AVSYNC_USED_PCR
1889 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001890 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08001891 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
1892 }
1893#endif
Wentao MA96f68962022-06-15 19:45:35 +08001894 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001895 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001896 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001897 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001898}
hualing chen040df222020-01-17 13:35:02 +08001899/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001900 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001901 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001902 * \retval DVR_SUCCESS On success
1903 * \return Error code
1904 */
hualing chen040df222020-01-17 13:35:02 +08001905int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1906 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa22bc852022-10-13 12:18:06 +08001907 DVR_RETURN_IF_FALSE(player);
hualing chena540a7e2020-03-27 16:44:05 +08001908
Wentao MA96f68962022-06-15 19:45:35 +08001909 DVR_PB_INFO("add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001910 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001911
hualing chen040df222020-01-17 13:35:02 +08001912 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
wentao.maa22bc852022-10-13 12:18:06 +08001913 DVR_RETURN_IF_FALSE(segment);
hualing chen040df222020-01-17 13:35:02 +08001914 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001915
Wentao MA270dc0f2022-08-23 13:17:26 +08001916 //not memcpy chunk info.
hualing chen040df222020-01-17 13:35:02 +08001917 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001918 //cp location
hualing chen040df222020-01-17 13:35:02 +08001919 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001920
Wentao MA96f68962022-06-15 19:45:35 +08001921 DVR_PB_INFO("add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001922 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001923
1924 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001925 segment->pids.video.pid = info->pids.video.pid;
1926 segment->pids.video.format = info->pids.video.format;
1927 segment->pids.video.type = info->pids.video.type;
1928
hualing chen2aba4022020-03-02 13:49:55 +08001929 segment->pids.audio.pid = info->pids.audio.pid;
1930 segment->pids.audio.format = info->pids.audio.format;
1931 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001932
hualing chen2aba4022020-03-02 13:49:55 +08001933 segment->pids.ad.pid = info->pids.ad.pid;
1934 segment->pids.ad.format = info->pids.ad.format;
1935 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001936
1937 segment->pids.pcr.pid = info->pids.pcr.pid;
1938
Wentao MA96f68962022-06-15 19:45:35 +08001939 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 +08001940 dvr_mutex_lock(&player->lock);
wentao.maa22bc852022-10-13 12:18:06 +08001941 list_add_tail(segment, &player->segment_list);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001942 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001943 DVR_PB_DEBUG("unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001944
hualing chen5cbe1a62020-02-10 16:36:36 +08001945 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001946}
hualing chen040df222020-01-17 13:35:02 +08001947/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001948 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001949 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001950 * \retval DVR_SUCCESS On success
1951 * \return Error code
1952 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001953int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001954 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001955 DVR_PB_INFO("remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001956 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001957 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001958 return DVR_FAILURE;
1959 }
1960
hualing chencc91e1c2020-02-28 13:26:17 +08001961 if (segment_id == player->cur_segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08001962 DVR_PB_INFO("not support remove current segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001963 return DVR_FAILURE;
1964 }
Wentao MA96f68962022-06-15 19:45:35 +08001965 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001966 dvr_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001967 DVR_PlaybackSegmentInfo_t *segment = NULL;
1968 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1969 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001970 {
hualing chen040df222020-01-17 13:35:02 +08001971 if (segment->segment_id == segment_id) {
1972 list_del(&segment->head);
1973 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001974 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001975 }
hualing chen86e7d482020-01-16 15:13:33 +08001976 }
Wentao MA96f68962022-06-15 19:45:35 +08001977 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001978 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001979
1980 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001981}
hualing chen040df222020-01-17 13:35:02 +08001982/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001983 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001984 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001985 * \retval DVR_SUCCESS On success
1986 * \return Error code
1987 */
hualing chen040df222020-01-17 13:35:02 +08001988int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001989 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001990 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001991 DVR_PB_INFO("update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001992 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001993 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001994 return DVR_FAILURE;
1995 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001996 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
Wentao MA96f68962022-06-15 19:45:35 +08001997 DVR_PB_INFO("vendor is amlogic. not hide or show av and update segment");
hualing chenf43b8ba2020-07-28 13:11:42 +08001998 return DVR_SUCCESS;
1999 }
hualing chena540a7e2020-03-27 16:44:05 +08002000
hualing chen040df222020-01-17 13:35:02 +08002001 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002002 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002003 dvr_mutex_lock(&player->lock);
wentao.mafd5283f2022-10-14 09:51:13 +08002004 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002005 // prefetch() here incurring self_assign is used to avoid some compiling
2006 // warnings.
2007 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002008 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002009 {
hualing chen040df222020-01-17 13:35:02 +08002010 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08002011 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08002012 }
hualing chen86e7d482020-01-16 15:13:33 +08002013 // if encramble to free, only set flag and return;
2014
2015 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08002016 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002017 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
2018 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08002019 //disable display, mute
Wentao MA96f68962022-06-15 19:45:35 +08002020 DVR_PB_INFO("mute av");
hualing chen2aba4022020-03-02 13:49:55 +08002021 AmTsPlayer_hideVideo(player->handle);
2022 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002023 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
2024 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002025 //enable display, unmute
Wentao MA96f68962022-06-15 19:45:35 +08002026 DVR_PB_INFO("unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08002027 AmTsPlayer_showVideo(player->handle);
2028 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002029 } else {
2030 //do nothing
2031 }
2032 } else {
2033 //do nothing
2034 }
2035 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08002036 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08002037 }
Wentao MA96f68962022-06-15 19:45:35 +08002038 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002039 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002040 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002041}
2042
2043
hualing chen99508642021-10-18 15:41:17 +08002044static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_PlaybackPids_t now_pids, DVR_PlaybackPids_t set_pids, int type) {
hualing chen040df222020-01-17 13:35:02 +08002045 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08002046 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08002047 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08002048
2049 if (type == 0) {
2050 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08002051 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08002052 } else if (type == 1) {
2053 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08002054 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08002055 } else if (type == 2) {
2056 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08002057 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08002058 } else {
2059 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08002060 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08002061 }
2062
hualing chena540a7e2020-03-27 16:44:05 +08002063 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002064 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002065 return DVR_FAILURE;
2066 }
hualing chen86e7d482020-01-16 15:13:33 +08002067 if (now_pid.pid == set_pid.pid) {
2068 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08002069 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08002070 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08002071 if (VALID_PID(now_pid.pid)) {
2072 //stop now stream
2073 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002074 //stop video
hualing chenc70a8df2020-05-12 19:23:11 +08002075 if (player->has_video == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002076 DVR_PB_INFO("stop video");
hualing chenc70a8df2020-05-12 19:23:11 +08002077 AmTsPlayer_stopVideoDecoding(player->handle);
2078 player->has_video = DVR_FALSE;
2079 }
hualing chen86e7d482020-01-16 15:13:33 +08002080 } else if (type == 1) {
2081 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002082 if (player->has_audio == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002083 DVR_PB_INFO("stop audio");
hualing chenc70a8df2020-05-12 19:23:11 +08002084 AmTsPlayer_stopAudioDecoding(player->handle);
2085 player->has_audio = DVR_FALSE;
2086 }
hualing chen86e7d482020-01-16 15:13:33 +08002087 } else if (type == 2) {
2088 //stop sub audio
Wentao MA96f68962022-06-15 19:45:35 +08002089 DVR_PB_INFO("stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002090 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002091 } else if (type == 3) {
2092 //pcr
2093 }
2094 }
2095 if (VALID_PID(set_pid.pid)) {
2096 //start
2097 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002098 //start video
2099 am_tsplayer_video_params video_params;
2100 video_params.pid = set_pid.pid;
2101 video_params.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002102 player->has_video = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002103 DVR_PB_INFO("start video pid[%d]fmt[%d]",video_params.pid, video_params.codectype);
2104 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen2aba4022020-03-02 13:49:55 +08002105 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002106 //playback_device_video_start(player->handle,&video_params);
hualing chen86e7d482020-01-16 15:13:33 +08002107 } else if (type == 1) {
2108 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002109 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002110 if (VALID_PID(set_pids.ad.pid)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002111 am_tsplayer_audio_params ad_params;
2112 ad_params.pid = set_pids.ad.pid;
2113 ad_params.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2114 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",ad_params.pid, ad_params.codectype);
2115 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen275379e2021-06-15 17:57:21 +08002116 AmTsPlayer_enableADMix(player->handle);
2117 }
2118
Wentao MA270dc0f2022-08-23 13:17:26 +08002119 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002120
Wentao MA270dc0f2022-08-23 13:17:26 +08002121 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002122
Wentao MA270dc0f2022-08-23 13:17:26 +08002123 audio_params.pid = set_pid.pid;
2124 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002125 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002126 DVR_PB_INFO("start audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2127 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002128 if (player->audio_presentation_id > -1) {
2129 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2130 }
hualing chenc70a8df2020-05-12 19:23:11 +08002131 AmTsPlayer_startAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002132 //playback_device_audio_start(player->handle,&audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002133 }
hualing chen86e7d482020-01-16 15:13:33 +08002134 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002135 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002136 if (set_pids.audio.pid == now_pids.audio.pid) {
2137 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002138 DVR_PB_INFO("stop audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002139 AmTsPlayer_stopAudioDecoding(player->handle);
2140 }
Wentao MA270dc0f2022-08-23 13:17:26 +08002141 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002142
Wentao MA270dc0f2022-08-23 13:17:26 +08002143 memset(&audio_params, 0, sizeof(audio_params));
2144 audio_params.pid = set_pid.pid;
2145 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002146 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002147 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2148 AmTsPlayer_setADParams(player->handle, &audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002149 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002150
2151 if (set_pids.audio.pid == now_pids.audio.pid) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002152 am_tsplayer_audio_params audio_params;
hualing chen99508642021-10-18 15:41:17 +08002153
Wentao MA270dc0f2022-08-23 13:17:26 +08002154 memset(&audio_params, 0, sizeof(audio_params));
hualing chen99508642021-10-18 15:41:17 +08002155
Wentao MA270dc0f2022-08-23 13:17:26 +08002156 audio_params.pid = set_pids.audio.pid;
2157 audio_params.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
hualing chen99508642021-10-18 15:41:17 +08002158 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002159 DVR_PB_INFO("restart audio when start ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002160 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002161 if (player->audio_presentation_id > -1) {
2162 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2163 }
hualing chen99508642021-10-18 15:41:17 +08002164 AmTsPlayer_startAudioDecoding(player->handle);
2165 }
hualing chenc70a8df2020-05-12 19:23:11 +08002166 }
hualing chen86e7d482020-01-16 15:13:33 +08002167 } else if (type == 3) {
2168 //pcr
Wentao MA96f68962022-06-15 19:45:35 +08002169 DVR_PB_INFO("start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002170 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002171 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002172 //audio and video all close
2173 if (!player->has_audio && !player->has_video) {
Wentao MA907b6432022-08-01 06:23:08 +00002174 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen5cbe1a62020-02-10 16:36:36 +08002175 }
hualing chen43a89bc2022-01-19 14:31:20 +08002176 } else if (type == 2) {
2177 //case disable ad
Wentao MA96f68962022-06-15 19:45:35 +08002178 DVR_PB_INFO("restart audio when stop ad");
hualing chen43a89bc2022-01-19 14:31:20 +08002179 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
Wentao MA6d045b32022-02-18 18:47:25 +08002180 if (VALID_PID(now_pids.audio.pid)) {
2181 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002182 DVR_PB_INFO("stop audio when stop ad pid [0x%x]", now_pids.audio.pid);
Wentao MA6d045b32022-02-18 18:47:25 +08002183 AmTsPlayer_stopAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002184 am_tsplayer_audio_params audio_params;
hualing chen43a89bc2022-01-19 14:31:20 +08002185
Wentao MA270dc0f2022-08-23 13:17:26 +08002186 memset(&audio_params, 0, sizeof(audio_params));
hualing chen43a89bc2022-01-19 14:31:20 +08002187
Wentao MA270dc0f2022-08-23 13:17:26 +08002188 audio_params.pid = now_pids.audio.pid;
2189 audio_params.codectype= _dvr_convert_stream_fmt(now_pids.audio.format, DVR_TRUE);
Wentao MA6d045b32022-02-18 18:47:25 +08002190 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002191 DVR_PB_INFO("restart audio when stop ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002192 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002193 if (player->audio_presentation_id > -1) {
2194 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2195 }
Wentao MA6d045b32022-02-18 18:47:25 +08002196 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen43a89bc2022-01-19 14:31:20 +08002197 }
Wentao MA6d045b32022-02-18 18:47:25 +08002198 }
hualing chen86e7d482020-01-16 15:13:33 +08002199 }
2200 }
2201 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002202}
hualing chena5f03222021-12-02 11:22:35 +08002203/**\brief dvr play back only update segment pids info
2204 * only update pid info not to start stop codec.
2205 * \param[in] handle playback handle
2206 * \param[in] segment_id need updated pids segment id
2207 * \param[in] p_pids need updated pids
2208 * \retval DVR_SUCCESS On success
2209 * \return Error code
2210 */
2211int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2212 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2213 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002214 DVR_PB_INFO("player is NULL");
hualing chena5f03222021-12-02 11:22:35 +08002215 return DVR_FAILURE;
2216 }
2217
2218 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002219 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002220 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002221 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 +08002222 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002223 // prefetch() here incurring self_assign is used to avoid some compiling
2224 // warnings.
2225 // coverity[self_assign]
hualing chena5f03222021-12-02 11:22:35 +08002226 list_for_each_entry(segment, &player->segment_list, head)
2227 {
2228 if (segment->segment_id == segment_id) {
2229 if (player->cur_segment_id == segment_id) {
2230 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002231 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chena5f03222021-12-02 11:22:35 +08002232 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002233 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002234 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002235 return 0;
2236 }
2237 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2238 }
2239 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002240 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002241 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002242 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002243 break;
2244 }
2245 }
Wentao MA96f68962022-06-15 19:45:35 +08002246 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002247 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002248 return DVR_SUCCESS;
2249}
2250
hualing chen5cbe1a62020-02-10 16:36:36 +08002251/**\brief dvr play back update segment pids
2252 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002253 * add pid stream and stop remove pid stream.
2254 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002255 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002256 * \retval DVR_SUCCESS On success
2257 * \return Error code
2258 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002259int 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 +08002260 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002261 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002262 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002263 return DVR_FAILURE;
2264 }
2265
hualing chen040df222020-01-17 13:35:02 +08002266 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002267 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002268 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002269 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 +08002270
wentao.mafd5283f2022-10-14 09:51:13 +08002271 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002272 // prefetch() here incurring self_assign is used to avoid some compiling
2273 // warnings.
2274 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08002275 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002276 {
hualing chen040df222020-01-17 13:35:02 +08002277 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002278
2279 if (player->cur_segment_id == segment_id) {
2280 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
Wentao MA16f870e2022-09-09 11:00:22 +08002281 || player->cmd.state == DVR_PLAYBACK_STATE_FB) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002282 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002283 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002284 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002285 return 0;
2286 }
2287
2288 //if segment is on going segment,we need stop start stream
2289 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA96f68962022-06-15 19:45:35 +08002290 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002291 dvr_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002292 if (segment->pids.audio.pid != p_pids->audio.pid &&
2293 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002294 //not used this to seek to start pos.we will
Wentao MA9a164002022-08-29 11:20:24 +08002295 //add update only api. if need seek to start
hualing chena5f03222021-12-02 11:22:35 +08002296 //pos, we will call only update api and used seek api
2297 //to start and stop av codec
2298 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002299 player->need_seek_start = DVR_FALSE;
2300 pthread_mutex_lock(&player->segment_lock);
2301 player->drop_ts = DVR_TRUE;
2302 player->ts_cache_len = 0;
2303 if (player->first_start_time > 0)
2304 player->first_start_time = player->first_start_time - 1;
2305 segment_seek(player->r_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002306 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 +08002307 pthread_mutex_unlock(&player->segment_lock);
2308 }
2309 }
hualing chen1679f812021-11-08 15:17:46 +08002310 //check video pids, stop or restart
2311 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
2312 //check sub audio pids stop or restart
2313 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
2314 //check audio pids stop or restart
2315 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
2316 //check pcr pids stop or restart
2317 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
2318
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002319 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002320 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2321 //if state is pause, we need process at resume api. we only record change info
2322 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2323 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2324 if (VALID_PID(segment->pids.video.pid)
2325 && VALID_PID(p_pids->video.pid)
2326 && segment->pids.video.pid != p_pids->video.pid) {
2327 //restart video
Wentao MA270dc0f2022-08-23 13:17:26 +08002328 v_cmd = DVR_PLAYBACK_CMD_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002329 }
2330 if (!VALID_PID(segment->pids.video.pid)
2331 && VALID_PID(p_pids->video.pid)
2332 && segment->pids.video.pid != p_pids->video.pid) {
2333 //start video
Wentao MA270dc0f2022-08-23 13:17:26 +08002334 v_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002335 }
2336 if (VALID_PID(segment->pids.video.pid)
2337 && !VALID_PID(p_pids->video.pid)
2338 && segment->pids.video.pid != p_pids->video.pid) {
2339 //stop video
Wentao MA270dc0f2022-08-23 13:17:26 +08002340 v_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002341 }
2342 if (VALID_PID(segment->pids.audio.pid)
2343 && VALID_PID(p_pids->audio.pid)
2344 && segment->pids.audio.pid != p_pids->audio.pid) {
2345 //restart audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002346 a_cmd = DVR_PLAYBACK_CMD_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002347 }
2348 if (!VALID_PID(segment->pids.audio.pid)
2349 && VALID_PID(p_pids->audio.pid)
2350 && segment->pids.audio.pid != p_pids->audio.pid) {
2351 //start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002352 a_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002353 }
2354 if (VALID_PID(segment->pids.audio.pid)
2355 && !VALID_PID(p_pids->audio.pid)
2356 && segment->pids.audio.pid != p_pids->audio.pid) {
2357 //stop audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002358 a_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002359 }
2360 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2361 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2362 //do nothing
2363 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2364 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2365 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2366 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2367 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2368 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002369 if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2370 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002371 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002372 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
2373 }else if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2374 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002375 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002376 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002377 } else {
2378 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002379 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002380 }
2381
Wentao MA270dc0f2022-08-23 13:17:26 +08002382 if (v_cmd == DVR_PLAYBACK_CMD_V_START
2383 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002384 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002385 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START_A_RESTART;
2386 } else if (v_cmd == DVR_PLAYBACK_CMD_V_START
2387 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002388 //not occur this case
2389 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2390 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2391 } else {
2392 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002393 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002394 }
2395
Wentao MA270dc0f2022-08-23 13:17:26 +08002396 if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2397 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002398 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002399 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_START;
2400 } else if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2401 && a_cmd == DVR_PLAYBACK_CMD_A_RESTART) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002402 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002403 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002404 } else {
2405 //not occur this case
2406 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2407 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2408 }
2409 }
2410 }
hualing chene10666f2020-04-14 13:58:37 +08002411 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002412 }
hualing chen86e7d482020-01-16 15:13:33 +08002413 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002414 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002415 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002416 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002417 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002418 }
hualing chen86e7d482020-01-16 15:13:33 +08002419 }
Wentao MA96f68962022-06-15 19:45:35 +08002420 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002421 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002422 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002423}
2424/**\brief Stop play, will stop video and audio
2425 * \param[in] handle playback handle
2426 * \param[in] clear is clear last frame
2427 * \retval DVR_SUCCESS On success
2428 * \return Error code
2429 */
hualing chen040df222020-01-17 13:35:02 +08002430int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2431 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002432 DVR_UNUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002433 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002434 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002435 return DVR_FAILURE;
2436 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002437 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002438 DVR_PB_INFO(":playback is stoped");
hualing chenb96aa2c2020-04-15 14:13:53 +08002439 return DVR_SUCCESS;
2440 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002441 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002442 DVR_PB_INFO(":playback is stoped");
Ke Gong3c0caba2020-04-21 22:58:18 -07002443 return DVR_SUCCESS;
2444 }
hualing chen87072a82020-03-12 16:20:12 +08002445 _stop_playback_thread(handle);
Wentao MA96f68962022-06-15 19:45:35 +08002446 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002447 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002448 DVR_PB_INFO(":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002449 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002450 if (player->has_video) {
2451 AmTsPlayer_resumeVideoDecoding(player->handle);
2452 }
2453 if (player->has_audio) {
2454 AmTsPlayer_resumeAudioDecoding(player->handle);
2455 }
2456 if (player->has_video) {
2457 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002458 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002459 AmTsPlayer_stopVideoDecoding(player->handle);
2460 }
2461 if (player->has_audio) {
2462 player->has_audio = DVR_FALSE;
2463 AmTsPlayer_stopAudioDecoding(player->handle);
2464 }
hualing chendf118dd2020-05-21 15:49:11 +08002465 if (player->has_ad_audio) {
2466 player->has_ad_audio =DVR_FALSE;
2467 AmTsPlayer_disableADMix(player->handle);
2468 }
hualing chen266b9502020-04-04 17:39:39 +08002469
hualing chen86e7d482020-01-16 15:13:33 +08002470 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002471 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2472 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002473 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen87072a82020-03-12 16:20:12 +08002474 player->cur_segment_id = UINT64_MAX;
2475 player->segment_is_open = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08002476 DVR_PB_DEBUG("unlock");
2477 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002478 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002479 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002480}
2481/**\brief Start play audio
2482 * \param[in] handle playback handle
2483 * \param[in] params audio playback params,contains fmt and pid...
2484 * \retval DVR_SUCCESS On success
2485 * \return Error code
2486 */
hualing chen2aba4022020-03-02 13:49:55 +08002487
Wentao MA270dc0f2022-08-23 13:17:26 +08002488int 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 +08002489 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002490
2491 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 chen86e7d482020-01-16 15:13:33 +08002495 _start_playback_thread(handle);
2496 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002497 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002498 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002499
Wentao MA270dc0f2022-08-23 13:17:26 +08002500 if (VALID_PID(ad_param->pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08002501 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002502 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002503 AmTsPlayer_setADParams(player->handle, ad_param);
hualing chendf118dd2020-05-21 15:49:11 +08002504 AmTsPlayer_enableADMix(player->handle);
2505 }
hualing chen969fe7b2021-05-26 15:13:17 +08002506 if (VALID_PID(param->pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08002507 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08002508 player->has_audio = DVR_TRUE;
2509 AmTsPlayer_setAudioParams(player->handle, param);
Wentao MA5629ad82022-08-24 10:03:02 +08002510 if (player->audio_presentation_id > -1) {
2511 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2512 }
hualing chen969fe7b2021-05-26 15:13:17 +08002513 AmTsPlayer_startAudioDecoding(player->handle);
2514 }
hualing chendf118dd2020-05-21 15:49:11 +08002515
hualing chen86e7d482020-01-16 15:13:33 +08002516 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002517 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen040df222020-01-17 13:35:02 +08002518 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002519 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002520 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002521 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002522 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002523}
2524/**\brief Stop play audio
2525 * \param[in] handle playback handle
2526 * \retval DVR_SUCCESS On success
2527 * \return Error code
2528 */
hualing chen040df222020-01-17 13:35:02 +08002529int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2530 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002531
2532 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002533 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002534 return DVR_FAILURE;
2535 }
2536
hualing chen2aba4022020-03-02 13:49:55 +08002537 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002538 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002539 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002540 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002541 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002542 _stop_playback_thread(handle);
2543 } else {
2544 //do nothing.video is playing
2545 }
Wentao MA96f68962022-06-15 19:45:35 +08002546 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002547 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002548
hualing chenf00cdc82020-06-10 14:23:35 +08002549 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002550 player->has_audio = DVR_FALSE;
2551 AmTsPlayer_stopAudioDecoding(player->handle);
2552 }
hualing chen87072a82020-03-12 16:20:12 +08002553
hualing chendf118dd2020-05-21 15:49:11 +08002554 if (player->has_ad_audio) {
2555 player->has_ad_audio =DVR_FALSE;
2556 AmTsPlayer_disableADMix(player->handle);
2557 }
2558
hualing chen87072a82020-03-12 16:20:12 +08002559 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002560 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002561
Wentao MA96f68962022-06-15 19:45:35 +08002562 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002563 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002564 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002565}
2566/**\brief Start play video
2567 * \param[in] handle playback handle
2568 * \param[in] params video playback params,contains fmt and pid...
2569 * \retval DVR_SUCCESS On success
2570 * \return Error code
2571 */
hualing chen2aba4022020-03-02 13:49:55 +08002572int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002573 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002574
2575 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002576 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002577 return DVR_FAILURE;
2578 }
2579
hualing chen86e7d482020-01-16 15:13:33 +08002580 _start_playback_thread(handle);
2581 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002582 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002583 dvr_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002584 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002585 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002586 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002587 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002588
2589 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002590 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002591 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08002592 DVR_PB_INFO("settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002593 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2594 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002595 }
2596 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002597 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen040df222020-01-17 13:35:02 +08002598 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002599 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002600 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002601 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002602 return DVR_SUCCESS;
2603}
2604/**\brief Stop play video
2605 * \param[in] handle playback handle
2606 * \retval DVR_SUCCESS On success
2607 * \return Error code
2608 */
hualing chen040df222020-01-17 13:35:02 +08002609int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2610 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002611
2612 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002613 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002614 return DVR_FAILURE;
2615 }
2616
hualing chen86e7d482020-01-16 15:13:33 +08002617 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002618 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002619 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002620 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002621 _stop_playback_thread(handle);
2622 } else {
2623 //do nothing.audio is playing
2624 }
hualing chen7a56cba2020-04-14 14:09:27 +08002625
Wentao MA96f68962022-06-15 19:45:35 +08002626 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002627 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002628
hualing chen87072a82020-03-12 16:20:12 +08002629 player->has_video = DVR_FALSE;
2630
2631 AmTsPlayer_stopVideoDecoding(player->handle);
2632 //playback_device_video_stop(player->handle);
2633
2634 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002635 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002636
Wentao MA96f68962022-06-15 19:45:35 +08002637 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002638 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002639 return DVR_SUCCESS;
2640}
2641/**\brief Pause play
2642 * \param[in] handle playback handle
2643 * \param[in] flush whether its internal buffers should be flushed
2644 * \retval DVR_SUCCESS On success
2645 * \return Error code
2646 */
hualing chen040df222020-01-17 13:35:02 +08002647int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2648 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002649 DVR_UNUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002650 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002651 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002652 return DVR_FAILURE;
2653 }
hualing chenf00cdc82020-06-10 14:23:35 +08002654 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
Wentao MA96f68962022-06-15 19:45:35 +08002655 DVR_PB_INFO("player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002656 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002657 }
Wentao MA96f68962022-06-15 19:45:35 +08002658 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002659 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002660 DVR_PB_DEBUG("get lock");
hualing chen266b9502020-04-04 17:39:39 +08002661 if (player->has_video)
2662 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002663 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002664 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002665
2666 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002667 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2668 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2669 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002670 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002671 } else {
2672 player->cmd.last_cmd = player->cmd.cur_cmd;
2673 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2674 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002675 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002676 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002677 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002678 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002679
hualing chen86e7d482020-01-16 15:13:33 +08002680 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002681}
2682
hualing chen5cbe1a62020-02-10 16:36:36 +08002683//not add lock
2684static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2685{
2686 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2687
hualing chena540a7e2020-03-27 16:44:05 +08002688 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002689 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002690 return DVR_FAILURE;
2691 }
2692
hualing chen5cbe1a62020-02-10 16:36:36 +08002693 //get video params and audio params
Wentao MA96f68962022-06-15 19:45:35 +08002694 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002695 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08002696 am_tsplayer_video_params video_params;
2697 am_tsplayer_audio_params audio_params;
2698 am_tsplayer_audio_params ad_params;
hualing chencc91e1c2020-02-28 13:26:17 +08002699 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002700
Wentao MA270dc0f2022-08-23 13:17:26 +08002701 memset(&video_params, 0, sizeof(video_params));
2702 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002703
Wentao MA270dc0f2022-08-23 13:17:26 +08002704 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
Wentao MA96f68962022-06-15 19:45:35 +08002705 DVR_PB_INFO("unlock cmd: %d", cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002706 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002707
2708 switch (cmd) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002709 case DVR_PLAYBACK_CMD_AV_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002710 //av restart
Wentao MA270dc0f2022-08-23 13:17:26 +08002711 DVR_PB_INFO("do_cmd av_restart");
hualing chen87072a82020-03-12 16:20:12 +08002712 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002713 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002714 case DVR_PLAYBACK_CMD_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002715 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002716 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002717 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002718 case DVR_PLAYBACK_CMD_V_START:
2719 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002720 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002721 case DVR_PLAYBACK_CMD_V_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002722 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002723 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002724 case DVR_PLAYBACK_CMD_A_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002725 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002726 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002727 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002728 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002729 case DVR_PLAYBACK_CMD_A_START:
2730 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002731 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002732 case DVR_PLAYBACK_CMD_A_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002733 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002734 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002735 case DVR_PLAYBACK_CMD_A_STOP_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002736 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2737 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002738 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002739 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002740 case DVR_PLAYBACK_CMD_A_STOP_V_START:
hualing chen2aba4022020-03-02 13:49:55 +08002741 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002742 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002743 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002744 case DVR_PLAYBACK_CMD_V_STOP_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002745 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2746 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002747 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002748 break;
2749 case DVR_PLAYBACK_CMD_STOP:
2750 break;
2751 case DVR_PLAYBACK_CMD_START:
2752 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002753 case DVR_PLAYBACK_CMD_A_START_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002754 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002755 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2756 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002757 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002758 case DVR_PLAYBACK_CMD_V_START_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002759 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002760 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2761 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002762 break;
2763 case DVR_PLAYBACK_CMD_FF:
2764 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002765 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002766 break;
2767 default:
2768 break;
2769 }
2770 return DVR_SUCCESS;
2771}
2772
2773/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002774 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002775 * \retval DVR_SUCCESS On success
2776 * \return Error code
2777 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002778int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2779 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002780 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002781 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002782 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002783 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002784 return DVR_FAILURE;
2785 }
2786
hualing chena991aa82021-08-16 10:21:15 +08002787 if (dvr_playback_check_limit(handle)) {
2788 //get id and pos to check if we can seek to this pos
Wentao MA96f68962022-06-15 19:45:35 +08002789 DVR_PB_INFO("player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002790 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2791 if (segmentid != player->cur_segment_id ||
2792 (segmentid == player->cur_segment_id &&
2793 pos > _dvr_get_cur_time(handle))) {
2794 //first to seek new pos and to resume
Wentao MA96f68962022-06-15 19:45:35 +08002795 DVR_PB_INFO("seek new pos and to resume");
hualing chena991aa82021-08-16 10:21:15 +08002796 dvr_playback_seek(handle, segmentid, pos);
2797 }
hualing chen7ea70a72021-09-09 11:25:13 +08002798 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002799 DVR_PB_INFO("player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002800 }
hualing chena991aa82021-08-16 10:21:15 +08002801
hualing chen5cbe1a62020-02-10 16:36:36 +08002802 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08002803 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002804 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002805 player->first_frame = 0;
2806 if (player->has_video)
2807 AmTsPlayer_pauseVideoDecoding(player->handle);
2808 if (player->has_audio)
2809 AmTsPlayer_pauseAudioDecoding(player->handle);
2810
hualing chen266b9502020-04-04 17:39:39 +08002811 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002812 DVR_PB_INFO("dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002813 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2814 AmTsPlayer_resumeVideoDecoding(player->handle);
2815 }
2816 if (player->has_audio) {
2817 AmTsPlayer_resumeAudioDecoding(player->handle);
2818 }
2819 //check is has audio param,if has audio .we need start audio,
2820 //we will stop audio when ff fb, if reach end, we will pause.so we need
2821 //start audio when resume play
2822
Wentao MA270dc0f2022-08-23 13:17:26 +08002823 am_tsplayer_video_params video_params;
2824 am_tsplayer_audio_params audio_params;
2825 am_tsplayer_audio_params ad_params;
hualing chen266b9502020-04-04 17:39:39 +08002826 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002827
Wentao MA270dc0f2022-08-23 13:17:26 +08002828 memset(&video_params, 0, sizeof(video_params));
2829 memset(&audio_params, 0, sizeof(audio_params));
2830 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
hualing chen266b9502020-04-04 17:39:39 +08002831 //valid audio pid, start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002832 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 +08002833 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002834 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002835 dvr_playback_change_seek_state(handle, ad_params.pid);
2836 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen969fe7b2021-05-26 15:13:17 +08002837 AmTsPlayer_enableADMix(player->handle);
2838 }
2839
Wentao MA270dc0f2022-08-23 13:17:26 +08002840 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 +08002841 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002842 dvr_playback_change_seek_state(handle, audio_params.pid);
2843 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002844 if (player->audio_presentation_id > -1) {
2845 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2846 }
hualing chen266b9502020-04-04 17:39:39 +08002847 AmTsPlayer_startAudioDecoding(player->handle);
2848 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08002849 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 +08002850 }
hualing chendf118dd2020-05-21 15:49:11 +08002851
hualing chen87072a82020-03-12 16:20:12 +08002852 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2853 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2854 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002855 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002856 } else {
2857 player->cmd.last_cmd = player->cmd.cur_cmd;
2858 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2859 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002860 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002861 }
Wentao MA96f68962022-06-15 19:45:35 +08002862 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002863 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002864 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
Wentao MA96f68962022-06-15 19:45:35 +08002865 DVR_PB_INFO("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002866 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002867 player->first_frame = 0;
2868 if (player->has_video)
2869 AmTsPlayer_pauseVideoDecoding(player->handle);
2870 if (player->has_audio)
2871 AmTsPlayer_pauseAudioDecoding(player->handle);
2872
hualing chene41f4372020-06-06 16:29:17 +08002873 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002874 DVR_PB_INFO("dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002875 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002876 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002877 }
hualing chen041c4092020-04-05 15:11:50 +08002878 if (player->has_audio)
2879 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002880 DVR_PB_INFO("set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen9811b212020-10-29 11:21:44 +08002881 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2882 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chend1686e52022-01-05 17:10:42 +08002883 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002884 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002885 DVR_PB_INFO("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002886 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002887 } else {
2888 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2889 {
Wentao MA96f68962022-06-15 19:45:35 +08002890 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002891 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002892 player->first_frame = 0;
2893 if (player->has_video)
2894 AmTsPlayer_pauseVideoDecoding(player->handle);
2895 if (player->has_audio)
2896 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002897 //clear flag
Wentao MA96f68962022-06-15 19:45:35 +08002898 DVR_PB_INFO("clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002899 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2900 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002901 if (player->has_video) {
2902 AmTsPlayer_resumeVideoDecoding(player->handle);
2903 }
2904 if (player->has_audio)
2905 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002906 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002907 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002908 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002909 }
2910 return DVR_SUCCESS;
2911}
2912
hualing chena540a7e2020-03-27 16:44:05 +08002913static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2914
2915 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2916 DVR_PlaybackSegmentInfo_t *segment = NULL;
2917 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2918 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2919
wentao.mafd5283f2022-10-14 09:51:13 +08002920 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08002921 // prefetch() here incurring self_assign is used to avoid some compiling
2922 // warnings.
2923 // coverity[self_assign]
hualing chena540a7e2020-03-27 16:44:05 +08002924 list_for_each_entry(segment, &player->segment_list, head)
2925 {
2926 if (segment->segment_id == segment_id) {
2927 cur_segment = segment;
2928 }
2929 if (segment->segment_id == set_seg_id) {
2930 set_segment = segment;
2931 }
2932 if (cur_segment != NULL && set_segment != NULL) {
2933 break;
2934 }
2935 }
2936 if (cur_segment == NULL || set_segment == NULL) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002937 DVR_PB_INFO("set segment or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002938 return DVR_TRUE;
2939 }
2940 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2941 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2942 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2943 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
Wentao MA96f68962022-06-15 19:45:35 +08002944 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 +08002945 return DVR_TRUE;
2946 }
Wentao MA96f68962022-06-15 19:45:35 +08002947 DVR_PB_INFO("play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002948 return DVR_FALSE;
2949}
2950
hualing chen03fd4942021-07-15 15:56:41 +08002951/**\brief set limit
2952 * \param[in] handle playback handle
2953 * \param[in] rec start time ms
2954 * \param[in] rec limit time ms
2955 * \retval DVR_SUCCESS On success
2956 * \return Error code
2957 */
hualing chen7ea70a72021-09-09 11:25:13 +08002958int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08002959{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2960
2961 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002962 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08002963 return DVR_FAILURE;
2964 }
hualing chen7ea70a72021-09-09 11:25:13 +08002965 _dvr_getClock_sec();
Wentao MA96f68962022-06-15 19:45:35 +08002966 DVR_PB_INFO("lock time %lu limit: %u player->state:%d", time, limit, player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002967 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002968 player->rec_start = time;
2969 player->limit = limit;
Wentao MA96f68962022-06-15 19:45:35 +08002970 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002971 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002972 return DVR_SUCCESS;
2973}
2974
hualing chen5cbe1a62020-02-10 16:36:36 +08002975/**\brief seek
2976 * \param[in] handle playback handle
2977 * \param[in] time_offset time offset base cur segment
2978 * \retval DVR_SUCCESS On success
2979 * \return Error code
2980 */
hualing chencc91e1c2020-02-28 13:26:17 +08002981int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002982 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002983 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08002984 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002985 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002986 return DVR_FAILURE;
2987 }
2988
Wentao MA96f68962022-06-15 19:45:35 +08002989 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 +08002990 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002991
hualing chena540a7e2020-03-27 16:44:05 +08002992 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
Wentao MA96f68962022-06-15 19:45:35 +08002993 DVR_PB_INFO("player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002994
hualing chen5cbe1a62020-02-10 16:36:36 +08002995 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08002996 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002997 if (ret ==DVR_FAILURE) {
wentao.maa210e5e2022-10-12 16:10:03 +08002998 DVR_PB_ERROR("unlock seek error at open segment");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002999 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003000 return DVR_FAILURE;
3001 }
3002 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
3003 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08003004 DVR_PB_INFO("is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08003005 time_offset = _dvr_get_end_time(handle);
3006 } else {
wentao.maa210e5e2022-10-12 16:10:03 +08003007 DVR_PB_ERROR("is not ongoing segment when seek end, return failure");
3008 return DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08003009 }
3010 }
3011
Wentao MA96f68962022-06-15 19:45:35 +08003012 DVR_PB_INFO("seek open id[%lld]flag[0x%x] time_offset %u",
hualing chen03fd4942021-07-15 15:56:41 +08003013 player->cur_segment.segment_id,
3014 player->cur_segment.flags,
3015 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08003016 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08003017 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3018 //forward playback.not seek end of file
3019 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
3020 //default -2000ms
3021 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
3022 }
hualing chen86e7d482020-01-16 15:13:33 +08003023 }
Wentao MA01de0e62022-01-10 18:48:23 +08003024 // Seek can be regarded as a new playback, so keep the start segment_id for it also
hualing chen8a657f32021-08-30 13:12:49 +08003025 if (player->need_seek_start == DVR_TRUE) {
3026 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
Wentao MA01de0e62022-01-10 18:48:23 +08003027 player->first_start_id = player->cur_segment.segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003028 }
hualing chen2aba4022020-03-02 13:49:55 +08003029 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08003030 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08003031 player->ts_cache_len = 0;
wentao.maa210e5e2022-10-12 16:10:03 +08003032 int offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08003033 DVR_PB_ERROR("seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08003034 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08003035 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08003036
hualing chen2aba4022020-03-02 13:49:55 +08003037 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08003038
3039 player->last_send_time_id = UINT64_MAX;
Wentao MA270dc0f2022-08-23 13:17:26 +08003040 player->last_segment_total = 0LL;
hualing chen03fd4942021-07-15 15:56:41 +08003041 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08003042 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08003043 player->fffb_current = _dvr_time_getClock();
3044 player->fffb_start = player->fffb_current;
3045 player->fffb_start_pcr = _dvr_get_cur_time(handle);
3046 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08003047 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08003048 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003049 //only seek file,not start
Wentao MA96f68962022-06-15 19:45:35 +08003050 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003051 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003052 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08003053 }
hualing chen86e7d482020-01-16 15:13:33 +08003054 //stop play
Wentao MA96f68962022-06-15 19:45:35 +08003055 DVR_PB_ERROR("seek stop play, not inject data has video[%d]audio[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003056 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08003057
hualing chen266b9502020-04-04 17:39:39 +08003058 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08003059 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003060 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003061 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003062 }
3063
hualing chen40dd5462021-11-26 19:56:20 +08003064
hualing chen266b9502020-04-04 17:39:39 +08003065 if (player->has_audio) {
3066 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003067 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003068 }
hualing chendf118dd2020-05-21 15:49:11 +08003069 if (player->has_ad_audio) {
3070 player->has_ad_audio =DVR_FALSE;
3071 AmTsPlayer_disableADMix(player->handle);
3072 }
3073
hualing chen86e7d482020-01-16 15:13:33 +08003074 //start play
Wentao MA270dc0f2022-08-23 13:17:26 +08003075 am_tsplayer_video_params video_params;
3076 am_tsplayer_audio_params audio_params;
3077 am_tsplayer_audio_params ad_params;
hualing chenb31a6c62020-01-13 17:27:00 +08003078
Wentao MA270dc0f2022-08-23 13:17:26 +08003079 memset(&video_params, 0, sizeof(video_params));
3080 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003081
hualing chen040df222020-01-17 13:35:02 +08003082 player->cur_segment_id = segment_id;
3083
3084 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08003085 //get segment info and audio video pid fmt ;
Wentao MA270dc0f2022-08-23 13:17:26 +08003086 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08003087 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003088 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chena5f03222021-12-02 11:22:35 +08003089 //audio and video pid is all invalid, return error.
Wentao MA270dc0f2022-08-23 13:17:26 +08003090 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 +08003091 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08003092 return -1;
3093 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003094 DVR_PB_ERROR("seek start[0x%x]", video_params.pid);
hualing chen86e7d482020-01-16 15:13:33 +08003095 //add
hualing chen040df222020-01-17 13:35:02 +08003096 if (sync == DVR_PLAYBACK_SYNC) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003097 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003098 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08003099 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08003100 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08003101 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08003102 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003103 //if is pause state. we need set trick mode.
Wentao MA96f68962022-06-15 19:45:35 +08003104 DVR_PB_INFO("seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003105 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08003106 }
Wentao MA96f68962022-06-15 19:45:35 +08003107 DVR_PB_INFO("start video");
Wentao MA270dc0f2022-08-23 13:17:26 +08003108 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003109 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003110 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08003111 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
3112 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
3113 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
3114 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
3115 AmTsPlayer_stopFast(player->handle);
3116 }
hualing chen266b9502020-04-04 17:39:39 +08003117 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08003118 } else {
3119 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08003120 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003121 if (VALID_PID(ad_params.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08003122 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003123 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003124 dvr_playback_change_seek_state(handle, ad_params.pid);
3125 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003126 AmTsPlayer_enableADMix(player->handle);
3127 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003128 if (VALID_PID(audio_params.pid) && player->speed == 1.0) {
Wentao MA96f68962022-06-15 19:45:35 +08003129 DVR_PB_INFO("start audio seek");
Wentao MA270dc0f2022-08-23 13:17:26 +08003130 dvr_playback_change_seek_state(handle, audio_params.pid);
3131 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003132 if (player->audio_presentation_id > -1) {
3133 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3134 }
hualing chen969fe7b2021-05-26 15:13:17 +08003135 AmTsPlayer_startAudioDecoding(player->handle);
3136 player->has_audio = DVR_TRUE;
3137 }
hualing chen43a89bc2022-01-19 14:31:20 +08003138#ifdef AVSYNC_USED_PCR
3139 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003140 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003141 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3142 }
3143#endif
hualing chen86e7d482020-01-16 15:13:33 +08003144 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003145 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen2aba4022020-03-02 13:49:55 +08003146 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00003147 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
Wentao MA270dc0f2022-08-23 13:17:26 +08003148 if (VALID_PID(audio_params.pid) || VALID_PID(video_params.pid))
hualing chena5f03222021-12-02 11:22:35 +08003149 player->seek_pause = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08003150 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 +08003151 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
Wentao MA16f870e2022-09-09 11:00:22 +08003152 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chen31140872020-03-25 12:29:26 +08003153 player->speed > 1.0f||
3154 player->speed <= -1.0f) {
Wentao MA96f68962022-06-15 19:45:35 +08003155 DVR_PB_INFO("not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003156 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003157 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003158 DVR_PB_INFO("set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003159 player->cmd.last_cmd = player->cmd.cur_cmd;
3160 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3161 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003162 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen2aba4022020-03-02 13:49:55 +08003163 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003164 player->last_send_time_id = UINT64_MAX;
Wentao MA96f68962022-06-15 19:45:35 +08003165 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003166 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003167
3168 return DVR_SUCCESS;
3169}
hualing chen5cbe1a62020-02-10 16:36:36 +08003170
Wentao MAac5ea062022-08-11 11:44:27 +08003171// Get current playback time position of the ongoing segment.
3172// Notice the return value may be negative. This is because previous segment's
3173// data cached in demux buffer need to be considered.
hualing chen5cbe1a62020-02-10 16:36:36 +08003174static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3175 //get cur time of segment
3176 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003177
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003178 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003179 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003180 return DVR_FAILURE;
3181 }
3182
Wentao MA270dc0f2022-08-23 13:17:26 +08003183 int64_t cache = 0;//default es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003184 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003185 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003186 uint64_t cur = 0;
3187 if (player->ts_cache_len > 0 && pos < 0) {
3188 //this case is open new segment end,but cache data is last segment.
3189 //we need used last segment len to send play time.
3190 cur = 0;
3191 } else {
3192 cur = segment_tell_position_time(player->r_handle, pos);
3193 }
hualing chen21a40372021-10-29 11:07:26 +08003194 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003195 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08003196 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 +08003197 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3198 cache = 0;
3199 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003200 int cur_time = (int)(cur > cache ? cur - cache : 0);
3201 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003202}
3203
Wentao MAac5ea062022-08-11 11:44:27 +08003204// Get current playback time position of the ongoing segment.
3205// Notice the return value may be negative. This is because previous segment's
3206// data cached in demux buffer need to be considered.
hualing chen969fe7b2021-05-26 15:13:17 +08003207static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3208 //get cur time of segment
3209 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3210
Wentao MA804bab12022-11-29 10:01:26 +08003211 DVR_RETURN_IF_FALSE(player != NULL);
3212 DVR_RETURN_IF_FALSE(player->handle != 0);
hualing chen969fe7b2021-05-26 15:13:17 +08003213
hualing chen969fe7b2021-05-26 15:13:17 +08003214 pthread_mutex_lock(&player->segment_lock);
Wentao MA804bab12022-11-29 10:01:26 +08003215 const loff_t pos = segment_tell_position(player->r_handle);
3216 const uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003217 pthread_mutex_unlock(&player->segment_lock);
Wentao MA01de0e62022-01-10 18:48:23 +08003218
Wentao MA804bab12022-11-29 10:01:26 +08003219 int cache = 0;
3220 get_effective_tsplayer_delay_time(player, &cache);
Wentao MA01de0e62022-01-10 18:48:23 +08003221
hualing chen969fe7b2021-05-26 15:13:17 +08003222 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3223 cache = 0;
3224 }
Wentao MA804bab12022-11-29 10:01:26 +08003225
3226 const int cur_time = (int)(cur - cache);
3227 *id = player->cur_segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003228
Wentao MA80179512022-11-03 12:20:03 +08003229 DVR_PB_INFO("***get playback slider position within segment. segment_id [%lld],"
3230 " segment_slider_pos[%7d ms] = segment_read_pos[%7lld ms] - tsplayer_cache_len[%5lld ms],"
3231 " last id [%lld] pos [%lld]",
3232 player->cur_segment_id,cur_time,cur,cache,player->last_send_time_id,pos);
Wentao MA804bab12022-11-29 10:01:26 +08003233
hualing chen969fe7b2021-05-26 15:13:17 +08003234 return cur_time;
3235}
3236
hualing chencc91e1c2020-02-28 13:26:17 +08003237//get current segment current pcr time of read pos
3238static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3239 //get cur time of segment
3240 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003241
3242 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003243 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003244 return DVR_FAILURE;
3245 }
3246
hualing chen2aba4022020-03-02 13:49:55 +08003247 pthread_mutex_lock(&player->segment_lock);
3248 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen2aba4022020-03-02 13:49:55 +08003249 pthread_mutex_unlock(&player->segment_lock);
3250 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003251}
3252
hualing chen03fd4942021-07-15 15:56:41 +08003253DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3254{
3255 //check is set limit info
3256 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3257
3258 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003259 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003260 return DVR_FALSE;
3261 }
3262 if (player->rec_start > 0 || player->limit > 0) {
3263 return DVR_TRUE;
3264 }
3265 return DVR_FALSE;
3266}
3267
3268/**\brief set DVR playback calculate expired time len
3269 * \param[in] handle, DVR playback session handle
3270 * \return DVR_SUCCESS on success
3271 * \return error code on failure
3272 */
hualing chen7ea70a72021-09-09 11:25:13 +08003273uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003274{
3275 //calculate expired time to play
3276 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003277 uint32_t cur_time;
3278 uint32_t tmp_time;
3279 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003280 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003281 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003282 return expired;
3283 }
hualing chen7ea70a72021-09-09 11:25:13 +08003284 if (player->rec_start == 0 || player->limit == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003285 DVR_PB_INFO("rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003286 return expired;
3287 }
3288 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003289 cur_time = _dvr_getClock_sec();
3290 if ((cur_time - player->rec_start) > player->limit) {
3291 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3292 expired = *(int*)&tmp_time;
Wentao MA96f68962022-06-15 19:45:35 +08003293 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 +08003294 cur_time,
3295 player->rec_start,
3296 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003297 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3298 }
hualing chen03fd4942021-07-15 15:56:41 +08003299 return expired;
3300}
3301
3302/**\brief set DVR playback obsolete time
3303 * \param[in] handle, DVR playback session handle
3304 * \param[in] obsolete, obsolete len
3305 * \return DVR_SUCCESS on success
3306 * \return error code on failure
3307 */
3308int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3309{
3310 int expired = 0;
3311 //calculate expired time to play
3312 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3313
3314 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003315 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003316 return DVR_FALSE;
3317 }
3318 //get system time
Wentao MA96f68962022-06-15 19:45:35 +08003319 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003320 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003321 player->obsolete = obsolete;
Wentao MA96f68962022-06-15 19:45:35 +08003322 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003323 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003324 return expired;
3325}
3326
3327/**\brief update DVR playback newest segment duration
3328 * \param[in] handle, DVR playback session handle
3329 * \param[in] segmentid, newest segment id
3330 * \param[in] dur dur time ms
3331 * \return DVR_SUCCESS on success
3332 * \return error code on failure
3333 */
3334int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3335uint64_t segmentid, int dur)
3336{
3337 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3338 DVR_PlaybackSegmentInfo_t *segment;
3339 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3340
3341 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003342 DVR_PB_INFO(" player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003343 return DVR_FAILURE;
3344 }
3345 //update the newest segment duration on timeshift mode
wentao.mafd5283f2022-10-14 09:51:13 +08003346 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003347 // prefetch() here incurring self_assign is used to avoid some compiling
3348 // warnings.
3349 // coverity[self_assign]
hualing chen03fd4942021-07-15 15:56:41 +08003350 list_for_each_entry(segment, &player->segment_list, head)
3351 {
3352 if (segment->segment_id == segmentid) {
3353 segment->duration = dur;
3354 break;
3355 }
3356 pre_segment = segment;
3357 }
3358
3359 return DVR_SUCCESS;
3360}
3361
hualing chen7ea70a72021-09-09 11:25:13 +08003362static uint32_t dvr_playback_calculate_last_valid_segment(
3363 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003364{
hualing chen7ea70a72021-09-09 11:25:13 +08003365 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003366 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003367 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003368 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003369 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003370 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3371
3372 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003373 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003374 return DVR_FAILURE;
3375 }
3376 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003377 if (expired == 0) {
3378 *segmentid = player->cur_segment_id;
3379 *pos = 0;
3380 return DVR_SUCCESS;
3381 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003382 DVR_PlaybackSegmentInfo_t *p_seg;
wentao.mafd5283f2022-10-14 09:51:13 +08003383 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08003384 // prefetch() here incurring self_assign is used to avoid some compiling
3385 // warnings.
3386 // coverity[self_assign]
Wentao MA270dc0f2022-08-23 13:17:26 +08003387 list_for_each_entry_reverse(p_seg, &player->segment_list, head) {
3388 segment_id = p_seg->segment_id;
hualing chen03fd4942021-07-15 15:56:41 +08003389
Wentao MA270dc0f2022-08-23 13:17:26 +08003390 if ((player->obsolete + pre_off + p_seg->duration) > expired)
hualing chen03fd4942021-07-15 15:56:41 +08003391 break;
3392
Wentao MA270dc0f2022-08-23 13:17:26 +08003393 last_segment_id = p_seg->segment_id;
3394 pre_off += p_seg->duration;
hualing chen03fd4942021-07-15 15:56:41 +08003395 }
3396
3397 if (last_segment_id == segment_id) {
3398 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3399 off = expired;
3400 } else if (player->obsolete >= expired) {
3401 off = 0;
3402 } else {
3403 off = expired - pre_off - player->obsolete;
3404 }
3405 *segmentid = segment_id;
3406 *pos = off;
3407 return DVR_SUCCESS;
3408}
3409
hualing chen4b7c15d2020-04-07 16:13:48 +08003410#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003411//start replay
3412static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3413
3414 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3415 //calculate pcr seek time
3416 int t_diff = 0;
3417 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003418 uint64_t segmentid = 0;
3419 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003420 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003421 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003422 return DVR_FAILURE;
3423 }
3424
hualing chen5cbe1a62020-02-10 16:36:36 +08003425 if (player->fffb_start == -1) {
3426 //set fffb start time ms
3427 player->fffb_start = _dvr_time_getClock();
3428 player->fffb_current = player->fffb_start;
3429 //get segment current time pos
3430 player->fffb_start_pcr = _dvr_get_cur_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003431 DVR_PB_INFO("calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
hualing chen03fd4942021-07-15 15:56:41 +08003432 player->fffb_start_pcr, player->speed);
hualing chene41f4372020-06-06 16:29:17 +08003433 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003434 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003435 } else {
3436 player->fffb_current = _dvr_time_getClock();
3437 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003438 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003439 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003440 if (seek_time <= 0) {
3441 //need seek to pre one segment
3442 seek_time = 0;
3443 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003444 //seek segment pos
3445 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003446 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003447 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003448 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3449 //set seek time to 0;
Wentao MA96f68962022-06-15 19:45:35 +08003450 DVR_PB_INFO("segment seek to 0 at fb mode [%d]id[%lld]",
hualing chen03fd4942021-07-15 15:56:41 +08003451 seek_time,
3452 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003453 seek_time = 0;
3454 }
hualing chen03fd4942021-07-15 15:56:41 +08003455 if (IS_FB(player->speed)
3456 && dvr_playback_check_limit(handle)) {
3457 //fb case.check expired time
3458 //get id and pos to check if we can seek to this pos
3459 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3460 //case cur id < segment id
3461 if (player->cur_segment_id < segmentid) {
3462 //expired ts data is player,return error
3463 //
3464 pthread_mutex_unlock(&player->segment_lock);
3465 return 0;
3466 } else if (player->cur_segment_id == segmentid) {
3467 //id is same,compare seek pos
3468 if (seek_time < pos) {
3469 //expired ts data is player,return error
3470 //
3471 pthread_mutex_unlock(&player->segment_lock);
3472 return 0;
3473 }
3474 }
3475 //case can play
3476 }
hualing chen041c4092020-04-05 15:11:50 +08003477 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
3478 seek_time = 0;
3479 }
hualing chen2aba4022020-03-02 13:49:55 +08003480 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003481 } else {
3482 //
Wentao MA96f68962022-06-15 19:45:35 +08003483 DVR_PB_INFO("segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003484 }
Wentao MA96f68962022-06-15 19:45:35 +08003485 DVR_PB_INFO("calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003486 seek_time,
3487 player->speed,
3488 player->cur_segment_id,
3489 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003490 }
hualing chen2aba4022020-03-02 13:49:55 +08003491 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003492}
3493
3494
3495//start replay
3496static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3497 //
3498 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003499
3500 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003501 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003502 return DVR_FAILURE;
3503 }
3504
hualing chen5cbe1a62020-02-10 16:36:36 +08003505 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003506 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08003507 DVR_PB_INFO("fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003508 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003509 AmTsPlayer_stopVideoDecoding(player->handle);
3510 }
3511 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003512 DVR_PB_INFO("fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003513 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003514 AmTsPlayer_stopAudioDecoding(player->handle);
3515 }
hualing chendf118dd2020-05-21 15:49:11 +08003516 if (player->has_ad_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003517 DVR_PB_INFO("fffb stop audio");
hualing chendf118dd2020-05-21 15:49:11 +08003518 player->has_ad_audio =DVR_FALSE;
3519 AmTsPlayer_disableADMix(player->handle);
3520 }
hualing chen2aba4022020-03-02 13:49:55 +08003521
hualing chen5cbe1a62020-02-10 16:36:36 +08003522 //start video and audio
3523
Wentao MA270dc0f2022-08-23 13:17:26 +08003524 am_tsplayer_video_params video_params;
3525 am_tsplayer_audio_params audio_params;
3526 am_tsplayer_audio_params ad_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003527
Wentao MA270dc0f2022-08-23 13:17:26 +08003528 memset(&video_params, 0, sizeof(video_params));
3529 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003530
hualing chen87072a82020-03-12 16:20:12 +08003531 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003532
3533 //get segment info and audio video pid fmt ;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003534 //dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08003535 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003536 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003537 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
3538 //audio and video pids are all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003539 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003540 return -1;
3541 }
3542
Wentao MA270dc0f2022-08-23 13:17:26 +08003543 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003544 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003545 DVR_PB_INFO("fffb start video");
3546 //DVR_PB_INFO("fffb start video and save last frame");
hualing chen0888c032020-12-18 17:54:57 +08003547 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003548 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003549 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
Wentao MA270dc0f2022-08-23 13:17:26 +08003550 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003551 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003552 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003553 //playback_device_video_start(player->handle , &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003554 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003555 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003556 }
hualing chen31140872020-03-25 12:29:26 +08003557 //fffb mode need stop fast;
Wentao MA96f68962022-06-15 19:45:35 +08003558 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003559 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003560 return 0;
3561}
3562
3563static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3564 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003565 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003566 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003567 return DVR_FAILURE;
3568 }
3569
3570 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003571 DVR_PB_INFO("lock speed [%f]", player->speed);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003572 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003573
hualing chen2aba4022020-03-02 13:49:55 +08003574 int seek_time = _dvr_playback_calculate_seekpos(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003575 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 +08003576
hualing chen87072a82020-03-12 16:20:12 +08003577 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3578 //seek time set 0
3579 seek_time = 0;
3580 }
hualing chen041c4092020-04-05 15:11:50 +08003581 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003582 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3583 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003584 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003585 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003586 DVR_PB_DEBUG("unlock");
hualing chen87072a82020-03-12 16:20:12 +08003587 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003588 //send event here and pause
3589 DVR_Play_Notify_t notify;
3590 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003591 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003592 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003593 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08003594 DVR_PB_INFO("*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08003595 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003596 return DVR_SUCCESS;
3597 }
hualing chen2932d372020-04-29 13:44:00 +08003598 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003599 _dvr_init_fffb_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003600 DVR_PB_INFO("*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003601 }
3602 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003603 _dvr_playback_fffb_replay(handle);
3604
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003605 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003606 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003607
hualing chen5cbe1a62020-02-10 16:36:36 +08003608 return DVR_SUCCESS;
3609}
3610
hualing chen87072a82020-03-12 16:20:12 +08003611//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003612static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003613 //
3614 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003615
3616 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003617 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003618 return DVR_FAILURE;
3619 }
3620
hualing chen5cbe1a62020-02-10 16:36:36 +08003621 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003622 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003623 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003624 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003625 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003626 }
3627
3628 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003629 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003630 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003631 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003632 //start video and audio
3633
Wentao MA270dc0f2022-08-23 13:17:26 +08003634 am_tsplayer_video_params video_params;
3635 am_tsplayer_audio_params audio_params;
3636 am_tsplayer_audio_params ad_params;
hualing chen87072a82020-03-12 16:20:12 +08003637 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003638
Wentao MA270dc0f2022-08-23 13:17:26 +08003639 memset(&video_params, 0, sizeof(video_params));
3640 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003641
hualing chen5cbe1a62020-02-10 16:36:36 +08003642 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08003643 DVR_PB_INFO("into");
Wentao MA270dc0f2022-08-23 13:17:26 +08003644 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003645 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003646 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003647 //audio and video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003648 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003649 return -1;
3650 }
3651
Wentao MA270dc0f2022-08-23 13:17:26 +08003652 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003653 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003654 if (trick == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003655 DVR_PB_INFO("settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003656 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003657 }
hualing chen266b9502020-04-04 17:39:39 +08003658 else {
hualing chen2aba4022020-03-02 13:49:55 +08003659 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003660 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003661 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003662 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003663 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003664 }
hualing chena540a7e2020-03-27 16:44:05 +08003665
3666 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
Wentao MA96f68962022-06-15 19:45:35 +08003667 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08003668 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003669 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003670 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08003671 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08003672 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003673 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003674 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003675 AmTsPlayer_enableADMix(player->handle);
3676 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003677 if (VALID_PID(audio_params.pid)) {
hualing chen969fe7b2021-05-26 15:13:17 +08003678 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003679 DVR_PB_INFO("start audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003680 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003681 if (player->audio_presentation_id > -1) {
3682 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3683 }
hualing chen969fe7b2021-05-26 15:13:17 +08003684 AmTsPlayer_startAudioDecoding(player->handle);
3685 }
hualing chendf118dd2020-05-21 15:49:11 +08003686
Wentao MA96f68962022-06-15 19:45:35 +08003687 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003688 AmTsPlayer_stopFast(player->handle);
3689 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3690 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3691 }
hualing chen43a89bc2022-01-19 14:31:20 +08003692#ifdef AVSYNC_USED_PCR
3693 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003694 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003695 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3696 }
3697#endif
hualing chen2aba4022020-03-02 13:49:55 +08003698 player->cmd.last_cmd = player->cmd.cur_cmd;
3699 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003700 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003701 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen5cbe1a62020-02-10 16:36:36 +08003702 return 0;
3703}
3704
3705
hualing chenb31a6c62020-01-13 17:27:00 +08003706/**\brief Set play speed
3707 * \param[in] handle playback handle
3708 * \param[in] speed playback speed
3709 * \retval DVR_SUCCESS On success
3710 * \return Error code
3711 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003712int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3713
3714 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003715
3716 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003717 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003718 return DVR_FAILURE;
3719 }
3720
hualing chena540a7e2020-03-27 16:44:05 +08003721 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08003722 DVR_PB_INFO(" func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003723 return DVR_FAILURE;
3724 }
hualing chenf00cdc82020-06-10 14:23:35 +08003725 if (speed.speed.speed == player->cmd.speed.speed.speed) {
Wentao MA96f68962022-06-15 19:45:35 +08003726 DVR_PB_INFO(" func: eq speed [%d]", speed.speed.speed);
hualing chenf00cdc82020-06-10 14:23:35 +08003727 return DVR_SUCCESS;
3728 }
Wentao MA96f68962022-06-15 19:45:35 +08003729 DVR_PB_INFO("lock func: speed [%d]", speed.speed.speed);
hualing chen1679f812021-11-08 15:17:46 +08003730
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003731 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003732 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3733 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3734 player->cmd.last_cmd = player->cmd.cur_cmd;
3735 }
hualing chene41f4372020-06-06 16:29:17 +08003736
hualing chen31140872020-03-25 12:29:26 +08003737 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003738 IS_KERNEL_SPEED(speed.speed.speed) ) {
3739 //case 1. not start play.only set speed
3740 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3741 //only set speed.and return;
3742 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3743 player->cmd.speed.speed = speed.speed;
3744 player->speed = (float)speed.speed.speed/(float)100;
3745 player->fffb_play = DVR_FALSE;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003746 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003747 DVR_PB_DEBUG("unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003748 return DVR_SUCCESS;
3749 }
3750 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003751 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3752 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003753 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003754 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3755 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003756 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003757 AmTsPlayer_stopFast(player->handle);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003758 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003759 DVR_PB_DEBUG("unlock ---\r\n");
Wentao MA270dc0f2022-08-23 13:17:26 +08003760 _dvr_cmd(handle, DVR_PLAYBACK_CMD_A_START);
Wentao MA96f68962022-06-15 19:45:35 +08003761 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003762 dvr_mutex_lock(&player->lock);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003763 } else {
3764 //set play speed and if audio is start, stop audio.
3765 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003766 DVR_PB_INFO("fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003767 AmTsPlayer_stopAudioDecoding(player->handle);
3768 player->has_audio = DVR_FALSE;
3769 }
Wentao MA96f68962022-06-15 19:45:35 +08003770 DVR_PB_INFO("start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003771 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003772 }
hualing chenbcada022020-04-22 14:27:01 +08003773 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003774 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003775 player->cmd.speed.speed = speed.speed;
3776 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA96f68962022-06-15 19:45:35 +08003777 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003778 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003779 return DVR_SUCCESS;
3780 }
hualing chen31140872020-03-25 12:29:26 +08003781 //case 3 fffb mode
3782 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3783 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3784 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003785 DVR_PB_INFO("set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003786 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003787 player->cmd.speed.speed = speed.speed;
3788 player->speed = (float)speed.speed.speed/(float)100;
3789 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003790 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003791 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003792 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003793 return DVR_SUCCESS;
3794 }
3795 }
3796 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003797 IS_KERNEL_SPEED(speed.speed.speed)) {
3798 //case 1. cur speed is kernel support speed,set kernel speed.
3799 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003800 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003801 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3802 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003803 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003804 AmTsPlayer_stopFast(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003805 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003806 } else {
3807 //set play speed and if audio is start, stop audio.
3808 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003809 DVR_PB_INFO("fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003810 AmTsPlayer_stopAudioDecoding(player->handle);
3811 player->has_audio = DVR_FALSE;
3812 }
Wentao MA96f68962022-06-15 19:45:35 +08003813 DVR_PB_INFO("start fast");
hualing chenf00cdc82020-06-10 14:23:35 +08003814 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003815 }
hualing chena540a7e2020-03-27 16:44:05 +08003816 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003817 player->cmd.speed.speed = speed.speed;
3818 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003819 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003820 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003821 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003822 return DVR_SUCCESS;
3823 }
3824 //case 2 fffb mode
3825 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3826 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3827 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003828 DVR_PB_INFO("set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003829 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003830 player->cmd.speed.speed = speed.speed;
3831 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA270dc0f2022-08-23 13:17:26 +08003832 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
hualing chenbcada022020-04-22 14:27:01 +08003833 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003834 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003835 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003836 return DVR_SUCCESS;
3837 }
hualing chen31140872020-03-25 12:29:26 +08003838 }
hualing chena540a7e2020-03-27 16:44:05 +08003839 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3840 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003841 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003842 } else {
hualing chen31140872020-03-25 12:29:26 +08003843 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003844 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3845 else
3846 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003847 player->fffb_play = DVR_TRUE;
3848 }
3849 DVR_Bool_t init_last_time = DVR_FALSE;
3850 if (player->speed > 0.0f && speed.speed.speed < 0) {
3851 init_last_time = DVR_TRUE;
3852 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3853 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003854 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003855 player->cmd.speed.mode = speed.mode;
3856 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003857 player->speed = (float)speed.speed.speed/(float)100;
3858 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003859 _dvr_init_fffb_t(handle);
3860 if (init_last_time == DVR_TRUE)
3861 player->last_send_time_id = UINT64_MAX;
3862
hualing chen87072a82020-03-12 16:20:12 +08003863 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003864 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3865 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003866 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003867 DVR_PB_INFO("set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003868 _dvr_playback_replay(handle, DVR_FALSE);
3869 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3870 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003871 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
Wentao MA96f68962022-06-15 19:45:35 +08003872 DVR_PB_INFO("set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003873 }
Wentao MA96f68962022-06-15 19:45:35 +08003874 DVR_PB_INFO("unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003875 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003876 return DVR_SUCCESS;
3877}
hualing chen2932d372020-04-29 13:44:00 +08003878
hualing chenb31a6c62020-01-13 17:27:00 +08003879/**\brief Get playback status
3880 * \param[in] handle playback handle
3881 * \param[out] p_status playback status
3882 * \retval DVR_SUCCESS On success
3883 * \return Error code
3884 */
hualing chen2932d372020-04-29 13:44:00 +08003885static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3886 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003887//
3888 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003889 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003890 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003891 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003892 return DVR_FAILURE;
3893 }
hualing chen1679f812021-11-08 15:17:46 +08003894 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003895 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003896 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003897 }
3898
hualing chen5cbe1a62020-02-10 16:36:36 +08003899 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003900 //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 +08003901 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3902 player->state == DVR_PLAYBACK_STATE_START) {
3903 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3904 }
hualing chen041c4092020-04-05 15:11:50 +08003905
hualing chencc91e1c2020-02-28 13:26:17 +08003906 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003907 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003908
3909 if (CONTROL_SPEED_ENABLE == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08003910 if (player->con_spe.ply_sta == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003911 DVR_PB_INFO("player dur[%u] sta[%u] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08003912 player->con_spe.ply_dur,
3913 player->con_spe.ply_sta,
3914 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003915 player->con_spe.ply_sta = p_status->time_cur;
3916 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3917 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
Wentao MA96f68962022-06-15 19:45:35 +08003918 DVR_PB_INFO("player dur[%u] sta[%u] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003919 player->con_spe.ply_dur,
3920 player->con_spe.ply_sta,
3921 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003922 player->con_spe.ply_sta = p_status->time_cur;
3923 }
3924
3925 if (player->con_spe.sys_sta == 0) {
3926 player->con_spe.sys_sta = _dvr_time_getClock();
3927 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3928 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3929 player->con_spe.sys_sta = _dvr_time_getClock();
3930 }
3931 }
3932
hualing chen4b7c15d2020-04-07 16:13:48 +08003933 if (player->last_send_time_id == UINT64_MAX) {
3934 player->last_send_time_id = player->cur_segment_id;
3935 player->last_cur_time = p_status->time_cur;
3936 }
3937 if (player->last_send_time_id == player->cur_segment_id) {
Wentao MA80179512022-11-03 12:20:03 +08003938 if (player->speed > 1.0f ) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003939 //ff
3940 if (p_status->time_cur < player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08003941 DVR_PB_INFO("get ff time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003942 player->last_cur_time,
3943 p_status->time_cur,
3944 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08003945 p_status->time_cur = player->last_cur_time;
3946 } else {
3947 player->last_cur_time = p_status->time_cur;
3948 }
hualing chene41f4372020-06-06 16:29:17 +08003949 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003950 //fb
3951 if (p_status->time_cur > player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08003952 DVR_PB_INFO("get fb time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003953 player->last_cur_time,
3954 p_status->time_cur,
3955 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08003956 p_status->time_cur = player->last_cur_time;
3957 } else {
3958 player->last_cur_time = p_status->time_cur;
3959 }
3960 }
hualing chend241c7a2021-06-22 13:34:27 +08003961 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003962 player->last_cur_time = p_status->time_cur;
3963 }
hualing chen969fe7b2021-05-26 15:13:17 +08003964 player->last_send_time_id = segment_id;
3965 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003966
hualing chen5cbe1a62020-02-10 16:36:36 +08003967 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003968 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003969 p_status->flags = player->cur_segment.flags;
Wentao MA96f68962022-06-15 19:45:35 +08003970 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 +08003971 _dvr_playback_state_toString(player->state),
3972 _dvr_playback_state_toString(p_status->state),
3973 p_status->time_cur, p_status->time_end,
3974 p_status->segment_id,player->play_flag,
3975 player->speed,
3976 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08003977 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003978 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003979 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003980 }
hualing chen2932d372020-04-29 13:44:00 +08003981 return DVR_SUCCESS;
3982}
3983
3984
3985/**\brief Get playback status
3986 * \param[in] handle playback handle
3987 * \param[out] p_status playback status
3988 * \retval DVR_SUCCESS On success
3989 * \return Error code
3990 */
3991int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3992 DVR_PlaybackStatus_t *p_status) {
3993//
3994 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3995
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003996 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3997
hualing chen2932d372020-04-29 13:44:00 +08003998 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003999 DVR_PB_INFO("player is NULL");
hualing chen2932d372020-04-29 13:44:00 +08004000 return DVR_FAILURE;
4001 }
Wentao MA96f68962022-06-15 19:45:35 +08004002 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004003 dvr_mutex_lock(&player->lock);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004004 if (!player->has_video && !player->has_audio)
4005 p_status->time_cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08004006 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004007 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08004008
hualing chenb31a6c62020-01-13 17:27:00 +08004009 return DVR_SUCCESS;
4010}
4011
hualing chen040df222020-01-17 13:35:02 +08004012void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
4013 if (segment != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004014 DVR_PB_INFO("segment id: %lld", segment->segment_id);
4015 DVR_PB_INFO("segment flag: %d", segment->flags);
4016 DVR_PB_INFO("segment location: [%s]", segment->location);
4017 DVR_PB_INFO("segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
4018 DVR_PB_INFO("segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
4019 DVR_PB_INFO("segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
4020 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 +08004021 }
hualing chenb31a6c62020-01-13 17:27:00 +08004022}
4023
hualing chen5cbe1a62020-02-10 16:36:36 +08004024int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004025 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08004026
hualing chena540a7e2020-03-27 16:44:05 +08004027 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004028 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004029 return DVR_FAILURE;
4030 }
4031
hualing chen040df222020-01-17 13:35:02 +08004032 DVR_PlaybackSegmentInfo_t *segment;
wentao.mafd5283f2022-10-14 09:51:13 +08004033 // This error is suppressed as the macro code is picked from kernel.
wentao.maa22bc852022-10-13 12:18:06 +08004034 // prefetch() here incurring self_assign is used to avoid some compiling
4035 // warnings.
4036 // coverity[self_assign]
hualing chen040df222020-01-17 13:35:02 +08004037 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08004038 {
Wentao MA07d3d742022-09-06 09:58:05 +08004039 if (segment->segment_id == segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004040 _dvr_dump_segment(segment);
Wentao MA07d3d742022-09-06 09:58:05 +08004041 break;
hualing chen86e7d482020-01-16 15:13:33 +08004042 }
4043 }
4044 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08004045}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004046
pengfei.liu27cc4ec2020-04-03 16:28:16 +08004047int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004048{
4049 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4050 DVR_RETURN_IF_FALSE(player);
4051 DVR_RETURN_IF_FALSE(func);
4052
Wentao MA96f68962022-06-15 19:45:35 +08004053 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004054 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004055
4056 player->dec_func = func;
4057 player->dec_userdata = userdata;
4058
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004059 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004060 DVR_PB_INFO("out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004061 return DVR_SUCCESS;
4062}
4063
4064int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
4065{
4066 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4067 DVR_RETURN_IF_FALSE(player);
4068 DVR_RETURN_IF_FALSE(p_secure_buf);
4069 DVR_RETURN_IF_FALSE(len);
4070
Wentao MA96f68962022-06-15 19:45:35 +08004071 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004072 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004073
4074 player->is_secure_mode = 1;
4075 player->secure_buffer = p_secure_buf;
4076 player->secure_buffer_size = len;
4077
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004078 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004079 DVR_PB_INFO("out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004080 return DVR_SUCCESS;
4081}
Wentao MA5629ad82022-08-24 10:03:02 +08004082
4083int dvr_playback_set_ac4_preselection_id(DVR_PlaybackHandle_t handle, int presel_id)
4084{
4085 DVR_Playback_t *player = (DVR_Playback_t *) handle;
wentao.maa210e5e2022-10-12 16:10:03 +08004086 DVR_RETURN_IF_FALSE(player != NULL);
Wentao MA5629ad82022-08-24 10:03:02 +08004087
4088 player->audio_presentation_id = presel_id;
4089 am_tsplayer_result ret = AmTsPlayer_setParams(player->handle,
4090 AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &presel_id);
4091 DVR_RETURN_IF_FALSE(ret == AM_TSPLAYER_OK);
4092
4093 return DVR_SUCCESS;
4094}
Wentao MAa0b9c002022-11-10 17:47:27 +08004095
4096// This function ensures a valid TsPlayer delay time is provided or else it
4097// returns DVR_FAILURE. It is designed to workaround a weakness of
4098// AmTsPlayer_getDelayTime at starting phase of a playback in a short period
4099// of 20ms or less. During the said period, getDelayTime does NOT work as
4100// expect to return real delay length because demux isn't actually running
4101// to provide valid pts to TsPlayer.
Wentao MA804bab12022-11-29 10:01:26 +08004102static int get_effective_tsplayer_delay_time(DVR_Playback_t* play, int *time)
Wentao MAa0b9c002022-11-10 17:47:27 +08004103{
4104 int64_t delay=0;
4105 uint64_t pts_a=0;
4106 uint64_t pts_v=0;
4107
Wentao MA804bab12022-11-29 10:01:26 +08004108 DVR_RETURN_IF_FALSE(play != NULL);
4109 DVR_RETURN_IF_FALSE(play->handle != NULL);
Wentao MAa0b9c002022-11-10 17:47:27 +08004110
Wentao MA804bab12022-11-29 10:01:26 +08004111 AmTsPlayer_getDelayTime(play->handle, &delay);
4112 // In scambled stream situation, the returned TsPlayer delay time is
4113 // invalid and dirty. An additional time check agaginst 15 minutes (900s)
4114 // is introduced to insure such error condition is handled properly.
4115 DVR_RETURN_IF_FALSE((delay >= 0) && (delay <= 900*1000));
Wentao MAa0b9c002022-11-10 17:47:27 +08004116
Wentao MA804bab12022-11-29 10:01:26 +08004117 if (play->delay_is_effective) {
4118 *time = (int)delay;
Wentao MAa0b9c002022-11-10 17:47:27 +08004119 return DVR_SUCCESS;
4120 } else if (delay > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004121 *time = (int)delay;
4122 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004123 return DVR_SUCCESS;
4124 }
4125
Wentao MA804bab12022-11-29 10:01:26 +08004126 AmTsPlayer_getPts(play->handle, TS_STREAM_AUDIO, &pts_a);
4127 AmTsPlayer_getPts(play->handle, TS_STREAM_VIDEO, &pts_v);
Wentao MAa0b9c002022-11-10 17:47:27 +08004128 if ((int64_t)pts_a > 0 || (int64_t)pts_v > 0) {
Wentao MA804bab12022-11-29 10:01:26 +08004129 *time = (int)delay;
4130 play->delay_is_effective=DVR_TRUE;
Wentao MAa0b9c002022-11-10 17:47:27 +08004131 return DVR_SUCCESS;
4132 }
4133
4134 return DVR_FAILURE;
4135}
4136