blob: 2996c28bec741f8485f323c83a8507166da663e7 [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);
hualing chen87072a82020-03-12 16:20:12 +080066
hualing chenbcada022020-04-22 14:27:01 +080067
hualing chena5f03222021-12-02 11:22:35 +080068
hualing chenbcada022020-04-22 14:27:01 +080069static char* _cmd_toString(int cmd)
70{
71
72 char *string[DVR_PLAYBACK_CMD_NONE+1]={
73 "start",
74 "stop",
Wentao MA270dc0f2022-08-23 13:17:26 +080075 "v_start",
76 "a_start",
77 "v_stop",
78 "a_stop",
79 "v_restart",
80 "a_restart",
81 "av_restart",
82 "v_stop_a_start",
83 "a_stop_v_start",
84 "v_stop_a_restart",
85 "a_stop_v_restart",
86 "v_start_a_restart",
87 "a_start_v_restart",
hualing chenbcada022020-04-22 14:27:01 +080088 "pause",
89 "resume",
90 "seek",
91 "ff",
92 "fb",
93 "NONE"
94 };
95
96 if (cmd > DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +080097 return "unknown";
hualing chenbcada022020-04-22 14:27:01 +080098 } else {
99 return string[cmd];
100 }
101}
102
103
Wentao MA907b6432022-08-01 06:23:08 +0000104static char* _dvr_playback_state_toString(int state)
hualing chen6d24aa92020-03-23 18:43:47 +0800105{
Wentao MA907b6432022-08-01 06:23:08 +0000106 char *strings[5]={
107 "START",
108 "STOP",
109 "PAUSE",
110 "FF",
111 "FB",
hualing chen6d24aa92020-03-23 18:43:47 +0800112 };
113
Wentao MA907b6432022-08-01 06:23:08 +0000114 if (state >= 5 || state < 0) {
115 return "UNKNOWN";
hualing chen6d24aa92020-03-23 18:43:47 +0800116 }
Wentao MA907b6432022-08-01 06:23:08 +0000117 return strings[state];
hualing chen6d24aa92020-03-23 18:43:47 +0800118}
hualing chena540a7e2020-03-27 16:44:05 +0800119
120static DVR_Bool_t _dvr_support_speed(int speed) {
121
122 DVR_Bool_t ret = DVR_FALSE;
123
124 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800125 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800126 case PLAYBACK_SPEED_FBX2:
127 case PLAYBACK_SPEED_FBX4:
128 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800129 case PLAYBACK_SPEED_FBX16:
130 case PLAYBACK_SPEED_FBX12:
131 case PLAYBACK_SPEED_FBX32:
132 case PLAYBACK_SPEED_FBX48:
133 case PLAYBACK_SPEED_FBX64:
134 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800135 case PLAYBACK_SPEED_S2:
136 case PLAYBACK_SPEED_S4:
137 case PLAYBACK_SPEED_S8:
138 case PLAYBACK_SPEED_X1:
139 case PLAYBACK_SPEED_X2:
140 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800141 case PLAYBACK_SPEED_X3:
142 case PLAYBACK_SPEED_X5:
143 case PLAYBACK_SPEED_X6:
144 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800145 case PLAYBACK_SPEED_X8:
146 case PLAYBACK_SPEED_X12:
147 case PLAYBACK_SPEED_X16:
148 case PLAYBACK_SPEED_X32:
149 case PLAYBACK_SPEED_X48:
150 case PLAYBACK_SPEED_X64:
151 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800152 ret = DVR_TRUE;
153 break;
154 default:
Wentao MA96f68962022-06-15 19:45:35 +0800155 DVR_PB_INFO("not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800156 break;
157 }
158 return ret;
159}
Wentao MA907b6432022-08-01 06:23:08 +0000160
hualing chen6e4bfa52020-03-13 14:37:11 +0800161void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
162{
Wentao MA96f68962022-06-15 19:45:35 +0800163 DVR_PB_INFO("in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800164 DVR_Playback_t *player = NULL;
165 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800166 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800167 DVR_PB_INFO("play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800168 }
169 switch (event->type) {
170 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
171 {
Wentao MA96f68962022-06-15 19:45:35 +0800172 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800173 event->event.video_format.frame_width,
174 event->event.video_format.frame_height,
175 event->event.video_format.frame_rate);
176 break;
177 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800178 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
179 {
Wentao MA96f68962022-06-15 19:45:35 +0800180 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800181 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800182 break;
183 }
184 default:
185 break;
186 }
187}
hualing chen2aba4022020-03-02 13:49:55 +0800188void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
189{
hualing chen6e4bfa52020-03-13 14:37:11 +0800190 DVR_Playback_t *player = NULL;
191 if (user_data != NULL) {
192 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800193 DVR_PB_INFO("play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800194 }
hualing chen2aba4022020-03-02 13:49:55 +0800195 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800196 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
197 {
Wentao MA96f68962022-06-15 19:45:35 +0800198 DVR_PB_INFO("[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800199 event->event.video_format.frame_width,
200 event->event.video_format.frame_height,
201 event->event.video_format.frame_rate);
202 break;
203 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800204 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
205 {
Wentao MA96f68962022-06-15 19:45:35 +0800206 DVR_PB_INFO("[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chene41f4372020-06-06 16:29:17 +0800207 if (player->first_trans_ok == DVR_FALSE) {
208 player->first_trans_ok = DVR_TRUE;
209 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
210 }
hualing chen30423862021-04-16 14:39:12 +0800211 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800212 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800213 player->seek_pause = DVR_FALSE;
214 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800215 break;
216 }
hualing chen487ae6d2020-07-22 10:34:11 +0800217 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
Wentao MA96f68962022-06-15 19:45:35 +0800218 DVR_PB_INFO("[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
hualing chen487ae6d2020-07-22 10:34:11 +0800219 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
220 player->first_trans_ok = DVR_TRUE;
221 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
222 }
223 if (player != NULL && player->has_video == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +0800224 DVR_PB_INFO("[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
hualing chen487ae6d2020-07-22 10:34:11 +0800225 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800226 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800227 }
228 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800229 default:
Wentao MA270dc0f2022-08-23 13:17:26 +0800230 DVR_PB_INFO("[evt]unknown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800231 break;
232 }
233 if (player&&player->player_callback_func) {
Wentao MA96f68962022-06-15 19:45:35 +0800234 DVR_PB_INFO("player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800235 player->player_callback_func(player->player_callback_userdata, event);
236 } else if (player == NULL){
Wentao MA96f68962022-06-15 19:45:35 +0800237 DVR_PB_INFO("player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800238 } else {
Wentao MA96f68962022-06-15 19:45:35 +0800239 DVR_PB_INFO("player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800240 }
241}
hualing chencc91e1c2020-02-28 13:26:17 +0800242
hualing chen5cbe1a62020-02-10 16:36:36 +0800243//convert video and audio fmt
244static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
245 int format = 0;
246 if (is_audio == DVR_FALSE) {
247 //for video fmt
248 switch (fmt)
249 {
250 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800251 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800252 break;
253 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800254 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800255 break;
256 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800257 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800258 break;
259 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800260 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800261 break;
hualing chena540a7e2020-03-27 16:44:05 +0800262 case DVR_VIDEO_FORMAT_VP9:
263 format = AV_VIDEO_CODEC_VP9;
264 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800265 }
266 } else {
267 //for audio fmt
268 switch (fmt)
269 {
270 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800271 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800272 break;
273 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800274 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800275 break;
276 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800277 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800278 break;
279 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800280 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800281 break;
hualing chena540a7e2020-03-27 16:44:05 +0800282 case DVR_AUDIO_FORMAT_AAC:
283 format = AV_AUDIO_CODEC_AAC;
284 break;
285 case DVR_AUDIO_FORMAT_LATM:
286 format = AV_AUDIO_CODEC_LATM;
287 break;
288 case DVR_AUDIO_FORMAT_PCM:
289 format = AV_AUDIO_CODEC_PCM;
290 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800291 case DVR_AUDIO_FORMAT_AC4:
292 format = AV_AUDIO_CODEC_AC4;
293 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800294 }
295 }
296 return format;
297}
hualing chen040df222020-01-17 13:35:02 +0800298static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800299{
hualing chen040df222020-01-17 13:35:02 +0800300 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800301
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800302 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800303 return -1;
304
hualing chena540a7e2020-03-27 16:44:05 +0800305 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800306}
hualing chena540a7e2020-03-27 16:44:05 +0800307
hualing chen7ea70a72021-09-09 11:25:13 +0800308
309//get sys time sec
310static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800311{
312 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800313 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800314 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800315 s = (uint32_t)(ts.tv_sec);
Wentao MA96f68962022-06-15 19:45:35 +0800316 DVR_PB_INFO("n:%u", s);
hualing chen7ea70a72021-09-09 11:25:13 +0800317 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800318}
hualing chen86e7d482020-01-16 15:13:33 +0800319
hualing chen7ea70a72021-09-09 11:25:13 +0800320//get sys time ms
321static uint32_t _dvr_time_getClock(void)
322{
323 struct timespec ts;
324 uint32_t ms;
325 clock_gettime(CLOCK_REALTIME, &ts);
326 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
327 return ms;
328}
hualing chenb31a6c62020-01-13 17:27:00 +0800329
Wentao MA270dc0f2022-08-23 13:17:26 +0800330//timeout wait signal
hualing chen040df222020-01-17 13:35:02 +0800331static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800332{
hualing chen040df222020-01-17 13:35:02 +0800333 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800334
hualing chena540a7e2020-03-27 16:44:05 +0800335
336 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800337 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800338 return DVR_FAILURE;
339 }
340
hualing chen86e7d482020-01-16 15:13:33 +0800341 struct timespec ts;
342 clock_gettime(CLOCK_MONOTONIC, &ts);
343 //ms为毫秒,换算成秒
344 ts.tv_sec += ms/1000;
345 //在outtime的基础上,增加ms毫秒
346 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
347 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
348 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
349 //us的值有可能超过1秒,
350 ts.tv_sec += us / 1000000;
351 us = us % 1000000;
352 ts.tv_nsec = us * 1000;//换算成纳秒
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800353
354 int val = dvr_mutex_save(&player->lock);
355 pthread_cond_timedwait(&player->cond, &player->lock.lock, &ts);
356 dvr_mutex_restore(&player->lock, val);
hualing chen86e7d482020-01-16 15:13:33 +0800357 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800358}
hualing chen31140872020-03-25 12:29:26 +0800359//get tsplay delay time ms
360static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
361 DVR_Playback_t *player = (DVR_Playback_t *) handle;
362 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800363 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800364 DVR_PB_INFO("tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800365 return 0;
366 }
367 AmTsPlayer_getDelayTime(player->handle, &cache);
Wentao MA96f68962022-06-15 19:45:35 +0800368 DVR_PB_INFO("tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800369 return cache;
370}
hualing chenb31a6c62020-01-13 17:27:00 +0800371//send signal
hualing chen040df222020-01-17 13:35:02 +0800372static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800373{
hualing chen87072a82020-03-12 16:20:12 +0800374 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800375
376 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800377 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800378 return DVR_FAILURE;
379 }
Wentao MA96f68962022-06-15 19:45:35 +0800380 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800381 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800382 pthread_cond_signal(&player->cond);
Wentao MA96f68962022-06-15 19:45:35 +0800383 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800384 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800385 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800386}
387
hualing chen2932d372020-04-29 13:44:00 +0800388//send playback event, need check is need lock first
389static 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 +0800390
391 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800392
393 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800394 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800395 return DVR_FAILURE;
396 }
397
hualing chencc91e1c2020-02-28 13:26:17 +0800398 switch (evt) {
399 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800400 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800401 break;
402 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
403 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800404 DVR_PB_INFO("trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800405 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800406 break;
407 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
408 break;
409 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
410 break;
411 case DVR_PLAYBACK_EVENT_NO_KEY:
412 break;
413 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800414 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800415 DVR_PB_INFO("reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800416 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800417 break;
418 case DVR_PLAYBACK_EVENT_REACHED_END:
419 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800420 DVR_PB_INFO("reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800421 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800422 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800423 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800424 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800425 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800426 default:
427 break;
428 }
429 if (player->openParams.event_fn != NULL)
430 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800431 return DVR_SUCCESS;
432}
hualing chen2932d372020-04-29 13:44:00 +0800433static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800434{
435 DVR_Play_Notify_t notify;
436 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
437 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
438 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800439 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800440 return DVR_SUCCESS;
441}
442
hualing chen2932d372020-04-29 13:44:00 +0800443static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800444{
445 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800446
hualing chene3797f02021-01-13 14:53:28 +0800447 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800448 if (CONTROL_SPEED_ENABLE == 0)
449 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800450 }
hualing chena540a7e2020-03-27 16:44:05 +0800451 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800452 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800453 return DVR_FAILURE;
454 }
455
hualing chen03fd4942021-07-15 15:56:41 +0800456 if (player->send_time == 0) {
hualing chend241c7a2021-06-22 13:34:27 +0800457 if (CONTROL_SPEED_ENABLE == 0)
458 player->send_time = _dvr_time_getClock() + 500;
459 else
460 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800461 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen56c0a162022-01-27 17:01:50 +0800462 if ((player->send_time - _dvr_time_getClock()) > 1000) {
463 player->send_time = _dvr_time_getClock() + 500;
Wentao MA96f68962022-06-15 19:45:35 +0800464 DVR_PB_INFO("player send time occur system time changed!!!!!");
hualing chen56c0a162022-01-27 17:01:50 +0800465 } else {
466 return DVR_SUCCESS;
467 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800468 }
hualing chend241c7a2021-06-22 13:34:27 +0800469 if (CONTROL_SPEED_ENABLE == 0)
470 player->send_time = _dvr_time_getClock() + 500;
471 else
472 player->send_time = _dvr_time_getClock() + 20;
473
hualing chen6e4bfa52020-03-13 14:37:11 +0800474 DVR_Play_Notify_t notify;
475 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
476 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
477 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800478 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800479 return DVR_SUCCESS;
480}
481
hualing chencc91e1c2020-02-28 13:26:17 +0800482//check is ongoing segment
483static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
484
485 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800486 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800487
488 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800489 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800490 return DVR_FAILURE;
491 }
hualing chen87072a82020-03-12 16:20:12 +0800492 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800493 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800494 return DVR_FALSE;
495 }
hualing chencc91e1c2020-02-28 13:26:17 +0800496 return DVR_TRUE;
497}
hualing chen4b7c15d2020-04-07 16:13:48 +0800498
499
500static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
501 DVR_Playback_t *player = (DVR_Playback_t *) handle;
502 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800503 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800504 player->fffb_current = player->fffb_start;
505 //get segment current time pos
506 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800507 player->next_fffb_time = _dvr_time_getClock();
508
509 return DVR_SUCCESS;
510}
511
hualing chen2aba4022020-03-02 13:49:55 +0800512static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
513 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800514 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800515 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800516 player->fffb_current = player->fffb_start;
517 //get segment current time pos
518 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800519
hualing chen2aba4022020-03-02 13:49:55 +0800520 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800521 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800522 return DVR_SUCCESS;
523}
hualing chencc91e1c2020-02-28 13:26:17 +0800524//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800525static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
526
527 DVR_Playback_t *player = (DVR_Playback_t *) handle;
528 DVR_PlaybackSegmentInfo_t *segment;
529 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
530
hualing chena540a7e2020-03-27 16:44:05 +0800531 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800532 DVR_PB_INFO(" player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800533 return DVR_FAILURE;
534 }
535
hualing chen87072a82020-03-12 16:20:12 +0800536 int found = 0;
537 int found_eq_id = 0;
538 list_for_each_entry(segment, &player->segment_list, head)
539 {
540 if (player->segment_is_open == DVR_FALSE) {
541 //get first segment from list, case segment is not open
542 if (!IS_FB(player->speed))
543 found = 1;
544 } else if (segment->segment_id == segmentid) {
545 //find cur segment, we need get next one
546 found_eq_id = 1;
547 if (!IS_FB(player->speed)) {
548 found = 1;
549 continue;
550 } else {
551 //if is fb mode.we need used pre segment
552 if (pre_segment != NULL) {
553 found = 1;
554 } else {
555 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800556 DVR_PB_INFO("not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800557 return DVR_FAILURE;
558 }
559 }
560 }
561 if (found == 1) {
562 found = 2;
563 break;
564 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800565 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800566 }
567 if (found != 2) {
568 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800569 DVR_PB_INFO("not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800570 return DVR_FAILURE;
571 }
Wentao MA96f68962022-06-15 19:45:35 +0800572 DVR_PB_INFO("found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800573 return DVR_SUCCESS;
574}
575
576//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800577static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800578
hualing chen040df222020-01-17 13:35:02 +0800579 DVR_Playback_t *player = (DVR_Playback_t *) handle;
580 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800581 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800582 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800583 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800584 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800585 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800586 return DVR_FAILURE;
587 }
588
hualing chen03fd4942021-07-15 15:56:41 +0800589 if (IS_FB(player->speed)
590 && dvr_playback_check_limit(handle)) {
591 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
592 //case cur id < segment id
593 if (player->cur_segment_id <= segmentid) {
594 //expired ts data is player,return error
Wentao MA96f68962022-06-15 19:45:35 +0800595 DVR_PB_INFO("reach start segment ,return error");
hualing chen03fd4942021-07-15 15:56:41 +0800596 return DVR_FAILURE;
597 }
Wentao MA96f68962022-06-15 19:45:35 +0800598 DVR_PB_INFO("has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800599 }
600
hualing chen86e7d482020-01-16 15:13:33 +0800601 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800602 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800603
hualing chen040df222020-01-17 13:35:02 +0800604 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800605 {
hualing chencc91e1c2020-02-28 13:26:17 +0800606 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800607 //get first segment from list, case segment is not open
608 if (!IS_FB(player->speed))
609 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800610 } else if (segment->segment_id == player->cur_segment_id) {
611 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800612 found_eq_id = 1;
613 if (!IS_FB(player->speed)) {
614 found = 1;
615 continue;
616 } else {
617 //if is fb mode.we need used pre segment
618 if (pre_segment != NULL) {
619 found = 1;
620 } else {
621 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800622 DVR_PB_INFO("not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800623 return DVR_FAILURE;
624 }
625 }
hualing chen86e7d482020-01-16 15:13:33 +0800626 }
627 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800628 if (IS_FB(player->speed)) {
629 //used pre segment
630 segment = pre_segment;
631 }
hualing chencc91e1c2020-02-28 13:26:17 +0800632 //save segment info
633 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800634 if (player->r_handle)
Wentao MA270dc0f2022-08-23 13:17:26 +0800635 player->last_segment_total = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800636 player->last_segment.segment_id = player->cur_segment.segment_id;
637 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800638 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
639 //pids
640 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
641
hualing chen5cbe1a62020-02-10 16:36:36 +0800642 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800643 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800644 player->cur_segment_id = segment->segment_id;
645 player->cur_segment.segment_id = segment->segment_id;
646 player->cur_segment.flags = segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800647 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 +0800648 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800649 //pids
hualing chen040df222020-01-17 13:35:02 +0800650 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800651 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800652 break;
hualing chen86e7d482020-01-16 15:13:33 +0800653 }
hualing chen2aba4022020-03-02 13:49:55 +0800654 pre_segment = segment;
655 }
656 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
657 //used the last one segment to open
658 //get segment info
659 player->segment_is_open = DVR_TRUE;
660 player->cur_segment_id = pre_segment->segment_id;
661 player->cur_segment.segment_id = pre_segment->segment_id;
662 player->cur_segment.flags = pre_segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800663 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 +0800664 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
665 //pids
666 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
667 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800668 }
669 if (found != 2) {
670 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800671 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800672 }
673 return DVR_SUCCESS;
674}
hualing chen040df222020-01-17 13:35:02 +0800675//open next segment to play,if reach list end return errro.
676static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800677{
hualing chen040df222020-01-17 13:35:02 +0800678 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800679 Segment_OpenParams_t params;
680 int ret = DVR_SUCCESS;
681
hualing chena540a7e2020-03-27 16:44:05 +0800682 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800683 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800684 return DVR_FAILURE;
685 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800686 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800687retry:
hualing chena540a7e2020-03-27 16:44:05 +0800688 ret = _dvr_get_next_segmentId(handle);
689 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800690 DVR_PB_INFO("not found segment info");
hualing chen4b7c15d2020-04-07 16:13:48 +0800691 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800692 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800693 }
694
695 if (player->r_handle != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800696 DVR_PB_INFO("close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800697 segment_close(player->r_handle);
698 player->r_handle = NULL;
699 }
700
701 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
Wentao MA270dc0f2022-08-23 13:17:26 +0800702 //cp current segment path to location
hualing chen5cbe1a62020-02-10 16:36:36 +0800703 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800704 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800705 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800706 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 +0800707
hualing chen86e7d482020-01-16 15:13:33 +0800708 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800709 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800710 DVR_PB_INFO("open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800711 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800712 }
Wentao MA01de0e62022-01-10 18:48:23 +0800713 // Keep the start segment_id when the first segment_open is called during a playback
714 if (player->first_start_id == UINT64_MAX) {
715 player->first_start_id = player->cur_segment.segment_id;
716 }
hualing chen87072a82020-03-12 16:20:12 +0800717 pthread_mutex_unlock(&player->segment_lock);
718 int total = _dvr_get_end_time( handle);
719 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800720 if (IS_FB(player->speed)) {
721 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800722 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800723 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +0800724 DVR_PB_INFO("seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800725 }
hualing chen87072a82020-03-12 16:20:12 +0800726 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800727 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +0800728 DVR_PB_INFO("next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800729 return ret;
730}
731
hualing chen5cbe1a62020-02-10 16:36:36 +0800732//open next segment to play,if reach list end return errro.
733static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
734{
735 DVR_Playback_t *player = (DVR_Playback_t *) handle;
736 Segment_OpenParams_t params;
737 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800738 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800739 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800740 return DVR_FAILURE;
741 }
hualing chencc91e1c2020-02-28 13:26:17 +0800742 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800743 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800744 }
hualing chencc91e1c2020-02-28 13:26:17 +0800745 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800746 if (id < 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800747 DVR_PB_INFO("not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800748 return DVR_FAILURE;
749 }
Wentao MA96f68962022-06-15 19:45:35 +0800750 DVR_PB_INFO("start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800751 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800752
753 DVR_PlaybackSegmentInfo_t *segment;
754
755 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800756
hualing chen5cbe1a62020-02-10 16:36:36 +0800757 list_for_each_entry(segment, &player->segment_list, head)
758 {
Wentao MA96f68962022-06-15 19:45:35 +0800759 DVR_PB_INFO("see 1 location [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800760 if (segment->segment_id == segment_id) {
761 found = 1;
762 }
763 if (found == 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800764 DVR_PB_INFO("found [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800765 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800766 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800767 player->cur_segment_id = segment->segment_id;
768 player->cur_segment.segment_id = segment->segment_id;
769 player->cur_segment.flags = segment->flags;
Wentao MAe88ad702022-09-02 10:35:00 +0800770 const int len = strlen(segment->location);
771 if (len >= DVR_MAX_LOCATION_SIZE || len <= 0) {
772 DVR_PB_ERROR("Invalid segment.location length %d",len);
773 pthread_mutex_unlock(&player->segment_lock);
774 return DVR_FAILURE;
775 }
776 strncpy(player->cur_segment.location, segment->location, len+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800777 //pids
778 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +0800779 DVR_PB_INFO("cur found location [%s]id[%lld]flag[%x]", player->cur_segment.location, player->cur_segment.segment_id,player->cur_segment.flags);
hualing chencc91e1c2020-02-28 13:26:17 +0800780 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800781 }
782 }
hualing chencc91e1c2020-02-28 13:26:17 +0800783 if (found == 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800784 DVR_PB_INFO("not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800785 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800786 return DVR_FAILURE;
787 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800788 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
Wentao MAe88ad702022-09-02 10:35:00 +0800789
790 const int len2 = strlen(player->cur_segment.location);
791 if (len2 >= DVR_MAX_LOCATION_SIZE || len2 <= 0) {
792 DVR_PB_ERROR("Invalid cur_segment.location length %d",len2);
793 pthread_mutex_unlock(&player->segment_lock);
794 return DVR_FAILURE;
795 }
796 strncpy(params.location, player->cur_segment.location, len2+1);
hualing chen5cbe1a62020-02-10 16:36:36 +0800797 params.segment_id = (uint64_t)player->cur_segment.segment_id;
798 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800799 DVR_PB_INFO("open segment location[%s][%lld]cur flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen2aba4022020-03-02 13:49:55 +0800800 if (player->r_handle != NULL) {
801 segment_close(player->r_handle);
802 player->r_handle = NULL;
803 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800804 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800805 if (ret == DVR_FAILURE) {
Wentao MA270dc0f2022-08-23 13:17:26 +0800806 DVR_PB_INFO("segment open error");
hualing chen4b7c15d2020-04-07 16:13:48 +0800807 }
Wentao MA01de0e62022-01-10 18:48:23 +0800808 // Keep the start segment_id when the first segment_open is called during a playback
809 if (player->first_start_id == UINT64_MAX) {
810 player->first_start_id = player->cur_segment.segment_id;
811 }
hualing chen2aba4022020-03-02 13:49:55 +0800812 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800813 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800814
Wentao MA96f68962022-06-15 19:45:35 +0800815 DVR_PB_INFO("player->dur [%d]cur id [%lld]cur flag [0x%x]\r\n", player->dur,player->cur_segment.segment_id, player->cur_segment.flags);
hualing chen5cbe1a62020-02-10 16:36:36 +0800816 return ret;
817}
818
819
820//get play info by segment id
821static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
822 uint64_t segment_id,
Wentao MA270dc0f2022-08-23 13:17:26 +0800823 am_tsplayer_video_params *video_param,
824 am_tsplayer_audio_params *audio_param, am_tsplayer_audio_params *ad_param) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800825
826 DVR_Playback_t *player = (DVR_Playback_t *) handle;
827 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800828 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800829 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800830 return DVR_FAILURE;
831 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800832
833 int found = 0;
834
835 list_for_each_entry(segment, &player->segment_list, head)
836 {
hualing chen87072a82020-03-12 16:20:12 +0800837 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800838 //get first segment from list
839 found = 1;
840 }
841 if (segment->segment_id == segment_id) {
842 found = 1;
843 }
844 if (found == 1) {
845 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800846 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800847 player->cur_segment_id = segment->segment_id;
Wentao MA96f68962022-06-15 19:45:35 +0800848 DVR_PB_INFO("get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800849 player->cur_segment.segment_id = segment->segment_id;
850 player->cur_segment.flags = segment->flags;
851 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800852 player->cur_segment.pids.video.pid = segment->pids.video.pid;
853 player->cur_segment.pids.video.format = segment->pids.video.format;
854 player->cur_segment.pids.video.type = segment->pids.video.type;
855 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
856 player->cur_segment.pids.audio.format = segment->pids.audio.format;
857 player->cur_segment.pids.audio.type = segment->pids.audio.type;
858 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
859 player->cur_segment.pids.ad.format = segment->pids.ad.format;
860 player->cur_segment.pids.ad.type = segment->pids.ad.type;
861 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800862 //
Wentao MA270dc0f2022-08-23 13:17:26 +0800863 video_param->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
864 video_param->pid = segment->pids.video.pid;
865 audio_param->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
866 audio_param->pid = segment->pids.audio.pid;
867 ad_param->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
868 ad_param->pid =segment->pids.ad.pid;
869 DVR_PB_INFO("get play info success[0x%x]apid[0x%x]vfmt[%d]afmt[%d]", video_param->pid, audio_param->pid, video_param->codectype, audio_param->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800870 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800871 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800872 }
873 }
hualing chencc91e1c2020-02-28 13:26:17 +0800874 if (found != 2) {
875 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800876 DVR_PB_INFO("get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800877 return DVR_FAILURE;
878 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800879
880 return DVR_SUCCESS;
881}
hualing chencc91e1c2020-02-28 13:26:17 +0800882static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
883 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800884 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800885 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800886 return DVR_FAILURE;
887 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800888
hualing chencc91e1c2020-02-28 13:26:17 +0800889 //compare cur segment
890 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
891 {
892 //check video pids, stop or restart
hualing chen99508642021-10-18 15:41:17 +0800893 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800894 //check sub audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800895 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800896 //check audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800897 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 1);
Wentao MA96f68962022-06-15 19:45:35 +0800898 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 +0800899 //check pcr pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800900 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800901 }
hualing chena540a7e2020-03-27 16:44:05 +0800902 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800903}
hualing chen5cbe1a62020-02-10 16:36:36 +0800904
hualing chend241c7a2021-06-22 13:34:27 +0800905static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
906{
907 DVR_Playback_t *player = (DVR_Playback_t *) handle;
908 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800909 DVR_PB_INFO("player is NULL");
hualing chend241c7a2021-06-22 13:34:27 +0800910 return DVR_TRUE;
911 }
912 char buf[10];
913 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800914 DVR_PB_INFO("player get prop[%d][%s]", atoi(buf), buf);
hualing chend241c7a2021-06-22 13:34:27 +0800915
916 if (atoi(buf) != 1) {
917 //return DVR_TRUE;
918 }
919
Wentao MA96f68962022-06-15 19:45:35 +0800920 DVR_PB_INFO(":play speed: %f ply dur: %u sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800921 player->speed,
922 player->con_spe.ply_dur,
923 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800924
925 if (player->speed != 1.0f)
926 return DVR_TRUE;
927
928 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800929 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800930 return DVR_FALSE;
931
932 return DVR_TRUE;
933}
934
hualing chencc91e1c2020-02-28 13:26:17 +0800935static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
936{
937 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800938 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800939 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800940 return DVR_FAILURE;
941 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800942 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
Wentao MA96f68962022-06-15 19:45:35 +0800943 DVR_PB_INFO("vendor is amlogic. no used segment flag to hide or show av");
hualing chenf43b8ba2020-07-28 13:11:42 +0800944 return DVR_SUCCESS;
945 }
Wentao MA96f68962022-06-15 19:45:35 +0800946 DVR_PB_INFO("flag[0x%x]id[%lld]last[0x%x][%llu]",
hualing chen03fd4942021-07-15 15:56:41 +0800947 player->cur_segment.flags,
948 player->cur_segment.segment_id,
949 player->last_segment.flags,
950 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800951 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
952 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800953 //enable display
Wentao MA96f68962022-06-15 19:45:35 +0800954 DVR_PB_INFO("unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800955 AmTsPlayer_showVideo(player->handle);
956 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800957 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
958 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800959 //disable display
Wentao MA96f68962022-06-15 19:45:35 +0800960 DVR_PB_INFO("mute");
hualing chen2aba4022020-03-02 13:49:55 +0800961 AmTsPlayer_hideVideo(player->handle);
962 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800963 }
964 return DVR_SUCCESS;
965}
hualing chene3797f02021-01-13 14:53:28 +0800966/*
Wentao MA270dc0f2022-08-23 13:17:26 +0800967if decode success first time.
968success: return true
hualing chene3797f02021-01-13 14:53:28 +0800969fail: return false
970*/
Wentao MA270dc0f2022-08-23 13:17:26 +0800971static DVR_Bool_t _dvr_pauselive_decode_success(DVR_PlaybackHandle_t handle) {
hualing chena540a7e2020-03-27 16:44:05 +0800972 DVR_Playback_t *player = (DVR_Playback_t *) handle;
973 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800974 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800975 return DVR_TRUE;
976 }
hualing chene3797f02021-01-13 14:53:28 +0800977 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800978 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800979 } else {
980 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800981 }
982}
hualing chen86e7d482020-01-16 15:13:33 +0800983static void* _dvr_playback_thread(void *arg)
984{
hualing chen040df222020-01-17 13:35:02 +0800985 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800986 //int need_open_segment = 1;
Wentao MA270dc0f2022-08-23 13:17:26 +0800987 am_tsplayer_input_buffer input_buffer;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800988 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800989 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800990
hualing chen39628212020-05-14 10:35:13 +0800991 #define MAX_REACHEND_TIMEOUT (3000)
992 int reach_end_timeout = 0;//ms
993 int cache_time = 0;
hualing chenb9a1a2c2021-12-31 11:27:59 +0800994 int timeout = 200;//ms
hualing chen40dd5462021-11-26 19:56:20 +0800995 int check_no_data_time = 4;
hualing chen2aba4022020-03-02 13:49:55 +0800996 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800997 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800998 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800999 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +08001000 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001001 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +08001002 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001003 DVR_Bool_t goto_rewrite = DVR_FALSE;
yinming ding0ce94922021-09-08 15:09:15 +08001004 char prop_buf[10];
1005
1006 memset(prop_buf, 0 ,sizeof(prop_buf));
1007 dvr_prop_read("vendor.tv.libdvr.writetm", prop_buf, sizeof(prop_buf));
Wentao MA96f68962022-06-15 19:45:35 +08001008 DVR_PB_INFO("---vendor.tv.libdvr.writetm get prop[%d][%s]block_size[%d]", atoi(prop_buf), prop_buf, player->openParams.block_size);
yinming ding0ce94922021-09-08 15:09:15 +08001009 if (atoi(prop_buf) > 0)
1010 write_timeout_ms = atoi(prop_buf);
hualing chen03fd4942021-07-15 15:56:41 +08001011
hualing chen56c0a162022-01-27 17:01:50 +08001012
1013 memset(prop_buf, 0 ,sizeof(prop_buf));
1014 dvr_prop_read("vendor.tv.libdvr.waittm", prop_buf, sizeof(prop_buf));
Wentao MA96f68962022-06-15 19:45:35 +08001015 DVR_PB_INFO("---vendor.tv.libdvr.waittm get prop[%d][%s]block_size[%d]", atoi(prop_buf), prop_buf, player->openParams.block_size);
hualing chen56c0a162022-01-27 17:01:50 +08001016 if (atoi(prop_buf) > 0)
1017 timeout = atoi(prop_buf);
1018
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001019 if (player->is_secure_mode) {
1020 if (dec_buf_size > player->secure_buffer_size) {
Wentao MA96f68962022-06-15 19:45:35 +08001021 DVR_PB_INFO("playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001022 return NULL;
1023 }
1024 }
hualing chen86e7d482020-01-16 15:13:33 +08001025 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001026 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +08001027 DVR_PB_INFO("Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001028 return NULL;
1029 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001030 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1031 input_buffer.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001032
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001033 dec_bufs.buf_data = malloc(dec_buf_size);
1034 if (!dec_bufs.buf_data) {
Wentao MA96f68962022-06-15 19:45:35 +08001035 DVR_PB_INFO("Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +08001036 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001037 return NULL;
1038 }
1039 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1040 dec_bufs.buf_size = dec_buf_size;
1041
hualing chencc91e1c2020-02-28 13:26:17 +08001042 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001043 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1044 }
hualing chen86e7d482020-01-16 15:13:33 +08001045
hualing chen86e7d482020-01-16 15:13:33 +08001046 if (ret != DVR_SUCCESS) {
1047 if (buf != NULL) {
1048 free(buf);
1049 buf = NULL;
1050 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001051 free(dec_bufs.buf_data);
Wentao MA96f68962022-06-15 19:45:35 +08001052 DVR_PB_INFO("get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001053 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001054 }
Wentao MA96f68962022-06-15 19:45:35 +08001055 DVR_PB_INFO("--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001056 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001057 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1058 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1059 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1060 player->first_trans_ok = DVR_TRUE;
1061 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1062 }
hualing chencc91e1c2020-02-28 13:26:17 +08001063 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001064 //set video show
1065 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001066 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1067 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001068 int trick_stat = 0;
1069 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001070
hualing chen86e7d482020-01-16 15:13:33 +08001071 //check trick stat
Wentao MA96f68962022-06-15 19:45:35 +08001072 //DVR_PB_INFO("lock check_no_data_time:%d", check_no_data_time);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001073 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001074
Wentao MA907b6432022-08-01 06:23:08 +00001075 {
Wentao MA9a164002022-08-29 11:20:24 +08001076 static struct timespec _prev_ts={0,0};
Wentao MA907b6432022-08-01 06:23:08 +00001077 struct timespec _nowts,_diffts;
1078 clock_gettime(CLOCK_MONOTONIC, &_nowts);
Wentao MA9a164002022-08-29 11:20:24 +08001079 clock_timespec_subtract(&_nowts,&_prev_ts,&_diffts);
Wentao MA907b6432022-08-01 06:23:08 +00001080 if (_diffts.tv_sec>0) {
1081 char _logbuf[512]={0};
1082 char* _pbuf=_logbuf;
1083 int _nchar=0;
1084 DVR_PlaybackSegmentInfo_t* _segment;
1085 list_for_each_entry(_segment, &player->segment_list, head) {
1086 if (player->cur_segment_id == _segment->segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08001087 int seg_size = segment_get_cur_segment_size(player->r_handle);
1088 int read_ptr = segment_tell_position(player->r_handle);
Wentao MA907b6432022-08-01 06:23:08 +00001089 float progress = -1.0f;
Wentao MA9a164002022-08-29 11:20:24 +08001090 if (seg_size>0) {
1091 progress = (float)read_ptr*100/seg_size;
Wentao MA907b6432022-08-01 06:23:08 +00001092 }
1093 _nchar=sprintf(_pbuf,"%lld(%.1f%), ",_segment->segment_id,progress);
1094 } else {
1095 _nchar=sprintf(_pbuf,"%lld, ",_segment->segment_id);
1096 }
1097 if (_nchar<0) {
1098 break;
1099 }
1100 _pbuf+=_nchar;
1101 if (_pbuf-_logbuf+10 >= sizeof(_logbuf)) {
1102 sprintf(_pbuf,"...");
1103 break;
1104 }
1105 }
Wentao MA9a164002022-08-29 11:20:24 +08001106 DVR_PB_INFO("clk: %08u, seg_list: %s",_nowts.tv_sec,_logbuf);
1107 _prev_ts=_nowts;
Wentao MA907b6432022-08-01 06:23:08 +00001108 }
1109 }
1110
hualing chen2aba4022020-03-02 13:49:55 +08001111 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1112 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001113 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001114 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001115 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001116 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001117 {
hualing chen2aba4022020-03-02 13:49:55 +08001118 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1119 if (trick_stat > 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001120 DVR_PB_INFO("trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001121 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001122 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 +08001123 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001124 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001125 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001126 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
Wentao MA270dc0f2022-08-23 13:17:26 +08001127 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_V_START
1128 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_A_START
hualing chen2aba4022020-03-02 13:49:55 +08001129 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
Wentao MA96f68962022-06-15 19:45:35 +08001130 DVR_PB_INFO("pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001131 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001132 //need change to pause state
1133 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1134 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00001135 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08001136 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001137 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001138 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001139 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001140 AmTsPlayer_pauseVideoDecoding(player->handle);
1141 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001142 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001143 DVR_PB_INFO("clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001144 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001145 }
1146 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1147 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001148 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001149 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001150 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001151 DVR_PB_INFO("fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001152 player->speed,
1153 player->fffb_current,
1154 _dvr_time_getClock(),
1155 _dvr_playback_state_toString(player->state),
1156 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001157 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001158 //dvr_mutex_unlock(&player->lock);
1159 //dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001160 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001161 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001162 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001163 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001164 } else if (_dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001165 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 +08001166 player->speed,
1167 player->fffb_current,
1168 _dvr_time_getClock(),
1169 _dvr_playback_state_toString(player->state),
1170 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001171 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001172 //dvr_mutex_unlock(&player->lock);
1173 //dvr_mutex_lock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001174 AmTsPlayer_pauseVideoDecoding(player->handle);
1175 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001176 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001177 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001178 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001179 }
Wentao MA96f68962022-06-15 19:45:35 +08001180 DVR_PB_INFO("fffb play-------speed[%f][%d][%d][%s][%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001181 player->speed,
1182 goto_rewrite,
1183 real_read,
1184 _dvr_playback_state_toString(player->state),
1185 player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001186 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001187 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001188 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1189 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001190 DVR_PB_INFO("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001191 dvr_mutex_unlock(&player->lock);
1192
hualing chen2aba4022020-03-02 13:49:55 +08001193 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001194 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001195 dvr_mutex_lock(&player->lock);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001196 player->fffb_play = DVR_FALSE;
hualing chen1ffd85b2021-08-16 15:18:43 +08001197 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1198 //on pause state,user seek to new pos,we need pause and wait
1199 //user to resume
Wentao MA96f68962022-06-15 19:45:35 +08001200 DVR_PB_INFO("pause, when got first frame event when user seek end");
hualing chen1ffd85b2021-08-16 15:18:43 +08001201 player->first_frame = 0;
1202 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1203 AmTsPlayer_pauseVideoDecoding(player->handle);
1204 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001205 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001206 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001207 //for first into fffb when reset speed
1208 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1209 _dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001210 DVR_PB_INFO("fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001211 player->speed,
1212 player->fffb_current,
1213 _dvr_time_getClock(),
1214 _dvr_playback_state_toString(player->state),
1215 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001216 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001217 //dvr_mutex_unlock(&player->lock);
1218 //dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001219 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001220 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001221 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001222 continue;
1223 }
Wentao MA96f68962022-06-15 19:45:35 +08001224 DVR_PB_INFO("fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001225 player->speed,
1226 goto_rewrite,
1227 real_read,
1228 _dvr_playback_state_toString(player->state),
1229 player->cmd.cur_cmd,
1230 player->fffb_play);
Wentao MA96f68962022-06-15 19:45:35 +08001231 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001232 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001233 goto_rewrite = DVR_FALSE;
1234 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001235 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001236 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1237 player->first_frame = 0;
1238 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001239 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001240 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001241 }
hualing chenb31a6c62020-01-13 17:27:00 +08001242 }
hualing chen86e7d482020-01-16 15:13:33 +08001243
hualing chen30423862021-04-16 14:39:12 +08001244 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1245 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001246 //check is need send time send end
Wentao MA96f68962022-06-15 19:45:35 +08001247 DVR_PB_INFO("pause, continue");
1248 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001249 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001250 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001251 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001252 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001253 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001254 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001255 continue;
1256 }
hualing chen266b9502020-04-04 17:39:39 +08001257 //when seek action is done. we need drop write timeout data.
1258 if (player->drop_ts == DVR_TRUE) {
1259 goto_rewrite = DVR_FALSE;
1260 real_read = 0;
1261 player->drop_ts = DVR_FALSE;
1262 }
hualing chen2aba4022020-03-02 13:49:55 +08001263 if (goto_rewrite == DVR_TRUE) {
1264 goto_rewrite = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001265 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001266 dvr_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001267 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Wentao MA96f68962022-06-15 19:45:35 +08001268 //DVR_PB_INFO("rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001269 goto rewrite;
1270 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001271 //.check is need send time send end
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001272 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001273 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001274 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001275 pthread_mutex_lock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001276 //DVR_PB_INFO("start read");
hualing chen87072a82020-03-12 16:20:12 +08001277 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001278 real_read = real_read + read;
1279 player->ts_cache_len = real_read;
Wentao MA96f68962022-06-15 19:45:35 +08001280 //DVR_PB_INFO("start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001281 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001282 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001283 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001284 if (read < 0 && errno == EIO) {
1285 //EIO ERROR, EXIT THRAD
Wentao MA96f68962022-06-15 19:45:35 +08001286 DVR_PB_INFO("read error.EIO error, exit thread");
hualing chenb5cd42e2020-04-15 17:03:34 +08001287 DVR_Play_Notify_t notify;
1288 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1289 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001290 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001291 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001292 goto end;
1293 } else if (read < 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001294 DVR_PB_INFO("read error.:%d EIO:%d", errno, EIO);
hualing chenb5cd42e2020-04-15 17:03:34 +08001295 }
hualing chen87072a82020-03-12 16:20:12 +08001296 //if on fb mode and read file end , we need calculate pos to retry read.
1297 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001298 DVR_PB_INFO("recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
hualing chen03fd4942021-07-15 15:56:41 +08001299 read,
1300 real_read,
1301 buf_len,
1302 player->speed,
1303 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001304 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001305 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001306 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001307 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001308 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001309 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001310 continue;
1311 }
Wentao MA96f68962022-06-15 19:45:35 +08001312 //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 +08001313 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001314 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001315 #define MIN_CACHE_TIME (3000)
1316 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001317 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001318 if (_cache_time > MIN_CACHE_TIME) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001319 //dvr_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001320 /*if cache time > 20s , we think get time is error,*/
1321 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
Wentao MA907b6432022-08-01 06:23:08 +00001322 DVR_PB_WARN("read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
hualing chene3797f02021-01-13 14:53:28 +08001323 }
hualing chen1679f812021-11-08 15:17:46 +08001324 //_dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001325 //dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001326 // DVR_PB_INFO("read end but cache time is %d > %d, to sleep end and continue", _cache_time, MIN_CACHE_TIME);
hualing chene41f4372020-06-06 16:29:17 +08001327 //continue;
1328 }
hualing chen969fe7b2021-05-26 15:13:17 +08001329
hualing chen040df222020-01-17 13:35:02 +08001330 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001331 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001332 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001333
1334 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen1679f812021-11-08 15:17:46 +08001335
1336 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1337 player->noData++;
Wentao MA96f68962022-06-15 19:45:35 +08001338 DVR_PB_INFO("playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001339 if (player->noData == check_no_data_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001340 DVR_PB_INFO("playback send nodata event nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001341 //send event here and pause
1342 DVR_Play_Notify_t notify;
1343 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1344 notify.event = DVR_PLAYBACK_EVENT_NODATA;
Wentao MA96f68962022-06-15 19:45:35 +08001345 DVR_PB_INFO("send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001346 //get play statue not here
1347 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1348 }
1349 }
1350 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001351 if ((ret != DVR_SUCCESS &&
hualing chen03fd4942021-07-15 15:56:41 +08001352 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001353 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001354 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
Wentao MA270dc0f2022-08-23 13:17:26 +08001355 _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player)) ||
hualing chen39628212020-05-14 10:35:13 +08001356 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001357 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001358 DVR_Play_Notify_t notify;
1359 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1360 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1361 //get play statue not here
1362 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001363 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001364 //continue,timeshift mode, when read end,need wait cur recording segment
Wentao MA96f68962022-06-15 19:45:35 +08001365 DVR_PB_INFO("playback is send end delay:[%d]reach_end_timeout[%d]ms", delay, reach_end_timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001366 dvr_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001367 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001368 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001369 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001370 } else if (ret != DVR_SUCCESS) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001371 DVR_PB_INFO("delay:%d pauselive:%d", delay, _dvr_pauselive_decode_success((DVR_PlaybackHandle_t)player));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001372 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08001373 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001374 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08001375 delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chena540a7e2020-03-27 16:44:05 +08001376 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001377 if (delay < cache_time) {
1378 //delay time is changed and then has data to play, so not start timeout
hualing chen1679f812021-11-08 15:17:46 +08001379 reach_end_timeout = 0;
hualing chen39628212020-05-14 10:35:13 +08001380 } else {
1381 reach_end_timeout = reach_end_timeout + timeout;
1382 }
1383 cache_time = delay;
hualing chen31140872020-03-25 12:29:26 +08001384 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001385 }
hualing chen39628212020-05-14 10:35:13 +08001386 reach_end_timeout = 0;
1387 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001388 //change next segment success case
1389 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001390 dvr_mutex_lock(&player->lock);
hualing chen40dd5462021-11-26 19:56:20 +08001391 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001392 DVR_PB_INFO("_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001393 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1394 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001395 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001396 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001397 real_read = real_read + read;
1398 player->ts_cache_len = real_read;
1399 pthread_mutex_unlock(&player->segment_lock);
1400
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001401 dvr_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001402 }//read len 0 check end
hualing chen40dd5462021-11-26 19:56:20 +08001403 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001404 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001405 DVR_PB_INFO("playback send data event resume[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001406 //send event here and pause
1407 DVR_Play_Notify_t notify;
1408 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1409 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
Wentao MA96f68962022-06-15 19:45:35 +08001410 DVR_PB_INFO("----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001411 //get play statue not here
1412 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001413 }
hualing chen39628212020-05-14 10:35:13 +08001414 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001415 //real_read = real_read + read;
Wentao MA270dc0f2022-08-23 13:17:26 +08001416 input_buffer.buf_size = real_read;
1417 input_buffer.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001418
Wentao MA270dc0f2022-08-23 13:17:26 +08001419 //check read data len,if len < 0, we need continue
1420 if (input_buffer.buf_size <= 0 || input_buffer.buf_data == NULL) {
1421 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 +08001422 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001423 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001424 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001425 }
hualing chen266b9502020-04-04 17:39:39 +08001426 //if need write whole block size, we need check read buf len is eq block size.
1427 if (b_writed_whole_block == DVR_TRUE) {
1428 //buf_len is block size value.
1429 if (real_read < buf_len) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001430 //continue to read data from file
Wentao MA96f68962022-06-15 19:45:35 +08001431 DVR_PB_INFO("read buf len[%d] is < block size [%d]", real_read, buf_len);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001432 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001433 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1434 dvr_mutex_unlock(&player->lock);
1435 DVR_PB_INFO("read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001436 continue;
1437 } else if (real_read > buf_len) {
Wentao MA96f68962022-06-15 19:45:35 +08001438 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 +08001439 }
1440 }
1441
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001442 //if (player->is_secure_mode && player->dec_func) {
1443 if (player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001444 DVR_CryptoParams_t crypto_params;
1445
1446 memset(&crypto_params, 0, sizeof(crypto_params));
1447 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1448 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1449 crypto_params.segment_id = player->cur_segment.segment_id;
Wentao MA270dc0f2022-08-23 13:17:26 +08001450 crypto_params.offset = segment_tell_position(player->r_handle) - input_buffer.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001451 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
Wentao MA96f68962022-06-15 19:45:35 +08001452 DVR_PB_INFO("offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001453 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1454 crypto_params.input_buffer.addr = (size_t)buf;
1455 crypto_params.input_buffer.size = real_read;
1456
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001457 if (player->is_secure_mode) {
1458 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1459 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1460 crypto_params.output_buffer.size = dec_buf_size;
1461 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001462 input_buffer.buf_data = player->secure_buffer;
1463 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001464 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001465 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001466 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001467 input_buffer.buf_size = crypto_params.output_size;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001468 } else { // only for NAGRA
1469 crypto_params.output_buffer.type = crypto_params.input_buffer.type;
1470 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1471 crypto_params.output_buffer.size = crypto_params.input_buffer.size;
1472 ret = player->dec_func(&crypto_params, player->dec_userdata);
Wentao MA270dc0f2022-08-23 13:17:26 +08001473 input_buffer.buf_data = (uint8_t*)crypto_params.output_buffer.addr;
1474 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001475 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001476 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001477 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001478 input_buffer.buf_size = crypto_params.output_buffer.size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001479 }
Yahui Han1fbf3292021-11-08 18:17:19 +08001480 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001481 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001482 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
Wentao MA270dc0f2022-08-23 13:17:26 +08001483 input_buffer.buf_data = dec_bufs.buf_data;
1484 input_buffer.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1485 input_buffer.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001486 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001487rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001488 if (player->drop_ts == DVR_TRUE) {
1489 //need drop ts data when seek occur.we need read next loop,drop this ts data
1490 goto_rewrite = DVR_FALSE;
1491 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001492 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001493 player->drop_ts = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001494 DVR_PB_INFO("----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001495 continue;
1496 }
hualing chen21a40372021-10-29 11:07:26 +08001497
1498 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001499 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001500 //used for printf first write data time.
1501 //to check change channel kpi.
1502 if (first_write == 0) {
1503 first_write++;
Wentao MA270dc0f2022-08-23 13:17:26 +08001504 DVR_PB_INFO("----first write ts data");
hualing chenb9a02922021-12-14 11:29:47 +08001505 }
1506
Wentao MA270dc0f2022-08-23 13:17:26 +08001507 ret = AmTsPlayer_writeData(player->handle, &input_buffer, write_timeout_ms);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001508 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001509 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001510 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001511 real_read = 0;
1512 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001513 if (CONTROL_SPEED_ENABLE == 1) {
1514check0:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001515 if (!player->is_running) {
1516 DVR_PB_DG(1, "playback thread exit");
1517 break;
1518 }
hualing chend241c7a2021-06-22 13:34:27 +08001519 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001520 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001521 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001522 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001523 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1524 goto check0;
1525 }
1526 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001527 //DVR_PB_INFO("write write_success:%d input_buffer.buf_size:%d", write_success, input_buffer.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001528 continue;
hualing chen87072a82020-03-12 16:20:12 +08001529 } else {
hualing chen21a40372021-10-29 11:07:26 +08001530 pthread_mutex_unlock(&player->segment_lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001531 DVR_PB_INFO("write time out write_success:%d input_buffer.buf_size:%d systime:%u",
hualing chen03fd4942021-07-15 15:56:41 +08001532 write_success,
Wentao MA270dc0f2022-08-23 13:17:26 +08001533 input_buffer.buf_size,
hualing chen03fd4942021-07-15 15:56:41 +08001534 _dvr_time_getClock());
1535
hualing chena540a7e2020-03-27 16:44:05 +08001536 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001537 if (CONTROL_SPEED_ENABLE == 1) {
1538check1:
Yahui Hanc7ab63d2022-08-29 15:59:08 +08001539 if (!player->is_running) {
1540 DVR_PB_DG(1, "playback thread exit");
1541 break;
1542 }
hualing chend241c7a2021-06-22 13:34:27 +08001543 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001544 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001545 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001546 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001547 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1548 goto check1;
1549 }
1550 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001551 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001552 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001553 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001554 if (!player->is_running) {
Wentao MA96f68962022-06-15 19:45:35 +08001555 DVR_PB_INFO("playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001556 break;
1557 }
hualing chen2aba4022020-03-02 13:49:55 +08001558 goto_rewrite = DVR_TRUE;
1559 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001560 }
1561 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001562end:
Wentao MA96f68962022-06-15 19:45:35 +08001563 DVR_PB_INFO("playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001564 free(buf);
1565 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001566 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001567}
1568
1569
hualing chen040df222020-01-17 13:35:02 +08001570static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001571{
hualing chen040df222020-01-17 13:35:02 +08001572 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001573
1574 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001575 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001576 return DVR_FAILURE;
1577 }
Wentao MA96f68962022-06-15 19:45:35 +08001578 DVR_PB_INFO("start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001579 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001580 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001581 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001582 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001583 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001584 if (rc < 0)
1585 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001586 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001587}
1588
1589
hualing chen040df222020-01-17 13:35:02 +08001590static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001591{
hualing chen040df222020-01-17 13:35:02 +08001592 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001593
1594 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001595 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001596 return DVR_FAILURE;
1597 }
1598
Wentao MA96f68962022-06-15 19:45:35 +08001599 DVR_PB_INFO("stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001600 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001601 {
1602 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001603 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001604 pthread_join(player->playback_thread, NULL);
1605 }
1606 if (player->r_handle) {
1607 segment_close(player->r_handle);
1608 player->r_handle = NULL;
1609 }
Wentao MA96f68962022-06-15 19:45:35 +08001610 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001611 return 0;
1612}
1613
hualing chen1679f812021-11-08 15:17:46 +08001614static int getFakePid()
1615{
1616 char fake_pid_prop[] = "vendor.tv.dtv.fake_pid";
1617 char buf[32];
1618 int pid = 0xffff;
1619
1620 dvr_prop_read(fake_pid_prop, buf, sizeof(buf));
1621
1622 if (sscanf(buf, "%i", &pid) != 1)
1623 {
Wentao MA96f68962022-06-15 19:45:35 +08001624 DVR_PB_INFO("get fake pid error");
hualing chen1679f812021-11-08 15:17:46 +08001625 pid = 0xffff;
1626 }
1627 return pid;
1628}
1629
1630void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1631
1632 DVR_ASSERT(handle);
1633 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1634 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001635 DVR_PB_INFO("player is NULL");
hualing chen1679f812021-11-08 15:17:46 +08001636 return ;
1637 }
1638 if (player->need_seek_start == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001639 DVR_PB_INFO("player need_seek_start is false");
hualing chen1679f812021-11-08 15:17:46 +08001640 return ;
1641 }
1642
hualing chena5f03222021-12-02 11:22:35 +08001643 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001644 player->need_seek_start = DVR_FALSE;
1645 }
Wentao MA96f68962022-06-15 19:45:35 +08001646 DVR_PB_INFO("player player->need_seek_start=%d", player->need_seek_start);
hualing chen1679f812021-11-08 15:17:46 +08001647}
1648
hualing chenb31a6c62020-01-13 17:27:00 +08001649/**\brief Open an dvr palyback
1650 * \param[out] p_handle dvr playback addr
1651 * \param[in] params dvr playback open parameters
1652 * \retval DVR_SUCCESS On success
1653 * \return Error code
1654 */
hualing chen040df222020-01-17 13:35:02 +08001655int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001656
hualing chen040df222020-01-17 13:35:02 +08001657 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001658 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001659
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001660 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001661
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001662 dvr_mutex_init(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001663 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001664 pthread_condattr_init(&cattr);
1665 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1666 pthread_cond_init(&player->cond, &cattr);
1667 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001668
hualing chen5cbe1a62020-02-10 16:36:36 +08001669 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001670 INIT_LIST_HEAD(&player->segment_list);
1671 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1672 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001673 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001674 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00001675 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen86e7d482020-01-16 15:13:33 +08001676 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001677 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001678 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001679
hualing chen86e7d482020-01-16 15:13:33 +08001680 //store open params
hualing chen040df222020-01-17 13:35:02 +08001681 player->openParams.dmx_dev_id = params->dmx_dev_id;
1682 player->openParams.block_size = params->block_size;
Wentao MA96f68962022-06-15 19:45:35 +08001683 DVR_PB_INFO("playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001684 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001685 player->openParams.event_fn = params->event_fn;
1686 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001687 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001688 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001689
hualing chen5cbe1a62020-02-10 16:36:36 +08001690 player->has_pids = params->has_pids;
1691
hualing chen2aba4022020-03-02 13:49:55 +08001692 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001693
1694 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1695 //for test get callback
1696 if (0 && player->player_callback_func == NULL) {
1697 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1698 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
Wentao MA96f68962022-06-15 19:45:35 +08001699 DVR_PB_INFO("playback open get callback[%p][%p][%p][%p]",
hualing chen03fd4942021-07-15 15:56:41 +08001700 player->player_callback_func,
1701 player->player_callback_userdata,
1702 _dvr_tsplayer_callback_test,
1703 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001704 }
1705 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001706
hualing chen86e7d482020-01-16 15:13:33 +08001707 //init has audio and video
1708 player->has_video = DVR_FALSE;
1709 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001710 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001711 player->last_segment_id = 0LL;
1712 player->segment_is_open = DVR_FALSE;
Wentao MA5629ad82022-08-24 10:03:02 +08001713 player->audio_presentation_id = -1;
hualing chenb31a6c62020-01-13 17:27:00 +08001714
hualing chen5cbe1a62020-02-10 16:36:36 +08001715 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001716 player->fffb_current = 0;
1717 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001718 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001719 //seek time
1720 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001721 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001722
Yahui Han1fbf3292021-11-08 18:17:19 +08001723 //allocate cryptor if have clearkey
1724 if (params->keylen > 0) {
1725 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +08001726 (uint8_t *)params->cleariv,
1727 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +08001728 if (!player->cryptor) {
Wentao MA96f68962022-06-15 19:45:35 +08001729 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +08001730 }
1731 } else {
1732 player->cryptor = NULL;
1733 }
1734
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001735 //init secure stuff
1736 player->dec_func = NULL;
1737 player->dec_userdata = NULL;
1738 player->is_secure_mode = 0;
1739 player->secure_buffer = NULL;
1740 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001741 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001742
hualing chen4b7c15d2020-04-07 16:13:48 +08001743 player->fffb_play = DVR_FALSE;
1744
1745 player->last_send_time_id = UINT64_MAX;
1746 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001747 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001748
hualing chend241c7a2021-06-22 13:34:27 +08001749 //speed con init
1750 if (CONTROL_SPEED_ENABLE == 1) {
1751 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001752 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001753 player->con_spe.sys_dur = 0;
1754 player->con_spe.sys_sta = 0;
1755 }
1756
hualing chen03fd4942021-07-15 15:56:41 +08001757 //limit info
1758 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001759 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001760 //need seek to start pos
1761 player->first_start_time = 0;
Wentao MA01de0e62022-01-10 18:48:23 +08001762 player->first_start_id = UINT64_MAX;
1763 player->check_cache_flag = DVR_TRUE;
hualing chen8a657f32021-08-30 13:12:49 +08001764 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001765 //fake_pid init
1766 player->fake_pid = getFakePid();
hualing chen86e7d482020-01-16 15:13:33 +08001767 *p_handle = player;
1768 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001769}
1770
1771/**\brief Close an dvr palyback
1772 * \param[in] handle playback handle
1773 * \retval DVR_SUCCESS On success
1774 * \return Error code
1775 */
hualing chen040df222020-01-17 13:35:02 +08001776int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001777
hualing chen86e7d482020-01-16 15:13:33 +08001778 DVR_ASSERT(handle);
Wentao MA96f68962022-06-15 19:45:35 +08001779 DVR_PB_INFO(":into");
hualing chen040df222020-01-17 13:35:02 +08001780 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001781 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001782 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001783 return DVR_FAILURE;
1784 }
1785
hualing chencc91e1c2020-02-28 13:26:17 +08001786 if (player->state != DVR_PLAYBACK_STATE_STOP)
1787 {
Wentao MA96f68962022-06-15 19:45:35 +08001788 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001789 if (player->cryptor) {
1790 am_crypt_des_close(player->cryptor);
1791 player->cryptor = NULL;
1792 }
hualing chencc91e1c2020-02-28 13:26:17 +08001793 dvr_playback_stop(handle, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08001794 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
hualing chenb96aa2c2020-04-15 14:13:53 +08001795 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001796 DVR_PB_INFO(":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001797 }
Wentao MA96f68962022-06-15 19:45:35 +08001798 DVR_PB_INFO(":into");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001799 dvr_mutex_destroy(&player->lock);
Zhiqiang Hanc9513462022-06-21 09:55:23 +08001800 pthread_mutex_destroy(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001801 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001802
1803 if (player) {
1804 free(player);
1805 player = NULL;
1806 }
Wentao MA96f68962022-06-15 19:45:35 +08001807 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001808 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001809}
1810
Wentao MA270dc0f2022-08-23 13:17:26 +08001811/**\brief Start play audio and video, used start audio api and start video api
hualing chenb31a6c62020-01-13 17:27:00 +08001812 * \param[in] handle playback handle
1813 * \param[in] params audio playback params,contains fmt and pid...
1814 * \retval DVR_SUCCESS On success
1815 * \return Error code
1816 */
hualing chen040df222020-01-17 13:35:02 +08001817int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1818 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA270dc0f2022-08-23 13:17:26 +08001819 am_tsplayer_video_params video_params;
1820 am_tsplayer_audio_params audio_params;
1821 am_tsplayer_audio_params ad_params;
hualing chena540a7e2020-03-27 16:44:05 +08001822
Wentao MA270dc0f2022-08-23 13:17:26 +08001823 memset(&video_params, 0, sizeof(video_params));
1824 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001825
hualing chena540a7e2020-03-27 16:44:05 +08001826 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001827 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001828 return DVR_FAILURE;
1829 }
hualing chencc91e1c2020-02-28 13:26:17 +08001830 uint64_t segment_id = player->cur_segment_id;
Wentao MA96f68962022-06-15 19:45:35 +08001831 DVR_PB_INFO("[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001832
hualing chena540a7e2020-03-27 16:44:05 +08001833 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001834 //can used start api to resume playback
1835 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1836 return dvr_playback_resume(handle);
1837 }
hualing chen87072a82020-03-12 16:20:12 +08001838 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA270dc0f2022-08-23 13:17:26 +08001839 //if flag is paused and not decode first frame. if user resume, we need
hualing chen9b434f02020-06-10 15:06:54 +08001840 //clear flag and set trickmode none
1841 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001842 DVR_PB_INFO("[%p]clear pause live flag and clear trick mode", handle);
hualing chen9b434f02020-06-10 15:06:54 +08001843 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1844 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1845 }
Wentao MA96f68962022-06-15 19:45:35 +08001846 DVR_PB_INFO("stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001847 return DVR_SUCCESS;
1848 }
hualing chen86e7d482020-01-16 15:13:33 +08001849 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001850 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001851 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08001852 DVR_PB_INFO("lock flag:0x%x", flag);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001853 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08001854 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08001855 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08001856 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
1857 //audio and video pids are all invalid, return error.
1858 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 +08001859 dvr_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001860 DVR_Play_Notify_t notify;
1861 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1862 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1863 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1864 notify.info.transition_failed_data.segment_id = segment_id;
1865 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001866 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001867 return -1;
1868 }
hualing chen31140872020-03-25 12:29:26 +08001869
hualing chencc91e1c2020-02-28 13:26:17 +08001870 {
Wentao MA270dc0f2022-08-23 13:17:26 +08001871 if (VALID_PID(video_params.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001872 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001873 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001874 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001875 DVR_PB_INFO("set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001876 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1877 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001878 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
Wentao MA96f68962022-06-15 19:45:35 +08001879 DVR_PB_INFO("set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001880 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001881 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001882 DVR_PB_INFO("set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001883 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001884 }
hualing chena93bbbc2020-12-22 17:23:42 +08001885 AmTsPlayer_showVideo(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08001886 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08001887 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001888 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001889 }
hualing chena540a7e2020-03-27 16:44:05 +08001890
Wentao MA270dc0f2022-08-23 13:17:26 +08001891 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 +08001892 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001893 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1894 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1895 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001896 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001897 } else {
1898 player->cmd.last_cmd = player->cmd.cur_cmd;
1899 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001900 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001901 //set fast play
Wentao MA96f68962022-06-15 19:45:35 +08001902 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08001903 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001904 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08001905 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08001906 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08001907 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08001908 dvr_playback_change_seek_state(handle, ad_params.pid);
1909 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08001910 AmTsPlayer_enableADMix(player->handle);
1911 }
Wentao MA270dc0f2022-08-23 13:17:26 +08001912 if (VALID_PID(audio_params.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001913 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08001914 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08001915 dvr_playback_change_seek_state(handle, audio_params.pid);
1916 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08001917 if (player->audio_presentation_id > -1) {
1918 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
1919 }
hualing chen969fe7b2021-05-26 15:13:17 +08001920 AmTsPlayer_startAudioDecoding(player->handle);
1921 }
hualing chen31140872020-03-25 12:29:26 +08001922 }
hualing chencc91e1c2020-02-28 13:26:17 +08001923 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00001924 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chencc91e1c2020-02-28 13:26:17 +08001925 }
hualing chen86e7d482020-01-16 15:13:33 +08001926 }
hualing chen43a89bc2022-01-19 14:31:20 +08001927#ifdef AVSYNC_USED_PCR
1928 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001929 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08001930 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
1931 }
1932#endif
Wentao MA96f68962022-06-15 19:45:35 +08001933 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001934 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001935 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001936 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001937}
hualing chen040df222020-01-17 13:35:02 +08001938/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001939 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001940 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001941 * \retval DVR_SUCCESS On success
1942 * \return Error code
1943 */
hualing chen040df222020-01-17 13:35:02 +08001944int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1945 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001946
hualing chena540a7e2020-03-27 16:44:05 +08001947 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001948 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001949 return DVR_FAILURE;
1950 }
1951
Wentao MA96f68962022-06-15 19:45:35 +08001952 DVR_PB_INFO("add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001953 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001954
hualing chen040df222020-01-17 13:35:02 +08001955 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1956 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001957
Wentao MA270dc0f2022-08-23 13:17:26 +08001958 //not memcpy chunk info.
hualing chen040df222020-01-17 13:35:02 +08001959 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001960 //cp location
hualing chen040df222020-01-17 13:35:02 +08001961 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001962
Wentao MA96f68962022-06-15 19:45:35 +08001963 DVR_PB_INFO("add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001964 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001965
1966 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001967 segment->pids.video.pid = info->pids.video.pid;
1968 segment->pids.video.format = info->pids.video.format;
1969 segment->pids.video.type = info->pids.video.type;
1970
hualing chen2aba4022020-03-02 13:49:55 +08001971 segment->pids.audio.pid = info->pids.audio.pid;
1972 segment->pids.audio.format = info->pids.audio.format;
1973 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001974
hualing chen2aba4022020-03-02 13:49:55 +08001975 segment->pids.ad.pid = info->pids.ad.pid;
1976 segment->pids.ad.format = info->pids.ad.format;
1977 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001978
1979 segment->pids.pcr.pid = info->pids.pcr.pid;
1980
Wentao MA96f68962022-06-15 19:45:35 +08001981 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 +08001982 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001983 list_add_tail(&segment->head, &player->segment_list);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001984 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001985 DVR_PB_DEBUG("unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001986
hualing chen5cbe1a62020-02-10 16:36:36 +08001987 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001988}
hualing chen040df222020-01-17 13:35:02 +08001989/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001990 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001991 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001992 * \retval DVR_SUCCESS On success
1993 * \return Error code
1994 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001995int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001996 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001997 DVR_PB_INFO("remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001998 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001999 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002000 return DVR_FAILURE;
2001 }
2002
hualing chencc91e1c2020-02-28 13:26:17 +08002003 if (segment_id == player->cur_segment_id) {
Wentao MA9a164002022-08-29 11:20:24 +08002004 DVR_PB_INFO("not support remove current segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08002005 return DVR_FAILURE;
2006 }
Wentao MA96f68962022-06-15 19:45:35 +08002007 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002008 dvr_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08002009 DVR_PlaybackSegmentInfo_t *segment = NULL;
2010 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
2011 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002012 {
hualing chen040df222020-01-17 13:35:02 +08002013 if (segment->segment_id == segment_id) {
2014 list_del(&segment->head);
2015 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08002016 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002017 }
hualing chen86e7d482020-01-16 15:13:33 +08002018 }
Wentao MA96f68962022-06-15 19:45:35 +08002019 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002020 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002021
2022 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002023}
hualing chen040df222020-01-17 13:35:02 +08002024/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08002025 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08002026 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08002027 * \retval DVR_SUCCESS On success
2028 * \return Error code
2029 */
hualing chen040df222020-01-17 13:35:02 +08002030int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08002031 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08002032 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08002033 DVR_PB_INFO("update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08002034 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002035 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002036 return DVR_FAILURE;
2037 }
hualing chenf43b8ba2020-07-28 13:11:42 +08002038 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
Wentao MA96f68962022-06-15 19:45:35 +08002039 DVR_PB_INFO("vendor is amlogic. not hide or show av and update segment");
hualing chenf43b8ba2020-07-28 13:11:42 +08002040 return DVR_SUCCESS;
2041 }
hualing chena540a7e2020-03-27 16:44:05 +08002042
hualing chen040df222020-01-17 13:35:02 +08002043 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002044 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002045 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08002046 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002047 {
hualing chen040df222020-01-17 13:35:02 +08002048 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08002049 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08002050 }
hualing chen86e7d482020-01-16 15:13:33 +08002051 // if encramble to free, only set flag and return;
2052
2053 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08002054 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002055 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
2056 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08002057 //disable display, mute
Wentao MA96f68962022-06-15 19:45:35 +08002058 DVR_PB_INFO("mute av");
hualing chen2aba4022020-03-02 13:49:55 +08002059 AmTsPlayer_hideVideo(player->handle);
2060 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002061 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
2062 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002063 //enable display, unmute
Wentao MA96f68962022-06-15 19:45:35 +08002064 DVR_PB_INFO("unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08002065 AmTsPlayer_showVideo(player->handle);
2066 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002067 } else {
2068 //do nothing
2069 }
2070 } else {
2071 //do nothing
2072 }
2073 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08002074 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08002075 }
Wentao MA96f68962022-06-15 19:45:35 +08002076 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002077 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002078 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002079}
2080
2081
hualing chen99508642021-10-18 15:41:17 +08002082static 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 +08002083 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08002084 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08002085 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08002086
2087 if (type == 0) {
2088 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08002089 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08002090 } else if (type == 1) {
2091 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08002092 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08002093 } else if (type == 2) {
2094 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08002095 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08002096 } else {
2097 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08002098 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08002099 }
2100
hualing chena540a7e2020-03-27 16:44:05 +08002101 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002102 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002103 return DVR_FAILURE;
2104 }
Wentao MA96f68962022-06-15 19:45:35 +08002105 DVR_PB_INFO(" do check");
hualing chen86e7d482020-01-16 15:13:33 +08002106 if (now_pid.pid == set_pid.pid) {
2107 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08002108 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08002109 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08002110 if (VALID_PID(now_pid.pid)) {
2111 //stop now stream
2112 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002113 //stop video
hualing chenc70a8df2020-05-12 19:23:11 +08002114 if (player->has_video == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002115 DVR_PB_INFO("stop video");
hualing chenc70a8df2020-05-12 19:23:11 +08002116 AmTsPlayer_stopVideoDecoding(player->handle);
2117 player->has_video = DVR_FALSE;
2118 }
hualing chen86e7d482020-01-16 15:13:33 +08002119 } else if (type == 1) {
2120 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002121 if (player->has_audio == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002122 DVR_PB_INFO("stop audio");
hualing chenc70a8df2020-05-12 19:23:11 +08002123 AmTsPlayer_stopAudioDecoding(player->handle);
2124 player->has_audio = DVR_FALSE;
2125 }
hualing chen86e7d482020-01-16 15:13:33 +08002126 } else if (type == 2) {
2127 //stop sub audio
Wentao MA96f68962022-06-15 19:45:35 +08002128 DVR_PB_INFO("stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002129 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002130 } else if (type == 3) {
2131 //pcr
2132 }
2133 }
2134 if (VALID_PID(set_pid.pid)) {
2135 //start
2136 if (type == 0) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002137 //start video
2138 am_tsplayer_video_params video_params;
2139 video_params.pid = set_pid.pid;
2140 video_params.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002141 player->has_video = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002142 DVR_PB_INFO("start video pid[%d]fmt[%d]",video_params.pid, video_params.codectype);
2143 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen2aba4022020-03-02 13:49:55 +08002144 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002145 //playback_device_video_start(player->handle,&video_params);
hualing chen86e7d482020-01-16 15:13:33 +08002146 } else if (type == 1) {
2147 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002148 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002149 if (VALID_PID(set_pids.ad.pid)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002150 am_tsplayer_audio_params ad_params;
2151 ad_params.pid = set_pids.ad.pid;
2152 ad_params.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2153 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",ad_params.pid, ad_params.codectype);
2154 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen275379e2021-06-15 17:57:21 +08002155 AmTsPlayer_enableADMix(player->handle);
2156 }
2157
Wentao MA270dc0f2022-08-23 13:17:26 +08002158 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002159
Wentao MA270dc0f2022-08-23 13:17:26 +08002160 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002161
Wentao MA270dc0f2022-08-23 13:17:26 +08002162 audio_params.pid = set_pid.pid;
2163 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002164 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002165 DVR_PB_INFO("start audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2166 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002167 if (player->audio_presentation_id > -1) {
2168 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2169 }
hualing chenc70a8df2020-05-12 19:23:11 +08002170 AmTsPlayer_startAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002171 //playback_device_audio_start(player->handle,&audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002172 }
hualing chen86e7d482020-01-16 15:13:33 +08002173 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002174 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002175 if (set_pids.audio.pid == now_pids.audio.pid) {
2176 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002177 DVR_PB_INFO("stop audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002178 AmTsPlayer_stopAudioDecoding(player->handle);
2179 }
Wentao MA270dc0f2022-08-23 13:17:26 +08002180 am_tsplayer_audio_params audio_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002181
Wentao MA270dc0f2022-08-23 13:17:26 +08002182 memset(&audio_params, 0, sizeof(audio_params));
2183 audio_params.pid = set_pid.pid;
2184 audio_params.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
hualing chenc70a8df2020-05-12 19:23:11 +08002185 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002186 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",audio_params.pid, audio_params.codectype);
2187 AmTsPlayer_setADParams(player->handle, &audio_params);
hualing chenc70a8df2020-05-12 19:23:11 +08002188 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002189
2190 if (set_pids.audio.pid == now_pids.audio.pid) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002191 am_tsplayer_audio_params audio_params;
hualing chen99508642021-10-18 15:41:17 +08002192
Wentao MA270dc0f2022-08-23 13:17:26 +08002193 memset(&audio_params, 0, sizeof(audio_params));
hualing chen99508642021-10-18 15:41:17 +08002194
Wentao MA270dc0f2022-08-23 13:17:26 +08002195 audio_params.pid = set_pids.audio.pid;
2196 audio_params.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
hualing chen99508642021-10-18 15:41:17 +08002197 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002198 DVR_PB_INFO("restart audio when start ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002199 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002200 if (player->audio_presentation_id > -1) {
2201 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2202 }
hualing chen99508642021-10-18 15:41:17 +08002203 AmTsPlayer_startAudioDecoding(player->handle);
2204 }
hualing chenc70a8df2020-05-12 19:23:11 +08002205 }
hualing chen86e7d482020-01-16 15:13:33 +08002206 } else if (type == 3) {
2207 //pcr
Wentao MA96f68962022-06-15 19:45:35 +08002208 DVR_PB_INFO("start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002209 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002210 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002211 //audio and video all close
2212 if (!player->has_audio && !player->has_video) {
Wentao MA907b6432022-08-01 06:23:08 +00002213 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen5cbe1a62020-02-10 16:36:36 +08002214 }
hualing chen43a89bc2022-01-19 14:31:20 +08002215 } else if (type == 2) {
2216 //case disable ad
Wentao MA96f68962022-06-15 19:45:35 +08002217 DVR_PB_INFO("restart audio when stop ad");
hualing chen43a89bc2022-01-19 14:31:20 +08002218 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
Wentao MA6d045b32022-02-18 18:47:25 +08002219 if (VALID_PID(now_pids.audio.pid)) {
2220 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002221 DVR_PB_INFO("stop audio when stop ad pid [0x%x]", now_pids.audio.pid);
Wentao MA6d045b32022-02-18 18:47:25 +08002222 AmTsPlayer_stopAudioDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08002223 am_tsplayer_audio_params audio_params;
hualing chen43a89bc2022-01-19 14:31:20 +08002224
Wentao MA270dc0f2022-08-23 13:17:26 +08002225 memset(&audio_params, 0, sizeof(audio_params));
hualing chen43a89bc2022-01-19 14:31:20 +08002226
Wentao MA270dc0f2022-08-23 13:17:26 +08002227 audio_params.pid = now_pids.audio.pid;
2228 audio_params.codectype= _dvr_convert_stream_fmt(now_pids.audio.format, DVR_TRUE);
Wentao MA6d045b32022-02-18 18:47:25 +08002229 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002230 DVR_PB_INFO("restart audio when stop ad");
Wentao MA270dc0f2022-08-23 13:17:26 +08002231 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002232 if (player->audio_presentation_id > -1) {
2233 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2234 }
Wentao MA6d045b32022-02-18 18:47:25 +08002235 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen43a89bc2022-01-19 14:31:20 +08002236 }
Wentao MA6d045b32022-02-18 18:47:25 +08002237 }
hualing chen86e7d482020-01-16 15:13:33 +08002238 }
2239 }
2240 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002241}
hualing chena5f03222021-12-02 11:22:35 +08002242/**\brief dvr play back only update segment pids info
2243 * only update pid info not to start stop codec.
2244 * \param[in] handle playback handle
2245 * \param[in] segment_id need updated pids segment id
2246 * \param[in] p_pids need updated pids
2247 * \retval DVR_SUCCESS On success
2248 * \return Error code
2249 */
2250int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2251 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2252 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002253 DVR_PB_INFO("player is NULL");
hualing chena5f03222021-12-02 11:22:35 +08002254 return DVR_FAILURE;
2255 }
2256
2257 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002258 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002259 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002260 DVR_PB_INFO("get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
hualing chena5f03222021-12-02 11:22:35 +08002261 list_for_each_entry(segment, &player->segment_list, head)
2262 {
2263 if (segment->segment_id == segment_id) {
2264 if (player->cur_segment_id == segment_id) {
2265 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
2266 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
2267 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002268 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002269 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002270 return 0;
2271 }
2272 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2273 }
2274 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002275 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002276 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002277 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002278 break;
2279 }
2280 }
Wentao MA96f68962022-06-15 19:45:35 +08002281 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002282 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002283 return DVR_SUCCESS;
2284}
2285
hualing chen5cbe1a62020-02-10 16:36:36 +08002286/**\brief dvr play back update segment pids
2287 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002288 * add pid stream and stop remove pid stream.
2289 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002290 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002291 * \retval DVR_SUCCESS On success
2292 * \return Error code
2293 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002294int 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 +08002295 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002296 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002297 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002298 return DVR_FAILURE;
2299 }
2300
hualing chen040df222020-01-17 13:35:02 +08002301 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002302 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002303 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002304 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 +08002305
hualing chen040df222020-01-17 13:35:02 +08002306 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002307 {
hualing chen040df222020-01-17 13:35:02 +08002308 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002309
2310 if (player->cur_segment_id == segment_id) {
2311 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
2312 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
2313 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002314 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002315 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002316 return 0;
2317 }
2318
2319 //if segment is on going segment,we need stop start stream
2320 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA96f68962022-06-15 19:45:35 +08002321 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002322 dvr_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002323 if (segment->pids.audio.pid != p_pids->audio.pid &&
2324 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002325 //not used this to seek to start pos.we will
Wentao MA9a164002022-08-29 11:20:24 +08002326 //add update only api. if need seek to start
hualing chena5f03222021-12-02 11:22:35 +08002327 //pos, we will call only update api and used seek api
2328 //to start and stop av codec
2329 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002330 player->need_seek_start = DVR_FALSE;
2331 pthread_mutex_lock(&player->segment_lock);
2332 player->drop_ts = DVR_TRUE;
2333 player->ts_cache_len = 0;
2334 if (player->first_start_time > 0)
2335 player->first_start_time = player->first_start_time - 1;
2336 segment_seek(player->r_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002337 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 +08002338 pthread_mutex_unlock(&player->segment_lock);
2339 }
2340 }
hualing chen1679f812021-11-08 15:17:46 +08002341 //check video pids, stop or restart
2342 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
2343 //check sub audio pids stop or restart
2344 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
2345 //check audio pids stop or restart
2346 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
2347 //check pcr pids stop or restart
2348 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
2349
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002350 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002351 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2352 //if state is pause, we need process at resume api. we only record change info
2353 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2354 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2355 if (VALID_PID(segment->pids.video.pid)
2356 && VALID_PID(p_pids->video.pid)
2357 && segment->pids.video.pid != p_pids->video.pid) {
2358 //restart video
Wentao MA270dc0f2022-08-23 13:17:26 +08002359 v_cmd = DVR_PLAYBACK_CMD_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002360 }
2361 if (!VALID_PID(segment->pids.video.pid)
2362 && VALID_PID(p_pids->video.pid)
2363 && segment->pids.video.pid != p_pids->video.pid) {
2364 //start video
Wentao MA270dc0f2022-08-23 13:17:26 +08002365 v_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002366 }
2367 if (VALID_PID(segment->pids.video.pid)
2368 && !VALID_PID(p_pids->video.pid)
2369 && segment->pids.video.pid != p_pids->video.pid) {
2370 //stop video
Wentao MA270dc0f2022-08-23 13:17:26 +08002371 v_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002372 }
2373 if (VALID_PID(segment->pids.audio.pid)
2374 && VALID_PID(p_pids->audio.pid)
2375 && segment->pids.audio.pid != p_pids->audio.pid) {
2376 //restart audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002377 a_cmd = DVR_PLAYBACK_CMD_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002378 }
2379 if (!VALID_PID(segment->pids.audio.pid)
2380 && VALID_PID(p_pids->audio.pid)
2381 && segment->pids.audio.pid != p_pids->audio.pid) {
2382 //start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002383 a_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002384 }
2385 if (VALID_PID(segment->pids.audio.pid)
2386 && !VALID_PID(p_pids->audio.pid)
2387 && segment->pids.audio.pid != p_pids->audio.pid) {
2388 //stop audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002389 a_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08002390 }
2391 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2392 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2393 //do nothing
2394 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2395 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2396 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2397 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2398 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2399 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002400 if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
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_AV_RESTART;
2404 }else if (v_cmd == DVR_PLAYBACK_CMD_V_RESTART
2405 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002406 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002407 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002408 } else {
2409 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002410 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002411 }
2412
Wentao MA270dc0f2022-08-23 13:17:26 +08002413 if (v_cmd == DVR_PLAYBACK_CMD_V_START
2414 && (a_cmd == DVR_PLAYBACK_CMD_A_RESTART)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002415 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002416 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START_A_RESTART;
2417 } else if (v_cmd == DVR_PLAYBACK_CMD_V_START
2418 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002419 //not occur this case
2420 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2421 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2422 } else {
2423 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002424 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP_V_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08002425 }
2426
Wentao MA270dc0f2022-08-23 13:17:26 +08002427 if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2428 && a_cmd == DVR_PLAYBACK_CMD_A_START) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002429 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002430 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_START;
2431 } else if (v_cmd == DVR_PLAYBACK_CMD_V_STOP
2432 && a_cmd == DVR_PLAYBACK_CMD_A_RESTART) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002433 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002434 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP_A_RESTART;
hualing chen5cbe1a62020-02-10 16:36:36 +08002435 } else {
2436 //not occur this case
2437 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2438 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2439 }
2440 }
2441 }
hualing chene10666f2020-04-14 13:58:37 +08002442 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002443 }
hualing chen86e7d482020-01-16 15:13:33 +08002444 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002445 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002446 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002447 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002448 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002449 }
hualing chen86e7d482020-01-16 15:13:33 +08002450 }
Wentao MA96f68962022-06-15 19:45:35 +08002451 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002452 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002453 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002454}
2455/**\brief Stop play, will stop video and audio
2456 * \param[in] handle playback handle
2457 * \param[in] clear is clear last frame
2458 * \retval DVR_SUCCESS On success
2459 * \return Error code
2460 */
hualing chen040df222020-01-17 13:35:02 +08002461int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2462 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002463 DVR_UNUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002464 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002465 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002466 return DVR_FAILURE;
2467 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002468 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002469 DVR_PB_INFO(":playback is stoped");
hualing chenb96aa2c2020-04-15 14:13:53 +08002470 return DVR_SUCCESS;
2471 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002472 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002473 DVR_PB_INFO(":playback is stoped");
Ke Gong3c0caba2020-04-21 22:58:18 -07002474 return DVR_SUCCESS;
2475 }
hualing chen87072a82020-03-12 16:20:12 +08002476 _stop_playback_thread(handle);
Wentao MA96f68962022-06-15 19:45:35 +08002477 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002478 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002479 DVR_PB_INFO(":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002480 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002481 if (player->has_video) {
2482 AmTsPlayer_resumeVideoDecoding(player->handle);
2483 }
2484 if (player->has_audio) {
2485 AmTsPlayer_resumeAudioDecoding(player->handle);
2486 }
2487 if (player->has_video) {
2488 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002489 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002490 AmTsPlayer_stopVideoDecoding(player->handle);
2491 }
2492 if (player->has_audio) {
2493 player->has_audio = DVR_FALSE;
2494 AmTsPlayer_stopAudioDecoding(player->handle);
2495 }
hualing chendf118dd2020-05-21 15:49:11 +08002496 if (player->has_ad_audio) {
2497 player->has_ad_audio =DVR_FALSE;
2498 AmTsPlayer_disableADMix(player->handle);
2499 }
hualing chen266b9502020-04-04 17:39:39 +08002500
hualing chen86e7d482020-01-16 15:13:33 +08002501 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002502 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2503 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002504 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
hualing chen87072a82020-03-12 16:20:12 +08002505 player->cur_segment_id = UINT64_MAX;
2506 player->segment_is_open = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08002507 DVR_PB_DEBUG("unlock");
2508 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002509 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002510 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002511}
2512/**\brief Start play audio
2513 * \param[in] handle playback handle
2514 * \param[in] params audio playback params,contains fmt and pid...
2515 * \retval DVR_SUCCESS On success
2516 * \return Error code
2517 */
hualing chen2aba4022020-03-02 13:49:55 +08002518
Wentao MA270dc0f2022-08-23 13:17:26 +08002519int 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 +08002520 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002521
2522 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002523 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002524 return DVR_FAILURE;
2525 }
hualing chen86e7d482020-01-16 15:13:33 +08002526 _start_playback_thread(handle);
2527 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002528 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002529 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002530
Wentao MA270dc0f2022-08-23 13:17:26 +08002531 if (VALID_PID(ad_param->pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08002532 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002533 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002534 AmTsPlayer_setADParams(player->handle, ad_param);
hualing chendf118dd2020-05-21 15:49:11 +08002535 AmTsPlayer_enableADMix(player->handle);
2536 }
hualing chen969fe7b2021-05-26 15:13:17 +08002537 if (VALID_PID(param->pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08002538 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08002539 player->has_audio = DVR_TRUE;
2540 AmTsPlayer_setAudioParams(player->handle, param);
Wentao MA5629ad82022-08-24 10:03:02 +08002541 if (player->audio_presentation_id > -1) {
2542 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2543 }
hualing chen969fe7b2021-05-26 15:13:17 +08002544 AmTsPlayer_startAudioDecoding(player->handle);
2545 }
hualing chendf118dd2020-05-21 15:49:11 +08002546
hualing chen86e7d482020-01-16 15:13:33 +08002547 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002548 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen040df222020-01-17 13:35:02 +08002549 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002550 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002551 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002552 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002553 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002554}
2555/**\brief Stop play audio
2556 * \param[in] handle playback handle
2557 * \retval DVR_SUCCESS On success
2558 * \return Error code
2559 */
hualing chen040df222020-01-17 13:35:02 +08002560int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2561 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002562
2563 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002564 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002565 return DVR_FAILURE;
2566 }
2567
hualing chen2aba4022020-03-02 13:49:55 +08002568 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002569 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002570 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002571 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002572 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002573 _stop_playback_thread(handle);
2574 } else {
2575 //do nothing.video is playing
2576 }
Wentao MA96f68962022-06-15 19:45:35 +08002577 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002578 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002579
hualing chenf00cdc82020-06-10 14:23:35 +08002580 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002581 player->has_audio = DVR_FALSE;
2582 AmTsPlayer_stopAudioDecoding(player->handle);
2583 }
hualing chen87072a82020-03-12 16:20:12 +08002584
hualing chendf118dd2020-05-21 15:49:11 +08002585 if (player->has_ad_audio) {
2586 player->has_ad_audio =DVR_FALSE;
2587 AmTsPlayer_disableADMix(player->handle);
2588 }
2589
hualing chen87072a82020-03-12 16:20:12 +08002590 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002591 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002592
Wentao MA96f68962022-06-15 19:45:35 +08002593 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002594 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002595 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002596}
2597/**\brief Start play video
2598 * \param[in] handle playback handle
2599 * \param[in] params video playback params,contains fmt and pid...
2600 * \retval DVR_SUCCESS On success
2601 * \return Error code
2602 */
hualing chen2aba4022020-03-02 13:49:55 +08002603int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002604 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002605
2606 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002607 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002608 return DVR_FAILURE;
2609 }
2610
hualing chen86e7d482020-01-16 15:13:33 +08002611 _start_playback_thread(handle);
2612 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002613 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002614 dvr_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002615 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002616 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002617 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002618 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002619
2620 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002621 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002622 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08002623 DVR_PB_INFO("settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002624 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2625 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002626 }
2627 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002628 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_START;
hualing chen040df222020-01-17 13:35:02 +08002629 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002630 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002631 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002632 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002633 return DVR_SUCCESS;
2634}
2635/**\brief Stop play video
2636 * \param[in] handle playback handle
2637 * \retval DVR_SUCCESS On success
2638 * \return Error code
2639 */
hualing chen040df222020-01-17 13:35:02 +08002640int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2641 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002642
2643 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002644 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002645 return DVR_FAILURE;
2646 }
2647
hualing chen86e7d482020-01-16 15:13:33 +08002648 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002649 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
Wentao MA907b6432022-08-01 06:23:08 +00002650 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_STOP);
Wentao MA9a164002022-08-29 11:20:24 +08002651 //destroy thread
hualing chen86e7d482020-01-16 15:13:33 +08002652 _stop_playback_thread(handle);
2653 } else {
2654 //do nothing.audio is playing
2655 }
hualing chen7a56cba2020-04-14 14:09:27 +08002656
Wentao MA96f68962022-06-15 19:45:35 +08002657 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002658 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002659
hualing chen87072a82020-03-12 16:20:12 +08002660 player->has_video = DVR_FALSE;
2661
2662 AmTsPlayer_stopVideoDecoding(player->handle);
2663 //playback_device_video_stop(player->handle);
2664
2665 player->cmd.last_cmd = player->cmd.cur_cmd;
Wentao MA270dc0f2022-08-23 13:17:26 +08002666 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_V_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002667
Wentao MA96f68962022-06-15 19:45:35 +08002668 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002669 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002670 return DVR_SUCCESS;
2671}
2672/**\brief Pause play
2673 * \param[in] handle playback handle
2674 * \param[in] flush whether its internal buffers should be flushed
2675 * \retval DVR_SUCCESS On success
2676 * \return Error code
2677 */
hualing chen040df222020-01-17 13:35:02 +08002678int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2679 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002680 DVR_UNUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002681 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002682 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002683 return DVR_FAILURE;
2684 }
hualing chenf00cdc82020-06-10 14:23:35 +08002685 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
Wentao MA96f68962022-06-15 19:45:35 +08002686 DVR_PB_INFO("player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002687 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002688 }
Wentao MA96f68962022-06-15 19:45:35 +08002689 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002690 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002691 DVR_PB_DEBUG("get lock");
hualing chen266b9502020-04-04 17:39:39 +08002692 if (player->has_video)
2693 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002694 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002695 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002696
2697 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002698 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2699 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2700 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002701 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002702 } else {
2703 player->cmd.last_cmd = player->cmd.cur_cmd;
2704 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2705 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00002706 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
hualing chen87072a82020-03-12 16:20:12 +08002707 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002708 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002709 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002710
hualing chen86e7d482020-01-16 15:13:33 +08002711 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002712}
2713
hualing chen5cbe1a62020-02-10 16:36:36 +08002714//not add lock
2715static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2716{
2717 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2718
hualing chena540a7e2020-03-27 16:44:05 +08002719 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002720 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002721 return DVR_FAILURE;
2722 }
2723
hualing chen5cbe1a62020-02-10 16:36:36 +08002724 //get video params and audio params
Wentao MA96f68962022-06-15 19:45:35 +08002725 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002726 dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08002727 am_tsplayer_video_params video_params;
2728 am_tsplayer_audio_params audio_params;
2729 am_tsplayer_audio_params ad_params;
hualing chencc91e1c2020-02-28 13:26:17 +08002730 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002731
Wentao MA270dc0f2022-08-23 13:17:26 +08002732 memset(&video_params, 0, sizeof(video_params));
2733 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002734
Wentao MA270dc0f2022-08-23 13:17:26 +08002735 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
Wentao MA96f68962022-06-15 19:45:35 +08002736 DVR_PB_INFO("unlock cmd: %d", cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002737 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002738
2739 switch (cmd) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002740 case DVR_PLAYBACK_CMD_AV_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002741 //av restart
Wentao MA270dc0f2022-08-23 13:17:26 +08002742 DVR_PB_INFO("do_cmd av_restart");
hualing chen87072a82020-03-12 16:20:12 +08002743 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002744 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002745 case DVR_PLAYBACK_CMD_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002746 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002747 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002748 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002749 case DVR_PLAYBACK_CMD_V_START:
2750 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002751 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002752 case DVR_PLAYBACK_CMD_V_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002753 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002754 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002755 case DVR_PLAYBACK_CMD_A_RESTART:
hualing chen5cbe1a62020-02-10 16:36:36 +08002756 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002757 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002758 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002759 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002760 case DVR_PLAYBACK_CMD_A_START:
2761 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002762 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002763 case DVR_PLAYBACK_CMD_A_STOP:
hualing chen2aba4022020-03-02 13:49:55 +08002764 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002765 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002766 case DVR_PLAYBACK_CMD_A_STOP_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002767 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2768 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002769 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002770 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002771 case DVR_PLAYBACK_CMD_A_STOP_V_START:
hualing chen2aba4022020-03-02 13:49:55 +08002772 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002773 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002774 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002775 case DVR_PLAYBACK_CMD_V_STOP_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002776 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2777 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002778 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002779 break;
2780 case DVR_PLAYBACK_CMD_STOP:
2781 break;
2782 case DVR_PLAYBACK_CMD_START:
2783 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002784 case DVR_PLAYBACK_CMD_A_START_V_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002785 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002786 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2787 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002788 break;
Wentao MA270dc0f2022-08-23 13:17:26 +08002789 case DVR_PLAYBACK_CMD_V_START_A_RESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002790 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
Wentao MA270dc0f2022-08-23 13:17:26 +08002791 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &video_params);
2792 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08002793 break;
2794 case DVR_PLAYBACK_CMD_FF:
2795 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002796 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002797 break;
2798 default:
2799 break;
2800 }
2801 return DVR_SUCCESS;
2802}
2803
2804/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002805 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002806 * \retval DVR_SUCCESS On success
2807 * \return Error code
2808 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002809int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2810 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002811 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002812 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002813 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002814 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002815 return DVR_FAILURE;
2816 }
2817
hualing chena991aa82021-08-16 10:21:15 +08002818 if (dvr_playback_check_limit(handle)) {
2819 //get id and pos to check if we can seek to this pos
Wentao MA96f68962022-06-15 19:45:35 +08002820 DVR_PB_INFO("player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002821 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2822 if (segmentid != player->cur_segment_id ||
2823 (segmentid == player->cur_segment_id &&
2824 pos > _dvr_get_cur_time(handle))) {
2825 //first to seek new pos and to resume
Wentao MA96f68962022-06-15 19:45:35 +08002826 DVR_PB_INFO("seek new pos and to resume");
hualing chena991aa82021-08-16 10:21:15 +08002827 dvr_playback_seek(handle, segmentid, pos);
2828 }
hualing chen7ea70a72021-09-09 11:25:13 +08002829 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002830 DVR_PB_INFO("player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002831 }
hualing chena991aa82021-08-16 10:21:15 +08002832
hualing chen5cbe1a62020-02-10 16:36:36 +08002833 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08002834 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002835 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002836 player->first_frame = 0;
2837 if (player->has_video)
2838 AmTsPlayer_pauseVideoDecoding(player->handle);
2839 if (player->has_audio)
2840 AmTsPlayer_pauseAudioDecoding(player->handle);
2841
hualing chen266b9502020-04-04 17:39:39 +08002842 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002843 DVR_PB_INFO("dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002844 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2845 AmTsPlayer_resumeVideoDecoding(player->handle);
2846 }
2847 if (player->has_audio) {
2848 AmTsPlayer_resumeAudioDecoding(player->handle);
2849 }
2850 //check is has audio param,if has audio .we need start audio,
2851 //we will stop audio when ff fb, if reach end, we will pause.so we need
2852 //start audio when resume play
2853
Wentao MA270dc0f2022-08-23 13:17:26 +08002854 am_tsplayer_video_params video_params;
2855 am_tsplayer_audio_params audio_params;
2856 am_tsplayer_audio_params ad_params;
hualing chen266b9502020-04-04 17:39:39 +08002857 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002858
Wentao MA270dc0f2022-08-23 13:17:26 +08002859 memset(&video_params, 0, sizeof(video_params));
2860 memset(&audio_params, 0, sizeof(audio_params));
2861 _dvr_playback_get_playinfo(handle, segmentid, &video_params, &audio_params, &ad_params);
hualing chen266b9502020-04-04 17:39:39 +08002862 //valid audio pid, start audio
Wentao MA270dc0f2022-08-23 13:17:26 +08002863 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 +08002864 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002865 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08002866 dvr_playback_change_seek_state(handle, ad_params.pid);
2867 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chen969fe7b2021-05-26 15:13:17 +08002868 AmTsPlayer_enableADMix(player->handle);
2869 }
2870
Wentao MA270dc0f2022-08-23 13:17:26 +08002871 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 +08002872 player->has_audio = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08002873 dvr_playback_change_seek_state(handle, audio_params.pid);
2874 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08002875 if (player->audio_presentation_id > -1) {
2876 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
2877 }
hualing chen266b9502020-04-04 17:39:39 +08002878 AmTsPlayer_startAudioDecoding(player->handle);
2879 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08002880 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 +08002881 }
hualing chendf118dd2020-05-21 15:49:11 +08002882
hualing chen87072a82020-03-12 16:20:12 +08002883 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2884 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2885 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002886 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002887 } else {
2888 player->cmd.last_cmd = player->cmd.cur_cmd;
2889 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2890 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002891 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen87072a82020-03-12 16:20:12 +08002892 }
Wentao MA96f68962022-06-15 19:45:35 +08002893 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002894 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002895 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
Wentao MA96f68962022-06-15 19:45:35 +08002896 DVR_PB_INFO("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002897 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002898 player->first_frame = 0;
2899 if (player->has_video)
2900 AmTsPlayer_pauseVideoDecoding(player->handle);
2901 if (player->has_audio)
2902 AmTsPlayer_pauseAudioDecoding(player->handle);
2903
hualing chene41f4372020-06-06 16:29:17 +08002904 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002905 DVR_PB_INFO("dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002906 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002907 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002908 }
hualing chen041c4092020-04-05 15:11:50 +08002909 if (player->has_audio)
2910 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002911 DVR_PB_INFO("set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen9811b212020-10-29 11:21:44 +08002912 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2913 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chend1686e52022-01-05 17:10:42 +08002914 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00002915 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
Wentao MA96f68962022-06-15 19:45:35 +08002916 DVR_PB_INFO("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002917 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002918 } else {
2919 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2920 {
Wentao MA96f68962022-06-15 19:45:35 +08002921 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002922 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002923 player->first_frame = 0;
2924 if (player->has_video)
2925 AmTsPlayer_pauseVideoDecoding(player->handle);
2926 if (player->has_audio)
2927 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002928 //clear flag
Wentao MA96f68962022-06-15 19:45:35 +08002929 DVR_PB_INFO("clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002930 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2931 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002932 if (player->has_video) {
2933 AmTsPlayer_resumeVideoDecoding(player->handle);
2934 }
2935 if (player->has_audio)
2936 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002937 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002938 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002939 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002940 }
2941 return DVR_SUCCESS;
2942}
2943
hualing chena540a7e2020-03-27 16:44:05 +08002944static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2945
2946 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2947 DVR_PlaybackSegmentInfo_t *segment = NULL;
2948 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2949 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2950
2951 list_for_each_entry(segment, &player->segment_list, head)
2952 {
2953 if (segment->segment_id == segment_id) {
2954 cur_segment = segment;
2955 }
2956 if (segment->segment_id == set_seg_id) {
2957 set_segment = segment;
2958 }
2959 if (cur_segment != NULL && set_segment != NULL) {
2960 break;
2961 }
2962 }
2963 if (cur_segment == NULL || set_segment == NULL) {
Wentao MA270dc0f2022-08-23 13:17:26 +08002964 DVR_PB_INFO("set segment or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002965 return DVR_TRUE;
2966 }
2967 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2968 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2969 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2970 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
Wentao MA96f68962022-06-15 19:45:35 +08002971 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 +08002972 return DVR_TRUE;
2973 }
Wentao MA96f68962022-06-15 19:45:35 +08002974 DVR_PB_INFO("play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002975 return DVR_FALSE;
2976}
2977
hualing chen03fd4942021-07-15 15:56:41 +08002978/**\brief set limit
2979 * \param[in] handle playback handle
2980 * \param[in] rec start time ms
2981 * \param[in] rec limit time ms
2982 * \retval DVR_SUCCESS On success
2983 * \return Error code
2984 */
hualing chen7ea70a72021-09-09 11:25:13 +08002985int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08002986{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2987
2988 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002989 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08002990 return DVR_FAILURE;
2991 }
hualing chen7ea70a72021-09-09 11:25:13 +08002992 _dvr_getClock_sec();
Wentao MA96f68962022-06-15 19:45:35 +08002993 DVR_PB_INFO("lock time %lu limit: %u player->state:%d", time, limit, player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002994 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002995 player->rec_start = time;
2996 player->limit = limit;
Wentao MA96f68962022-06-15 19:45:35 +08002997 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002998 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002999 return DVR_SUCCESS;
3000}
3001
hualing chen5cbe1a62020-02-10 16:36:36 +08003002/**\brief seek
3003 * \param[in] handle playback handle
3004 * \param[in] time_offset time offset base cur segment
3005 * \retval DVR_SUCCESS On success
3006 * \return Error code
3007 */
hualing chencc91e1c2020-02-28 13:26:17 +08003008int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08003009 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08003010 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08003011 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003012 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003013 return DVR_FAILURE;
3014 }
3015
Wentao MA96f68962022-06-15 19:45:35 +08003016 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 +08003017 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003018
hualing chen86e7d482020-01-16 15:13:33 +08003019 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08003020 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
Wentao MA96f68962022-06-15 19:45:35 +08003021 DVR_PB_INFO("player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08003022
hualing chen5cbe1a62020-02-10 16:36:36 +08003023 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08003024 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08003025 if (ret ==DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +08003026 DVR_PB_INFO("unlock seek error at open segment");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003027 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003028 return DVR_FAILURE;
3029 }
3030 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
3031 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08003032 DVR_PB_INFO("is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08003033 time_offset = _dvr_get_end_time(handle);
3034 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003035 DVR_PB_INFO("is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08003036 time_offset = _dvr_get_end_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08003037 ret = DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08003038 }
3039 }
3040
Wentao MA96f68962022-06-15 19:45:35 +08003041 DVR_PB_INFO("seek open id[%lld]flag[0x%x] time_offset %u",
hualing chen03fd4942021-07-15 15:56:41 +08003042 player->cur_segment.segment_id,
3043 player->cur_segment.flags,
3044 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08003045 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08003046 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3047 //forward playback.not seek end of file
3048 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
3049 //default -2000ms
3050 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
3051 }
hualing chen86e7d482020-01-16 15:13:33 +08003052 }
Wentao MA01de0e62022-01-10 18:48:23 +08003053 // Seek can be regarded as a new playback, so keep the start segment_id for it also
hualing chen8a657f32021-08-30 13:12:49 +08003054 if (player->need_seek_start == DVR_TRUE) {
3055 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
Wentao MA01de0e62022-01-10 18:48:23 +08003056 player->first_start_id = player->cur_segment.segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08003057 }
hualing chen2aba4022020-03-02 13:49:55 +08003058 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08003059 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08003060 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08003061 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08003062 DVR_PB_ERROR("seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08003063 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08003064 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08003065
hualing chen2aba4022020-03-02 13:49:55 +08003066 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08003067
3068 player->last_send_time_id = UINT64_MAX;
Wentao MA270dc0f2022-08-23 13:17:26 +08003069 player->last_segment_total = 0LL;
hualing chen03fd4942021-07-15 15:56:41 +08003070 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08003071 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08003072 player->fffb_current = _dvr_time_getClock();
3073 player->fffb_start = player->fffb_current;
3074 player->fffb_start_pcr = _dvr_get_cur_time(handle);
3075 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08003076 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08003077 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003078 //only seek file,not start
Wentao MA96f68962022-06-15 19:45:35 +08003079 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003080 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003081 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08003082 }
hualing chen86e7d482020-01-16 15:13:33 +08003083 //stop play
Wentao MA96f68962022-06-15 19:45:35 +08003084 DVR_PB_ERROR("seek stop play, not inject data has video[%d]audio[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003085 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08003086
hualing chen266b9502020-04-04 17:39:39 +08003087 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08003088 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003089 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003090 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003091 }
3092
hualing chen40dd5462021-11-26 19:56:20 +08003093
hualing chen266b9502020-04-04 17:39:39 +08003094 if (player->has_audio) {
3095 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003096 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003097 }
hualing chendf118dd2020-05-21 15:49:11 +08003098 if (player->has_ad_audio) {
3099 player->has_ad_audio =DVR_FALSE;
3100 AmTsPlayer_disableADMix(player->handle);
3101 }
3102
hualing chen86e7d482020-01-16 15:13:33 +08003103 //start play
Wentao MA270dc0f2022-08-23 13:17:26 +08003104 am_tsplayer_video_params video_params;
3105 am_tsplayer_audio_params audio_params;
3106 am_tsplayer_audio_params ad_params;
hualing chenb31a6c62020-01-13 17:27:00 +08003107
Wentao MA270dc0f2022-08-23 13:17:26 +08003108 memset(&video_params, 0, sizeof(video_params));
3109 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003110
hualing chen040df222020-01-17 13:35:02 +08003111 player->cur_segment_id = segment_id;
3112
3113 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08003114 //get segment info and audio video pid fmt ;
Wentao MA270dc0f2022-08-23 13:17:26 +08003115 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen86e7d482020-01-16 15:13:33 +08003116 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003117 if (video_params.pid != player->fake_pid && !VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chena5f03222021-12-02 11:22:35 +08003118 //audio and video pid is all invalid, return error.
Wentao MA270dc0f2022-08-23 13:17:26 +08003119 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 +08003120 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08003121 return -1;
3122 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003123 DVR_PB_ERROR("seek start[0x%x]", video_params.pid);
hualing chen86e7d482020-01-16 15:13:33 +08003124 //add
hualing chen040df222020-01-17 13:35:02 +08003125 if (sync == DVR_PLAYBACK_SYNC) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003126 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003127 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08003128 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08003129 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08003130 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08003131 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003132 //if is pause state. we need set trick mode.
Wentao MA96f68962022-06-15 19:45:35 +08003133 DVR_PB_INFO("seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003134 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08003135 }
Wentao MA96f68962022-06-15 19:45:35 +08003136 DVR_PB_INFO("start video");
Wentao MA270dc0f2022-08-23 13:17:26 +08003137 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003138 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003139 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08003140 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
3141 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
3142 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
3143 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
3144 AmTsPlayer_stopFast(player->handle);
3145 }
hualing chen266b9502020-04-04 17:39:39 +08003146 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08003147 } else {
3148 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08003149 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003150 if (VALID_PID(ad_params.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08003151 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003152 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003153 dvr_playback_change_seek_state(handle, ad_params.pid);
3154 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003155 AmTsPlayer_enableADMix(player->handle);
3156 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003157 if (VALID_PID(audio_params.pid) && player->speed == 1.0) {
Wentao MA96f68962022-06-15 19:45:35 +08003158 DVR_PB_INFO("start audio seek");
Wentao MA270dc0f2022-08-23 13:17:26 +08003159 dvr_playback_change_seek_state(handle, audio_params.pid);
3160 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003161 if (player->audio_presentation_id > -1) {
3162 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3163 }
hualing chen969fe7b2021-05-26 15:13:17 +08003164 AmTsPlayer_startAudioDecoding(player->handle);
3165 player->has_audio = DVR_TRUE;
3166 }
hualing chen43a89bc2022-01-19 14:31:20 +08003167#ifdef AVSYNC_USED_PCR
3168 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003169 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003170 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3171 }
3172#endif
hualing chen86e7d482020-01-16 15:13:33 +08003173 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003174 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen2aba4022020-03-02 13:49:55 +08003175 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
Wentao MA907b6432022-08-01 06:23:08 +00003176 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_PAUSE);
Wentao MA270dc0f2022-08-23 13:17:26 +08003177 if (VALID_PID(audio_params.pid) || VALID_PID(video_params.pid))
hualing chena5f03222021-12-02 11:22:35 +08003178 player->seek_pause = DVR_TRUE;
Wentao MA270dc0f2022-08-23 13:17:26 +08003179 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 +08003180 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3181 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08003182 player->speed > 1.0f||
3183 player->speed <= -1.0f) {
Wentao MA96f68962022-06-15 19:45:35 +08003184 DVR_PB_INFO("not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003185 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003186 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003187 DVR_PB_INFO("set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003188 player->cmd.last_cmd = player->cmd.cur_cmd;
3189 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3190 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003191 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen2aba4022020-03-02 13:49:55 +08003192 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003193 player->last_send_time_id = UINT64_MAX;
Wentao MA96f68962022-06-15 19:45:35 +08003194 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003195 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003196
3197 return DVR_SUCCESS;
3198}
hualing chen5cbe1a62020-02-10 16:36:36 +08003199
Wentao MAac5ea062022-08-11 11:44:27 +08003200// Get current playback time position of the ongoing segment.
3201// Notice the return value may be negative. This is because previous segment's
3202// data cached in demux buffer need to be considered.
hualing chen5cbe1a62020-02-10 16:36:36 +08003203static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3204 //get cur time of segment
3205 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003206
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003207 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003208 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003209 return DVR_FAILURE;
3210 }
3211
Wentao MA270dc0f2022-08-23 13:17:26 +08003212 int64_t cache = 0;//default es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003213 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003214 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003215 uint64_t cur = 0;
3216 if (player->ts_cache_len > 0 && pos < 0) {
3217 //this case is open new segment end,but cache data is last segment.
3218 //we need used last segment len to send play time.
3219 cur = 0;
3220 } else {
3221 cur = segment_tell_position_time(player->r_handle, pos);
3222 }
hualing chen21a40372021-10-29 11:07:26 +08003223 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003224 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08003225 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 +08003226 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3227 cache = 0;
3228 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003229 int cur_time = (int)(cur > cache ? cur - cache : 0);
3230 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003231}
3232
Wentao MAac5ea062022-08-11 11:44:27 +08003233// Get current playback time position of the ongoing segment.
3234// Notice the return value may be negative. This is because previous segment's
3235// data cached in demux buffer need to be considered.
hualing chen969fe7b2021-05-26 15:13:17 +08003236static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3237 //get cur time of segment
3238 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3239
hualing chen03fd4942021-07-15 15:56:41 +08003240 if (player == NULL || player->handle == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003241 DVR_PB_INFO("player is NULL");
hualing chen969fe7b2021-05-26 15:13:17 +08003242 return DVR_FAILURE;
3243 }
3244
Wentao MA270dc0f2022-08-23 13:17:26 +08003245 int64_t cache = 0;//default es buf cache 500ms
hualing chen969fe7b2021-05-26 15:13:17 +08003246 int cur_time = 0;
hualing chen969fe7b2021-05-26 15:13:17 +08003247 pthread_mutex_lock(&player->segment_lock);
hualing chena5f03222021-12-02 11:22:35 +08003248 loff_t tmp_pos = segment_tell_position(player->r_handle);
3249 loff_t pos = tmp_pos - player->ts_cache_len;
3250 uint64_t cur = 0;
3251 if (player->ts_cache_len > 0 && (tmp_pos < player->ts_cache_len)) {
3252 //this case is open new segment end,but cache data is last segment.
3253 //we need used last segment len to send play time.
3254 cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003255 DVR_PB_INFO("change segment [%lld][%lld]",
hualing chen926a8ec2021-12-20 20:38:24 +08003256 player->last_segment_id, player->cur_segment_id);
hualing chena5f03222021-12-02 11:22:35 +08003257 } else {
3258 cur = segment_tell_position_time(player->r_handle, pos);
3259 }
hualing chen21a40372021-10-29 11:07:26 +08003260 AmTsPlayer_getDelayTime(player->handle, &cache);
Wentao MAaf716972021-12-28 13:28:52 +08003261
hualing chen969fe7b2021-05-26 15:13:17 +08003262 pthread_mutex_unlock(&player->segment_lock);
Wentao MA01de0e62022-01-10 18:48:23 +08003263
3264 // The idea here is to work around a weakness of AmTsPlayer_getDelayTime at
3265 // starting phase of a playback in a short period of 20ms or less. During the
3266 // said period, getDelayTime does NOT work as expect to return real cache
3267 // length because demux isn't actually running to provide valid pts to
3268 // TsPlayer. "cache==0" implies the situation that playback is NOT actually
3269 // started. Under such conditions a '0' cache size may NOT reflect actual data
3270 // length remaining in TsPlayer cache, therefore corresponding libdvr 'cur' is
3271 // useless if data in TsPlayer cache is not considered, so it needs to be
Wentao MA270dc0f2022-08-23 13:17:26 +08003272 // reset to a previous valid state. To make the reset operation stricter, extra
Wentao MA01de0e62022-01-10 18:48:23 +08003273 // AmTsPlayer_getPts invocations on both video/audio are introduced to test if
3274 // TsPlayer can get valid pts which indicates the actual running status of
3275 // demux. (JIRA issue: SWPL-68740)
3276 if (player->first_start_id != UINT64_MAX && cache == 0
3277 && player->check_cache_flag == DVR_TRUE ) {
3278 uint64_t pts_a=0;
3279 uint64_t pts_v=0;
3280 AmTsPlayer_getPts(player->handle, TS_STREAM_AUDIO, &pts_a);
3281 AmTsPlayer_getPts(player->handle, TS_STREAM_VIDEO, &pts_v);
3282 if ((int64_t)pts_a <= 0 && (int64_t)pts_v <= 0) {
3283 // Identified the wired situation and just return previous valid state
3284 cur = player->first_start_time;
3285 *id = player->first_start_id;
3286 return cur;
3287 }
3288 }
3289 if (cache != 0) {
3290 // Do NOT permit to enter 'if' code block above any more
3291 player->check_cache_flag=DVR_FALSE;
3292 }
3293
Wentao MA96f68962022-06-15 19:45:35 +08003294 DVR_PB_INFO("***get play cur time [%lld] cache:%lld cur id [%lld]"
3295 " last id [%lld] pb cache len [%d] pos [%lld][%lld]",
hualing chen926a8ec2021-12-20 20:38:24 +08003296 cur,
3297 cache,
3298 player->cur_segment_id,
3299 player->last_send_time_id,
3300 player->ts_cache_len,
3301 pos,
3302 tmp_pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003303 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3304 cache = 0;
3305 }
3306 if (cur > cache) {
3307 cur_time = (int)(cur - cache);
3308 *id = player->cur_segment_id;
Wentao MA270dc0f2022-08-23 13:17:26 +08003309 } else if (player->last_segment_total > 0) {
hualing chend1686e52022-01-05 17:10:42 +08003310 //if at fb mode,we not used last id to replace cur id if cache > cur time.
3311 //this case only used for normal speed or ff speed
3312 if (!IS_FB(player->speed) && player->last_segment_id <= player->cur_segment_id) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003313 if (player->last_segment_total > (cache - cur))
3314 cur_time = (int)(player->last_segment_total - (cache - cur));
hualing chend1686e52022-01-05 17:10:42 +08003315 else
Wentao MA270dc0f2022-08-23 13:17:26 +08003316 cur_time = (int)(player->last_segment_total - cur);
hualing chen8a657f32021-08-30 13:12:49 +08003317
hualing chend1686e52022-01-05 17:10:42 +08003318 *id = player->last_segment_id;
3319 } else {//fb mode
3320 cur_time = (int)(cur);
3321 *id = player->cur_segment_id;
3322 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003323 DVR_PB_INFO("get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_total);
hualing chen969fe7b2021-05-26 15:13:17 +08003324 } else {
3325 cur_time = 0;
3326 *id = player->cur_segment_id;
3327 }
hualing chen969fe7b2021-05-26 15:13:17 +08003328 return cur_time;
3329}
3330
hualing chencc91e1c2020-02-28 13:26:17 +08003331//get current segment current pcr time of read pos
3332static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3333 //get cur time of segment
3334 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003335
3336 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003337 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003338 return DVR_FAILURE;
3339 }
3340
hualing chen2aba4022020-03-02 13:49:55 +08003341 pthread_mutex_lock(&player->segment_lock);
3342 uint64_t end = segment_tell_total_time(player->r_handle);
Wentao MA96f68962022-06-15 19:45:35 +08003343 DVR_PB_INFO("get total time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08003344 pthread_mutex_unlock(&player->segment_lock);
3345 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003346}
3347
hualing chen03fd4942021-07-15 15:56:41 +08003348DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3349{
3350 //check is set limit info
3351 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3352
3353 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003354 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003355 return DVR_FALSE;
3356 }
3357 if (player->rec_start > 0 || player->limit > 0) {
3358 return DVR_TRUE;
3359 }
3360 return DVR_FALSE;
3361}
3362
3363/**\brief set DVR playback calculate expired time len
3364 * \param[in] handle, DVR playback session handle
3365 * \return DVR_SUCCESS on success
3366 * \return error code on failure
3367 */
hualing chen7ea70a72021-09-09 11:25:13 +08003368uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003369{
3370 //calculate expired time to play
3371 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003372 uint32_t cur_time;
3373 uint32_t tmp_time;
3374 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003375 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003376 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003377 return expired;
3378 }
hualing chen7ea70a72021-09-09 11:25:13 +08003379 if (player->rec_start == 0 || player->limit == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003380 DVR_PB_INFO("rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003381 return expired;
3382 }
3383 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003384 cur_time = _dvr_getClock_sec();
3385 if ((cur_time - player->rec_start) > player->limit) {
3386 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3387 expired = *(int*)&tmp_time;
Wentao MA96f68962022-06-15 19:45:35 +08003388 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 +08003389 cur_time,
3390 player->rec_start,
3391 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003392 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3393 }
hualing chen03fd4942021-07-15 15:56:41 +08003394 return expired;
3395}
3396
3397/**\brief set DVR playback obsolete time
3398 * \param[in] handle, DVR playback session handle
3399 * \param[in] obsolete, obsolete len
3400 * \return DVR_SUCCESS on success
3401 * \return error code on failure
3402 */
3403int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3404{
3405 int expired = 0;
3406 //calculate expired time to play
3407 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3408
3409 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003410 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003411 return DVR_FALSE;
3412 }
3413 //get system time
Wentao MA96f68962022-06-15 19:45:35 +08003414 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003415 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003416 player->obsolete = obsolete;
Wentao MA96f68962022-06-15 19:45:35 +08003417 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003418 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003419 return expired;
3420}
3421
3422/**\brief update DVR playback newest segment duration
3423 * \param[in] handle, DVR playback session handle
3424 * \param[in] segmentid, newest segment id
3425 * \param[in] dur dur time ms
3426 * \return DVR_SUCCESS on success
3427 * \return error code on failure
3428 */
3429int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3430uint64_t segmentid, int dur)
3431{
3432 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3433 DVR_PlaybackSegmentInfo_t *segment;
3434 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3435
3436 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003437 DVR_PB_INFO(" player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003438 return DVR_FAILURE;
3439 }
3440 //update the newest segment duration on timeshift mode
3441 list_for_each_entry(segment, &player->segment_list, head)
3442 {
3443 if (segment->segment_id == segmentid) {
3444 segment->duration = dur;
3445 break;
3446 }
3447 pre_segment = segment;
3448 }
3449
3450 return DVR_SUCCESS;
3451}
3452
hualing chen7ea70a72021-09-09 11:25:13 +08003453static uint32_t dvr_playback_calculate_last_valid_segment(
3454 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003455{
hualing chen7ea70a72021-09-09 11:25:13 +08003456 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003457 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003458 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003459 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003460 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003461 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3462
3463 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003464 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003465 return DVR_FAILURE;
3466 }
3467 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003468 if (expired == 0) {
3469 *segmentid = player->cur_segment_id;
3470 *pos = 0;
3471 return DVR_SUCCESS;
3472 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003473 DVR_PlaybackSegmentInfo_t *p_seg;
3474 list_for_each_entry_reverse(p_seg, &player->segment_list, head) {
3475 segment_id = p_seg->segment_id;
hualing chen03fd4942021-07-15 15:56:41 +08003476
Wentao MA270dc0f2022-08-23 13:17:26 +08003477 if ((player->obsolete + pre_off + p_seg->duration) > expired)
hualing chen03fd4942021-07-15 15:56:41 +08003478 break;
3479
Wentao MA270dc0f2022-08-23 13:17:26 +08003480 last_segment_id = p_seg->segment_id;
3481 pre_off += p_seg->duration;
hualing chen03fd4942021-07-15 15:56:41 +08003482 }
3483
3484 if (last_segment_id == segment_id) {
3485 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3486 off = expired;
3487 } else if (player->obsolete >= expired) {
3488 off = 0;
3489 } else {
3490 off = expired - pre_off - player->obsolete;
3491 }
3492 *segmentid = segment_id;
3493 *pos = off;
3494 return DVR_SUCCESS;
3495}
3496
hualing chen4b7c15d2020-04-07 16:13:48 +08003497#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003498//start replay
3499static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3500
3501 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3502 //calculate pcr seek time
3503 int t_diff = 0;
3504 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003505 uint64_t segmentid = 0;
3506 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003507 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003508 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003509 return DVR_FAILURE;
3510 }
3511
hualing chen5cbe1a62020-02-10 16:36:36 +08003512 if (player->fffb_start == -1) {
3513 //set fffb start time ms
3514 player->fffb_start = _dvr_time_getClock();
3515 player->fffb_current = player->fffb_start;
3516 //get segment current time pos
3517 player->fffb_start_pcr = _dvr_get_cur_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003518 DVR_PB_INFO("calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
hualing chen03fd4942021-07-15 15:56:41 +08003519 player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003520 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08003521 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003522 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003523 } else {
3524 player->fffb_current = _dvr_time_getClock();
3525 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003526 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003527 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003528 if (seek_time <= 0) {
3529 //need seek to pre one segment
3530 seek_time = 0;
3531 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003532 //seek segment pos
3533 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003534 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003535 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003536 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3537 //set seek time to 0;
Wentao MA96f68962022-06-15 19:45:35 +08003538 DVR_PB_INFO("segment seek to 0 at fb mode [%d]id[%lld]",
hualing chen03fd4942021-07-15 15:56:41 +08003539 seek_time,
3540 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003541 seek_time = 0;
3542 }
hualing chen03fd4942021-07-15 15:56:41 +08003543 if (IS_FB(player->speed)
3544 && dvr_playback_check_limit(handle)) {
3545 //fb case.check expired time
3546 //get id and pos to check if we can seek to this pos
3547 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3548 //case cur id < segment id
3549 if (player->cur_segment_id < segmentid) {
3550 //expired ts data is player,return error
3551 //
3552 pthread_mutex_unlock(&player->segment_lock);
3553 return 0;
3554 } else if (player->cur_segment_id == segmentid) {
3555 //id is same,compare seek pos
3556 if (seek_time < pos) {
3557 //expired ts data is player,return error
3558 //
3559 pthread_mutex_unlock(&player->segment_lock);
3560 return 0;
3561 }
3562 }
3563 //case can play
3564 }
hualing chen041c4092020-04-05 15:11:50 +08003565 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
3566 seek_time = 0;
3567 }
hualing chen2aba4022020-03-02 13:49:55 +08003568 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003569 } else {
3570 //
Wentao MA96f68962022-06-15 19:45:35 +08003571 DVR_PB_INFO("segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003572 }
Wentao MA96f68962022-06-15 19:45:35 +08003573 DVR_PB_INFO("calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003574 seek_time,
3575 player->speed,
3576 player->cur_segment_id,
3577 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003578 }
hualing chen2aba4022020-03-02 13:49:55 +08003579 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003580}
3581
3582
3583//start replay
3584static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3585 //
3586 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003587
3588 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003589 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003590 return DVR_FAILURE;
3591 }
3592
hualing chen5cbe1a62020-02-10 16:36:36 +08003593 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003594 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08003595 DVR_PB_INFO("fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003596 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003597 AmTsPlayer_stopVideoDecoding(player->handle);
3598 }
3599 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003600 DVR_PB_INFO("fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003601 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003602 AmTsPlayer_stopAudioDecoding(player->handle);
3603 }
hualing chendf118dd2020-05-21 15:49:11 +08003604 if (player->has_ad_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003605 DVR_PB_INFO("fffb stop audio");
hualing chendf118dd2020-05-21 15:49:11 +08003606 player->has_ad_audio =DVR_FALSE;
3607 AmTsPlayer_disableADMix(player->handle);
3608 }
hualing chen2aba4022020-03-02 13:49:55 +08003609
hualing chen5cbe1a62020-02-10 16:36:36 +08003610 //start video and audio
3611
Wentao MA270dc0f2022-08-23 13:17:26 +08003612 am_tsplayer_video_params video_params;
3613 am_tsplayer_audio_params audio_params;
3614 am_tsplayer_audio_params ad_params;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003615
Wentao MA270dc0f2022-08-23 13:17:26 +08003616 memset(&video_params, 0, sizeof(video_params));
3617 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003618
hualing chen87072a82020-03-12 16:20:12 +08003619 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003620
3621 //get segment info and audio video pid fmt ;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003622 //dvr_mutex_lock(&player->lock);
Wentao MA270dc0f2022-08-23 13:17:26 +08003623 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003624 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003625 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
3626 //audio and video pids are all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003627 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003628 return -1;
3629 }
3630
Wentao MA270dc0f2022-08-23 13:17:26 +08003631 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003632 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003633 DVR_PB_INFO("fffb start video");
3634 //DVR_PB_INFO("fffb start video and save last frame");
hualing chen0888c032020-12-18 17:54:57 +08003635 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003636 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003637 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
Wentao MA270dc0f2022-08-23 13:17:26 +08003638 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003639 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003640 AmTsPlayer_startVideoDecoding(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003641 //playback_device_video_start(player->handle , &video_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003642 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003643 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003644 }
hualing chen31140872020-03-25 12:29:26 +08003645 //fffb mode need stop fast;
Wentao MA96f68962022-06-15 19:45:35 +08003646 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003647 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003648 return 0;
3649}
3650
3651static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3652 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003653 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003654 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003655 return DVR_FAILURE;
3656 }
3657
3658 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003659 DVR_PB_INFO("lock speed [%f]", player->speed);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003660 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003661
hualing chen2aba4022020-03-02 13:49:55 +08003662 int seek_time = _dvr_playback_calculate_seekpos(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003663 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 +08003664
hualing chen87072a82020-03-12 16:20:12 +08003665 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3666 //seek time set 0
3667 seek_time = 0;
3668 }
hualing chen041c4092020-04-05 15:11:50 +08003669 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003670 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3671 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003672 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003673 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003674 DVR_PB_DEBUG("unlock");
hualing chen87072a82020-03-12 16:20:12 +08003675 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003676 //send event here and pause
3677 DVR_Play_Notify_t notify;
3678 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003679 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003680 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003681 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08003682 DVR_PB_INFO("*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08003683 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003684 return DVR_SUCCESS;
3685 }
hualing chen2932d372020-04-29 13:44:00 +08003686 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003687 _dvr_init_fffb_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003688 DVR_PB_INFO("*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003689 }
3690 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003691 _dvr_playback_fffb_replay(handle);
3692
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003693 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003694 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003695
hualing chen5cbe1a62020-02-10 16:36:36 +08003696 return DVR_SUCCESS;
3697}
3698
hualing chen87072a82020-03-12 16:20:12 +08003699//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003700static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003701 //
3702 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003703
3704 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003705 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003706 return DVR_FAILURE;
3707 }
3708
hualing chen5cbe1a62020-02-10 16:36:36 +08003709 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003710 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003711 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003712 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003713 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003714 }
3715
3716 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003717 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003718 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003719 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003720 //start video and audio
3721
Wentao MA270dc0f2022-08-23 13:17:26 +08003722 am_tsplayer_video_params video_params;
3723 am_tsplayer_audio_params audio_params;
3724 am_tsplayer_audio_params ad_params;
hualing chen87072a82020-03-12 16:20:12 +08003725 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003726
Wentao MA270dc0f2022-08-23 13:17:26 +08003727 memset(&video_params, 0, sizeof(video_params));
3728 memset(&audio_params, 0, sizeof(audio_params));
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003729
hualing chen5cbe1a62020-02-10 16:36:36 +08003730 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08003731 DVR_PB_INFO("into");
Wentao MA270dc0f2022-08-23 13:17:26 +08003732 _dvr_playback_get_playinfo(handle, segment_id, &video_params, &audio_params, &ad_params);
hualing chen5cbe1a62020-02-10 16:36:36 +08003733 //start audio and video
Wentao MA270dc0f2022-08-23 13:17:26 +08003734 if (!VALID_PID(video_params.pid) && !VALID_PID(audio_params.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003735 //audio and video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003736 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003737 return -1;
3738 }
3739
Wentao MA270dc0f2022-08-23 13:17:26 +08003740 if (VALID_PID(video_params.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003741 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003742 if (trick == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003743 DVR_PB_INFO("settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003744 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003745 }
hualing chen266b9502020-04-04 17:39:39 +08003746 else {
hualing chen2aba4022020-03-02 13:49:55 +08003747 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003748 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003749 AmTsPlayer_setVideoParams(player->handle, &video_params);
hualing chen21a40372021-10-29 11:07:26 +08003750 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003751 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003752 }
hualing chena540a7e2020-03-27 16:44:05 +08003753
3754 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
Wentao MA96f68962022-06-15 19:45:35 +08003755 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08003756 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003757 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003758 } else {
Wentao MA270dc0f2022-08-23 13:17:26 +08003759 if (VALID_PID(ad_params.pid)) {
hualing chendf118dd2020-05-21 15:49:11 +08003760 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003761 DVR_PB_INFO("start ad audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003762 AmTsPlayer_setADParams(player->handle, &ad_params);
hualing chendf118dd2020-05-21 15:49:11 +08003763 AmTsPlayer_enableADMix(player->handle);
3764 }
Wentao MA270dc0f2022-08-23 13:17:26 +08003765 if (VALID_PID(audio_params.pid)) {
hualing chen969fe7b2021-05-26 15:13:17 +08003766 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003767 DVR_PB_INFO("start audio");
Wentao MA270dc0f2022-08-23 13:17:26 +08003768 AmTsPlayer_setAudioParams(player->handle, &audio_params);
Wentao MA5629ad82022-08-24 10:03:02 +08003769 if (player->audio_presentation_id > -1) {
3770 AmTsPlayer_setParams(player->handle, AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &player->audio_presentation_id);
3771 }
hualing chen969fe7b2021-05-26 15:13:17 +08003772 AmTsPlayer_startAudioDecoding(player->handle);
3773 }
hualing chendf118dd2020-05-21 15:49:11 +08003774
Wentao MA96f68962022-06-15 19:45:35 +08003775 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003776 AmTsPlayer_stopFast(player->handle);
3777 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3778 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3779 }
hualing chen43a89bc2022-01-19 14:31:20 +08003780#ifdef AVSYNC_USED_PCR
3781 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003782 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003783 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3784 }
3785#endif
hualing chen2aba4022020-03-02 13:49:55 +08003786 player->cmd.last_cmd = player->cmd.cur_cmd;
3787 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003788 player->cmd.state = DVR_PLAYBACK_STATE_START;
Wentao MA907b6432022-08-01 06:23:08 +00003789 DVR_PLAYER_CHANGE_STATE(player,DVR_PLAYBACK_STATE_START);
hualing chen5cbe1a62020-02-10 16:36:36 +08003790 return 0;
3791}
3792
3793
hualing chenb31a6c62020-01-13 17:27:00 +08003794/**\brief Set play speed
3795 * \param[in] handle playback handle
3796 * \param[in] speed playback speed
3797 * \retval DVR_SUCCESS On success
3798 * \return Error code
3799 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003800int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3801
3802 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003803
3804 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003805 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003806 return DVR_FAILURE;
3807 }
3808
hualing chena540a7e2020-03-27 16:44:05 +08003809 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08003810 DVR_PB_INFO(" func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003811 return DVR_FAILURE;
3812 }
hualing chenf00cdc82020-06-10 14:23:35 +08003813 if (speed.speed.speed == player->cmd.speed.speed.speed) {
Wentao MA96f68962022-06-15 19:45:35 +08003814 DVR_PB_INFO(" func: eq speed [%d]", speed.speed.speed);
hualing chenf00cdc82020-06-10 14:23:35 +08003815 return DVR_SUCCESS;
3816 }
Wentao MA96f68962022-06-15 19:45:35 +08003817 DVR_PB_INFO("lock func: speed [%d]", speed.speed.speed);
hualing chen1679f812021-11-08 15:17:46 +08003818
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003819 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003820 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3821 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3822 player->cmd.last_cmd = player->cmd.cur_cmd;
3823 }
hualing chene41f4372020-06-06 16:29:17 +08003824
hualing chen31140872020-03-25 12:29:26 +08003825 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003826 IS_KERNEL_SPEED(speed.speed.speed) ) {
3827 //case 1. not start play.only set speed
3828 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3829 //only set speed.and return;
3830 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3831 player->cmd.speed.speed = speed.speed;
3832 player->speed = (float)speed.speed.speed/(float)100;
3833 player->fffb_play = DVR_FALSE;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003834 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003835 DVR_PB_DEBUG("unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003836 return DVR_SUCCESS;
3837 }
3838 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003839 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3840 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003841 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003842 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3843 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003844 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003845 AmTsPlayer_stopFast(player->handle);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003846 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003847 DVR_PB_DEBUG("unlock ---\r\n");
Wentao MA270dc0f2022-08-23 13:17:26 +08003848 _dvr_cmd(handle, DVR_PLAYBACK_CMD_A_START);
Wentao MA96f68962022-06-15 19:45:35 +08003849 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003850 dvr_mutex_lock(&player->lock);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003851 } else {
3852 //set play speed and if audio is start, stop audio.
3853 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003854 DVR_PB_INFO("fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003855 AmTsPlayer_stopAudioDecoding(player->handle);
3856 player->has_audio = DVR_FALSE;
3857 }
Wentao MA96f68962022-06-15 19:45:35 +08003858 DVR_PB_INFO("start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003859 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003860 }
hualing chenbcada022020-04-22 14:27:01 +08003861 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003862 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003863 player->cmd.speed.speed = speed.speed;
3864 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA96f68962022-06-15 19:45:35 +08003865 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003866 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003867 return DVR_SUCCESS;
3868 }
hualing chen31140872020-03-25 12:29:26 +08003869 //case 3 fffb mode
3870 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3871 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3872 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003873 DVR_PB_INFO("set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003874 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003875 player->cmd.speed.speed = speed.speed;
3876 player->speed = (float)speed.speed.speed/(float)100;
3877 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003878 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003879 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003880 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003881 return DVR_SUCCESS;
3882 }
3883 }
3884 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003885 IS_KERNEL_SPEED(speed.speed.speed)) {
3886 //case 1. cur speed is kernel support speed,set kernel speed.
3887 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003888 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003889 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3890 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003891 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003892 AmTsPlayer_stopFast(player->handle);
Wentao MA270dc0f2022-08-23 13:17:26 +08003893 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_A_START;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003894 } else {
3895 //set play speed and if audio is start, stop audio.
3896 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003897 DVR_PB_INFO("fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003898 AmTsPlayer_stopAudioDecoding(player->handle);
3899 player->has_audio = DVR_FALSE;
3900 }
Wentao MA96f68962022-06-15 19:45:35 +08003901 DVR_PB_INFO("start fast");
hualing chenf00cdc82020-06-10 14:23:35 +08003902 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003903 }
hualing chena540a7e2020-03-27 16:44:05 +08003904 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003905 player->cmd.speed.speed = speed.speed;
3906 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003907 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003908 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003909 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003910 return DVR_SUCCESS;
3911 }
3912 //case 2 fffb mode
3913 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3914 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3915 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003916 DVR_PB_INFO("set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003917 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003918 player->cmd.speed.speed = speed.speed;
3919 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA270dc0f2022-08-23 13:17:26 +08003920 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
hualing chenbcada022020-04-22 14:27:01 +08003921 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003922 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003923 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003924 return DVR_SUCCESS;
3925 }
hualing chen31140872020-03-25 12:29:26 +08003926 }
hualing chena540a7e2020-03-27 16:44:05 +08003927 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3928 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003929 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003930 } else {
hualing chen31140872020-03-25 12:29:26 +08003931 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003932 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3933 else
3934 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003935 player->fffb_play = DVR_TRUE;
3936 }
3937 DVR_Bool_t init_last_time = DVR_FALSE;
3938 if (player->speed > 0.0f && speed.speed.speed < 0) {
3939 init_last_time = DVR_TRUE;
3940 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3941 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003942 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003943 player->cmd.speed.mode = speed.mode;
3944 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003945 player->speed = (float)speed.speed.speed/(float)100;
3946 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003947 _dvr_init_fffb_t(handle);
3948 if (init_last_time == DVR_TRUE)
3949 player->last_send_time_id = UINT64_MAX;
3950
hualing chen87072a82020-03-12 16:20:12 +08003951 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003952 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3953 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003954 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003955 DVR_PB_INFO("set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003956 _dvr_playback_replay(handle, DVR_FALSE);
3957 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3958 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
Wentao MA270dc0f2022-08-23 13:17:26 +08003959 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AV_RESTART;
Wentao MA96f68962022-06-15 19:45:35 +08003960 DVR_PB_INFO("set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003961 }
Wentao MA96f68962022-06-15 19:45:35 +08003962 DVR_PB_INFO("unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003963 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003964 return DVR_SUCCESS;
3965}
hualing chen2932d372020-04-29 13:44:00 +08003966
hualing chenb31a6c62020-01-13 17:27:00 +08003967/**\brief Get playback status
3968 * \param[in] handle playback handle
3969 * \param[out] p_status playback status
3970 * \retval DVR_SUCCESS On success
3971 * \return Error code
3972 */
hualing chen2932d372020-04-29 13:44:00 +08003973static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3974 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003975//
3976 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003977 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003978 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003979 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003980 return DVR_FAILURE;
3981 }
hualing chen1679f812021-11-08 15:17:46 +08003982 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003983 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003984 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003985 }
3986
hualing chen5cbe1a62020-02-10 16:36:36 +08003987 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003988 //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 +08003989 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3990 player->state == DVR_PLAYBACK_STATE_START) {
3991 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3992 }
hualing chen041c4092020-04-05 15:11:50 +08003993
hualing chencc91e1c2020-02-28 13:26:17 +08003994 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003995 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003996
3997 if (CONTROL_SPEED_ENABLE == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08003998 if (player->con_spe.ply_sta == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003999 DVR_PB_INFO("player dur[%u] sta[%u] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08004000 player->con_spe.ply_dur,
4001 player->con_spe.ply_sta,
4002 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08004003 player->con_spe.ply_sta = p_status->time_cur;
4004 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
4005 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
Wentao MA96f68962022-06-15 19:45:35 +08004006 DVR_PB_INFO("player dur[%u] sta[%u] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004007 player->con_spe.ply_dur,
4008 player->con_spe.ply_sta,
4009 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08004010 player->con_spe.ply_sta = p_status->time_cur;
4011 }
4012
4013 if (player->con_spe.sys_sta == 0) {
4014 player->con_spe.sys_sta = _dvr_time_getClock();
4015 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
4016 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
4017 player->con_spe.sys_sta = _dvr_time_getClock();
4018 }
4019 }
4020
hualing chen4b7c15d2020-04-07 16:13:48 +08004021 if (player->last_send_time_id == UINT64_MAX) {
4022 player->last_send_time_id = player->cur_segment_id;
4023 player->last_cur_time = p_status->time_cur;
4024 }
4025 if (player->last_send_time_id == player->cur_segment_id) {
4026 if (player->speed > 0.0f ) {
4027 //ff
4028 if (p_status->time_cur < player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004029 DVR_PB_INFO("get ff time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004030 player->last_cur_time,
4031 p_status->time_cur,
4032 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08004033 p_status->time_cur = player->last_cur_time;
4034 } else {
4035 player->last_cur_time = p_status->time_cur;
4036 }
hualing chene41f4372020-06-06 16:29:17 +08004037 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08004038 //fb
4039 if (p_status->time_cur > player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08004040 DVR_PB_INFO("get fb time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08004041 player->last_cur_time,
4042 p_status->time_cur,
4043 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08004044 p_status->time_cur = player->last_cur_time;
4045 } else {
4046 player->last_cur_time = p_status->time_cur;
4047 }
4048 }
hualing chend241c7a2021-06-22 13:34:27 +08004049 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08004050 player->last_cur_time = p_status->time_cur;
4051 }
hualing chen969fe7b2021-05-26 15:13:17 +08004052 player->last_send_time_id = segment_id;
4053 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08004054
hualing chen5cbe1a62020-02-10 16:36:36 +08004055 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08004056 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08004057 p_status->flags = player->cur_segment.flags;
Wentao MA96f68962022-06-15 19:45:35 +08004058 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 +08004059 _dvr_playback_state_toString(player->state),
4060 _dvr_playback_state_toString(p_status->state),
4061 p_status->time_cur, p_status->time_end,
4062 p_status->segment_id,player->play_flag,
4063 player->speed,
4064 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08004065 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08004066 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004067 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08004068 }
hualing chen2932d372020-04-29 13:44:00 +08004069 return DVR_SUCCESS;
4070}
4071
4072
4073/**\brief Get playback status
4074 * \param[in] handle playback handle
4075 * \param[out] p_status playback status
4076 * \retval DVR_SUCCESS On success
4077 * \return Error code
4078 */
4079int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
4080 DVR_PlaybackStatus_t *p_status) {
4081//
4082 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4083
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004084 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
4085
hualing chen2932d372020-04-29 13:44:00 +08004086 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004087 DVR_PB_INFO("player is NULL");
hualing chen2932d372020-04-29 13:44:00 +08004088 return DVR_FAILURE;
4089 }
Wentao MA96f68962022-06-15 19:45:35 +08004090 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004091 dvr_mutex_lock(&player->lock);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004092 if (!player->has_video && !player->has_audio)
4093 p_status->time_cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08004094 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004095 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08004096
hualing chenb31a6c62020-01-13 17:27:00 +08004097 return DVR_SUCCESS;
4098}
4099
hualing chen040df222020-01-17 13:35:02 +08004100void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
4101 if (segment != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004102 DVR_PB_INFO("segment id: %lld", segment->segment_id);
4103 DVR_PB_INFO("segment flag: %d", segment->flags);
4104 DVR_PB_INFO("segment location: [%s]", segment->location);
4105 DVR_PB_INFO("segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
4106 DVR_PB_INFO("segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
4107 DVR_PB_INFO("segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
4108 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 +08004109 }
hualing chenb31a6c62020-01-13 17:27:00 +08004110}
4111
hualing chen5cbe1a62020-02-10 16:36:36 +08004112int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004113 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08004114
hualing chena540a7e2020-03-27 16:44:05 +08004115 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004116 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004117 return DVR_FAILURE;
4118 }
4119
hualing chen040df222020-01-17 13:35:02 +08004120 DVR_PlaybackSegmentInfo_t *segment;
4121 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08004122 {
hualing chen040df222020-01-17 13:35:02 +08004123 if (segment_id >= 0) {
4124 if (segment->segment_id == segment_id) {
4125 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08004126 break;
4127 }
4128 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08004129 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08004130 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08004131 }
4132 }
4133 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08004134}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004135
pengfei.liu27cc4ec2020-04-03 16:28:16 +08004136int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004137{
4138 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4139 DVR_RETURN_IF_FALSE(player);
4140 DVR_RETURN_IF_FALSE(func);
4141
Wentao MA96f68962022-06-15 19:45:35 +08004142 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004143 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004144
4145 player->dec_func = func;
4146 player->dec_userdata = userdata;
4147
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004148 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004149 DVR_PB_INFO("out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004150 return DVR_SUCCESS;
4151}
4152
4153int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
4154{
4155 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4156 DVR_RETURN_IF_FALSE(player);
4157 DVR_RETURN_IF_FALSE(p_secure_buf);
4158 DVR_RETURN_IF_FALSE(len);
4159
Wentao MA96f68962022-06-15 19:45:35 +08004160 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004161 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004162
4163 player->is_secure_mode = 1;
4164 player->secure_buffer = p_secure_buf;
4165 player->secure_buffer_size = len;
4166
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004167 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004168 DVR_PB_INFO("out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004169 return DVR_SUCCESS;
4170}
Wentao MA5629ad82022-08-24 10:03:02 +08004171
4172int dvr_playback_set_ac4_preselection_id(DVR_PlaybackHandle_t handle, int presel_id)
4173{
4174 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4175 DVR_RETURN_IF_FALSE(player == NULL);
4176
4177 player->audio_presentation_id = presel_id;
4178 am_tsplayer_result ret = AmTsPlayer_setParams(player->handle,
4179 AM_TSPLAYER_KEY_AUDIO_PRESENTATION_ID, &presel_id);
4180 DVR_RETURN_IF_FALSE(ret == AM_TSPLAYER_OK);
4181
4182 return DVR_SUCCESS;
4183}