blob: f35a078334867d3557bce71bb30878355599dd9d [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"
18
Gong Ke2a0ebbe2021-05-25 15:22:50 +080019#define DVR_PB_DG(_level, _fmt...) \
20 DVR_DEBUG_FL(_level, "playback", _fmt)
hualing chena540a7e2020-03-27 16:44:05 +080021
hualing chenb31a6c62020-01-13 17:27:00 +080022#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080023
hualing chend241c7a2021-06-22 13:34:27 +080024#define CONTROL_SPEED_ENABLE 0
hualing chena540a7e2020-03-27 16:44:05 +080025
26#define FF_SPEED (2.0f)
27#define FB_SPEED (-1.0f)
28#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080029#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080030
31#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))
32#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
33
hualing chenb31a6c62020-01-13 17:27:00 +080034
hualing chenb5cd42e2020-04-15 17:03:34 +080035#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080036#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080037//if tsplayer delay time < 200 and no data can read, we will pause
38#define MIN_TSPLAYER_DELAY_TIME (200)
39
hualing chen041c4092020-04-05 15:11:50 +080040#define MAX_CACHE_TIME (30000)
41
hualing chena540a7e2020-03-27 16:44:05 +080042static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080043//
44static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chen275379e2021-06-15 17:57:21 +080045static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_PlaybackPids_t pids, int type);
hualing chencc91e1c2020-02-28 13:26:17 +080046static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
47static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080048static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080049static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080050static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
51 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080052static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen03fd4942021-07-15 15:56:41 +080053static int dvr_playback_calculate_last_valid_segment(
54 DVR_PlaybackHandle_t handle, uint64_t *segmentid, int *pos);
hualing chen87072a82020-03-12 16:20:12 +080055
hualing chenbcada022020-04-22 14:27:01 +080056
57static char* _cmd_toString(int cmd)
58{
59
60 char *string[DVR_PLAYBACK_CMD_NONE+1]={
61 "start",
62 "stop",
63 "vstart",
64 "astart",
65 "vstop",
66 "astop",
67 "vrestart",
68 "arestart",
69 "avrestart",
70 "vstopastart",
71 "astopvstart",
72 "vstoparestart",
73 "astopvrestart",
74 "vstartarestart",
75 "astartvrestart",
76 "pause",
77 "resume",
78 "seek",
79 "ff",
80 "fb",
81 "NONE"
82 };
83
84 if (cmd > DVR_PLAYBACK_CMD_NONE) {
85 return "unkown";
86 } else {
87 return string[cmd];
88 }
89}
90
91
hualing chen6d24aa92020-03-23 18:43:47 +080092static char* _dvr_playback_state_toString(int stat)
93{
94 char *string[DVR_PLAYBACK_STATE_FB+1]={
95 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080096 "stop",
hualing chen31140872020-03-25 12:29:26 +080097 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080098 "ff",
99 "fb"
100 };
101
102 if (stat > DVR_PLAYBACK_STATE_FB) {
103 return "unkown";
104 } else {
105 return string[stat];
106 }
107}
hualing chena540a7e2020-03-27 16:44:05 +0800108
109static DVR_Bool_t _dvr_support_speed(int speed) {
110
111 DVR_Bool_t ret = DVR_FALSE;
112
113 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800114 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800115 case PLAYBACK_SPEED_FBX2:
116 case PLAYBACK_SPEED_FBX4:
117 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800118 case PLAYBACK_SPEED_FBX16:
119 case PLAYBACK_SPEED_FBX12:
120 case PLAYBACK_SPEED_FBX32:
121 case PLAYBACK_SPEED_FBX48:
122 case PLAYBACK_SPEED_FBX64:
123 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800124 case PLAYBACK_SPEED_S2:
125 case PLAYBACK_SPEED_S4:
126 case PLAYBACK_SPEED_S8:
127 case PLAYBACK_SPEED_X1:
128 case PLAYBACK_SPEED_X2:
129 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800130 case PLAYBACK_SPEED_X3:
131 case PLAYBACK_SPEED_X5:
132 case PLAYBACK_SPEED_X6:
133 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800134 case PLAYBACK_SPEED_X8:
135 case PLAYBACK_SPEED_X12:
136 case PLAYBACK_SPEED_X16:
137 case PLAYBACK_SPEED_X32:
138 case PLAYBACK_SPEED_X48:
139 case PLAYBACK_SPEED_X64:
140 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800141 ret = DVR_TRUE;
142 break;
143 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800144 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800145 break;
146 }
147 return ret;
148}
hualing chen6e4bfa52020-03-13 14:37:11 +0800149void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
150{
hualing chen4b7c15d2020-04-07 16:13:48 +0800151 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800152 DVR_Playback_t *player = NULL;
153 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800154 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800155 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800156 }
157 switch (event->type) {
158 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
159 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800160 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800161 event->event.video_format.frame_width,
162 event->event.video_format.frame_height,
163 event->event.video_format.frame_rate);
164 break;
165 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800166 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
167 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800168 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800169 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800170 break;
171 }
172 default:
173 break;
174 }
175}
hualing chen2aba4022020-03-02 13:49:55 +0800176void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
177{
hualing chen6e4bfa52020-03-13 14:37:11 +0800178 DVR_Playback_t *player = NULL;
179 if (user_data != NULL) {
180 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800181 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800182 }
hualing chen2aba4022020-03-02 13:49:55 +0800183 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800184 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
185 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800186 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800187 event->event.video_format.frame_width,
188 event->event.video_format.frame_height,
189 event->event.video_format.frame_rate);
190 break;
191 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800192 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
193 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800194 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chene41f4372020-06-06 16:29:17 +0800195 if (player->first_trans_ok == DVR_FALSE) {
196 player->first_trans_ok = DVR_TRUE;
197 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
198 }
hualing chen30423862021-04-16 14:39:12 +0800199 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800200 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800201 player->seek_pause = DVR_FALSE;
202 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800203 break;
204 }
hualing chen487ae6d2020-07-22 10:34:11 +0800205 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
206 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
207 player->first_trans_ok = DVR_TRUE;
208 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
209 }
210 if (player != NULL && player->has_video == DVR_FALSE) {
211 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
212 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800213 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800214 }
215 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800216 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800217 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800218 break;
219 }
220 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800221 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800222 player->player_callback_func(player->player_callback_userdata, event);
223 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800224 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800225 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800226 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800227 }
228}
hualing chencc91e1c2020-02-28 13:26:17 +0800229
hualing chen5cbe1a62020-02-10 16:36:36 +0800230//convert video and audio fmt
231static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
232 int format = 0;
233 if (is_audio == DVR_FALSE) {
234 //for video fmt
235 switch (fmt)
236 {
237 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800238 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800239 break;
240 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800241 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800242 break;
243 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800244 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800245 break;
246 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800247 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800248 break;
hualing chena540a7e2020-03-27 16:44:05 +0800249 case DVR_VIDEO_FORMAT_VP9:
250 format = AV_VIDEO_CODEC_VP9;
251 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800252 }
253 } else {
254 //for audio fmt
255 switch (fmt)
256 {
257 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800258 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800259 break;
260 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800261 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800262 break;
263 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800264 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800265 break;
266 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800267 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800268 break;
hualing chena540a7e2020-03-27 16:44:05 +0800269 case DVR_AUDIO_FORMAT_AAC:
270 format = AV_AUDIO_CODEC_AAC;
271 break;
272 case DVR_AUDIO_FORMAT_LATM:
273 format = AV_AUDIO_CODEC_LATM;
274 break;
275 case DVR_AUDIO_FORMAT_PCM:
276 format = AV_AUDIO_CODEC_PCM;
277 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800278 case DVR_AUDIO_FORMAT_AC4:
279 format = AV_AUDIO_CODEC_AC4;
280 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800281 }
282 }
283 return format;
284}
hualing chen040df222020-01-17 13:35:02 +0800285static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800286{
hualing chen040df222020-01-17 13:35:02 +0800287 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800288
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800289 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800290 return -1;
291
hualing chena540a7e2020-03-27 16:44:05 +0800292 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800293}
hualing chena540a7e2020-03-27 16:44:05 +0800294
hualing chen5cbe1a62020-02-10 16:36:36 +0800295//get sys time ms
hualing chen03fd4942021-07-15 15:56:41 +0800296static uint64_t _dvr_time_getClock(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800297{
298 struct timespec ts;
hualing chen03fd4942021-07-15 15:56:41 +0800299 uint64_t ms;
hualing chen5cbe1a62020-02-10 16:36:36 +0800300
hualing chen03fd4942021-07-15 15:56:41 +0800301 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen5cbe1a62020-02-10 16:36:36 +0800302 ms = ts.tv_sec*1000+ts.tv_nsec/1000000;
303
304 return ms;
305}
hualing chen86e7d482020-01-16 15:13:33 +0800306
hualing chenb31a6c62020-01-13 17:27:00 +0800307
308//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800309static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800310{
hualing chen040df222020-01-17 13:35:02 +0800311 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800312
hualing chena540a7e2020-03-27 16:44:05 +0800313
314 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800315 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800316 return DVR_FAILURE;
317 }
318
hualing chen86e7d482020-01-16 15:13:33 +0800319 struct timespec ts;
320 clock_gettime(CLOCK_MONOTONIC, &ts);
321 //ms为毫秒,换算成秒
322 ts.tv_sec += ms/1000;
323 //在outtime的基础上,增加ms毫秒
324 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
325 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
326 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
327 //us的值有可能超过1秒,
328 ts.tv_sec += us / 1000000;
329 us = us % 1000000;
330 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800331 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
332 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800333}
hualing chen31140872020-03-25 12:29:26 +0800334//get tsplay delay time ms
335static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
336 DVR_Playback_t *player = (DVR_Playback_t *) handle;
337 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800338 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800339 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800340 return 0;
341 }
342 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800343 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800344 return cache;
345}
hualing chenb31a6c62020-01-13 17:27:00 +0800346//send signal
hualing chen040df222020-01-17 13:35:02 +0800347static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800348{
hualing chen87072a82020-03-12 16:20:12 +0800349 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800350
351 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800352 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800353 return DVR_FAILURE;
354 }
355
hualing chen87072a82020-03-12 16:20:12 +0800356 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800357 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800358 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800359 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800360}
361
hualing chen2932d372020-04-29 13:44:00 +0800362//send playback event, need check is need lock first
363static 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 +0800364
365 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800366
367 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800368 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800369 return DVR_FAILURE;
370 }
371
hualing chencc91e1c2020-02-28 13:26:17 +0800372 switch (evt) {
373 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800374 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800375 break;
376 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
377 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800378 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800379 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800380 break;
381 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
382 break;
383 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
384 break;
385 case DVR_PLAYBACK_EVENT_NO_KEY:
386 break;
387 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800388 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800389 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800390 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800391 break;
392 case DVR_PLAYBACK_EVENT_REACHED_END:
393 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800394 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800395 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800396 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800397 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800398 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800399 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800400 default:
401 break;
402 }
403 if (player->openParams.event_fn != NULL)
404 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800405 return DVR_SUCCESS;
406}
hualing chen2932d372020-04-29 13:44:00 +0800407static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800408{
409 DVR_Play_Notify_t notify;
410 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
411 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
412 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800413 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800414 return DVR_SUCCESS;
415}
416
hualing chen2932d372020-04-29 13:44:00 +0800417static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800418{
419 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800420
hualing chene3797f02021-01-13 14:53:28 +0800421 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800422 if (CONTROL_SPEED_ENABLE == 0)
423 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800424 }
hualing chena540a7e2020-03-27 16:44:05 +0800425 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800426 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800427 return DVR_FAILURE;
428 }
429
hualing chen03fd4942021-07-15 15:56:41 +0800430 if (player->send_time == 0) {
hualing chend241c7a2021-06-22 13:34:27 +0800431 if (CONTROL_SPEED_ENABLE == 0)
432 player->send_time = _dvr_time_getClock() + 500;
433 else
434 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800435 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800436 return DVR_SUCCESS;
437 }
hualing chend241c7a2021-06-22 13:34:27 +0800438 if (CONTROL_SPEED_ENABLE == 0)
439 player->send_time = _dvr_time_getClock() + 500;
440 else
441 player->send_time = _dvr_time_getClock() + 20;
442
hualing chen6e4bfa52020-03-13 14:37:11 +0800443 DVR_Play_Notify_t notify;
444 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
445 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
446 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800447 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800448 return DVR_SUCCESS;
449}
450
hualing chencc91e1c2020-02-28 13:26:17 +0800451//check is ongoing segment
452static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
453
454 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800455 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800456
457 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800458 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800459 return DVR_FAILURE;
460 }
hualing chen87072a82020-03-12 16:20:12 +0800461 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800462 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800463 return DVR_FALSE;
464 }
hualing chencc91e1c2020-02-28 13:26:17 +0800465 return DVR_TRUE;
466}
hualing chen4b7c15d2020-04-07 16:13:48 +0800467
468
469static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
470 DVR_Playback_t *player = (DVR_Playback_t *) handle;
471 player->fffb_start = _dvr_time_getClock();
hualing chen03fd4942021-07-15 15:56:41 +0800472 DVR_PB_DG(1, " player->fffb_start:%lld", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800473 player->fffb_current = player->fffb_start;
474 //get segment current time pos
475 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800476 player->next_fffb_time = _dvr_time_getClock();
477
478 return DVR_SUCCESS;
479}
480
hualing chen2aba4022020-03-02 13:49:55 +0800481static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
482 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800483 player->fffb_start = _dvr_time_getClock();
hualing chen03fd4942021-07-15 15:56:41 +0800484 DVR_PB_DG(1, " player->fffb_start:%lld", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800485 player->fffb_current = player->fffb_start;
486 //get segment current time pos
487 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800488
hualing chen2aba4022020-03-02 13:49:55 +0800489 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800490 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800491 return DVR_SUCCESS;
492}
hualing chencc91e1c2020-02-28 13:26:17 +0800493//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800494static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
495
496 DVR_Playback_t *player = (DVR_Playback_t *) handle;
497 DVR_PlaybackSegmentInfo_t *segment;
498 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
499
hualing chena540a7e2020-03-27 16:44:05 +0800500 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800501 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800502 return DVR_FAILURE;
503 }
504
hualing chen87072a82020-03-12 16:20:12 +0800505 int found = 0;
506 int found_eq_id = 0;
507 list_for_each_entry(segment, &player->segment_list, head)
508 {
509 if (player->segment_is_open == DVR_FALSE) {
510 //get first segment from list, case segment is not open
511 if (!IS_FB(player->speed))
512 found = 1;
513 } else if (segment->segment_id == segmentid) {
514 //find cur segment, we need get next one
515 found_eq_id = 1;
516 if (!IS_FB(player->speed)) {
517 found = 1;
518 continue;
519 } else {
520 //if is fb mode.we need used pre segment
521 if (pre_segment != NULL) {
522 found = 1;
523 } else {
524 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800525 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800526 return DVR_FAILURE;
527 }
528 }
529 }
530 if (found == 1) {
531 found = 2;
532 break;
533 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800534 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800535 }
536 if (found != 2) {
537 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800538 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800539 return DVR_FAILURE;
540 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800541 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800542 return DVR_SUCCESS;
543}
544
545//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800546static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800547
hualing chen040df222020-01-17 13:35:02 +0800548 DVR_Playback_t *player = (DVR_Playback_t *) handle;
549 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800550 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800551 uint64_t segmentid;
552 int pos;
hualing chena540a7e2020-03-27 16:44:05 +0800553 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800554 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800555 return DVR_FAILURE;
556 }
557
hualing chen03fd4942021-07-15 15:56:41 +0800558 if (IS_FB(player->speed)
559 && dvr_playback_check_limit(handle)) {
560 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
561 //case cur id < segment id
562 if (player->cur_segment_id <= segmentid) {
563 //expired ts data is player,return error
564 DVR_PB_DG(1, "reach start segment ,return error");
565 return DVR_FAILURE;
566 }
567 DVR_PB_DG(1, "has segment to fb play [%lld][%d]", segmentid, pos);
568 }
569
hualing chen86e7d482020-01-16 15:13:33 +0800570 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800571 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800572
hualing chen040df222020-01-17 13:35:02 +0800573 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800574 {
hualing chencc91e1c2020-02-28 13:26:17 +0800575 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800576 //get first segment from list, case segment is not open
577 if (!IS_FB(player->speed))
578 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800579 } else if (segment->segment_id == player->cur_segment_id) {
580 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800581 found_eq_id = 1;
582 if (!IS_FB(player->speed)) {
583 found = 1;
584 continue;
585 } else {
586 //if is fb mode.we need used pre segment
587 if (pre_segment != NULL) {
588 found = 1;
589 } else {
590 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800591 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800592 return DVR_FAILURE;
593 }
594 }
hualing chen86e7d482020-01-16 15:13:33 +0800595 }
596 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800597 if (IS_FB(player->speed)) {
598 //used pre segment
599 segment = pre_segment;
600 }
hualing chencc91e1c2020-02-28 13:26:17 +0800601 //save segment info
602 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800603 if (player->r_handle)
604 player->last_segment_tatol = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800605 player->last_segment.segment_id = player->cur_segment.segment_id;
606 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800607 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
608 //pids
609 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
610
hualing chen5cbe1a62020-02-10 16:36:36 +0800611 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800612 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800613 player->cur_segment_id = segment->segment_id;
614 player->cur_segment.segment_id = segment->segment_id;
615 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800616 DVR_PB_DG(1, "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 +0800617 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800618 //pids
hualing chen040df222020-01-17 13:35:02 +0800619 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800620 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800621 break;
hualing chen86e7d482020-01-16 15:13:33 +0800622 }
hualing chen2aba4022020-03-02 13:49:55 +0800623 pre_segment = segment;
624 }
625 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
626 //used the last one segment to open
627 //get segment info
628 player->segment_is_open = DVR_TRUE;
629 player->cur_segment_id = pre_segment->segment_id;
630 player->cur_segment.segment_id = pre_segment->segment_id;
631 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800632 DVR_PB_DG(1, "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 +0800633 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
634 //pids
635 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
636 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800637 }
638 if (found != 2) {
639 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800640 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800641 }
642 return DVR_SUCCESS;
643}
hualing chen040df222020-01-17 13:35:02 +0800644//open next segment to play,if reach list end return errro.
645static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800646{
hualing chen040df222020-01-17 13:35:02 +0800647 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800648 Segment_OpenParams_t params;
649 int ret = DVR_SUCCESS;
650
hualing chena540a7e2020-03-27 16:44:05 +0800651 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800652 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800653 return DVR_FAILURE;
654 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800655 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800656
657 ret = _dvr_get_next_segmentId(handle);
658 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800659 DVR_PB_DG(1, "not found segment info");
660 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800661 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800662 }
663
664 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800665 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800666 segment_close(player->r_handle);
667 player->r_handle = NULL;
668 }
669
670 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800671 //cp chur segment path to location
672 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800673 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800674 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800675 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
676
hualing chen86e7d482020-01-16 15:13:33 +0800677 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800678 if (ret == DVR_FAILURE) {
679 DVR_PB_DG(1, "open segment error");
680 }
hualing chen87072a82020-03-12 16:20:12 +0800681 pthread_mutex_unlock(&player->segment_lock);
682 int total = _dvr_get_end_time( handle);
683 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800684 if (IS_FB(player->speed)) {
685 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800686 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800687 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800688 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800689 }
hualing chen87072a82020-03-12 16:20:12 +0800690 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800691 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800692 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800693 return ret;
694}
695
hualing chen5cbe1a62020-02-10 16:36:36 +0800696//open next segment to play,if reach list end return errro.
697static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
698{
699 DVR_Playback_t *player = (DVR_Playback_t *) handle;
700 Segment_OpenParams_t params;
701 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800702 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800703 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800704 return DVR_FAILURE;
705 }
hualing chencc91e1c2020-02-28 13:26:17 +0800706 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800707 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800708 }
hualing chencc91e1c2020-02-28 13:26:17 +0800709 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800710 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800711 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800712 return DVR_FAILURE;
713 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800714 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800715 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800716
717 DVR_PlaybackSegmentInfo_t *segment;
718
719 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800720
hualing chen5cbe1a62020-02-10 16:36:36 +0800721 list_for_each_entry(segment, &player->segment_list, head)
722 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800723 DVR_PB_DG(1, "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 +0800724 if (segment->segment_id == segment_id) {
725 found = 1;
726 }
727 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800728 DVR_PB_DG(1, "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 +0800729 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800730 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800731 player->cur_segment_id = segment->segment_id;
732 player->cur_segment.segment_id = segment->segment_id;
733 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800734 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800735 //pids
736 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800737 DVR_PB_DG(1, "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 +0800738 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800739 }
740 }
hualing chencc91e1c2020-02-28 13:26:17 +0800741 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800742 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800743 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800744 return DVR_FAILURE;
745 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800746 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800747 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800748 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800749 params.segment_id = (uint64_t)player->cur_segment.segment_id;
750 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800751 DVR_PB_DG(1, "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 +0800752 if (player->r_handle != NULL) {
753 segment_close(player->r_handle);
754 player->r_handle = NULL;
755 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800756 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800757 if (ret == DVR_FAILURE) {
758 DVR_PB_DG(1, "segment opne error");
759 }
hualing chen2aba4022020-03-02 13:49:55 +0800760 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800761 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800762
hualing chen4b7c15d2020-04-07 16:13:48 +0800763 DVR_PB_DG(1, "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 +0800764 return ret;
765}
766
767
768//get play info by segment id
769static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
770 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800771 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800772 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800773
774 DVR_Playback_t *player = (DVR_Playback_t *) handle;
775 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800776 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800777 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800778 return DVR_FAILURE;
779 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800780
781 int found = 0;
782
783 list_for_each_entry(segment, &player->segment_list, head)
784 {
hualing chen87072a82020-03-12 16:20:12 +0800785 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800786 //get first segment from list
787 found = 1;
788 }
789 if (segment->segment_id == segment_id) {
790 found = 1;
791 }
792 if (found == 1) {
793 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800794 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800795 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800796 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800797 player->cur_segment.segment_id = segment->segment_id;
798 player->cur_segment.flags = segment->flags;
799 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800800 player->cur_segment.pids.video.pid = segment->pids.video.pid;
801 player->cur_segment.pids.video.format = segment->pids.video.format;
802 player->cur_segment.pids.video.type = segment->pids.video.type;
803 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
804 player->cur_segment.pids.audio.format = segment->pids.audio.format;
805 player->cur_segment.pids.audio.type = segment->pids.audio.type;
806 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
807 player->cur_segment.pids.ad.format = segment->pids.ad.format;
808 player->cur_segment.pids.ad.type = segment->pids.ad.type;
809 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800810 //
hualing chen2aba4022020-03-02 13:49:55 +0800811 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800812 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800813 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800814 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800815 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
816 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800817 DVR_PB_DG(1, "get play info sucess[0x%x]apid[0x%x]vfmt[%d]afmt[%d]", vparam->pid, aparam->pid, vparam->codectype, aparam->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800818 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800819 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800820 }
821 }
hualing chencc91e1c2020-02-28 13:26:17 +0800822 if (found != 2) {
823 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800824 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800825 return DVR_FAILURE;
826 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800827
828 return DVR_SUCCESS;
829}
hualing chencc91e1c2020-02-28 13:26:17 +0800830static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
831 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800832 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800833 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800834 return DVR_FAILURE;
835 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800836
hualing chencc91e1c2020-02-28 13:26:17 +0800837 //compare cur segment
838 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
839 {
840 //check video pids, stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800841 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800842 //check sub audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800843 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800844 //check audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800845 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids, 1);
hualing chene3797f02021-01-13 14:53:28 +0800846 DVR_PB_DG(1, ":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 +0800847 //check pcr pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800848 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800849 }
hualing chena540a7e2020-03-27 16:44:05 +0800850 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800851}
hualing chen5cbe1a62020-02-10 16:36:36 +0800852
hualing chend241c7a2021-06-22 13:34:27 +0800853static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
854{
855 DVR_Playback_t *player = (DVR_Playback_t *) handle;
856 if (player == NULL) {
857 DVR_PB_DG(1, "player is NULL");
858 return DVR_TRUE;
859 }
860 char buf[10];
861 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
862 DVR_PB_DG(1, "player get prop[%d][%s]", atoi(buf), buf);
863
864 if (atoi(buf) != 1) {
865 //return DVR_TRUE;
866 }
867
hualing chen03fd4942021-07-15 15:56:41 +0800868 DVR_PB_DG(1, ":play speed: %f ply dur: %lld sys_dur: %lld",
869 player->speed,
870 player->con_spe.ply_dur,
871 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800872
873 if (player->speed != 1.0f)
874 return DVR_TRUE;
875
876 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800877 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800878 return DVR_FALSE;
879
880 return DVR_TRUE;
881}
882
hualing chencc91e1c2020-02-28 13:26:17 +0800883static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
884{
885 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800886 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800887 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800888 return DVR_FAILURE;
889 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800890 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
891 DVR_PB_DG(1, "vendor is amlogic. no used segment flag to hide or show av");
892 return DVR_SUCCESS;
893 }
hualing chen03fd4942021-07-15 15:56:41 +0800894 DVR_PB_DG(1, "flag[0x%x]id[%lld]last[0x%x][%llu]",
895 player->cur_segment.flags,
896 player->cur_segment.segment_id,
897 player->last_segment.flags,
898 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800899 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
900 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800901 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800902 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800903 AmTsPlayer_showVideo(player->handle);
904 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800905 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
906 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800907 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800908 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800909 AmTsPlayer_hideVideo(player->handle);
910 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800911 }
912 return DVR_SUCCESS;
913}
hualing chene3797f02021-01-13 14:53:28 +0800914/*
915if decodec sucess first time.
916sucess: return true
917fail: return false
918*/
hualing chena540a7e2020-03-27 16:44:05 +0800919static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
920 DVR_Playback_t *player = (DVR_Playback_t *) handle;
921 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800922 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800923 return DVR_TRUE;
924 }
hualing chene3797f02021-01-13 14:53:28 +0800925 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800926 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800927 } else {
928 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800929 }
930}
hualing chen86e7d482020-01-16 15:13:33 +0800931static void* _dvr_playback_thread(void *arg)
932{
hualing chen040df222020-01-17 13:35:02 +0800933 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800934 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800935 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800936 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800937 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800938
hualing chen39628212020-05-14 10:35:13 +0800939 #define MAX_REACHEND_TIMEOUT (3000)
940 int reach_end_timeout = 0;//ms
941 int cache_time = 0;
hualing chen6d24aa92020-03-23 18:43:47 +0800942 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800943 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800944 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800945 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800946 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
947
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800948 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800949 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800950 DVR_Bool_t goto_rewrite = DVR_FALSE;
hualing chen03fd4942021-07-15 15:56:41 +0800951
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800952 if (player->is_secure_mode) {
953 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800954 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800955 return NULL;
956 }
957 }
hualing chen86e7d482020-01-16 15:13:33 +0800958 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800959 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800960 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800961 return NULL;
962 }
hualing chen2aba4022020-03-02 13:49:55 +0800963 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
964 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800965
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800966 dec_bufs.buf_data = malloc(dec_buf_size);
967 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800968 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800969 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800970 return NULL;
971 }
972 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
973 dec_bufs.buf_size = dec_buf_size;
974
hualing chencc91e1c2020-02-28 13:26:17 +0800975 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800976 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
977 }
hualing chen86e7d482020-01-16 15:13:33 +0800978
hualing chen86e7d482020-01-16 15:13:33 +0800979 if (ret != DVR_SUCCESS) {
980 if (buf != NULL) {
981 free(buf);
982 buf = NULL;
983 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800984 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +0800985 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +0800986 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +0800987 }
hualing chen4fe3bee2020-10-23 13:58:52 +0800988 DVR_PB_DG(1, "player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +0800989 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +0800990 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
991 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
992 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
993 player->first_trans_ok = DVR_TRUE;
994 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
995 }
hualing chencc91e1c2020-02-28 13:26:17 +0800996 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +0800997 //set video show
998 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +0800999
hualing chen86e7d482020-01-16 15:13:33 +08001000 int trick_stat = 0;
1001 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001002
hualing chen86e7d482020-01-16 15:13:33 +08001003 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +08001004 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001005
hualing chen2aba4022020-03-02 13:49:55 +08001006 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1007 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001008 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001009 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001010 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001011 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001012 {
hualing chen2aba4022020-03-02 13:49:55 +08001013 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1014 if (trick_stat > 0) {
hualing chen03fd4942021-07-15 15:56:41 +08001015 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
1016 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001017 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 +08001018 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001019 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001020 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001021 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
1022 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +08001023 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
1024 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chen03fd4942021-07-15 15:56:41 +08001025 DVR_PB_DG(1, "pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
1026 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001027 //need change to pause state
1028 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1029 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +08001030 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001031 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001032 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001033 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001034 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001035 AmTsPlayer_pauseVideoDecoding(player->handle);
1036 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001037 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001038 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001039 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001040 }
1041 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1042 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001043 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001044 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001045 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen03fd4942021-07-15 15:56:41 +08001046 DVR_PB_DG(1, "fffb pause state----speed[%f] fffb cur[%lld] cur sys[%lld] [%s] [%lld]",
1047 player->speed,
1048 player->fffb_current,
1049 _dvr_time_getClock(),
1050 _dvr_playback_state_toString(player->state),
1051 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001052 //used timeout wait need lock first,so we unlock and lock
1053 //pthread_mutex_unlock(&player->lock);
1054 //pthread_mutex_lock(&player->lock);
1055 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1056 pthread_mutex_unlock(&player->lock);
1057 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001058 } else if (_dvr_time_getClock() < player->next_fffb_time) {
hualing chen03fd4942021-07-15 15:56:41 +08001059 DVR_PB_DG(1, "fffb timeout-to pause video---speed[%f] fffb cur[%lld] cur sys[%lld] [%s] [%lld]",
1060 player->speed,
1061 player->fffb_current,
1062 _dvr_time_getClock(),
1063 _dvr_playback_state_toString(player->state),
1064 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001065 //used timeout wait need lock first,so we unlock and lock
1066 //pthread_mutex_unlock(&player->lock);
1067 //pthread_mutex_lock(&player->lock);
1068 AmTsPlayer_pauseVideoDecoding(player->handle);
1069 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1070 pthread_mutex_unlock(&player->lock);
1071 continue;
1072
hualing chen2aba4022020-03-02 13:49:55 +08001073 }
hualing chen03fd4942021-07-15 15:56:41 +08001074 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d][%s][%d]",
1075 player->speed,
1076 goto_rewrite,
1077 real_read,
1078 _dvr_playback_state_toString(player->state),
1079 player->cmd.cur_cmd);
1080
hualing chen2aba4022020-03-02 13:49:55 +08001081 pthread_mutex_unlock(&player->lock);
1082 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001083 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001084 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1085 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001086 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001087 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001088 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08001089 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1090 //on pause state,user seek to new pos,we need pause and wait
1091 //user to resume
1092 DVR_PB_DG(1, "pause, when got first frame event when user seek end");
1093 player->first_frame = 0;
1094 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1095 AmTsPlayer_pauseVideoDecoding(player->handle);
1096 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001097 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001098 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001099 //for first into fffb when reset speed
1100 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1101 _dvr_time_getClock() < player->next_fffb_time) {
hualing chen03fd4942021-07-15 15:56:41 +08001102 DVR_PB_DG(1, "fffb timeout-fffb play---speed[%f] fffb cur[%lld] cur sys[%lld] [%s] [%lld]",
1103 player->speed,
1104 player->fffb_current,
1105 _dvr_time_getClock(),
1106 _dvr_playback_state_toString(player->state),
1107 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001108 //used timeout wait need lock first,so we unlock and lock
1109 //pthread_mutex_unlock(&player->lock);
1110 //pthread_mutex_lock(&player->lock);
1111 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1112 pthread_mutex_unlock(&player->lock);
1113 continue;
1114 }
hualing chen03fd4942021-07-15 15:56:41 +08001115 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
1116 player->speed,
1117 goto_rewrite,
1118 real_read,
1119 _dvr_playback_state_toString(player->state),
1120 player->cmd.cur_cmd,
1121 player->fffb_play);
hualing chen4b7c15d2020-04-07 16:13:48 +08001122 pthread_mutex_unlock(&player->lock);
1123 goto_rewrite = DVR_FALSE;
1124 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001125 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001126 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1127 player->first_frame = 0;
1128 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1129 pthread_mutex_lock(&player->lock);
1130 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001131 }
hualing chenb31a6c62020-01-13 17:27:00 +08001132 }
hualing chen86e7d482020-01-16 15:13:33 +08001133
hualing chen30423862021-04-16 14:39:12 +08001134 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1135 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001136 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001137 DVR_PB_DG(1, "pause, continue");
hualing chen2932d372020-04-29 13:44:00 +08001138 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen87072a82020-03-12 16:20:12 +08001139 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1140 pthread_mutex_unlock(&player->lock);
1141 continue;
1142 }
hualing chen266b9502020-04-04 17:39:39 +08001143 //when seek action is done. we need drop write timeout data.
1144 if (player->drop_ts == DVR_TRUE) {
1145 goto_rewrite = DVR_FALSE;
1146 real_read = 0;
1147 player->drop_ts = DVR_FALSE;
1148 }
hualing chen2aba4022020-03-02 13:49:55 +08001149 if (goto_rewrite == DVR_TRUE) {
1150 goto_rewrite = DVR_FALSE;
1151 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001152 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001153 goto rewrite;
1154 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001155 //.check is need send time send end
hualing chen2932d372020-04-29 13:44:00 +08001156 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001157 pthread_mutex_lock(&player->segment_lock);
hualing chene41f4372020-06-06 16:29:17 +08001158 //DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001159 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chenfbf8e022020-06-15 13:43:11 +08001160 //DVR_PB_DG(1, "start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001161 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001162 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001163 if (read < 0 && errno == EIO) {
1164 //EIO ERROR, EXIT THRAD
1165 DVR_PB_DG(1, "read error.EIO error, exit thread");
1166 DVR_Play_Notify_t notify;
1167 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1168 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001169 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001170 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001171 goto end;
1172 } else if (read < 0) {
1173 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1174 }
hualing chen87072a82020-03-12 16:20:12 +08001175 //if on fb mode and read file end , we need calculate pos to retry read.
1176 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen03fd4942021-07-15 15:56:41 +08001177 DVR_PB_DG(1, "recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
1178 read,
1179 real_read,
1180 buf_len,
1181 player->speed,
1182 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001183 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
1184 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001185 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1186 pthread_mutex_unlock(&player->lock);
1187 continue;
1188 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001189 //DVR_PB_DG(1, "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 +08001190 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001191 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001192 #define MIN_CACHE_TIME (3000)
1193 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001194 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001195 if (_cache_time > MIN_CACHE_TIME) {
hualing chene41f4372020-06-06 16:29:17 +08001196 pthread_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001197 /*if cache time > 20s , we think get time is error,*/
1198 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
1199 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1200 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1201 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1202 }
1203 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
hualing chene41f4372020-06-06 16:29:17 +08001204 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001205 DVR_PB_DG(1, "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 +08001206 //continue;
1207 }
hualing chen969fe7b2021-05-26 15:13:17 +08001208
hualing chen040df222020-01-17 13:35:02 +08001209 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001210 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001211 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001212
1213 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chene3797f02021-01-13 14:53:28 +08001214 if (ret != DVR_SUCCESS) {
1215 player->noData++;
1216 DVR_PB_DG(1, "playback is sleep:[%d]ms nodata[%d]", timeout, player->noData);
1217 if (player->noData == 4) {
1218 DVR_PB_DG(1, "playback send nodata event nodata[%d]", player->noData);
1219 //send event here and pause
1220 DVR_Play_Notify_t notify;
1221 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1222 notify.event = DVR_PLAYBACK_EVENT_NODATA;
1223 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_NODATA");
1224 //get play statue not here
1225 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1226 }
1227 }
1228 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001229 if ((ret != DVR_SUCCESS &&
hualing chen03fd4942021-07-15 15:56:41 +08001230 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001231 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001232 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001233 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1234 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001235 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001236 DVR_Play_Notify_t notify;
1237 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1238 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1239 //get play statue not here
1240 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001241 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001242 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001243 DVR_PB_DG(1, "playback is send end delay:[%d]reach_end_timeout[%d]ms", delay, reach_end_timeout);
hualing chen31140872020-03-25 12:29:26 +08001244 pthread_mutex_lock(&player->lock);
1245 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1246 pthread_mutex_unlock(&player->lock);
1247 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001248 } else if (ret != DVR_SUCCESS) {
1249 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001250 if (delay < cache_time) {
1251 //delay time is changed and then has data to play, so not start timeout
1252 } else {
1253 reach_end_timeout = reach_end_timeout + timeout;
1254 }
1255 cache_time = delay;
hualing chen4b7c15d2020-04-07 16:13:48 +08001256 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001257 pthread_mutex_lock(&player->lock);
1258 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1259 pthread_mutex_unlock(&player->lock);
1260 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001261 }
hualing chen39628212020-05-14 10:35:13 +08001262 reach_end_timeout = 0;
1263 cache_time = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001264 pthread_mutex_lock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001265 //change next segment success case
1266 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001267 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001268 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1269 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen86e7d482020-01-16 15:13:33 +08001270 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen87072a82020-03-12 16:20:12 +08001271 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001272 }//read len 0 check end
1273 if (player->noData > 0) {
1274 player->noData = 0;
1275 DVR_PB_DG(1, "playback send data event resume[%d]", player->noData);
1276 //send event here and pause
1277 DVR_Play_Notify_t notify;
1278 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1279 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
1280 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_DATARESUME");
1281 //get play statue not here
1282 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001283 }
hualing chen39628212020-05-14 10:35:13 +08001284 reach_end_timeout = 0;
hualing chen86e7d482020-01-16 15:13:33 +08001285 real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001286 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001287 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001288
hualing chena540a7e2020-03-27 16:44:05 +08001289 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001290 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001291 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001292 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001293 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001294 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001295 }
hualing chen266b9502020-04-04 17:39:39 +08001296 //if need write whole block size, we need check read buf len is eq block size.
1297 if (b_writed_whole_block == DVR_TRUE) {
1298 //buf_len is block size value.
1299 if (real_read < buf_len) {
1300 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001301 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001302 pthread_mutex_lock(&player->lock);
1303 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1304 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001305 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001306 continue;
1307 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001308 DVR_PB_DG(1, "read buf len[%d] is > block size [%d],this error occur", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001309 }
1310 }
1311
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001312 if (player->dec_func) {
1313 DVR_CryptoParams_t crypto_params;
1314
1315 memset(&crypto_params, 0, sizeof(crypto_params));
1316 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1317 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1318 crypto_params.segment_id = player->cur_segment.segment_id;
hualing chen1f26ffa2020-11-03 10:39:20 +08001319 crypto_params.offset = segment_tell_position(player->r_handle) - wbufs.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001320 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
1321 DVR_PB_DG(1, "offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001322 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1323 crypto_params.input_buffer.addr = (size_t)buf;
1324 crypto_params.input_buffer.size = real_read;
1325
1326 if (player->is_secure_mode) {
1327 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1328 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1329 crypto_params.output_buffer.size = dec_buf_size;
1330 ret = player->dec_func(&crypto_params, player->dec_userdata);
1331 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001332 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001333 } else {
1334 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1335 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1336 crypto_params.output_buffer.size = dec_buf_size;
1337 ret = player->dec_func(&crypto_params, player->dec_userdata);
1338 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001339 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001340 }
1341 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001342 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001343 }
pengfei.liufda2a972020-04-09 14:47:15 +08001344 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001345 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001346rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001347 if (player->drop_ts == DVR_TRUE) {
1348 //need drop ts data when seek occur.we need read next loop,drop this ts data
1349 goto_rewrite = DVR_FALSE;
1350 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001351 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001352 player->drop_ts = DVR_FALSE;
1353 continue;
1354 }
hualing chen5605eed2020-05-26 18:18:06 +08001355 player->ts_cache_len = real_read;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001356 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1357 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001358 player->ts_cache_len = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001359 real_read = 0;
1360 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001361 if (CONTROL_SPEED_ENABLE == 1) {
1362check0:
1363 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1364 pthread_mutex_lock(&player->lock);
1365 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1366 pthread_mutex_unlock(&player->lock);
1367 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1368 goto check0;
1369 }
1370 }
hualing chen5605eed2020-05-26 18:18:06 +08001371 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001372 continue;
hualing chen87072a82020-03-12 16:20:12 +08001373 } else {
hualing chen03fd4942021-07-15 15:56:41 +08001374 DVR_PB_DG(1, "write time out write_success:%d wbufs.buf_size:%d systime:%lld",
1375 write_success,
1376 wbufs.buf_size,
1377 _dvr_time_getClock());
1378
hualing chena540a7e2020-03-27 16:44:05 +08001379 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001380 if (CONTROL_SPEED_ENABLE == 1) {
1381check1:
1382 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1383 pthread_mutex_lock(&player->lock);
1384 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1385 pthread_mutex_unlock(&player->lock);
1386 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1387 goto check1;
1388 }
1389 }
hualing chencc91e1c2020-02-28 13:26:17 +08001390 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001391 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001392 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001393 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001394 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001395 break;
1396 }
hualing chen2aba4022020-03-02 13:49:55 +08001397 goto_rewrite = DVR_TRUE;
1398 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001399 }
1400 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001401end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001402 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001403 free(buf);
1404 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001405 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001406}
1407
1408
hualing chen040df222020-01-17 13:35:02 +08001409static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001410{
hualing chen040df222020-01-17 13:35:02 +08001411 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001412
1413 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001414 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001415 return DVR_FAILURE;
1416 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001417 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001418 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001419 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001420 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001421 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001422 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001423 if (rc < 0)
1424 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001425 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001426}
1427
1428
hualing chen040df222020-01-17 13:35:02 +08001429static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001430{
hualing chen040df222020-01-17 13:35:02 +08001431 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001432
1433 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001434 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001435 return DVR_FAILURE;
1436 }
1437
hualing chen4b7c15d2020-04-07 16:13:48 +08001438 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001439 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001440 {
1441 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001442 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001443 pthread_join(player->playback_thread, NULL);
1444 }
1445 if (player->r_handle) {
1446 segment_close(player->r_handle);
1447 player->r_handle = NULL;
1448 }
hualing chen7a56cba2020-04-14 14:09:27 +08001449 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001450 return 0;
1451}
1452
hualing chenb31a6c62020-01-13 17:27:00 +08001453/**\brief Open an dvr palyback
1454 * \param[out] p_handle dvr playback addr
1455 * \param[in] params dvr playback open parameters
1456 * \retval DVR_SUCCESS On success
1457 * \return Error code
1458 */
hualing chen040df222020-01-17 13:35:02 +08001459int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001460
hualing chen040df222020-01-17 13:35:02 +08001461 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001462 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001463
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001464 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001465
hualing chen86e7d482020-01-16 15:13:33 +08001466 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001467 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001468 pthread_condattr_init(&cattr);
1469 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1470 pthread_cond_init(&player->cond, &cattr);
1471 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001472
hualing chen5cbe1a62020-02-10 16:36:36 +08001473 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001474 INIT_LIST_HEAD(&player->segment_list);
1475 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1476 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001477 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001478 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001479 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001480 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001481 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001482 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001483
hualing chen86e7d482020-01-16 15:13:33 +08001484 //store open params
hualing chen040df222020-01-17 13:35:02 +08001485 player->openParams.dmx_dev_id = params->dmx_dev_id;
1486 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001487 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001488 player->openParams.event_fn = params->event_fn;
1489 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001490 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001491 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001492
hualing chen5cbe1a62020-02-10 16:36:36 +08001493 player->has_pids = params->has_pids;
1494
hualing chen2aba4022020-03-02 13:49:55 +08001495 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001496
1497 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1498 //for test get callback
1499 if (0 && player->player_callback_func == NULL) {
1500 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1501 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen03fd4942021-07-15 15:56:41 +08001502 DVR_PB_DG(1, "playback open get callback[%p][%p][%p][%p]",
1503 player->player_callback_func,
1504 player->player_callback_userdata,
1505 _dvr_tsplayer_callback_test,
1506 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001507 }
1508 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001509
hualing chen86e7d482020-01-16 15:13:33 +08001510 //init has audio and video
1511 player->has_video = DVR_FALSE;
1512 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001513 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001514 player->last_segment_id = 0LL;
1515 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001516
hualing chen5cbe1a62020-02-10 16:36:36 +08001517 //init ff fb time
hualing chen03fd4942021-07-15 15:56:41 +08001518 player->fffb_current = UINT64_MAX;
1519 player->fffb_start = UINT64_MAX;
1520 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001521 //seek time
1522 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001523 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001524
1525 //init secure stuff
1526 player->dec_func = NULL;
1527 player->dec_userdata = NULL;
1528 player->is_secure_mode = 0;
1529 player->secure_buffer = NULL;
1530 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001531 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001532
hualing chen4b7c15d2020-04-07 16:13:48 +08001533 player->fffb_play = DVR_FALSE;
1534
1535 player->last_send_time_id = UINT64_MAX;
1536 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001537 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001538
hualing chend241c7a2021-06-22 13:34:27 +08001539 //speed con init
1540 if (CONTROL_SPEED_ENABLE == 1) {
1541 player->con_spe.ply_dur = 0;
1542 player->con_spe.ply_sta = -1;
1543 player->con_spe.sys_dur = 0;
1544 player->con_spe.sys_sta = 0;
1545 }
1546
hualing chen03fd4942021-07-15 15:56:41 +08001547 //limit info
1548 player->rec_start = 0;
1549 player->limit = -1;
hualing chen86e7d482020-01-16 15:13:33 +08001550 *p_handle = player;
1551 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001552}
1553
1554/**\brief Close an dvr palyback
1555 * \param[in] handle playback handle
1556 * \retval DVR_SUCCESS On success
1557 * \return Error code
1558 */
hualing chen040df222020-01-17 13:35:02 +08001559int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001560
hualing chen86e7d482020-01-16 15:13:33 +08001561 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001562 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001563 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001564 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001565 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001566 return DVR_FAILURE;
1567 }
1568
hualing chencc91e1c2020-02-28 13:26:17 +08001569 if (player->state != DVR_PLAYBACK_STATE_STOP)
1570 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001571 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001572 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001573 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1574 } else {
1575 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001576 }
hualing chen7a56cba2020-04-14 14:09:27 +08001577 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001578 pthread_mutex_destroy(&player->lock);
1579 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001580
1581 if (player) {
1582 free(player);
1583 player = NULL;
1584 }
hualing chen7a56cba2020-04-14 14:09:27 +08001585 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001586 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001587}
1588
hualing chenb31a6c62020-01-13 17:27:00 +08001589/**\brief Start play audio and video, used start auido api and start video api
1590 * \param[in] handle playback handle
1591 * \param[in] params audio playback params,contains fmt and pid...
1592 * \retval DVR_SUCCESS On success
1593 * \return Error code
1594 */
hualing chen040df222020-01-17 13:35:02 +08001595int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1596 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001597 am_tsplayer_video_params vparams;
1598 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001599 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001600
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001601 memset(&vparams, 0, sizeof(vparams));
1602 memset(&aparams, 0, sizeof(aparams));
1603
hualing chena540a7e2020-03-27 16:44:05 +08001604 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001605 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001606 return DVR_FAILURE;
1607 }
hualing chencc91e1c2020-02-28 13:26:17 +08001608 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001609 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001610
hualing chena540a7e2020-03-27 16:44:05 +08001611 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001612 //can used start api to resume playback
1613 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1614 return dvr_playback_resume(handle);
1615 }
hualing chen87072a82020-03-12 16:20:12 +08001616 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001617 //if flag is puased and not decodec first frame. if user resume, we need
1618 //clear flag and set trickmode none
1619 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1620 DVR_PB_DG(1, "[%p]clear pause live flag and clear trick mode", handle);
1621 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1622 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1623 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001624 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001625 return DVR_SUCCESS;
1626 }
hualing chen86e7d482020-01-16 15:13:33 +08001627 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001628 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001629 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001630 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001631 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001632 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001633 //start audio and video
Zhiqiang Hana9d261b2020-11-11 18:38:10 +08001634 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001635 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001636 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001637 pthread_mutex_unlock(&player->lock);
1638 DVR_Play_Notify_t notify;
1639 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1640 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1641 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1642 notify.info.transition_failed_data.segment_id = segment_id;
1643 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001644 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001645 return -1;
1646 }
hualing chen31140872020-03-25 12:29:26 +08001647
hualing chencc91e1c2020-02-28 13:26:17 +08001648 {
hualing chen86e7d482020-01-16 15:13:33 +08001649 if (VALID_PID(vparams.pid)) {
1650 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001651 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001652 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001653 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001654 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1655 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001656 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001657 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001658 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001659 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001660 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001661 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001662 }
hualing chena93bbbc2020-12-22 17:23:42 +08001663 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001664 AmTsPlayer_setVideoParams(player->handle, &vparams);
1665 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001666 }
hualing chena540a7e2020-03-27 16:44:05 +08001667
hualing chen4b7c15d2020-04-07 16:13:48 +08001668 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1669 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001670 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1671 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1672 player->cmd.state = DVR_PLAYBACK_STATE_START;
1673 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001674 } else {
1675 player->cmd.last_cmd = player->cmd.cur_cmd;
1676 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001677 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001678 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001679 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001680 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001681 } else {
hualing chendf118dd2020-05-21 15:49:11 +08001682 if (VALID_PID(adparams.pid)) {
1683 player->has_ad_audio = DVR_TRUE;
1684 DVR_PB_DG(1, "start ad audio");
1685 AmTsPlayer_setADParams(player->handle, &adparams);
1686 AmTsPlayer_enableADMix(player->handle);
1687 }
hualing chen969fe7b2021-05-26 15:13:17 +08001688 if (VALID_PID(aparams.pid)) {
1689 DVR_PB_DG(1, "start audio");
1690 player->has_audio = DVR_TRUE;
1691 AmTsPlayer_setAudioParams(player->handle, &aparams);
1692 AmTsPlayer_startAudioDecoding(player->handle);
1693 }
hualing chen31140872020-03-25 12:29:26 +08001694 }
hualing chencc91e1c2020-02-28 13:26:17 +08001695 player->cmd.state = DVR_PLAYBACK_STATE_START;
1696 player->state = DVR_PLAYBACK_STATE_START;
1697 }
hualing chen86e7d482020-01-16 15:13:33 +08001698 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001699 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001700 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001701 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001702 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001703}
hualing chen040df222020-01-17 13:35:02 +08001704/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001705 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001706 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001707 * \retval DVR_SUCCESS On success
1708 * \return Error code
1709 */
hualing chen040df222020-01-17 13:35:02 +08001710int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1711 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001712
hualing chena540a7e2020-03-27 16:44:05 +08001713 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001714 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001715 return DVR_FAILURE;
1716 }
1717
hualing chen4b7c15d2020-04-07 16:13:48 +08001718 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001719 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001720
hualing chen040df222020-01-17 13:35:02 +08001721 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1722 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001723
hualing chen86e7d482020-01-16 15:13:33 +08001724 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001725 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001726 //cp location
hualing chen040df222020-01-17 13:35:02 +08001727 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001728
hualing chen4b7c15d2020-04-07 16:13:48 +08001729 DVR_PB_DG(1, "add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001730 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001731
1732 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001733 segment->pids.video.pid = info->pids.video.pid;
1734 segment->pids.video.format = info->pids.video.format;
1735 segment->pids.video.type = info->pids.video.type;
1736
hualing chen2aba4022020-03-02 13:49:55 +08001737 segment->pids.audio.pid = info->pids.audio.pid;
1738 segment->pids.audio.format = info->pids.audio.format;
1739 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001740
hualing chen2aba4022020-03-02 13:49:55 +08001741 segment->pids.ad.pid = info->pids.ad.pid;
1742 segment->pids.ad.format = info->pids.ad.format;
1743 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001744
1745 segment->pids.pcr.pid = info->pids.pcr.pid;
1746
hualing chen4b7c15d2020-04-07 16:13:48 +08001747 DVR_PB_DG(1, "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);
hualing chen86e7d482020-01-16 15:13:33 +08001748 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001749 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001750 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001751 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001752
hualing chen5cbe1a62020-02-10 16:36:36 +08001753 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001754}
hualing chen040df222020-01-17 13:35:02 +08001755/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001756 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001757 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001758 * \retval DVR_SUCCESS On success
1759 * \return Error code
1760 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001761int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001762 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001763 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001764 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001765 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001766 return DVR_FAILURE;
1767 }
1768
hualing chencc91e1c2020-02-28 13:26:17 +08001769 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001770 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001771 return DVR_FAILURE;
1772 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001773 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001774 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001775 DVR_PlaybackSegmentInfo_t *segment = NULL;
1776 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1777 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001778 {
hualing chen040df222020-01-17 13:35:02 +08001779 if (segment->segment_id == segment_id) {
1780 list_del(&segment->head);
1781 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001782 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001783 }
hualing chen86e7d482020-01-16 15:13:33 +08001784 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001785 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001786 pthread_mutex_unlock(&player->lock);
1787
1788 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001789}
hualing chen040df222020-01-17 13:35:02 +08001790/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001791 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001792 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001793 * \retval DVR_SUCCESS On success
1794 * \return Error code
1795 */
hualing chen040df222020-01-17 13:35:02 +08001796int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001797 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001798 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001799 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001800 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001801 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001802 return DVR_FAILURE;
1803 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001804 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
1805 DVR_PB_DG(1, "vendor is amlogic. not hide or show av and update segment");
1806 return DVR_SUCCESS;
1807 }
hualing chena540a7e2020-03-27 16:44:05 +08001808
hualing chen040df222020-01-17 13:35:02 +08001809 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001810 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001811 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001812 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001813 {
hualing chen040df222020-01-17 13:35:02 +08001814 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001815 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001816 }
hualing chen86e7d482020-01-16 15:13:33 +08001817 // if encramble to free, only set flag and return;
1818
1819 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001820 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001821 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1822 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001823 //disable display, mute
hualing chen703f3572021-01-06 12:51:34 +08001824 DVR_PB_DG(1, "mute av");
hualing chen2aba4022020-03-02 13:49:55 +08001825 AmTsPlayer_hideVideo(player->handle);
1826 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001827 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1828 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001829 //enable display, unmute
hualing chen703f3572021-01-06 12:51:34 +08001830 DVR_PB_DG(1, "unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08001831 AmTsPlayer_showVideo(player->handle);
1832 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001833 } else {
1834 //do nothing
1835 }
1836 } else {
1837 //do nothing
1838 }
1839 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001840 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001841 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001842 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001843 pthread_mutex_unlock(&player->lock);
1844 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001845}
1846
1847
hualing chen275379e2021-06-15 17:57:21 +08001848static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_PlaybackPids_t set_pids, int type) {
hualing chen040df222020-01-17 13:35:02 +08001849 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08001850 DVR_StreamInfo_t set_pid;
1851
1852 if (type == 0) {
1853 set_pid = set_pids.video;
1854 } else if (type == 1) {
1855 set_pid = set_pids.audio;
1856 } else if (type == 2) {
1857 set_pid = set_pids.ad;
1858 } else {
1859 set_pid = set_pids.pcr;
1860 }
1861
hualing chena540a7e2020-03-27 16:44:05 +08001862 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001863 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001864 return DVR_FAILURE;
1865 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001866 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001867 if (now_pid.pid == set_pid.pid) {
1868 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001869 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001870 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001871 if (VALID_PID(now_pid.pid)) {
1872 //stop now stream
1873 if (type == 0) {
1874 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001875 if (player->has_video == DVR_TRUE) {
1876 DVR_PB_DG(1, "stop video");
1877 AmTsPlayer_stopVideoDecoding(player->handle);
1878 player->has_video = DVR_FALSE;
1879 }
hualing chen86e7d482020-01-16 15:13:33 +08001880 } else if (type == 1) {
1881 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08001882 if (player->has_audio == DVR_TRUE) {
1883 DVR_PB_DG(1, "stop audio");
1884 AmTsPlayer_stopAudioDecoding(player->handle);
1885 player->has_audio = DVR_FALSE;
1886 }
hualing chen86e7d482020-01-16 15:13:33 +08001887 } else if (type == 2) {
1888 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001889 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001890 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001891 } else if (type == 3) {
1892 //pcr
1893 }
1894 }
1895 if (VALID_PID(set_pid.pid)) {
1896 //start
1897 if (type == 0) {
1898 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001899 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001900 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001901 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001902 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001903 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001904 AmTsPlayer_setVideoParams(player->handle, &vparams);
1905 AmTsPlayer_startVideoDecoding(player->handle);
1906 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001907 } else if (type == 1) {
1908 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001909 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08001910 if (VALID_PID(set_pids.ad.pid)) {
1911 am_tsplayer_audio_params adparams;
1912 adparams.pid = set_pids.ad.pid;
1913 adparams.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
1914 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",adparams.pid, adparams.codectype);
1915 AmTsPlayer_setADParams(player->handle, &adparams);
1916 AmTsPlayer_enableADMix(player->handle);
1917 }
1918
hualing chenc70a8df2020-05-12 19:23:11 +08001919 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001920
1921 memset(&aparams, 0, sizeof(aparams));
1922
hualing chenc70a8df2020-05-12 19:23:11 +08001923 aparams.pid = set_pid.pid;
1924 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1925 player->has_audio = DVR_TRUE;
1926 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1927 AmTsPlayer_setAudioParams(player->handle, &aparams);
1928 AmTsPlayer_startAudioDecoding(player->handle);
1929 //playback_device_audio_start(player->handle,&aparams);
1930 }
hualing chen86e7d482020-01-16 15:13:33 +08001931 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001932 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chenc70a8df2020-05-12 19:23:11 +08001933 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001934
1935 memset(&aparams, 0, sizeof(aparams));
hualing chenc70a8df2020-05-12 19:23:11 +08001936 aparams.pid = set_pid.pid;
1937 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1938 player->has_audio = DVR_TRUE;
1939 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1940 AmTsPlayer_setADParams(player->handle, &aparams);
1941 AmTsPlayer_enableADMix(player->handle);
1942 //playback_device_audio_start(player->handle,&aparams);
1943 }
hualing chen86e7d482020-01-16 15:13:33 +08001944 } else if (type == 3) {
1945 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001946 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001947 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001948 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001949 //audio and video all close
1950 if (!player->has_audio && !player->has_video) {
1951 player->state = DVR_PLAYBACK_STATE_STOP;
1952 }
hualing chen86e7d482020-01-16 15:13:33 +08001953 }
1954 }
1955 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001956}
hualing chen5cbe1a62020-02-10 16:36:36 +08001957/**\brief dvr play back update segment pids
1958 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001959 * add pid stream and stop remove pid stream.
1960 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001961 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001962 * \retval DVR_SUCCESS On success
1963 * \return Error code
1964 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001965int 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 +08001966 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001967 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001968 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001969 return DVR_FAILURE;
1970 }
1971
hualing chen040df222020-01-17 13:35:02 +08001972 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001973 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001974 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001975 DVR_PB_DG(1, "get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001976
hualing chen040df222020-01-17 13:35:02 +08001977 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001978 {
hualing chen040df222020-01-17 13:35:02 +08001979 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001980
1981 if (player->cur_segment_id == segment_id) {
1982 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
1983 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
1984 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08001985 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08001986 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001987 return 0;
1988 }
1989
1990 //if segment is on going segment,we need stop start stream
1991 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08001992 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001993 //check video pids, stop or restart
hualing chen275379e2021-06-15 17:57:21 +08001994 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, *p_pids, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08001995 //check sub audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08001996 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, *p_pids, 2);
jianchuan.pinge5f8c5a2021-02-03 19:11:05 +08001997 //check audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08001998 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, *p_pids, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001999 //check pcr pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08002000 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, *p_pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +08002001 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002002 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2003 //if state is pause, we need process at resume api. we only record change info
2004 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2005 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2006 if (VALID_PID(segment->pids.video.pid)
2007 && VALID_PID(p_pids->video.pid)
2008 && segment->pids.video.pid != p_pids->video.pid) {
2009 //restart video
2010 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
2011 }
2012 if (!VALID_PID(segment->pids.video.pid)
2013 && VALID_PID(p_pids->video.pid)
2014 && segment->pids.video.pid != p_pids->video.pid) {
2015 //start video
2016 v_cmd = DVR_PLAYBACK_CMD_VSTART;
2017 }
2018 if (VALID_PID(segment->pids.video.pid)
2019 && !VALID_PID(p_pids->video.pid)
2020 && segment->pids.video.pid != p_pids->video.pid) {
2021 //stop video
2022 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
2023 }
2024 if (VALID_PID(segment->pids.audio.pid)
2025 && VALID_PID(p_pids->audio.pid)
2026 && segment->pids.audio.pid != p_pids->audio.pid) {
2027 //restart audio
2028 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
2029 }
2030 if (!VALID_PID(segment->pids.audio.pid)
2031 && VALID_PID(p_pids->audio.pid)
2032 && segment->pids.audio.pid != p_pids->audio.pid) {
2033 //start audio
2034 a_cmd = DVR_PLAYBACK_CMD_ASTART;
2035 }
2036 if (VALID_PID(segment->pids.audio.pid)
2037 && !VALID_PID(p_pids->audio.pid)
2038 && segment->pids.audio.pid != p_pids->audio.pid) {
2039 //stop audio
2040 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
2041 }
2042 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2043 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2044 //do nothing
2045 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2046 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2047 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2048 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2049 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2050 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
2051 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2052 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2053 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2054 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2055 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2056 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2057 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2058 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
2059 } else {
2060 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2061 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
2062 }
2063
2064 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2065 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2066 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2067 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
2068 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2069 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2070 //not occur this case
2071 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2072 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2073 } else {
2074 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2075 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
2076 }
2077
2078 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2079 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2080 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2081 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
2082 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2083 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
2084 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2085 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
2086 } else {
2087 //not occur this case
2088 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2089 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2090 }
2091 }
2092 }
hualing chene10666f2020-04-14 13:58:37 +08002093 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002094 }
hualing chen86e7d482020-01-16 15:13:33 +08002095 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08002096 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002097 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08002098 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002099 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002100 }
hualing chen86e7d482020-01-16 15:13:33 +08002101 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002102 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002103 pthread_mutex_unlock(&player->lock);
2104 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002105}
2106/**\brief Stop play, will stop video and audio
2107 * \param[in] handle playback handle
2108 * \param[in] clear is clear last frame
2109 * \retval DVR_SUCCESS On success
2110 * \return Error code
2111 */
hualing chen040df222020-01-17 13:35:02 +08002112int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2113 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002114 UNDVRUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002115 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002116 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002117 return DVR_FAILURE;
2118 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002119 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2120 DVR_PB_DG(1, ":playback is stoped");
2121 return DVR_SUCCESS;
2122 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002123 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2124 DVR_PB_DG(1, ":playback is stoped");
2125 return DVR_SUCCESS;
2126 }
hualing chen87072a82020-03-12 16:20:12 +08002127 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08002128 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002129 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002130 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002131 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002132 if (player->has_video) {
2133 AmTsPlayer_resumeVideoDecoding(player->handle);
2134 }
2135 if (player->has_audio) {
2136 AmTsPlayer_resumeAudioDecoding(player->handle);
2137 }
2138 if (player->has_video) {
2139 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002140 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002141 AmTsPlayer_stopVideoDecoding(player->handle);
2142 }
2143 if (player->has_audio) {
2144 player->has_audio = DVR_FALSE;
2145 AmTsPlayer_stopAudioDecoding(player->handle);
2146 }
hualing chendf118dd2020-05-21 15:49:11 +08002147 if (player->has_ad_audio) {
2148 player->has_ad_audio =DVR_FALSE;
2149 AmTsPlayer_disableADMix(player->handle);
2150 }
hualing chen266b9502020-04-04 17:39:39 +08002151
hualing chen86e7d482020-01-16 15:13:33 +08002152 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002153 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2154 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2155 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002156 player->cur_segment_id = UINT64_MAX;
2157 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002158 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08002159 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08002160 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002161 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002162}
2163/**\brief Start play audio
2164 * \param[in] handle playback handle
2165 * \param[in] params audio playback params,contains fmt and pid...
2166 * \retval DVR_SUCCESS On success
2167 * \return Error code
2168 */
hualing chen2aba4022020-03-02 13:49:55 +08002169
hualing chendf118dd2020-05-21 15:49:11 +08002170int dvr_playback_audio_start(DVR_PlaybackHandle_t handle, am_tsplayer_audio_params *param, am_tsplayer_audio_params *adparam) {
hualing chen040df222020-01-17 13:35:02 +08002171 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002172
2173 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002174 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002175 return DVR_FAILURE;
2176 }
hualing chen86e7d482020-01-16 15:13:33 +08002177 _start_playback_thread(handle);
2178 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002179 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002180 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002181
hualing chendf118dd2020-05-21 15:49:11 +08002182 if (VALID_PID(adparam->pid)) {
2183 player->has_ad_audio = DVR_TRUE;
2184 DVR_PB_DG(1, "start ad audio");
2185 AmTsPlayer_setADParams(player->handle, adparam);
2186 AmTsPlayer_enableADMix(player->handle);
2187 }
hualing chen969fe7b2021-05-26 15:13:17 +08002188 if (VALID_PID(param->pid)) {
2189 DVR_PB_DG(1, "start audio");
2190 player->has_audio = DVR_TRUE;
2191 AmTsPlayer_setAudioParams(player->handle, param);
2192 AmTsPlayer_startAudioDecoding(player->handle);
2193 }
hualing chendf118dd2020-05-21 15:49:11 +08002194
hualing chen86e7d482020-01-16 15:13:33 +08002195 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002196 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
2197 player->cmd.state = DVR_PLAYBACK_STATE_START;
2198 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002199 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002200 pthread_mutex_unlock(&player->lock);
2201 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002202}
2203/**\brief Stop play audio
2204 * \param[in] handle playback handle
2205 * \retval DVR_SUCCESS On success
2206 * \return Error code
2207 */
hualing chen040df222020-01-17 13:35:02 +08002208int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2209 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002210
2211 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002212 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002213 return DVR_FAILURE;
2214 }
2215
hualing chen2aba4022020-03-02 13:49:55 +08002216 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002217 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002218 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2219 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002220 //destory thread
2221 _stop_playback_thread(handle);
2222 } else {
2223 //do nothing.video is playing
2224 }
hualing chen7a56cba2020-04-14 14:09:27 +08002225 DVR_PB_DG(1, "lock");
2226 pthread_mutex_lock(&player->lock);
2227
hualing chenf00cdc82020-06-10 14:23:35 +08002228 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002229 player->has_audio = DVR_FALSE;
2230 AmTsPlayer_stopAudioDecoding(player->handle);
2231 }
hualing chen87072a82020-03-12 16:20:12 +08002232
hualing chendf118dd2020-05-21 15:49:11 +08002233 if (player->has_ad_audio) {
2234 player->has_ad_audio =DVR_FALSE;
2235 AmTsPlayer_disableADMix(player->handle);
2236 }
2237
hualing chen87072a82020-03-12 16:20:12 +08002238 player->cmd.last_cmd = player->cmd.cur_cmd;
2239 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2240
hualing chen4b7c15d2020-04-07 16:13:48 +08002241 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002242 pthread_mutex_unlock(&player->lock);
2243 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002244}
2245/**\brief Start play video
2246 * \param[in] handle playback handle
2247 * \param[in] params video playback params,contains fmt and pid...
2248 * \retval DVR_SUCCESS On success
2249 * \return Error code
2250 */
hualing chen2aba4022020-03-02 13:49:55 +08002251int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002252 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002253
2254 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002255 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002256 return DVR_FAILURE;
2257 }
2258
hualing chen86e7d482020-01-16 15:13:33 +08002259 _start_playback_thread(handle);
2260 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002261 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002262 pthread_mutex_lock(&player->lock);
2263 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002264 AmTsPlayer_setVideoParams(player->handle, param);
2265 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002266
2267 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002268 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002269 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002270 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002271 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2272 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002273 }
2274 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002275 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2276 player->cmd.state = DVR_PLAYBACK_STATE_START;
2277 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002278 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002279 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002280 return DVR_SUCCESS;
2281}
2282/**\brief Stop play video
2283 * \param[in] handle playback handle
2284 * \retval DVR_SUCCESS On success
2285 * \return Error code
2286 */
hualing chen040df222020-01-17 13:35:02 +08002287int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2288 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002289
2290 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002291 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002292 return DVR_FAILURE;
2293 }
2294
hualing chen86e7d482020-01-16 15:13:33 +08002295 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002296 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2297 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002298 //destory thread
2299 _stop_playback_thread(handle);
2300 } else {
2301 //do nothing.audio is playing
2302 }
hualing chen7a56cba2020-04-14 14:09:27 +08002303
2304 DVR_PB_DG(1, "lock");
2305 pthread_mutex_lock(&player->lock);
2306
hualing chen87072a82020-03-12 16:20:12 +08002307 player->has_video = DVR_FALSE;
2308
2309 AmTsPlayer_stopVideoDecoding(player->handle);
2310 //playback_device_video_stop(player->handle);
2311
2312 player->cmd.last_cmd = player->cmd.cur_cmd;
2313 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2314
hualing chen4b7c15d2020-04-07 16:13:48 +08002315 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002316 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002317 return DVR_SUCCESS;
2318}
2319/**\brief Pause play
2320 * \param[in] handle playback handle
2321 * \param[in] flush whether its internal buffers should be flushed
2322 * \retval DVR_SUCCESS On success
2323 * \return Error code
2324 */
hualing chen040df222020-01-17 13:35:02 +08002325int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2326 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002327 UNDVRUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002328 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002329 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002330 return DVR_FAILURE;
2331 }
hualing chenf00cdc82020-06-10 14:23:35 +08002332 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
2333 DVR_PB_DG(1, "player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002334 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002335 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002336 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002337 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002338 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002339 if (player->has_video)
2340 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002341 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002342 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002343
2344 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002345 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2346 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2347 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2348 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002349 } else {
2350 player->cmd.last_cmd = player->cmd.cur_cmd;
2351 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2352 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2353 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002354 }
hualing chen86e7d482020-01-16 15:13:33 +08002355 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002356 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002357
hualing chen86e7d482020-01-16 15:13:33 +08002358 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002359}
2360
hualing chen5cbe1a62020-02-10 16:36:36 +08002361//not add lock
2362static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2363{
2364 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2365
hualing chena540a7e2020-03-27 16:44:05 +08002366 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002367 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002368 return DVR_FAILURE;
2369 }
2370
hualing chen5cbe1a62020-02-10 16:36:36 +08002371 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002372 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002373 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002374 am_tsplayer_video_params vparams;
2375 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002376 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002377 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002378
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002379 memset(&vparams, 0, sizeof(vparams));
2380 memset(&aparams, 0, sizeof(aparams));
2381
hualing chendf118dd2020-05-21 15:49:11 +08002382 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002383 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002384 pthread_mutex_unlock(&player->lock);
2385
2386 switch (cmd) {
2387 case DVR_PLAYBACK_CMD_AVRESTART:
2388 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002389 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002390 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002391 break;
2392 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002393 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2394 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002395 break;
2396 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002397 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002398 break;
2399 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002400 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002401 break;
2402 case DVR_PLAYBACK_CMD_ARESTART:
2403 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002404 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002405 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002406 break;
2407 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002408 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002409 break;
2410 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002411 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002412 break;
2413 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002414 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2415 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2416 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002417 break;
2418 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002419 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2420 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002421 break;
2422 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002423 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2424 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002425 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002426 break;
2427 case DVR_PLAYBACK_CMD_STOP:
2428 break;
2429 case DVR_PLAYBACK_CMD_START:
2430 break;
2431 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002432 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2433 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002434 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002435 break;
2436 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002437 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2438 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002439 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002440 break;
2441 case DVR_PLAYBACK_CMD_FF:
2442 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002443 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002444 break;
2445 default:
2446 break;
2447 }
2448 return DVR_SUCCESS;
2449}
2450
2451/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002452 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002453 * \retval DVR_SUCCESS On success
2454 * \return Error code
2455 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002456int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2457 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002458 int pos = 0;
2459 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002460 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002461 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002462 return DVR_FAILURE;
2463 }
2464
hualing chena991aa82021-08-16 10:21:15 +08002465 if (dvr_playback_check_limit(handle)) {
2466 //get id and pos to check if we can seek to this pos
2467 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2468 if (segmentid != player->cur_segment_id ||
2469 (segmentid == player->cur_segment_id &&
2470 pos > _dvr_get_cur_time(handle))) {
2471 //first to seek new pos and to resume
2472 DVR_PB_DG(1, "seek new pos and to resume");
2473 dvr_playback_seek(handle, segmentid, pos);
2474 }
hualing chen03fd4942021-07-15 15:56:41 +08002475 }
hualing chena991aa82021-08-16 10:21:15 +08002476
hualing chen5cbe1a62020-02-10 16:36:36 +08002477 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002478 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002479 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002480 player->first_frame = 0;
2481 if (player->has_video)
2482 AmTsPlayer_pauseVideoDecoding(player->handle);
2483 if (player->has_audio)
2484 AmTsPlayer_pauseAudioDecoding(player->handle);
2485
hualing chen266b9502020-04-04 17:39:39 +08002486 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002487 DVR_PB_DG(1, "dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002488 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2489 AmTsPlayer_resumeVideoDecoding(player->handle);
2490 }
2491 if (player->has_audio) {
2492 AmTsPlayer_resumeAudioDecoding(player->handle);
2493 }
2494 //check is has audio param,if has audio .we need start audio,
2495 //we will stop audio when ff fb, if reach end, we will pause.so we need
2496 //start audio when resume play
2497
2498 am_tsplayer_video_params vparams;
2499 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002500 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002501 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002502
2503 memset(&vparams, 0, sizeof(vparams));
2504 memset(&aparams, 0, sizeof(aparams));
hualing chendf118dd2020-05-21 15:49:11 +08002505 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002506 //valid audio pid, start audio
hualing chen969fe7b2021-05-26 15:13:17 +08002507 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2508 player->has_ad_audio = DVR_TRUE;
2509 DVR_PB_DG(1, "start ad audio");
2510 AmTsPlayer_setADParams(player->handle, &adparams);
2511 AmTsPlayer_enableADMix(player->handle);
2512 }
2513
hualing chenc70a8df2020-05-12 19:23:11 +08002514 if (player->has_audio == DVR_FALSE && VALID_PID(aparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
hualing chen266b9502020-04-04 17:39:39 +08002515 player->has_audio = DVR_TRUE;
2516 AmTsPlayer_setAudioParams(player->handle, &aparams);
2517 AmTsPlayer_startAudioDecoding(player->handle);
2518 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002519 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d speed:%d", aparams.pid, player->has_audio, player->cmd.speed.speed.speed);
hualing chen266b9502020-04-04 17:39:39 +08002520 }
hualing chendf118dd2020-05-21 15:49:11 +08002521
hualing chen87072a82020-03-12 16:20:12 +08002522 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2523 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2524 player->cmd.state = DVR_PLAYBACK_STATE_START;
2525 player->state = DVR_PLAYBACK_STATE_START;
2526 } else {
2527 player->cmd.last_cmd = player->cmd.cur_cmd;
2528 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2529 player->cmd.state = DVR_PLAYBACK_STATE_START;
2530 player->state = DVR_PLAYBACK_STATE_START;
2531 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002532 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002533 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002534 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
hualing chen1ffd85b2021-08-16 15:18:43 +08002535 player->first_frame = 0;
2536 if (player->has_video)
2537 AmTsPlayer_pauseVideoDecoding(player->handle);
2538 if (player->has_audio)
2539 AmTsPlayer_pauseAudioDecoding(player->handle);
2540
hualing chene41f4372020-06-06 16:29:17 +08002541 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002542 DVR_PB_DG(1, "dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002543 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002544 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002545 }
hualing chen041c4092020-04-05 15:11:50 +08002546 if (player->has_audio)
2547 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002548 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002549 player->cmd.state = DVR_PLAYBACK_STATE_START;
2550 player->state = DVR_PLAYBACK_STATE_START;
hualing chen9811b212020-10-29 11:21:44 +08002551 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2552 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002553 } else {
2554 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2555 {
2556 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002557 player->first_frame = 0;
2558 if (player->has_video)
2559 AmTsPlayer_pauseVideoDecoding(player->handle);
2560 if (player->has_audio)
2561 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002562 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002563 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002564 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2565 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002566 if (player->has_video) {
2567 AmTsPlayer_resumeVideoDecoding(player->handle);
2568 }
2569 if (player->has_audio)
2570 AmTsPlayer_resumeAudioDecoding(player->handle);
2571
hualing chen041c4092020-04-05 15:11:50 +08002572 pthread_mutex_unlock(&player->lock);
2573 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002574 }
2575 return DVR_SUCCESS;
2576}
2577
hualing chena540a7e2020-03-27 16:44:05 +08002578static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2579
2580 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2581 DVR_PlaybackSegmentInfo_t *segment = NULL;
2582 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2583 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2584
2585 list_for_each_entry(segment, &player->segment_list, head)
2586 {
2587 if (segment->segment_id == segment_id) {
2588 cur_segment = segment;
2589 }
2590 if (segment->segment_id == set_seg_id) {
2591 set_segment = segment;
2592 }
2593 if (cur_segment != NULL && set_segment != NULL) {
2594 break;
2595 }
2596 }
2597 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002598 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002599 return DVR_TRUE;
2600 }
2601 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2602 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2603 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2604 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002605 DVR_PB_DG(1, "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 +08002606 return DVR_TRUE;
2607 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002608 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002609 return DVR_FALSE;
2610}
2611
hualing chen03fd4942021-07-15 15:56:41 +08002612/**\brief set limit
2613 * \param[in] handle playback handle
2614 * \param[in] rec start time ms
2615 * \param[in] rec limit time ms
2616 * \retval DVR_SUCCESS On success
2617 * \return Error code
2618 */
2619int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint64_t time, int32_t limit)
2620{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2621
2622 if (player == NULL) {
2623 DVR_PB_DG(1, "player is NULL");
2624 return DVR_FAILURE;
2625 }
2626
2627 DVR_PB_DG(1, "time %lld limit: %d player->state:%d", time, limit, player->state);
2628 pthread_mutex_lock(&player->lock);
2629 player->rec_start = time;
2630 player->limit = limit;
2631 pthread_mutex_unlock(&player->lock);
2632 return DVR_SUCCESS;
2633}
2634
hualing chen5cbe1a62020-02-10 16:36:36 +08002635/**\brief seek
2636 * \param[in] handle playback handle
2637 * \param[in] time_offset time offset base cur segment
2638 * \retval DVR_SUCCESS On success
2639 * \return Error code
2640 */
hualing chencc91e1c2020-02-28 13:26:17 +08002641int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002642 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002643 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08002644 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002645 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002646 return DVR_FAILURE;
2647 }
2648
hualing chen4b7c15d2020-04-07 16:13:48 +08002649 DVR_PB_DG(1, "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);
hualing chen86e7d482020-01-16 15:13:33 +08002650 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002651
hualing chen86e7d482020-01-16 15:13:33 +08002652 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002653 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002654 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002655
hualing chen5cbe1a62020-02-10 16:36:36 +08002656 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08002657 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002658 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002659 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002660 pthread_mutex_unlock(&player->lock);
2661 return DVR_FAILURE;
2662 }
2663 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2664 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002665 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002666 //pthread_mutex_unlock(&player->lock);
2667 //return DVR_SUCCESS;
2668 time_offset = _dvr_get_end_time(handle);
2669 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002670 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002671 time_offset = _dvr_get_end_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08002672 //pthread_mutex_unlock(&player->lock);
2673 //return DVR_FAILURE;
2674 ret = DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08002675 }
2676 }
2677
hualing chen03fd4942021-07-15 15:56:41 +08002678 DVR_PB_DG(1, "seek open id[%lld]flag[0x%x] time_offset %u",
2679 player->cur_segment.segment_id,
2680 player->cur_segment.flags,
2681 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08002682 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002683 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2684 //forward playback.not seek end of file
2685 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2686 //default -2000ms
2687 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2688 }
hualing chen86e7d482020-01-16 15:13:33 +08002689 }
hualing chen2aba4022020-03-02 13:49:55 +08002690 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002691 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002692 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002693 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002694 DVR_PB_DG(0, "seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08002695 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002696 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002697
hualing chen2aba4022020-03-02 13:49:55 +08002698 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002699
2700 player->last_send_time_id = UINT64_MAX;
hualing chen03fd4942021-07-15 15:56:41 +08002701 player->last_segment_tatol = 0LL;
2702 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08002703 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002704 player->fffb_current = _dvr_time_getClock();
2705 player->fffb_start = player->fffb_current;
2706 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2707 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002708 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002709 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002710 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002711 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002712 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002713 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002714 }
hualing chen86e7d482020-01-16 15:13:33 +08002715 //stop play
hualing chen03fd4942021-07-15 15:56:41 +08002716 DVR_PB_DG(0, "seek stop play, not inject data has video[%d]audio[%d]",
2717 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08002718
hualing chen266b9502020-04-04 17:39:39 +08002719 if (player->has_video) {
2720 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002721 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002722 }
2723
2724 if (player->has_audio) {
2725 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002726 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002727 }
hualing chendf118dd2020-05-21 15:49:11 +08002728 if (player->has_ad_audio) {
2729 player->has_ad_audio =DVR_FALSE;
2730 AmTsPlayer_disableADMix(player->handle);
2731 }
2732
hualing chen86e7d482020-01-16 15:13:33 +08002733 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002734 am_tsplayer_video_params vparams;
2735 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002736 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002737
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002738 memset(&vparams, 0, sizeof(vparams));
2739 memset(&aparams, 0, sizeof(aparams));
2740
hualing chen040df222020-01-17 13:35:02 +08002741 player->cur_segment_id = segment_id;
2742
2743 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002744 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002745 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002746 //start audio and video
Zhiqiang Han9adc9722020-11-11 18:38:10 +08002747 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08002748 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002749 DVR_PB_DG(0, "unlock seek start dvr play back start error, not found audio and video info");
hualing chen86e7d482020-01-16 15:13:33 +08002750 pthread_mutex_unlock(&player->lock);
2751 return -1;
2752 }
2753 //add
hualing chen040df222020-01-17 13:35:02 +08002754 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002755 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002756 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002757 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08002758 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002759 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002760 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002761 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002762 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002763 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002764 }
hualing chen2aba4022020-03-02 13:49:55 +08002765 AmTsPlayer_setVideoParams(player->handle, &vparams);
2766 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002767 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
2768 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
2769 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2770 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2771 AmTsPlayer_stopFast(player->handle);
2772 }
hualing chen266b9502020-04-04 17:39:39 +08002773 player->has_video = DVR_TRUE;
hualing chenb31a6c62020-01-13 17:27:00 +08002774 }
hualing chene41f4372020-06-06 16:29:17 +08002775 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08002776 player->has_ad_audio = DVR_TRUE;
2777 DVR_PB_DG(1, "start ad audio");
2778 AmTsPlayer_setADParams(player->handle, &adparams);
2779 AmTsPlayer_enableADMix(player->handle);
2780 }
hualing chen969fe7b2021-05-26 15:13:17 +08002781 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
2782 DVR_PB_DG(1, "start audio seek");
2783 AmTsPlayer_setAudioParams(player->handle, &aparams);
2784 AmTsPlayer_startAudioDecoding(player->handle);
2785 player->has_audio = DVR_TRUE;
2786 }
hualing chen86e7d482020-01-16 15:13:33 +08002787 }
hualing chen1ffd85b2021-08-16 15:18:43 +08002788 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen2aba4022020-03-02 13:49:55 +08002789 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2790 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen30423862021-04-16 14:39:12 +08002791 player->seek_pause = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002792 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002793 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2794 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002795 player->speed > 1.0f||
2796 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002797 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002798 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002799 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002800 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002801 player->cmd.last_cmd = player->cmd.cur_cmd;
2802 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2803 player->cmd.state = DVR_PLAYBACK_STATE_START;
2804 player->state = DVR_PLAYBACK_STATE_START;
2805 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002806 player->last_send_time_id = UINT64_MAX;
2807 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002808 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002809
2810 return DVR_SUCCESS;
2811}
hualing chen5cbe1a62020-02-10 16:36:36 +08002812
hualing chen5cbe1a62020-02-10 16:36:36 +08002813static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2814 //get cur time of segment
2815 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002816
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002817 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002818 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002819 return DVR_FAILURE;
2820 }
2821
hualing chen31140872020-03-25 12:29:26 +08002822 int64_t cache = 0;//defalut es buf cache 500ms
2823 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002824 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002825 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2826 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen2aba4022020-03-02 13:49:55 +08002827 pthread_mutex_unlock(&player->segment_lock);
hualing chenfbf8e022020-06-15 13:43:11 +08002828 DVR_PB_DG(1, "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 +08002829 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2830 cache = 0;
2831 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002832 int cur_time = (int)(cur > cache ? cur - cache : 0);
2833 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002834}
2835
hualing chen969fe7b2021-05-26 15:13:17 +08002836static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
2837 //get cur time of segment
2838 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2839
hualing chen03fd4942021-07-15 15:56:41 +08002840 if (player == NULL || player->handle == 0) {
hualing chen969fe7b2021-05-26 15:13:17 +08002841 DVR_PB_DG(1, "player is NULL");
2842 return DVR_FAILURE;
2843 }
2844
2845 int64_t cache = 0;//defalut es buf cache 500ms
2846 int cur_time = 0;
2847 AmTsPlayer_getDelayTime(player->handle, &cache);
2848 pthread_mutex_lock(&player->segment_lock);
2849 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2850 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
2851 pthread_mutex_unlock(&player->segment_lock);
2852 DVR_PB_DG(1, "get play 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);
2853 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2854 cache = 0;
2855 }
2856 if (cur > cache) {
2857 cur_time = (int)(cur - cache);
2858 *id = player->cur_segment_id;
2859 } else if (player->last_segment_tatol > 0) {
hualing chen969fe7b2021-05-26 15:13:17 +08002860 cur_time = (int)(player->last_segment_tatol - (cache - cur));
2861 *id = player->last_segment_id;
2862 DVR_PB_DG(1, "get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_tatol);
2863 } else {
2864 cur_time = 0;
2865 *id = player->cur_segment_id;
2866 }
2867
2868 return cur_time;
2869}
2870
hualing chencc91e1c2020-02-28 13:26:17 +08002871//get current segment current pcr time of read pos
2872static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2873 //get cur time of segment
2874 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002875
2876 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002877 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002878 return DVR_FAILURE;
2879 }
2880
hualing chen2aba4022020-03-02 13:49:55 +08002881 pthread_mutex_lock(&player->segment_lock);
2882 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002883 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002884 pthread_mutex_unlock(&player->segment_lock);
2885 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002886}
2887
hualing chen03fd4942021-07-15 15:56:41 +08002888DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
2889{
2890 //check is set limit info
2891 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2892
2893 if (player == NULL) {
2894 DVR_PB_DG(1, "player is NULL");
2895 return DVR_FALSE;
2896 }
2897 if (player->rec_start > 0 || player->limit > 0) {
2898 return DVR_TRUE;
2899 }
2900 return DVR_FALSE;
2901}
2902
2903/**\brief set DVR playback calculate expired time len
2904 * \param[in] handle, DVR playback session handle
2905 * \return DVR_SUCCESS on success
2906 * \return error code on failure
2907 */
2908int dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
2909{
2910 //calculate expired time to play
2911 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2912 uint64_t cur_time;
2913 int expired = 0;
2914 if (player == NULL) {
2915 DVR_PB_DG(1, "player is NULL");
2916 return expired;
2917 }
2918 if (player->rec_start < 0 || player->limit < 0) {
2919 return expired;
2920 }
2921 //get system time
2922 cur_time = _dvr_time_getClock();
2923 if ((cur_time - player->rec_start) > player->limit)
2924 expired = cur_time - player->rec_start - player->limit;
2925 DVR_PB_DG(1, "cur_time:%lld, rec start:%lld limit:%d c_r_diff:%lld",
2926 cur_time,
2927 player->rec_start,
2928 player->limit,
2929 cur_time - player->rec_start);
2930 return expired;
2931}
2932
2933/**\brief set DVR playback obsolete time
2934 * \param[in] handle, DVR playback session handle
2935 * \param[in] obsolete, obsolete len
2936 * \return DVR_SUCCESS on success
2937 * \return error code on failure
2938 */
2939int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
2940{
2941 int expired = 0;
2942 //calculate expired time to play
2943 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2944
2945 if (player == NULL) {
2946 DVR_PB_DG(1, "player is NULL");
2947 return DVR_FALSE;
2948 }
2949 //get system time
2950 pthread_mutex_lock(&player->lock);
2951 player->obsolete = obsolete;
2952 pthread_mutex_unlock(&player->lock);
2953 return expired;
2954}
2955
2956/**\brief update DVR playback newest segment duration
2957 * \param[in] handle, DVR playback session handle
2958 * \param[in] segmentid, newest segment id
2959 * \param[in] dur dur time ms
2960 * \return DVR_SUCCESS on success
2961 * \return error code on failure
2962 */
2963int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
2964uint64_t segmentid, int dur)
2965{
2966 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2967 DVR_PlaybackSegmentInfo_t *segment;
2968 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
2969
2970 if (player == NULL) {
2971 DVR_PB_DG(1, " player is NULL");
2972 return DVR_FAILURE;
2973 }
2974 //update the newest segment duration on timeshift mode
2975 list_for_each_entry(segment, &player->segment_list, head)
2976 {
2977 if (segment->segment_id == segmentid) {
2978 segment->duration = dur;
2979 break;
2980 }
2981 pre_segment = segment;
2982 }
2983
2984 return DVR_SUCCESS;
2985}
2986
2987static int dvr_playback_calculate_last_valid_segment(
2988 DVR_PlaybackHandle_t handle, uint64_t *segmentid, int *pos)
2989{
2990 int off = 0;
2991 uint64_t segment_id = 0;
2992 int pre_off = 0;
2993 uint64_t last_segment_id = 0;
2994 int expired = 0;
2995 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2996
2997 if (player == NULL) {
2998 DVR_PB_DG(1, "player is NULL");
2999 return DVR_FAILURE;
3000 }
3001 expired = dvr_playback_calculate_expiredlen(handle);
3002 DVR_PlaybackSegmentInfo_t *pseg;
3003 list_for_each_entry_reverse(pseg, &player->segment_list, head) {
3004 segment_id = pseg->segment_id;
3005
3006 if ((player->obsolete + pre_off + pseg->duration) > expired)
3007 break;
3008
3009 last_segment_id = pseg->segment_id;
3010 pre_off += pseg->duration;
3011 }
3012
3013 if (last_segment_id == segment_id) {
3014 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3015 off = expired;
3016 } else if (player->obsolete >= expired) {
3017 off = 0;
3018 } else {
3019 off = expired - pre_off - player->obsolete;
3020 }
3021 *segmentid = segment_id;
3022 *pos = off;
3023 return DVR_SUCCESS;
3024}
3025
hualing chen4b7c15d2020-04-07 16:13:48 +08003026#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003027//start replay
3028static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3029
3030 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3031 //calculate pcr seek time
3032 int t_diff = 0;
3033 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003034 uint64_t segmentid = 0;
3035 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003036 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003037 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003038 return DVR_FAILURE;
3039 }
3040
hualing chen5cbe1a62020-02-10 16:36:36 +08003041 if (player->fffb_start == -1) {
3042 //set fffb start time ms
3043 player->fffb_start = _dvr_time_getClock();
3044 player->fffb_current = player->fffb_start;
3045 //get segment current time pos
3046 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08003047 DVR_PB_DG(1, "calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
3048 player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003049 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08003050 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003051 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003052 } else {
3053 player->fffb_current = _dvr_time_getClock();
3054 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003055 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003056 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003057 if (seek_time <= 0) {
3058 //need seek to pre one segment
3059 seek_time = 0;
3060 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003061 //seek segment pos
3062 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003063 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003064 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003065 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3066 //set seek time to 0;
hualing chen03fd4942021-07-15 15:56:41 +08003067 DVR_PB_DG(1, "segment seek to 0 at fb mode [%d]id[%lld]",
3068 seek_time,
3069 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003070 seek_time = 0;
3071 }
hualing chen03fd4942021-07-15 15:56:41 +08003072 if (IS_FB(player->speed)
3073 && dvr_playback_check_limit(handle)) {
3074 //fb case.check expired time
3075 //get id and pos to check if we can seek to this pos
3076 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3077 //case cur id < segment id
3078 if (player->cur_segment_id < segmentid) {
3079 //expired ts data is player,return error
3080 //
3081 pthread_mutex_unlock(&player->segment_lock);
3082 return 0;
3083 } else if (player->cur_segment_id == segmentid) {
3084 //id is same,compare seek pos
3085 if (seek_time < pos) {
3086 //expired ts data is player,return error
3087 //
3088 pthread_mutex_unlock(&player->segment_lock);
3089 return 0;
3090 }
3091 }
3092 //case can play
3093 }
hualing chen041c4092020-04-05 15:11:50 +08003094 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
3095 seek_time = 0;
3096 }
hualing chen2aba4022020-03-02 13:49:55 +08003097 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003098 } else {
3099 //
hualing chen4b7c15d2020-04-07 16:13:48 +08003100 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003101 }
hualing chen03fd4942021-07-15 15:56:41 +08003102 DVR_PB_DG(1, "calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
3103 seek_time,
3104 player->speed,
3105 player->cur_segment_id,
3106 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003107 }
hualing chen2aba4022020-03-02 13:49:55 +08003108 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003109}
3110
3111
3112//start replay
3113static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3114 //
3115 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003116
3117 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003118 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003119 return DVR_FAILURE;
3120 }
3121
hualing chen5cbe1a62020-02-10 16:36:36 +08003122 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003123 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003124 DVR_PB_DG(1, "fffb stop video");
hualing chen2aba4022020-03-02 13:49:55 +08003125 AmTsPlayer_stopVideoDecoding(player->handle);
3126 }
3127 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003128 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003129 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003130 AmTsPlayer_stopAudioDecoding(player->handle);
3131 }
hualing chendf118dd2020-05-21 15:49:11 +08003132 if (player->has_ad_audio) {
3133 DVR_PB_DG(1, "fffb stop audio");
3134 player->has_ad_audio =DVR_FALSE;
3135 AmTsPlayer_disableADMix(player->handle);
3136 }
hualing chen2aba4022020-03-02 13:49:55 +08003137
hualing chen5cbe1a62020-02-10 16:36:36 +08003138 //start video and audio
3139
hualing chen2aba4022020-03-02 13:49:55 +08003140 am_tsplayer_video_params vparams;
3141 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003142 am_tsplayer_audio_params adparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003143
3144 memset(&vparams, 0, sizeof(vparams));
3145 memset(&aparams, 0, sizeof(aparams));
3146
hualing chen87072a82020-03-12 16:20:12 +08003147 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003148
3149 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08003150 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08003151 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003152 //start audio and video
3153 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
3154 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08003155 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08003156 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003157 return -1;
3158 }
3159
3160 if (VALID_PID(vparams.pid)) {
3161 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08003162 DVR_PB_DG(1, "fffb start video");
hualing chen0888c032020-12-18 17:54:57 +08003163 //DVR_PB_DG(1, "fffb start video and save last frame");
3164 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003165 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003166 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
3167 AmTsPlayer_setVideoParams(player->handle, &vparams);
3168 AmTsPlayer_startVideoDecoding(player->handle);
3169 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003170 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003171 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003172 }
hualing chen31140872020-03-25 12:29:26 +08003173 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08003174 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08003175 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08003176 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003177 return 0;
3178}
3179
3180static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3181 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003182 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003183 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003184 return DVR_FAILURE;
3185 }
3186
3187 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08003188 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003189 pthread_mutex_lock(&player->lock);
3190
hualing chen2aba4022020-03-02 13:49:55 +08003191 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003192 DVR_PB_DG(1, "get lock speed [%f]id [%lld]seek_time[%d]", player->speed, player->cur_segment_id, seek_time);
hualing chen041c4092020-04-05 15:11:50 +08003193
hualing chen87072a82020-03-12 16:20:12 +08003194 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3195 //seek time set 0
3196 seek_time = 0;
3197 }
hualing chen041c4092020-04-05 15:11:50 +08003198 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003199 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3200 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003201 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003202 pthread_mutex_unlock(&player->lock);
3203 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003204 //send event here and pause
3205 DVR_Play_Notify_t notify;
3206 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003207 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003208 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003209 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08003210 DVR_PB_DG(1, "*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08003211 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003212 return DVR_SUCCESS;
3213 }
hualing chen2932d372020-04-29 13:44:00 +08003214 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003215 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003216 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003217 }
3218 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003219 _dvr_playback_fffb_replay(handle);
3220
3221 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003222 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003223
hualing chen5cbe1a62020-02-10 16:36:36 +08003224 return DVR_SUCCESS;
3225}
3226
hualing chen87072a82020-03-12 16:20:12 +08003227//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003228static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003229 //
3230 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003231
3232 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003233 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003234 return DVR_FAILURE;
3235 }
3236
hualing chen5cbe1a62020-02-10 16:36:36 +08003237 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003238 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003239 player->has_video = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003240 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003241 }
3242
3243 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003244 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003245 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003246 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003247 //start video and audio
3248
hualing chen2aba4022020-03-02 13:49:55 +08003249 am_tsplayer_video_params vparams;
3250 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003251 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08003252 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003253
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003254 memset(&vparams, 0, sizeof(vparams));
3255 memset(&aparams, 0, sizeof(aparams));
3256
hualing chen5cbe1a62020-02-10 16:36:36 +08003257 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08003258 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08003259 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003260 //start audio and video
3261 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003262 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08003263 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003264 return -1;
3265 }
3266
3267 if (VALID_PID(vparams.pid)) {
3268 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003269 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003270 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003271 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003272 }
hualing chen266b9502020-04-04 17:39:39 +08003273 else {
hualing chen2aba4022020-03-02 13:49:55 +08003274 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003275 }
hualing chen2aba4022020-03-02 13:49:55 +08003276 AmTsPlayer_setVideoParams(player->handle, &vparams);
3277 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003278 }
hualing chena540a7e2020-03-27 16:44:05 +08003279
3280 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08003281 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08003282 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003283 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003284 } else {
hualing chendf118dd2020-05-21 15:49:11 +08003285 if (VALID_PID(adparams.pid)) {
3286 player->has_ad_audio = DVR_TRUE;
3287 DVR_PB_DG(1, "start ad audio");
3288 AmTsPlayer_setADParams(player->handle, &adparams);
3289 AmTsPlayer_enableADMix(player->handle);
3290 }
hualing chen969fe7b2021-05-26 15:13:17 +08003291 if (VALID_PID(aparams.pid)) {
3292 player->has_audio = DVR_TRUE;
3293 DVR_PB_DG(1, "start audio");
3294 AmTsPlayer_setAudioParams(player->handle, &aparams);
3295 AmTsPlayer_startAudioDecoding(player->handle);
3296 }
hualing chendf118dd2020-05-21 15:49:11 +08003297
hualing chen7a56cba2020-04-14 14:09:27 +08003298 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08003299 AmTsPlayer_stopFast(player->handle);
3300 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3301 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3302 }
hualing chen2aba4022020-03-02 13:49:55 +08003303 player->cmd.last_cmd = player->cmd.cur_cmd;
3304 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003305 player->cmd.state = DVR_PLAYBACK_STATE_START;
3306 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08003307 return 0;
3308}
3309
3310
hualing chenb31a6c62020-01-13 17:27:00 +08003311/**\brief Set play speed
3312 * \param[in] handle playback handle
3313 * \param[in] speed playback speed
3314 * \retval DVR_SUCCESS On success
3315 * \return Error code
3316 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003317int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3318
3319 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003320
3321 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003322 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003323 return DVR_FAILURE;
3324 }
3325
hualing chen4b7c15d2020-04-07 16:13:48 +08003326 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003327 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003328 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003329 return DVR_FAILURE;
3330 }
hualing chenf00cdc82020-06-10 14:23:35 +08003331 if (speed.speed.speed == player->cmd.speed.speed.speed) {
3332 DVR_PB_DG(1, " func: eq speed [%d]", speed.speed.speed);
3333 return DVR_SUCCESS;
3334 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003335 pthread_mutex_lock(&player->lock);
3336 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3337 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3338 player->cmd.last_cmd = player->cmd.cur_cmd;
3339 }
hualing chene41f4372020-06-06 16:29:17 +08003340
hualing chen31140872020-03-25 12:29:26 +08003341 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003342 IS_KERNEL_SPEED(speed.speed.speed) ) {
3343 //case 1. not start play.only set speed
3344 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3345 //only set speed.and return;
3346 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3347 player->cmd.speed.speed = speed.speed;
3348 player->speed = (float)speed.speed.speed/(float)100;
3349 player->fffb_play = DVR_FALSE;
3350 pthread_mutex_unlock(&player->lock);
3351 return DVR_SUCCESS;
3352 }
3353 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003354 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3355 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003356 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003357 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3358 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003359 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003360 AmTsPlayer_stopFast(player->handle);
3361 pthread_mutex_unlock(&player->lock);
3362 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
3363 pthread_mutex_lock(&player->lock);
3364 } else {
3365 //set play speed and if audio is start, stop audio.
3366 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003367 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003368 AmTsPlayer_stopAudioDecoding(player->handle);
3369 player->has_audio = DVR_FALSE;
3370 }
hualing chenb96aa2c2020-04-15 14:13:53 +08003371 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003372 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003373 }
hualing chenbcada022020-04-22 14:27:01 +08003374 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003375 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003376 player->cmd.speed.speed = speed.speed;
3377 player->speed = (float)speed.speed.speed/(float)100;
3378 pthread_mutex_unlock(&player->lock);
3379 return DVR_SUCCESS;
3380 }
hualing chen31140872020-03-25 12:29:26 +08003381 //case 3 fffb mode
3382 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3383 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3384 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003385 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003386 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003387 player->cmd.speed.speed = speed.speed;
3388 player->speed = (float)speed.speed.speed/(float)100;
3389 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003390 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003391 pthread_mutex_unlock(&player->lock);
3392 return DVR_SUCCESS;
3393 }
3394 }
3395 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003396 IS_KERNEL_SPEED(speed.speed.speed)) {
3397 //case 1. cur speed is kernel support speed,set kernel speed.
3398 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003399 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003400 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3401 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003402 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003403 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08003404 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003405 } else {
3406 //set play speed and if audio is start, stop audio.
3407 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003408 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003409 AmTsPlayer_stopAudioDecoding(player->handle);
3410 player->has_audio = DVR_FALSE;
3411 }
hualing chenf00cdc82020-06-10 14:23:35 +08003412 DVR_PB_DG(1, "start fast");
3413 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003414 }
hualing chena540a7e2020-03-27 16:44:05 +08003415 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003416 player->cmd.speed.speed = speed.speed;
3417 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003418 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003419 pthread_mutex_unlock(&player->lock);
3420 return DVR_SUCCESS;
3421 }
3422 //case 2 fffb mode
3423 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3424 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3425 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003426 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003427 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003428 player->cmd.speed.speed = speed.speed;
3429 player->speed = (float)speed.speed.speed/(float)100;
3430 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08003431 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003432 pthread_mutex_unlock(&player->lock);
3433 return DVR_SUCCESS;
3434 }
hualing chen31140872020-03-25 12:29:26 +08003435 }
hualing chena540a7e2020-03-27 16:44:05 +08003436 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3437 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003438 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003439 } else {
hualing chen31140872020-03-25 12:29:26 +08003440 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003441 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3442 else
3443 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003444 player->fffb_play = DVR_TRUE;
3445 }
3446 DVR_Bool_t init_last_time = DVR_FALSE;
3447 if (player->speed > 0.0f && speed.speed.speed < 0) {
3448 init_last_time = DVR_TRUE;
3449 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3450 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003451 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003452 player->cmd.speed.mode = speed.mode;
3453 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003454 player->speed = (float)speed.speed.speed/(float)100;
3455 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003456 _dvr_init_fffb_t(handle);
3457 if (init_last_time == DVR_TRUE)
3458 player->last_send_time_id = UINT64_MAX;
3459
hualing chen87072a82020-03-12 16:20:12 +08003460 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003461 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3462 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003463 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003464 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003465 _dvr_playback_replay(handle, DVR_FALSE);
3466 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3467 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
3468 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08003469 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003470 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003471 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08003472 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003473 return DVR_SUCCESS;
3474}
hualing chen2932d372020-04-29 13:44:00 +08003475
hualing chenb31a6c62020-01-13 17:27:00 +08003476/**\brief Get playback status
3477 * \param[in] handle playback handle
3478 * \param[out] p_status playback status
3479 * \retval DVR_SUCCESS On success
3480 * \return Error code
3481 */
hualing chen2932d372020-04-29 13:44:00 +08003482static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3483 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003484//
3485 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003486 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003487 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003488 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003489 return DVR_FAILURE;
3490 }
hualing chen2932d372020-04-29 13:44:00 +08003491 if (is_lock ==DVR_TRUE)
3492 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003493 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003494 //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 +08003495 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3496 player->state == DVR_PLAYBACK_STATE_START) {
3497 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3498 }
hualing chen041c4092020-04-05 15:11:50 +08003499
hualing chencc91e1c2020-02-28 13:26:17 +08003500 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003501 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003502
3503 if (CONTROL_SPEED_ENABLE == 1) {
3504 if (player->con_spe.ply_sta < 0) {
hualing chen03fd4942021-07-15 15:56:41 +08003505 DVR_PB_DG(1, "player dur[%lld] sta[%lld] cur[%d] -----reinit",
3506 player->con_spe.ply_dur,
3507 player->con_spe.ply_sta,
3508 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003509 player->con_spe.ply_sta = p_status->time_cur;
3510 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3511 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
hualing chen03fd4942021-07-15 15:56:41 +08003512 DVR_PB_DG(1, "player dur[%lld] sta[%lld] cur[%d]",
3513 player->con_spe.ply_dur,
3514 player->con_spe.ply_sta,
3515 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003516 player->con_spe.ply_sta = p_status->time_cur;
3517 }
3518
3519 if (player->con_spe.sys_sta == 0) {
3520 player->con_spe.sys_sta = _dvr_time_getClock();
3521 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3522 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3523 player->con_spe.sys_sta = _dvr_time_getClock();
3524 }
3525 }
3526
hualing chen4b7c15d2020-04-07 16:13:48 +08003527 if (player->last_send_time_id == UINT64_MAX) {
3528 player->last_send_time_id = player->cur_segment_id;
3529 player->last_cur_time = p_status->time_cur;
3530 }
3531 if (player->last_send_time_id == player->cur_segment_id) {
3532 if (player->speed > 0.0f ) {
3533 //ff
3534 if (p_status->time_cur < player->last_cur_time ) {
hualing chen03fd4942021-07-15 15:56:41 +08003535 DVR_PB_DG(1, "get ff time error last[%d]cur[%d]diff[%d]",
3536 player->last_cur_time,
3537 p_status->time_cur,
3538 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08003539 p_status->time_cur = player->last_cur_time;
3540 } else {
3541 player->last_cur_time = p_status->time_cur;
3542 }
hualing chene41f4372020-06-06 16:29:17 +08003543 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003544 //fb
3545 if (p_status->time_cur > player->last_cur_time ) {
hualing chen03fd4942021-07-15 15:56:41 +08003546 DVR_PB_DG(1, "get fb time error last[%d]cur[%d]diff[%d]",
3547 player->last_cur_time,
3548 p_status->time_cur,
3549 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08003550 p_status->time_cur = player->last_cur_time;
3551 } else {
3552 player->last_cur_time = p_status->time_cur;
3553 }
3554 }
hualing chend241c7a2021-06-22 13:34:27 +08003555 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003556 player->last_cur_time = p_status->time_cur;
3557 }
hualing chen969fe7b2021-05-26 15:13:17 +08003558 player->last_send_time_id = segment_id;
3559 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003560
hualing chen5cbe1a62020-02-10 16:36:36 +08003561 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003562 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003563 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08003564 DVR_PB_DG(1, "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 +08003565 _dvr_playback_state_toString(player->state),
3566 _dvr_playback_state_toString(p_status->state),
3567 p_status->time_cur, p_status->time_end,
3568 p_status->segment_id,player->play_flag,
3569 player->speed,
3570 is_lock);
hualing chen2932d372020-04-29 13:44:00 +08003571 if (is_lock ==DVR_TRUE)
3572 pthread_mutex_unlock(&player->lock);
3573 return DVR_SUCCESS;
3574}
3575
3576
3577/**\brief Get playback status
3578 * \param[in] handle playback handle
3579 * \param[out] p_status playback status
3580 * \retval DVR_SUCCESS On success
3581 * \return Error code
3582 */
3583int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3584 DVR_PlaybackStatus_t *p_status) {
3585//
3586 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3587
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003588 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3589
hualing chen2932d372020-04-29 13:44:00 +08003590 if (player == NULL) {
3591 DVR_PB_DG(1, "player is NULL");
3592 return DVR_FAILURE;
3593 }
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003594 pthread_mutex_lock(&player->lock);
3595 if (!player->has_video && !player->has_audio)
3596 p_status->time_cur = 0;
3597 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08003598
hualing chenb31a6c62020-01-13 17:27:00 +08003599 return DVR_SUCCESS;
3600}
3601
hualing chen040df222020-01-17 13:35:02 +08003602void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
3603 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003604 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
3605 DVR_PB_DG(1, "segment flag: %d", segment->flags);
3606 DVR_PB_DG(1, "segment location: [%s]", segment->location);
3607 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
3608 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
3609 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3610 DVR_PB_DG(1, "segment sub apid: 0x%x sub afmt:0x%x", segment->pids.ad.pid,segment->pids.ad.format);
hualing chen86e7d482020-01-16 15:13:33 +08003611 }
hualing chenb31a6c62020-01-13 17:27:00 +08003612}
3613
hualing chen5cbe1a62020-02-10 16:36:36 +08003614int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003615 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003616
hualing chena540a7e2020-03-27 16:44:05 +08003617 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003618 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003619 return DVR_FAILURE;
3620 }
3621
hualing chen040df222020-01-17 13:35:02 +08003622 DVR_PlaybackSegmentInfo_t *segment;
3623 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003624 {
hualing chen040df222020-01-17 13:35:02 +08003625 if (segment_id >= 0) {
3626 if (segment->segment_id == segment_id) {
3627 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003628 break;
3629 }
3630 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003631 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003632 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003633 }
3634 }
3635 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003636}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003637
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003638int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003639{
3640 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3641 DVR_RETURN_IF_FALSE(player);
3642 DVR_RETURN_IF_FALSE(func);
3643
hualing chen4b7c15d2020-04-07 16:13:48 +08003644 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003645 pthread_mutex_lock(&player->lock);
3646
3647 player->dec_func = func;
3648 player->dec_userdata = userdata;
3649
3650 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003651 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003652 return DVR_SUCCESS;
3653}
3654
3655int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3656{
3657 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3658 DVR_RETURN_IF_FALSE(player);
3659 DVR_RETURN_IF_FALSE(p_secure_buf);
3660 DVR_RETURN_IF_FALSE(len);
3661
hualing chen4b7c15d2020-04-07 16:13:48 +08003662 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003663 pthread_mutex_lock(&player->lock);
3664
3665 player->is_secure_mode = 1;
3666 player->secure_buffer = p_secure_buf;
3667 player->secure_buffer_size = len;
3668
3669 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003670 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003671 return DVR_SUCCESS;
3672}