blob: 0fb467adf06e9f79752a9c73fb8e4d01b333f289 [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <poll.h>
11#include <errno.h>
12#include <signal.h>
13#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080014#include <errno.h>
hualing chen03fd4942021-07-15 15:56:41 +080015#include "dvr_utils.h"
16#include "dvr_types.h"
hualing chenb31a6c62020-01-13 17:27:00 +080017#include "dvr_playback.h"
Yahui Han1fbf3292021-11-08 18:17:19 +080018#include "am_crypt.h"
hualing chenb31a6c62020-01-13 17:27:00 +080019
Gong Ke2a0ebbe2021-05-25 15:22:50 +080020#define DVR_PB_DG(_level, _fmt...) \
21 DVR_DEBUG_FL(_level, "playback", _fmt)
hualing chena540a7e2020-03-27 16:44:05 +080022
hualing chenb31a6c62020-01-13 17:27:00 +080023#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080024
hualing chend241c7a2021-06-22 13:34:27 +080025#define CONTROL_SPEED_ENABLE 0
hualing chena540a7e2020-03-27 16:44:05 +080026
27#define FF_SPEED (2.0f)
28#define FB_SPEED (-1.0f)
29#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080030#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080031
32#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))
33#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
34
hualing chenb31a6c62020-01-13 17:27:00 +080035
hualing chenb5cd42e2020-04-15 17:03:34 +080036#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080037#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080038//if tsplayer delay time < 200 and no data can read, we will pause
39#define MIN_TSPLAYER_DELAY_TIME (200)
40
hualing chen041c4092020-04-05 15:11:50 +080041#define MAX_CACHE_TIME (30000)
42
hualing chena540a7e2020-03-27 16:44:05 +080043static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080044//
45static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chen99508642021-10-18 15:41:17 +080046static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_PlaybackPids_t now_pids, DVR_PlaybackPids_t pids, int type);
hualing chencc91e1c2020-02-28 13:26:17 +080047static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
48static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080049static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080050static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080051static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
52 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080053static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen7ea70a72021-09-09 11:25:13 +080054static uint32_t dvr_playback_calculate_last_valid_segment(
55 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos);
hualing chen87072a82020-03-12 16:20:12 +080056
hualing chenbcada022020-04-22 14:27:01 +080057
58static char* _cmd_toString(int cmd)
59{
60
61 char *string[DVR_PLAYBACK_CMD_NONE+1]={
62 "start",
63 "stop",
64 "vstart",
65 "astart",
66 "vstop",
67 "astop",
68 "vrestart",
69 "arestart",
70 "avrestart",
71 "vstopastart",
72 "astopvstart",
73 "vstoparestart",
74 "astopvrestart",
75 "vstartarestart",
76 "astartvrestart",
77 "pause",
78 "resume",
79 "seek",
80 "ff",
81 "fb",
82 "NONE"
83 };
84
85 if (cmd > DVR_PLAYBACK_CMD_NONE) {
86 return "unkown";
87 } else {
88 return string[cmd];
89 }
90}
91
92
hualing chen6d24aa92020-03-23 18:43:47 +080093static char* _dvr_playback_state_toString(int stat)
94{
95 char *string[DVR_PLAYBACK_STATE_FB+1]={
96 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080097 "stop",
hualing chen31140872020-03-25 12:29:26 +080098 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080099 "ff",
100 "fb"
101 };
102
103 if (stat > DVR_PLAYBACK_STATE_FB) {
104 return "unkown";
105 } else {
106 return string[stat];
107 }
108}
hualing chena540a7e2020-03-27 16:44:05 +0800109
110static DVR_Bool_t _dvr_support_speed(int speed) {
111
112 DVR_Bool_t ret = DVR_FALSE;
113
114 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800115 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800116 case PLAYBACK_SPEED_FBX2:
117 case PLAYBACK_SPEED_FBX4:
118 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800119 case PLAYBACK_SPEED_FBX16:
120 case PLAYBACK_SPEED_FBX12:
121 case PLAYBACK_SPEED_FBX32:
122 case PLAYBACK_SPEED_FBX48:
123 case PLAYBACK_SPEED_FBX64:
124 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800125 case PLAYBACK_SPEED_S2:
126 case PLAYBACK_SPEED_S4:
127 case PLAYBACK_SPEED_S8:
128 case PLAYBACK_SPEED_X1:
129 case PLAYBACK_SPEED_X2:
130 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800131 case PLAYBACK_SPEED_X3:
132 case PLAYBACK_SPEED_X5:
133 case PLAYBACK_SPEED_X6:
134 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800135 case PLAYBACK_SPEED_X8:
136 case PLAYBACK_SPEED_X12:
137 case PLAYBACK_SPEED_X16:
138 case PLAYBACK_SPEED_X32:
139 case PLAYBACK_SPEED_X48:
140 case PLAYBACK_SPEED_X64:
141 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800142 ret = DVR_TRUE;
143 break;
144 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800145 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800146 break;
147 }
148 return ret;
149}
hualing chen6e4bfa52020-03-13 14:37:11 +0800150void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
151{
hualing chen4b7c15d2020-04-07 16:13:48 +0800152 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800153 DVR_Playback_t *player = NULL;
154 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800155 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800156 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800157 }
158 switch (event->type) {
159 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
160 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800161 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800162 event->event.video_format.frame_width,
163 event->event.video_format.frame_height,
164 event->event.video_format.frame_rate);
165 break;
166 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800167 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
168 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800169 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800170 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800171 break;
172 }
173 default:
174 break;
175 }
176}
hualing chen2aba4022020-03-02 13:49:55 +0800177void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
178{
hualing chen6e4bfa52020-03-13 14:37:11 +0800179 DVR_Playback_t *player = NULL;
180 if (user_data != NULL) {
181 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800182 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800183 }
hualing chen2aba4022020-03-02 13:49:55 +0800184 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800185 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
186 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800187 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800188 event->event.video_format.frame_width,
189 event->event.video_format.frame_height,
190 event->event.video_format.frame_rate);
191 break;
192 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800193 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
194 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800195 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chene41f4372020-06-06 16:29:17 +0800196 if (player->first_trans_ok == DVR_FALSE) {
197 player->first_trans_ok = DVR_TRUE;
198 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
199 }
hualing chen30423862021-04-16 14:39:12 +0800200 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800201 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800202 player->seek_pause = DVR_FALSE;
203 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800204 break;
205 }
hualing chen487ae6d2020-07-22 10:34:11 +0800206 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
hualing chen1679f812021-11-08 15:17:46 +0800207 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
hualing chen487ae6d2020-07-22 10:34:11 +0800208 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
209 player->first_trans_ok = DVR_TRUE;
210 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
211 }
212 if (player != NULL && player->has_video == DVR_FALSE) {
213 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
214 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800215 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800216 }
217 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800218 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800219 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800220 break;
221 }
222 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800223 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800224 player->player_callback_func(player->player_callback_userdata, event);
225 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800226 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800227 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800228 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800229 }
230}
hualing chencc91e1c2020-02-28 13:26:17 +0800231
hualing chen5cbe1a62020-02-10 16:36:36 +0800232//convert video and audio fmt
233static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
234 int format = 0;
235 if (is_audio == DVR_FALSE) {
236 //for video fmt
237 switch (fmt)
238 {
239 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800240 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800241 break;
242 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800243 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800244 break;
245 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800246 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800247 break;
248 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800249 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800250 break;
hualing chena540a7e2020-03-27 16:44:05 +0800251 case DVR_VIDEO_FORMAT_VP9:
252 format = AV_VIDEO_CODEC_VP9;
253 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800254 }
255 } else {
256 //for audio fmt
257 switch (fmt)
258 {
259 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800260 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800261 break;
262 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800263 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800264 break;
265 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800266 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800267 break;
268 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800269 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800270 break;
hualing chena540a7e2020-03-27 16:44:05 +0800271 case DVR_AUDIO_FORMAT_AAC:
272 format = AV_AUDIO_CODEC_AAC;
273 break;
274 case DVR_AUDIO_FORMAT_LATM:
275 format = AV_AUDIO_CODEC_LATM;
276 break;
277 case DVR_AUDIO_FORMAT_PCM:
278 format = AV_AUDIO_CODEC_PCM;
279 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800280 case DVR_AUDIO_FORMAT_AC4:
281 format = AV_AUDIO_CODEC_AC4;
282 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800283 }
284 }
285 return format;
286}
hualing chen040df222020-01-17 13:35:02 +0800287static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800288{
hualing chen040df222020-01-17 13:35:02 +0800289 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800290
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800291 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800292 return -1;
293
hualing chena540a7e2020-03-27 16:44:05 +0800294 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800295}
hualing chena540a7e2020-03-27 16:44:05 +0800296
hualing chen7ea70a72021-09-09 11:25:13 +0800297
298//get sys time sec
299static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800300{
301 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800302 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800303 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800304 s = (uint32_t)(ts.tv_sec);
305 DVR_PB_DG(1, "n:%u", s);
306 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800307}
hualing chen86e7d482020-01-16 15:13:33 +0800308
hualing chen7ea70a72021-09-09 11:25:13 +0800309//get sys time ms
310static uint32_t _dvr_time_getClock(void)
311{
312 struct timespec ts;
313 uint32_t ms;
314 clock_gettime(CLOCK_REALTIME, &ts);
315 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
316 return ms;
317}
hualing chenb31a6c62020-01-13 17:27:00 +0800318
319//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800320static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800321{
hualing chen040df222020-01-17 13:35:02 +0800322 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800323
hualing chena540a7e2020-03-27 16:44:05 +0800324
325 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800326 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800327 return DVR_FAILURE;
328 }
329
hualing chen86e7d482020-01-16 15:13:33 +0800330 struct timespec ts;
331 clock_gettime(CLOCK_MONOTONIC, &ts);
332 //ms为毫秒,换算成秒
333 ts.tv_sec += ms/1000;
334 //在outtime的基础上,增加ms毫秒
335 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
336 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
337 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
338 //us的值有可能超过1秒,
339 ts.tv_sec += us / 1000000;
340 us = us % 1000000;
341 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800342 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
343 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800344}
hualing chen31140872020-03-25 12:29:26 +0800345//get tsplay delay time ms
346static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
347 DVR_Playback_t *player = (DVR_Playback_t *) handle;
348 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800349 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800350 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800351 return 0;
352 }
353 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800354 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800355 return cache;
356}
hualing chenb31a6c62020-01-13 17:27:00 +0800357//send signal
hualing chen040df222020-01-17 13:35:02 +0800358static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800359{
hualing chen87072a82020-03-12 16:20:12 +0800360 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800361
362 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800363 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800364 return DVR_FAILURE;
365 }
hualing chen1679f812021-11-08 15:17:46 +0800366 DVR_PB_DG(1, "lock---");
hualing chen87072a82020-03-12 16:20:12 +0800367 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800368 pthread_cond_signal(&player->cond);
hualing chen1679f812021-11-08 15:17:46 +0800369 DVR_PB_DG(1, "unlock---");
hualing chen87072a82020-03-12 16:20:12 +0800370 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800371 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800372}
373
hualing chen2932d372020-04-29 13:44:00 +0800374//send playback event, need check is need lock first
375static 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 +0800376
377 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800378
379 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800380 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800381 return DVR_FAILURE;
382 }
383
hualing chencc91e1c2020-02-28 13:26:17 +0800384 switch (evt) {
385 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800386 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800387 break;
388 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
389 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800390 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800391 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800392 break;
393 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
394 break;
395 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
396 break;
397 case DVR_PLAYBACK_EVENT_NO_KEY:
398 break;
399 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800400 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800401 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800402 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800403 break;
404 case DVR_PLAYBACK_EVENT_REACHED_END:
405 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800406 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800407 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800408 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800409 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800410 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800411 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800412 default:
413 break;
414 }
415 if (player->openParams.event_fn != NULL)
416 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800417 return DVR_SUCCESS;
418}
hualing chen2932d372020-04-29 13:44:00 +0800419static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800420{
421 DVR_Play_Notify_t notify;
422 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
423 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
424 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800425 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800426 return DVR_SUCCESS;
427}
428
hualing chen2932d372020-04-29 13:44:00 +0800429static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800430{
431 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800432
hualing chene3797f02021-01-13 14:53:28 +0800433 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800434 if (CONTROL_SPEED_ENABLE == 0)
435 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800436 }
hualing chena540a7e2020-03-27 16:44:05 +0800437 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800438 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800439 return DVR_FAILURE;
440 }
441
hualing chen03fd4942021-07-15 15:56:41 +0800442 if (player->send_time == 0) {
hualing chend241c7a2021-06-22 13:34:27 +0800443 if (CONTROL_SPEED_ENABLE == 0)
444 player->send_time = _dvr_time_getClock() + 500;
445 else
446 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800447 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800448 return DVR_SUCCESS;
449 }
hualing chend241c7a2021-06-22 13:34:27 +0800450 if (CONTROL_SPEED_ENABLE == 0)
451 player->send_time = _dvr_time_getClock() + 500;
452 else
453 player->send_time = _dvr_time_getClock() + 20;
454
hualing chen6e4bfa52020-03-13 14:37:11 +0800455 DVR_Play_Notify_t notify;
456 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
457 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
458 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800459 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800460 return DVR_SUCCESS;
461}
462
hualing chencc91e1c2020-02-28 13:26:17 +0800463//check is ongoing segment
464static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
465
466 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800467 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800468
469 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800470 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800471 return DVR_FAILURE;
472 }
hualing chen87072a82020-03-12 16:20:12 +0800473 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800474 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800475 return DVR_FALSE;
476 }
hualing chencc91e1c2020-02-28 13:26:17 +0800477 return DVR_TRUE;
478}
hualing chen4b7c15d2020-04-07 16:13:48 +0800479
480
481static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
482 DVR_Playback_t *player = (DVR_Playback_t *) handle;
483 player->fffb_start = _dvr_time_getClock();
hualing chen7ea70a72021-09-09 11:25:13 +0800484 DVR_PB_DG(1, " player->fffb_start:%u", 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 chen4b7c15d2020-04-07 16:13:48 +0800488 player->next_fffb_time = _dvr_time_getClock();
489
490 return DVR_SUCCESS;
491}
492
hualing chen2aba4022020-03-02 13:49:55 +0800493static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
494 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800495 player->fffb_start = _dvr_time_getClock();
hualing chen7ea70a72021-09-09 11:25:13 +0800496 DVR_PB_DG(1, " player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800497 player->fffb_current = player->fffb_start;
498 //get segment current time pos
499 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800500
hualing chen2aba4022020-03-02 13:49:55 +0800501 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800502 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800503 return DVR_SUCCESS;
504}
hualing chencc91e1c2020-02-28 13:26:17 +0800505//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800506static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
507
508 DVR_Playback_t *player = (DVR_Playback_t *) handle;
509 DVR_PlaybackSegmentInfo_t *segment;
510 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
511
hualing chena540a7e2020-03-27 16:44:05 +0800512 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800513 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800514 return DVR_FAILURE;
515 }
516
hualing chen87072a82020-03-12 16:20:12 +0800517 int found = 0;
518 int found_eq_id = 0;
519 list_for_each_entry(segment, &player->segment_list, head)
520 {
521 if (player->segment_is_open == DVR_FALSE) {
522 //get first segment from list, case segment is not open
523 if (!IS_FB(player->speed))
524 found = 1;
525 } else if (segment->segment_id == segmentid) {
526 //find cur segment, we need get next one
527 found_eq_id = 1;
528 if (!IS_FB(player->speed)) {
529 found = 1;
530 continue;
531 } else {
532 //if is fb mode.we need used pre segment
533 if (pre_segment != NULL) {
534 found = 1;
535 } else {
536 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800537 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800538 return DVR_FAILURE;
539 }
540 }
541 }
542 if (found == 1) {
543 found = 2;
544 break;
545 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800546 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800547 }
548 if (found != 2) {
549 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800550 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800551 return DVR_FAILURE;
552 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800553 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800554 return DVR_SUCCESS;
555}
556
557//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800558static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800559
hualing chen040df222020-01-17 13:35:02 +0800560 DVR_Playback_t *player = (DVR_Playback_t *) handle;
561 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800562 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800563 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800564 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800565 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800566 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800567 return DVR_FAILURE;
568 }
569
hualing chen03fd4942021-07-15 15:56:41 +0800570 if (IS_FB(player->speed)
571 && dvr_playback_check_limit(handle)) {
572 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
573 //case cur id < segment id
574 if (player->cur_segment_id <= segmentid) {
575 //expired ts data is player,return error
576 DVR_PB_DG(1, "reach start segment ,return error");
577 return DVR_FAILURE;
578 }
hualing chen7ea70a72021-09-09 11:25:13 +0800579 DVR_PB_DG(1, "has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800580 }
581
hualing chen86e7d482020-01-16 15:13:33 +0800582 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800583 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800584
hualing chen040df222020-01-17 13:35:02 +0800585 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800586 {
hualing chencc91e1c2020-02-28 13:26:17 +0800587 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800588 //get first segment from list, case segment is not open
589 if (!IS_FB(player->speed))
590 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800591 } else if (segment->segment_id == player->cur_segment_id) {
592 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800593 found_eq_id = 1;
594 if (!IS_FB(player->speed)) {
595 found = 1;
596 continue;
597 } else {
598 //if is fb mode.we need used pre segment
599 if (pre_segment != NULL) {
600 found = 1;
601 } else {
602 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800603 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800604 return DVR_FAILURE;
605 }
606 }
hualing chen86e7d482020-01-16 15:13:33 +0800607 }
608 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800609 if (IS_FB(player->speed)) {
610 //used pre segment
611 segment = pre_segment;
612 }
hualing chencc91e1c2020-02-28 13:26:17 +0800613 //save segment info
614 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800615 if (player->r_handle)
616 player->last_segment_tatol = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800617 player->last_segment.segment_id = player->cur_segment.segment_id;
618 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800619 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
620 //pids
621 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
622
hualing chen5cbe1a62020-02-10 16:36:36 +0800623 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800624 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800625 player->cur_segment_id = segment->segment_id;
626 player->cur_segment.segment_id = segment->segment_id;
627 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800628 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 +0800629 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800630 //pids
hualing chen040df222020-01-17 13:35:02 +0800631 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800632 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800633 break;
hualing chen86e7d482020-01-16 15:13:33 +0800634 }
hualing chen2aba4022020-03-02 13:49:55 +0800635 pre_segment = segment;
636 }
637 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
638 //used the last one segment to open
639 //get segment info
640 player->segment_is_open = DVR_TRUE;
641 player->cur_segment_id = pre_segment->segment_id;
642 player->cur_segment.segment_id = pre_segment->segment_id;
643 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800644 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 +0800645 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
646 //pids
647 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
648 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800649 }
650 if (found != 2) {
651 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800652 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800653 }
654 return DVR_SUCCESS;
655}
hualing chen040df222020-01-17 13:35:02 +0800656//open next segment to play,if reach list end return errro.
657static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800658{
hualing chen040df222020-01-17 13:35:02 +0800659 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800660 Segment_OpenParams_t params;
661 int ret = DVR_SUCCESS;
662
hualing chena540a7e2020-03-27 16:44:05 +0800663 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800664 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800665 return DVR_FAILURE;
666 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800667 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800668
669 ret = _dvr_get_next_segmentId(handle);
670 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800671 DVR_PB_DG(1, "not found segment info");
672 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800673 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800674 }
675
676 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800677 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800678 segment_close(player->r_handle);
679 player->r_handle = NULL;
680 }
681
682 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800683 //cp chur segment path to location
684 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800685 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800686 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800687 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
688
hualing chen86e7d482020-01-16 15:13:33 +0800689 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800690 if (ret == DVR_FAILURE) {
691 DVR_PB_DG(1, "open segment error");
692 }
hualing chen87072a82020-03-12 16:20:12 +0800693 pthread_mutex_unlock(&player->segment_lock);
694 int total = _dvr_get_end_time( handle);
695 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800696 if (IS_FB(player->speed)) {
697 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800698 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800699 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800700 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800701 }
hualing chen87072a82020-03-12 16:20:12 +0800702 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800703 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800704 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800705 return ret;
706}
707
hualing chen5cbe1a62020-02-10 16:36:36 +0800708//open next segment to play,if reach list end return errro.
709static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
710{
711 DVR_Playback_t *player = (DVR_Playback_t *) handle;
712 Segment_OpenParams_t params;
713 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800714 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800715 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800716 return DVR_FAILURE;
717 }
hualing chencc91e1c2020-02-28 13:26:17 +0800718 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800719 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800720 }
hualing chencc91e1c2020-02-28 13:26:17 +0800721 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800722 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800723 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800724 return DVR_FAILURE;
725 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800726 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800727 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800728
729 DVR_PlaybackSegmentInfo_t *segment;
730
731 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800732
hualing chen5cbe1a62020-02-10 16:36:36 +0800733 list_for_each_entry(segment, &player->segment_list, head)
734 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800735 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 +0800736 if (segment->segment_id == segment_id) {
737 found = 1;
738 }
739 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800740 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 +0800741 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800742 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800743 player->cur_segment_id = segment->segment_id;
744 player->cur_segment.segment_id = segment->segment_id;
745 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800746 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800747 //pids
748 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800749 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 +0800750 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800751 }
752 }
hualing chencc91e1c2020-02-28 13:26:17 +0800753 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800754 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800755 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800756 return DVR_FAILURE;
757 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800758 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800759 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800760 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800761 params.segment_id = (uint64_t)player->cur_segment.segment_id;
762 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800763 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 +0800764 if (player->r_handle != NULL) {
765 segment_close(player->r_handle);
766 player->r_handle = NULL;
767 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800768 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800769 if (ret == DVR_FAILURE) {
770 DVR_PB_DG(1, "segment opne error");
771 }
hualing chen2aba4022020-03-02 13:49:55 +0800772 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800773 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800774
hualing chen4b7c15d2020-04-07 16:13:48 +0800775 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 +0800776 return ret;
777}
778
779
780//get play info by segment id
781static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
782 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800783 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800784 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800785
786 DVR_Playback_t *player = (DVR_Playback_t *) handle;
787 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800788 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800789 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800790 return DVR_FAILURE;
791 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800792
793 int found = 0;
794
795 list_for_each_entry(segment, &player->segment_list, head)
796 {
hualing chen87072a82020-03-12 16:20:12 +0800797 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800798 //get first segment from list
799 found = 1;
800 }
801 if (segment->segment_id == segment_id) {
802 found = 1;
803 }
804 if (found == 1) {
805 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800806 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800807 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800808 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800809 player->cur_segment.segment_id = segment->segment_id;
810 player->cur_segment.flags = segment->flags;
811 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800812 player->cur_segment.pids.video.pid = segment->pids.video.pid;
813 player->cur_segment.pids.video.format = segment->pids.video.format;
814 player->cur_segment.pids.video.type = segment->pids.video.type;
815 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
816 player->cur_segment.pids.audio.format = segment->pids.audio.format;
817 player->cur_segment.pids.audio.type = segment->pids.audio.type;
818 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
819 player->cur_segment.pids.ad.format = segment->pids.ad.format;
820 player->cur_segment.pids.ad.type = segment->pids.ad.type;
821 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800822 //
hualing chen2aba4022020-03-02 13:49:55 +0800823 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800824 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800825 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800826 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800827 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
828 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800829 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 +0800830 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800831 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800832 }
833 }
hualing chencc91e1c2020-02-28 13:26:17 +0800834 if (found != 2) {
835 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800836 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800837 return DVR_FAILURE;
838 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800839
840 return DVR_SUCCESS;
841}
hualing chencc91e1c2020-02-28 13:26:17 +0800842static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
843 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800844 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800845 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800846 return DVR_FAILURE;
847 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800848
hualing chencc91e1c2020-02-28 13:26:17 +0800849 //compare cur segment
850 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
851 {
852 //check video pids, stop or restart
hualing chen99508642021-10-18 15:41:17 +0800853 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800854 //check sub audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800855 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800856 //check audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800857 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 1);
hualing chene3797f02021-01-13 14:53:28 +0800858 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 +0800859 //check pcr pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800860 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800861 }
hualing chena540a7e2020-03-27 16:44:05 +0800862 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800863}
hualing chen5cbe1a62020-02-10 16:36:36 +0800864
hualing chend241c7a2021-06-22 13:34:27 +0800865static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
866{
867 DVR_Playback_t *player = (DVR_Playback_t *) handle;
868 if (player == NULL) {
869 DVR_PB_DG(1, "player is NULL");
870 return DVR_TRUE;
871 }
872 char buf[10];
873 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
874 DVR_PB_DG(1, "player get prop[%d][%s]", atoi(buf), buf);
875
876 if (atoi(buf) != 1) {
877 //return DVR_TRUE;
878 }
879
hualing chen7ea70a72021-09-09 11:25:13 +0800880 DVR_PB_DG(1, ":play speed: %f ply dur: %u sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800881 player->speed,
882 player->con_spe.ply_dur,
883 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800884
885 if (player->speed != 1.0f)
886 return DVR_TRUE;
887
888 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800889 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800890 return DVR_FALSE;
891
892 return DVR_TRUE;
893}
894
hualing chencc91e1c2020-02-28 13:26:17 +0800895static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
896{
897 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800898 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800899 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800900 return DVR_FAILURE;
901 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800902 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
903 DVR_PB_DG(1, "vendor is amlogic. no used segment flag to hide or show av");
904 return DVR_SUCCESS;
905 }
hualing chen03fd4942021-07-15 15:56:41 +0800906 DVR_PB_DG(1, "flag[0x%x]id[%lld]last[0x%x][%llu]",
907 player->cur_segment.flags,
908 player->cur_segment.segment_id,
909 player->last_segment.flags,
910 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800911 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
912 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800913 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800914 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800915 AmTsPlayer_showVideo(player->handle);
916 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800917 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
918 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800919 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800920 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800921 AmTsPlayer_hideVideo(player->handle);
922 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800923 }
924 return DVR_SUCCESS;
925}
hualing chene3797f02021-01-13 14:53:28 +0800926/*
927if decodec sucess first time.
928sucess: return true
929fail: return false
930*/
hualing chena540a7e2020-03-27 16:44:05 +0800931static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
932 DVR_Playback_t *player = (DVR_Playback_t *) handle;
933 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800934 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800935 return DVR_TRUE;
936 }
hualing chene3797f02021-01-13 14:53:28 +0800937 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800938 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800939 } else {
940 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800941 }
942}
hualing chen86e7d482020-01-16 15:13:33 +0800943static void* _dvr_playback_thread(void *arg)
944{
hualing chen040df222020-01-17 13:35:02 +0800945 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800946 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800947 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800948 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800949 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800950
hualing chen39628212020-05-14 10:35:13 +0800951 #define MAX_REACHEND_TIMEOUT (3000)
952 int reach_end_timeout = 0;//ms
953 int cache_time = 0;
hualing chen6d24aa92020-03-23 18:43:47 +0800954 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800955 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800956 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800957 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800958 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
959
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800960 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800961 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800962 DVR_Bool_t goto_rewrite = DVR_FALSE;
yinming ding0ce94922021-09-08 15:09:15 +0800963 char prop_buf[10];
964
965 memset(prop_buf, 0 ,sizeof(prop_buf));
966 dvr_prop_read("vendor.tv.libdvr.writetm", prop_buf, sizeof(prop_buf));
hualing chen1679f812021-11-08 15:17:46 +0800967 DVR_PB_DG(1, "---vendor.tv.libdvr.writetm get prop[%d][%s]", atoi(prop_buf), prop_buf);
yinming ding0ce94922021-09-08 15:09:15 +0800968 if (atoi(prop_buf) > 0)
969 write_timeout_ms = atoi(prop_buf);
hualing chen03fd4942021-07-15 15:56:41 +0800970
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800971 if (player->is_secure_mode) {
972 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800973 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800974 return NULL;
975 }
976 }
hualing chen86e7d482020-01-16 15:13:33 +0800977 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800978 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800979 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800980 return NULL;
981 }
hualing chen2aba4022020-03-02 13:49:55 +0800982 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
983 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800984
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800985 dec_bufs.buf_data = malloc(dec_buf_size);
986 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800987 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800988 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800989 return NULL;
990 }
991 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
992 dec_bufs.buf_size = dec_buf_size;
993
hualing chencc91e1c2020-02-28 13:26:17 +0800994 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800995 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
996 }
hualing chen86e7d482020-01-16 15:13:33 +0800997
hualing chen86e7d482020-01-16 15:13:33 +0800998 if (ret != DVR_SUCCESS) {
999 if (buf != NULL) {
1000 free(buf);
1001 buf = NULL;
1002 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001003 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +08001004 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001005 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001006 }
hualing chen1679f812021-11-08 15:17:46 +08001007 DVR_PB_DG(1, "--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001008 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001009 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1010 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1011 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1012 player->first_trans_ok = DVR_TRUE;
1013 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1014 }
hualing chencc91e1c2020-02-28 13:26:17 +08001015 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001016 //set video show
1017 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001018
hualing chen86e7d482020-01-16 15:13:33 +08001019 int trick_stat = 0;
1020 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001021
hualing chen86e7d482020-01-16 15:13:33 +08001022 //check trick stat
hualing chen1679f812021-11-08 15:17:46 +08001023 DVR_PB_DG(1, "lock");
hualing chencc91e1c2020-02-28 13:26:17 +08001024 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001025
hualing chen2aba4022020-03-02 13:49:55 +08001026 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1027 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001028 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001029 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001030 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001031 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001032 {
hualing chen2aba4022020-03-02 13:49:55 +08001033 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1034 if (trick_stat > 0) {
hualing chen03fd4942021-07-15 15:56:41 +08001035 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
1036 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001037 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 +08001038 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001039 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001040 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001041 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
1042 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +08001043 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
1044 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chen03fd4942021-07-15 15:56:41 +08001045 DVR_PB_DG(1, "pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
1046 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001047 //need change to pause state
1048 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1049 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +08001050 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001051 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001052 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001053 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001054 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001055 AmTsPlayer_pauseVideoDecoding(player->handle);
1056 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001057 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001058 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001059 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001060 }
1061 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1062 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001063 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001064 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001065 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen7ea70a72021-09-09 11:25:13 +08001066 DVR_PB_DG(1, "fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001067 player->speed,
1068 player->fffb_current,
1069 _dvr_time_getClock(),
1070 _dvr_playback_state_toString(player->state),
1071 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001072 //used timeout wait need lock first,so we unlock and lock
1073 //pthread_mutex_unlock(&player->lock);
1074 //pthread_mutex_lock(&player->lock);
1075 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001076 DVR_PB_DG(1, "unlock---");
hualing chen2aba4022020-03-02 13:49:55 +08001077 pthread_mutex_unlock(&player->lock);
1078 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001079 } else if (_dvr_time_getClock() < player->next_fffb_time) {
hualing chen7ea70a72021-09-09 11:25:13 +08001080 DVR_PB_DG(1, "fffb timeout-to pause video---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001081 player->speed,
1082 player->fffb_current,
1083 _dvr_time_getClock(),
1084 _dvr_playback_state_toString(player->state),
1085 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001086 //used timeout wait need lock first,so we unlock and lock
1087 //pthread_mutex_unlock(&player->lock);
1088 //pthread_mutex_lock(&player->lock);
1089 AmTsPlayer_pauseVideoDecoding(player->handle);
1090 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001091 DVR_PB_DG(1, "unlock---");
hualing chenb5cd42e2020-04-15 17:03:34 +08001092 pthread_mutex_unlock(&player->lock);
1093 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001094 }
hualing chen03fd4942021-07-15 15:56:41 +08001095 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d][%s][%d]",
1096 player->speed,
1097 goto_rewrite,
1098 real_read,
1099 _dvr_playback_state_toString(player->state),
1100 player->cmd.cur_cmd);
hualing chen1679f812021-11-08 15:17:46 +08001101 DVR_PB_DG(1, "unlock---");
hualing chen2aba4022020-03-02 13:49:55 +08001102 pthread_mutex_unlock(&player->lock);
1103 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001104 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001105 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1106 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001107 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001108 player->fffb_play = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08001109 DVR_PB_DG(1, "lock---");
hualing chen2aba4022020-03-02 13:49:55 +08001110 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08001111 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1112 //on pause state,user seek to new pos,we need pause and wait
1113 //user to resume
1114 DVR_PB_DG(1, "pause, when got first frame event when user seek end");
1115 player->first_frame = 0;
1116 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1117 AmTsPlayer_pauseVideoDecoding(player->handle);
1118 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001119 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001120 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001121 //for first into fffb when reset speed
1122 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1123 _dvr_time_getClock() < player->next_fffb_time) {
hualing chen7ea70a72021-09-09 11:25:13 +08001124 DVR_PB_DG(1, "fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001125 player->speed,
1126 player->fffb_current,
1127 _dvr_time_getClock(),
1128 _dvr_playback_state_toString(player->state),
1129 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001130 //used timeout wait need lock first,so we unlock and lock
1131 //pthread_mutex_unlock(&player->lock);
1132 //pthread_mutex_lock(&player->lock);
1133 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001134 DVR_PB_DG(1, "unlock---");
hualing chen4b7c15d2020-04-07 16:13:48 +08001135 pthread_mutex_unlock(&player->lock);
1136 continue;
1137 }
hualing chen03fd4942021-07-15 15:56:41 +08001138 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
1139 player->speed,
1140 goto_rewrite,
1141 real_read,
1142 _dvr_playback_state_toString(player->state),
1143 player->cmd.cur_cmd,
1144 player->fffb_play);
hualing chen1679f812021-11-08 15:17:46 +08001145 DVR_PB_DG(1, "unlock---");
hualing chen4b7c15d2020-04-07 16:13:48 +08001146 pthread_mutex_unlock(&player->lock);
1147 goto_rewrite = DVR_FALSE;
1148 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001149 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001150 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1151 player->first_frame = 0;
1152 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1153 pthread_mutex_lock(&player->lock);
1154 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001155 }
hualing chenb31a6c62020-01-13 17:27:00 +08001156 }
hualing chen86e7d482020-01-16 15:13:33 +08001157
hualing chen30423862021-04-16 14:39:12 +08001158 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1159 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001160 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001161 DVR_PB_DG(1, "pause, continue");
hualing chen1679f812021-11-08 15:17:46 +08001162 DVR_PB_DG(1, "unlock---");
1163 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001164 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen1679f812021-11-08 15:17:46 +08001165 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001166 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001167 DVR_PB_DG(1, "unlock---");
hualing chen87072a82020-03-12 16:20:12 +08001168 pthread_mutex_unlock(&player->lock);
1169 continue;
1170 }
hualing chen266b9502020-04-04 17:39:39 +08001171 //when seek action is done. we need drop write timeout data.
1172 if (player->drop_ts == DVR_TRUE) {
1173 goto_rewrite = DVR_FALSE;
1174 real_read = 0;
1175 player->drop_ts = DVR_FALSE;
1176 }
hualing chen2aba4022020-03-02 13:49:55 +08001177 if (goto_rewrite == DVR_TRUE) {
1178 goto_rewrite = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08001179 DVR_PB_DG(1, "unlock---");
1180
hualing chen2aba4022020-03-02 13:49:55 +08001181 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001182 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001183 goto rewrite;
1184 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001185 //.check is need send time send end
hualing chen1679f812021-11-08 15:17:46 +08001186 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001187 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen1679f812021-11-08 15:17:46 +08001188 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001189 pthread_mutex_lock(&player->segment_lock);
hualing chene41f4372020-06-06 16:29:17 +08001190 //DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001191 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001192 real_read = real_read + read;
1193 player->ts_cache_len = real_read;
hualing chenfbf8e022020-06-15 13:43:11 +08001194 //DVR_PB_DG(1, "start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001195 pthread_mutex_unlock(&player->segment_lock);
hualing chen1679f812021-11-08 15:17:46 +08001196 DVR_PB_DG(1, "unlock---");
hualing chen87072a82020-03-12 16:20:12 +08001197 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001198 if (read < 0 && errno == EIO) {
1199 //EIO ERROR, EXIT THRAD
1200 DVR_PB_DG(1, "read error.EIO error, exit thread");
1201 DVR_Play_Notify_t notify;
1202 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1203 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001204 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001205 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001206 goto end;
1207 } else if (read < 0) {
1208 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1209 }
hualing chen87072a82020-03-12 16:20:12 +08001210 //if on fb mode and read file end , we need calculate pos to retry read.
1211 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen03fd4942021-07-15 15:56:41 +08001212 DVR_PB_DG(1, "recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
1213 read,
1214 real_read,
1215 buf_len,
1216 player->speed,
1217 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001218 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
hualing chen1679f812021-11-08 15:17:46 +08001219 DVR_PB_DG(1, "lock---");
hualing chen87072a82020-03-12 16:20:12 +08001220 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001221 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001222 DVR_PB_DG(1, "unlock---");
hualing chen2aba4022020-03-02 13:49:55 +08001223 pthread_mutex_unlock(&player->lock);
1224 continue;
1225 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001226 //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 +08001227 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001228 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001229 #define MIN_CACHE_TIME (3000)
1230 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001231 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001232 if (_cache_time > MIN_CACHE_TIME) {
hualing chen1679f812021-11-08 15:17:46 +08001233 //pthread_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001234 /*if cache time > 20s , we think get time is error,*/
1235 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
1236 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1237 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1238 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1239 }
hualing chen1679f812021-11-08 15:17:46 +08001240 //_dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
1241 //pthread_mutex_unlock(&player->lock);
1242 // 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 +08001243 //continue;
1244 }
hualing chen969fe7b2021-05-26 15:13:17 +08001245
hualing chen040df222020-01-17 13:35:02 +08001246 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001247 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001248 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001249
1250 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen1679f812021-11-08 15:17:46 +08001251
1252 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1253 player->noData++;
1254 DVR_PB_DG(1, "playback nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001255 if (player->noData == 4) {
1256 DVR_PB_DG(1, "playback send nodata event nodata[%d]", player->noData);
1257 //send event here and pause
1258 DVR_Play_Notify_t notify;
1259 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1260 notify.event = DVR_PLAYBACK_EVENT_NODATA;
hualing chen1679f812021-11-08 15:17:46 +08001261 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001262 //get play statue not here
1263 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1264 }
1265 }
1266 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001267 if ((ret != DVR_SUCCESS &&
hualing chen03fd4942021-07-15 15:56:41 +08001268 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001269 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001270 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001271 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1272 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001273 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001274 DVR_Play_Notify_t notify;
1275 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1276 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1277 //get play statue not here
1278 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001279 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001280 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001281 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 +08001282 pthread_mutex_lock(&player->lock);
1283 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1284 pthread_mutex_unlock(&player->lock);
1285 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001286 } else if (ret != DVR_SUCCESS) {
hualing chen1679f812021-11-08 15:17:46 +08001287 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
1288 pthread_mutex_lock(&player->lock);
1289 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1290 pthread_mutex_unlock(&player->lock);
1291 delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chena540a7e2020-03-27 16:44:05 +08001292 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001293 if (delay < cache_time) {
1294 //delay time is changed and then has data to play, so not start timeout
hualing chen1679f812021-11-08 15:17:46 +08001295 reach_end_timeout = 0;
hualing chen39628212020-05-14 10:35:13 +08001296 } else {
1297 reach_end_timeout = reach_end_timeout + timeout;
1298 }
1299 cache_time = delay;
hualing chen31140872020-03-25 12:29:26 +08001300 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001301 }
hualing chen39628212020-05-14 10:35:13 +08001302 reach_end_timeout = 0;
1303 cache_time = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001304 pthread_mutex_lock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001305 //change next segment success case
1306 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001307 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001308 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1309 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001310 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001311 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001312 real_read = real_read + read;
1313 player->ts_cache_len = real_read;
1314 pthread_mutex_unlock(&player->segment_lock);
1315
hualing chen87072a82020-03-12 16:20:12 +08001316 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001317 }//read len 0 check end
hualing chen1679f812021-11-08 15:17:46 +08001318 if (player->noData >= 4) {
hualing chene3797f02021-01-13 14:53:28 +08001319 player->noData = 0;
1320 DVR_PB_DG(1, "playback send data event resume[%d]", player->noData);
1321 //send event here and pause
1322 DVR_Play_Notify_t notify;
1323 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1324 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
hualing chen1679f812021-11-08 15:17:46 +08001325 DVR_PB_DG(1, "----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001326 //get play statue not here
1327 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001328 }
hualing chen39628212020-05-14 10:35:13 +08001329 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001330 //real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001331 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001332 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001333
hualing chena540a7e2020-03-27 16:44:05 +08001334 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001335 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001336 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001337 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001338 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001339 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001340 }
hualing chen266b9502020-04-04 17:39:39 +08001341 //if need write whole block size, we need check read buf len is eq block size.
1342 if (b_writed_whole_block == DVR_TRUE) {
1343 //buf_len is block size value.
1344 if (real_read < buf_len) {
1345 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001346 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001347 pthread_mutex_lock(&player->lock);
1348 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1349 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001350 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001351 continue;
1352 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001353 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 +08001354 }
1355 }
1356
Yahui Han1fbf3292021-11-08 18:17:19 +08001357 if (player->is_secure_mode && player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001358 DVR_CryptoParams_t crypto_params;
1359
1360 memset(&crypto_params, 0, sizeof(crypto_params));
1361 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1362 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1363 crypto_params.segment_id = player->cur_segment.segment_id;
hualing chen1f26ffa2020-11-03 10:39:20 +08001364 crypto_params.offset = segment_tell_position(player->r_handle) - wbufs.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001365 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
1366 DVR_PB_DG(1, "offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001367 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1368 crypto_params.input_buffer.addr = (size_t)buf;
1369 crypto_params.input_buffer.size = real_read;
1370
Yahui Han1fbf3292021-11-08 18:17:19 +08001371 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1372 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1373 crypto_params.output_buffer.size = dec_buf_size;
1374 ret = player->dec_func(&crypto_params, player->dec_userdata);
1375 wbufs.buf_data = player->secure_buffer;
1376 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001377 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001378 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001379 }
pengfei.liufda2a972020-04-09 14:47:15 +08001380 wbufs.buf_size = crypto_params.output_size;
Yahui Han1fbf3292021-11-08 18:17:19 +08001381 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001382 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001383 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
1384 wbufs.buf_data = dec_bufs.buf_data;
1385 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1386 wbufs.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001387 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001388rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001389 if (player->drop_ts == DVR_TRUE) {
1390 //need drop ts data when seek occur.we need read next loop,drop this ts data
1391 goto_rewrite = DVR_FALSE;
1392 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001393 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001394 player->drop_ts = DVR_FALSE;
1395 continue;
1396 }
hualing chen21a40372021-10-29 11:07:26 +08001397
1398 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001399 player->ts_cache_len = real_read;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001400 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1401 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001402 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001403 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001404 real_read = 0;
1405 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001406 if (CONTROL_SPEED_ENABLE == 1) {
1407check0:
1408 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1409 pthread_mutex_lock(&player->lock);
1410 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1411 pthread_mutex_unlock(&player->lock);
1412 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1413 goto check0;
1414 }
1415 }
hualing chen5605eed2020-05-26 18:18:06 +08001416 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001417 continue;
hualing chen87072a82020-03-12 16:20:12 +08001418 } else {
hualing chen21a40372021-10-29 11:07:26 +08001419 pthread_mutex_unlock(&player->segment_lock);
hualing chen7ea70a72021-09-09 11:25:13 +08001420 DVR_PB_DG(1, "write time out write_success:%d wbufs.buf_size:%d systime:%u",
hualing chen03fd4942021-07-15 15:56:41 +08001421 write_success,
1422 wbufs.buf_size,
1423 _dvr_time_getClock());
1424
hualing chena540a7e2020-03-27 16:44:05 +08001425 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001426 if (CONTROL_SPEED_ENABLE == 1) {
1427check1:
1428 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1429 pthread_mutex_lock(&player->lock);
1430 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1431 pthread_mutex_unlock(&player->lock);
1432 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1433 goto check1;
1434 }
1435 }
hualing chencc91e1c2020-02-28 13:26:17 +08001436 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001437 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001438 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001439 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001440 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001441 break;
1442 }
hualing chen2aba4022020-03-02 13:49:55 +08001443 goto_rewrite = DVR_TRUE;
1444 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001445 }
1446 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001447end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001448 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001449 free(buf);
1450 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001451 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001452}
1453
1454
hualing chen040df222020-01-17 13:35:02 +08001455static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001456{
hualing chen040df222020-01-17 13:35:02 +08001457 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001458
1459 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001460 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001461 return DVR_FAILURE;
1462 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001463 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001464 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001465 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001466 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001467 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001468 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001469 if (rc < 0)
1470 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001471 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001472}
1473
1474
hualing chen040df222020-01-17 13:35:02 +08001475static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001476{
hualing chen040df222020-01-17 13:35:02 +08001477 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001478
1479 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001480 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001481 return DVR_FAILURE;
1482 }
1483
hualing chen4b7c15d2020-04-07 16:13:48 +08001484 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001485 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001486 {
1487 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001488 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001489 pthread_join(player->playback_thread, NULL);
1490 }
1491 if (player->r_handle) {
1492 segment_close(player->r_handle);
1493 player->r_handle = NULL;
1494 }
hualing chen7a56cba2020-04-14 14:09:27 +08001495 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001496 return 0;
1497}
1498
hualing chen1679f812021-11-08 15:17:46 +08001499static int getFakePid()
1500{
1501 char fake_pid_prop[] = "vendor.tv.dtv.fake_pid";
1502 char buf[32];
1503 int pid = 0xffff;
1504
1505 dvr_prop_read(fake_pid_prop, buf, sizeof(buf));
1506
1507 if (sscanf(buf, "%i", &pid) != 1)
1508 {
1509 DVR_PB_DG(1, "get fake pid error");
1510 pid = 0xffff;
1511 }
1512 return pid;
1513}
1514
1515void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1516
1517 DVR_ASSERT(handle);
1518 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1519 if (player == NULL) {
1520 DVR_PB_DG(1, "player is NULL");
1521 return ;
1522 }
1523 if (player->need_seek_start == DVR_FALSE) {
1524 DVR_PB_DG(1, "player need_seek_start is false");
1525 return ;
1526 }
1527
1528 int fake_pid = getFakePid();
1529 if (pid != fake_pid) {
1530 player->need_seek_start = DVR_FALSE;
1531 }
1532 DVR_PB_DG(1, "player player->need_seek_start=%d", player->need_seek_start);
1533}
1534
hualing chenb31a6c62020-01-13 17:27:00 +08001535/**\brief Open an dvr palyback
1536 * \param[out] p_handle dvr playback addr
1537 * \param[in] params dvr playback open parameters
1538 * \retval DVR_SUCCESS On success
1539 * \return Error code
1540 */
hualing chen040df222020-01-17 13:35:02 +08001541int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001542
hualing chen040df222020-01-17 13:35:02 +08001543 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001544 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001545
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001546 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001547
hualing chen86e7d482020-01-16 15:13:33 +08001548 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001549 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001550 pthread_condattr_init(&cattr);
1551 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1552 pthread_cond_init(&player->cond, &cattr);
1553 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001554
hualing chen5cbe1a62020-02-10 16:36:36 +08001555 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001556 INIT_LIST_HEAD(&player->segment_list);
1557 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1558 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001559 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001560 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001561 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001562 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001563 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001564 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001565
hualing chen86e7d482020-01-16 15:13:33 +08001566 //store open params
hualing chen040df222020-01-17 13:35:02 +08001567 player->openParams.dmx_dev_id = params->dmx_dev_id;
1568 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001569 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001570 player->openParams.event_fn = params->event_fn;
1571 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001572 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001573 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001574
hualing chen5cbe1a62020-02-10 16:36:36 +08001575 player->has_pids = params->has_pids;
1576
hualing chen2aba4022020-03-02 13:49:55 +08001577 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001578
1579 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1580 //for test get callback
1581 if (0 && player->player_callback_func == NULL) {
1582 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1583 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen03fd4942021-07-15 15:56:41 +08001584 DVR_PB_DG(1, "playback open get callback[%p][%p][%p][%p]",
1585 player->player_callback_func,
1586 player->player_callback_userdata,
1587 _dvr_tsplayer_callback_test,
1588 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001589 }
1590 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001591
hualing chen86e7d482020-01-16 15:13:33 +08001592 //init has audio and video
1593 player->has_video = DVR_FALSE;
1594 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001595 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001596 player->last_segment_id = 0LL;
1597 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001598
hualing chen5cbe1a62020-02-10 16:36:36 +08001599 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001600 player->fffb_current = 0;
1601 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001602 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001603 //seek time
1604 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001605 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001606
Yahui Han1fbf3292021-11-08 18:17:19 +08001607 //allocate cryptor if have clearkey
1608 if (params->keylen > 0) {
1609 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
1610 (uint8_t *)params->cleariv,
1611 params->keylen * 8);
1612 if (!player->cryptor) {
1613 DVR_DEBUG(1, "%s , open des cryptor failed!!!\n", __func__);
1614 }
1615 } else {
1616 player->cryptor = NULL;
1617 }
1618
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001619 //init secure stuff
1620 player->dec_func = NULL;
1621 player->dec_userdata = NULL;
1622 player->is_secure_mode = 0;
1623 player->secure_buffer = NULL;
1624 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001625 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001626
hualing chen4b7c15d2020-04-07 16:13:48 +08001627 player->fffb_play = DVR_FALSE;
1628
1629 player->last_send_time_id = UINT64_MAX;
1630 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001631 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001632
hualing chend241c7a2021-06-22 13:34:27 +08001633 //speed con init
1634 if (CONTROL_SPEED_ENABLE == 1) {
1635 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001636 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001637 player->con_spe.sys_dur = 0;
1638 player->con_spe.sys_sta = 0;
1639 }
1640
hualing chen03fd4942021-07-15 15:56:41 +08001641 //limit info
1642 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001643 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001644 //need seek to start pos
1645 player->first_start_time = 0;
1646 player->need_seek_start = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001647 *p_handle = player;
1648 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001649}
1650
1651/**\brief Close an dvr palyback
1652 * \param[in] handle playback handle
1653 * \retval DVR_SUCCESS On success
1654 * \return Error code
1655 */
hualing chen040df222020-01-17 13:35:02 +08001656int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001657
hualing chen86e7d482020-01-16 15:13:33 +08001658 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001659 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001660 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001661 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001662 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001663 return DVR_FAILURE;
1664 }
1665
hualing chencc91e1c2020-02-28 13:26:17 +08001666 if (player->state != DVR_PLAYBACK_STATE_STOP)
1667 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001668 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001669 if (player->cryptor) {
1670 am_crypt_des_close(player->cryptor);
1671 player->cryptor = NULL;
1672 }
hualing chencc91e1c2020-02-28 13:26:17 +08001673 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001674 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1675 } else {
1676 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001677 }
hualing chen7a56cba2020-04-14 14:09:27 +08001678 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001679 pthread_mutex_destroy(&player->lock);
1680 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001681
1682 if (player) {
1683 free(player);
1684 player = NULL;
1685 }
hualing chen7a56cba2020-04-14 14:09:27 +08001686 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001687 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001688}
1689
hualing chenb31a6c62020-01-13 17:27:00 +08001690/**\brief Start play audio and video, used start auido api and start video api
1691 * \param[in] handle playback handle
1692 * \param[in] params audio playback params,contains fmt and pid...
1693 * \retval DVR_SUCCESS On success
1694 * \return Error code
1695 */
hualing chen040df222020-01-17 13:35:02 +08001696int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1697 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001698 am_tsplayer_video_params vparams;
1699 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001700 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001701
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001702 memset(&vparams, 0, sizeof(vparams));
1703 memset(&aparams, 0, sizeof(aparams));
1704
hualing chena540a7e2020-03-27 16:44:05 +08001705 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001706 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001707 return DVR_FAILURE;
1708 }
hualing chencc91e1c2020-02-28 13:26:17 +08001709 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001710 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001711
hualing chena540a7e2020-03-27 16:44:05 +08001712 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001713 //can used start api to resume playback
1714 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1715 return dvr_playback_resume(handle);
1716 }
hualing chen87072a82020-03-12 16:20:12 +08001717 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001718 //if flag is puased and not decodec first frame. if user resume, we need
1719 //clear flag and set trickmode none
1720 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1721 DVR_PB_DG(1, "[%p]clear pause live flag and clear trick mode", handle);
1722 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1723 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1724 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001725 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001726 return DVR_SUCCESS;
1727 }
hualing chen86e7d482020-01-16 15:13:33 +08001728 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001729 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001730 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001731 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001732 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001733 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001734 //start audio and video
Zhiqiang Hana9d261b2020-11-11 18:38:10 +08001735 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001736 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001737 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001738 pthread_mutex_unlock(&player->lock);
1739 DVR_Play_Notify_t notify;
1740 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1741 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1742 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1743 notify.info.transition_failed_data.segment_id = segment_id;
1744 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001745 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001746 return -1;
1747 }
hualing chen31140872020-03-25 12:29:26 +08001748
hualing chencc91e1c2020-02-28 13:26:17 +08001749 {
hualing chen86e7d482020-01-16 15:13:33 +08001750 if (VALID_PID(vparams.pid)) {
1751 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001752 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001753 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001754 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001755 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1756 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001757 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001758 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001759 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001760 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001761 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001762 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001763 }
hualing chena93bbbc2020-12-22 17:23:42 +08001764 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001765 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08001766 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001767 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001768 }
hualing chena540a7e2020-03-27 16:44:05 +08001769
hualing chen4b7c15d2020-04-07 16:13:48 +08001770 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1771 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001772 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1773 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1774 player->cmd.state = DVR_PLAYBACK_STATE_START;
1775 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001776 } else {
1777 player->cmd.last_cmd = player->cmd.cur_cmd;
1778 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001779 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001780 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001781 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001782 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001783 } else {
hualing chendf118dd2020-05-21 15:49:11 +08001784 if (VALID_PID(adparams.pid)) {
1785 player->has_ad_audio = DVR_TRUE;
1786 DVR_PB_DG(1, "start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08001787 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chendf118dd2020-05-21 15:49:11 +08001788 AmTsPlayer_setADParams(player->handle, &adparams);
1789 AmTsPlayer_enableADMix(player->handle);
1790 }
hualing chen969fe7b2021-05-26 15:13:17 +08001791 if (VALID_PID(aparams.pid)) {
1792 DVR_PB_DG(1, "start audio");
1793 player->has_audio = DVR_TRUE;
hualing chen1679f812021-11-08 15:17:46 +08001794 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08001795 AmTsPlayer_setAudioParams(player->handle, &aparams);
1796 AmTsPlayer_startAudioDecoding(player->handle);
1797 }
hualing chen31140872020-03-25 12:29:26 +08001798 }
hualing chencc91e1c2020-02-28 13:26:17 +08001799 player->cmd.state = DVR_PLAYBACK_STATE_START;
1800 player->state = DVR_PLAYBACK_STATE_START;
1801 }
hualing chen86e7d482020-01-16 15:13:33 +08001802 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001803 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001804 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001805 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001806 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001807}
hualing chen040df222020-01-17 13:35:02 +08001808/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001809 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001810 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001811 * \retval DVR_SUCCESS On success
1812 * \return Error code
1813 */
hualing chen040df222020-01-17 13:35:02 +08001814int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1815 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001816
hualing chena540a7e2020-03-27 16:44:05 +08001817 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001818 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001819 return DVR_FAILURE;
1820 }
1821
hualing chen4b7c15d2020-04-07 16:13:48 +08001822 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001823 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001824
hualing chen040df222020-01-17 13:35:02 +08001825 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1826 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001827
hualing chen86e7d482020-01-16 15:13:33 +08001828 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001829 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001830 //cp location
hualing chen040df222020-01-17 13:35:02 +08001831 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001832
hualing chen4b7c15d2020-04-07 16:13:48 +08001833 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 +08001834 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001835
1836 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001837 segment->pids.video.pid = info->pids.video.pid;
1838 segment->pids.video.format = info->pids.video.format;
1839 segment->pids.video.type = info->pids.video.type;
1840
hualing chen2aba4022020-03-02 13:49:55 +08001841 segment->pids.audio.pid = info->pids.audio.pid;
1842 segment->pids.audio.format = info->pids.audio.format;
1843 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001844
hualing chen2aba4022020-03-02 13:49:55 +08001845 segment->pids.ad.pid = info->pids.ad.pid;
1846 segment->pids.ad.format = info->pids.ad.format;
1847 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001848
1849 segment->pids.pcr.pid = info->pids.pcr.pid;
1850
hualing chen4b7c15d2020-04-07 16:13:48 +08001851 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 +08001852 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001853 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001854 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001855 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001856
hualing chen5cbe1a62020-02-10 16:36:36 +08001857 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001858}
hualing chen040df222020-01-17 13:35:02 +08001859/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001860 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001861 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001862 * \retval DVR_SUCCESS On success
1863 * \return Error code
1864 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001865int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001866 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001867 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001868 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001869 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001870 return DVR_FAILURE;
1871 }
1872
hualing chencc91e1c2020-02-28 13:26:17 +08001873 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001874 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001875 return DVR_FAILURE;
1876 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001877 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001878 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001879 DVR_PlaybackSegmentInfo_t *segment = NULL;
1880 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1881 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001882 {
hualing chen040df222020-01-17 13:35:02 +08001883 if (segment->segment_id == segment_id) {
1884 list_del(&segment->head);
1885 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001886 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001887 }
hualing chen86e7d482020-01-16 15:13:33 +08001888 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001889 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001890 pthread_mutex_unlock(&player->lock);
1891
1892 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001893}
hualing chen040df222020-01-17 13:35:02 +08001894/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001895 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001896 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001897 * \retval DVR_SUCCESS On success
1898 * \return Error code
1899 */
hualing chen040df222020-01-17 13:35:02 +08001900int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001901 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001902 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001903 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001904 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001905 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001906 return DVR_FAILURE;
1907 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001908 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
1909 DVR_PB_DG(1, "vendor is amlogic. not hide or show av and update segment");
1910 return DVR_SUCCESS;
1911 }
hualing chena540a7e2020-03-27 16:44:05 +08001912
hualing chen040df222020-01-17 13:35:02 +08001913 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001914 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001915 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001916 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001917 {
hualing chen040df222020-01-17 13:35:02 +08001918 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001919 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001920 }
hualing chen86e7d482020-01-16 15:13:33 +08001921 // if encramble to free, only set flag and return;
1922
1923 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001924 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001925 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1926 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001927 //disable display, mute
hualing chen703f3572021-01-06 12:51:34 +08001928 DVR_PB_DG(1, "mute av");
hualing chen2aba4022020-03-02 13:49:55 +08001929 AmTsPlayer_hideVideo(player->handle);
1930 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001931 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1932 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001933 //enable display, unmute
hualing chen703f3572021-01-06 12:51:34 +08001934 DVR_PB_DG(1, "unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08001935 AmTsPlayer_showVideo(player->handle);
1936 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001937 } else {
1938 //do nothing
1939 }
1940 } else {
1941 //do nothing
1942 }
1943 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001944 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001945 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001946 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001947 pthread_mutex_unlock(&player->lock);
1948 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001949}
1950
1951
hualing chen99508642021-10-18 15:41:17 +08001952static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_PlaybackPids_t now_pids, DVR_PlaybackPids_t set_pids, int type) {
hualing chen040df222020-01-17 13:35:02 +08001953 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08001954 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08001955 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08001956
1957 if (type == 0) {
1958 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08001959 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08001960 } else if (type == 1) {
1961 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08001962 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08001963 } else if (type == 2) {
1964 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08001965 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08001966 } else {
1967 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08001968 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08001969 }
1970
hualing chena540a7e2020-03-27 16:44:05 +08001971 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001972 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001973 return DVR_FAILURE;
1974 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001975 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001976 if (now_pid.pid == set_pid.pid) {
1977 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001978 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001979 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001980 if (VALID_PID(now_pid.pid)) {
1981 //stop now stream
1982 if (type == 0) {
1983 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001984 if (player->has_video == DVR_TRUE) {
1985 DVR_PB_DG(1, "stop video");
1986 AmTsPlayer_stopVideoDecoding(player->handle);
1987 player->has_video = DVR_FALSE;
1988 }
hualing chen86e7d482020-01-16 15:13:33 +08001989 } else if (type == 1) {
1990 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08001991 if (player->has_audio == DVR_TRUE) {
1992 DVR_PB_DG(1, "stop audio");
1993 AmTsPlayer_stopAudioDecoding(player->handle);
1994 player->has_audio = DVR_FALSE;
1995 }
hualing chen86e7d482020-01-16 15:13:33 +08001996 } else if (type == 2) {
1997 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001998 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001999 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002000 } else if (type == 3) {
2001 //pcr
2002 }
2003 }
2004 if (VALID_PID(set_pid.pid)) {
2005 //start
2006 if (type == 0) {
2007 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08002008 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08002009 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08002010 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002011 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002012 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08002013 AmTsPlayer_setVideoParams(player->handle, &vparams);
2014 AmTsPlayer_startVideoDecoding(player->handle);
2015 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08002016 } else if (type == 1) {
2017 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002018 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002019 if (VALID_PID(set_pids.ad.pid)) {
2020 am_tsplayer_audio_params adparams;
2021 adparams.pid = set_pids.ad.pid;
2022 adparams.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2023 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",adparams.pid, adparams.codectype);
2024 AmTsPlayer_setADParams(player->handle, &adparams);
2025 AmTsPlayer_enableADMix(player->handle);
2026 }
2027
hualing chenc70a8df2020-05-12 19:23:11 +08002028 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002029
2030 memset(&aparams, 0, sizeof(aparams));
2031
hualing chenc70a8df2020-05-12 19:23:11 +08002032 aparams.pid = set_pid.pid;
2033 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
2034 player->has_audio = DVR_TRUE;
2035 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
2036 AmTsPlayer_setAudioParams(player->handle, &aparams);
2037 AmTsPlayer_startAudioDecoding(player->handle);
2038 //playback_device_audio_start(player->handle,&aparams);
2039 }
hualing chen86e7d482020-01-16 15:13:33 +08002040 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002041 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002042 if (set_pids.audio.pid == now_pids.audio.pid) {
2043 //stop audio if audio pid not change
2044 DVR_PB_DG(1, "stop audio when start ad");
2045 AmTsPlayer_stopAudioDecoding(player->handle);
2046 }
hualing chenc70a8df2020-05-12 19:23:11 +08002047 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002048
2049 memset(&aparams, 0, sizeof(aparams));
hualing chenc70a8df2020-05-12 19:23:11 +08002050 aparams.pid = set_pid.pid;
2051 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
2052 player->has_audio = DVR_TRUE;
2053 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
2054 AmTsPlayer_setADParams(player->handle, &aparams);
2055 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002056
2057 if (set_pids.audio.pid == now_pids.audio.pid) {
2058 am_tsplayer_audio_params aparams;
2059
2060 memset(&aparams, 0, sizeof(aparams));
2061
2062 aparams.pid = set_pids.audio.pid;
2063 aparams.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
2064 player->has_audio = DVR_TRUE;
2065 DVR_PB_DG(1, "restart audio when start ad");
2066 AmTsPlayer_setAudioParams(player->handle, &aparams);
2067 AmTsPlayer_startAudioDecoding(player->handle);
2068 }
hualing chenc70a8df2020-05-12 19:23:11 +08002069 }
hualing chen86e7d482020-01-16 15:13:33 +08002070 } else if (type == 3) {
2071 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08002072 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002073 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002074 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002075 //audio and video all close
2076 if (!player->has_audio && !player->has_video) {
2077 player->state = DVR_PLAYBACK_STATE_STOP;
2078 }
hualing chen86e7d482020-01-16 15:13:33 +08002079 }
2080 }
2081 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002082}
hualing chen5cbe1a62020-02-10 16:36:36 +08002083/**\brief dvr play back update segment pids
2084 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002085 * add pid stream and stop remove pid stream.
2086 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002087 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002088 * \retval DVR_SUCCESS On success
2089 * \return Error code
2090 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002091int 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 +08002092 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002093 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002094 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002095 return DVR_FAILURE;
2096 }
2097
hualing chen040df222020-01-17 13:35:02 +08002098 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08002099 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002100 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002101 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 +08002102
hualing chen040df222020-01-17 13:35:02 +08002103 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002104 {
hualing chen040df222020-01-17 13:35:02 +08002105 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002106
2107 if (player->cur_segment_id == segment_id) {
2108 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
2109 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
2110 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002111 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08002112 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002113 return 0;
2114 }
2115
2116 //if segment is on going segment,we need stop start stream
2117 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen1679f812021-11-08 15:17:46 +08002118 DVR_PB_DG(1, "unlock ---\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08002119 pthread_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002120 if (segment->pids.audio.pid != p_pids->audio.pid &&
2121 segment->pids.audio.pid == 0x1fff) {
2122 if (player->need_seek_start == DVR_TRUE) {
2123 player->need_seek_start = DVR_FALSE;
2124 pthread_mutex_lock(&player->segment_lock);
2125 player->drop_ts = DVR_TRUE;
2126 player->ts_cache_len = 0;
2127 if (player->first_start_time > 0)
2128 player->first_start_time = player->first_start_time - 1;
2129 segment_seek(player->r_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
hualing chen1679f812021-11-08 15:17:46 +08002130 DVR_PB_DG(0, "unlock segment update need seek time_offset %llu [0x%x][0x%x]", player->first_start_time, segment->pids.audio.pid, segment->pids.ad.pid);
hualing chen8a657f32021-08-30 13:12:49 +08002131 pthread_mutex_unlock(&player->segment_lock);
2132 }
2133 }
hualing chen1679f812021-11-08 15:17:46 +08002134 //check video pids, stop or restart
2135 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
2136 //check sub audio pids stop or restart
2137 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
2138 //check audio pids stop or restart
2139 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
2140 //check pcr pids stop or restart
2141 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
2142
hualing chencc91e1c2020-02-28 13:26:17 +08002143 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002144 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2145 //if state is pause, we need process at resume api. we only record change info
2146 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2147 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2148 if (VALID_PID(segment->pids.video.pid)
2149 && VALID_PID(p_pids->video.pid)
2150 && segment->pids.video.pid != p_pids->video.pid) {
2151 //restart video
2152 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
2153 }
2154 if (!VALID_PID(segment->pids.video.pid)
2155 && VALID_PID(p_pids->video.pid)
2156 && segment->pids.video.pid != p_pids->video.pid) {
2157 //start video
2158 v_cmd = DVR_PLAYBACK_CMD_VSTART;
2159 }
2160 if (VALID_PID(segment->pids.video.pid)
2161 && !VALID_PID(p_pids->video.pid)
2162 && segment->pids.video.pid != p_pids->video.pid) {
2163 //stop video
2164 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
2165 }
2166 if (VALID_PID(segment->pids.audio.pid)
2167 && VALID_PID(p_pids->audio.pid)
2168 && segment->pids.audio.pid != p_pids->audio.pid) {
2169 //restart audio
2170 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
2171 }
2172 if (!VALID_PID(segment->pids.audio.pid)
2173 && VALID_PID(p_pids->audio.pid)
2174 && segment->pids.audio.pid != p_pids->audio.pid) {
2175 //start audio
2176 a_cmd = DVR_PLAYBACK_CMD_ASTART;
2177 }
2178 if (VALID_PID(segment->pids.audio.pid)
2179 && !VALID_PID(p_pids->audio.pid)
2180 && segment->pids.audio.pid != p_pids->audio.pid) {
2181 //stop audio
2182 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
2183 }
2184 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2185 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2186 //do nothing
2187 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2188 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2189 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2190 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2191 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2192 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
2193 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2194 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2195 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2196 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2197 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2198 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2199 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2200 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
2201 } else {
2202 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2203 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
2204 }
2205
2206 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2207 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2208 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2209 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
2210 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2211 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2212 //not occur this case
2213 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2214 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2215 } else {
2216 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2217 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
2218 }
2219
2220 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2221 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2222 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2223 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
2224 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2225 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
2226 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2227 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
2228 } else {
2229 //not occur this case
2230 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2231 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2232 }
2233 }
2234 }
hualing chene10666f2020-04-14 13:58:37 +08002235 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002236 }
hualing chen86e7d482020-01-16 15:13:33 +08002237 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08002238 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002239 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08002240 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002241 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002242 }
hualing chen86e7d482020-01-16 15:13:33 +08002243 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002244 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002245 pthread_mutex_unlock(&player->lock);
2246 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002247}
2248/**\brief Stop play, will stop video and audio
2249 * \param[in] handle playback handle
2250 * \param[in] clear is clear last frame
2251 * \retval DVR_SUCCESS On success
2252 * \return Error code
2253 */
hualing chen040df222020-01-17 13:35:02 +08002254int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2255 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002256 UNDVRUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002257 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002258 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002259 return DVR_FAILURE;
2260 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002261 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2262 DVR_PB_DG(1, ":playback is stoped");
2263 return DVR_SUCCESS;
2264 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002265 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2266 DVR_PB_DG(1, ":playback is stoped");
2267 return DVR_SUCCESS;
2268 }
hualing chen87072a82020-03-12 16:20:12 +08002269 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08002270 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002271 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002272 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002273 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002274 if (player->has_video) {
2275 AmTsPlayer_resumeVideoDecoding(player->handle);
2276 }
2277 if (player->has_audio) {
2278 AmTsPlayer_resumeAudioDecoding(player->handle);
2279 }
2280 if (player->has_video) {
2281 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002282 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002283 AmTsPlayer_stopVideoDecoding(player->handle);
2284 }
2285 if (player->has_audio) {
2286 player->has_audio = DVR_FALSE;
2287 AmTsPlayer_stopAudioDecoding(player->handle);
2288 }
hualing chendf118dd2020-05-21 15:49:11 +08002289 if (player->has_ad_audio) {
2290 player->has_ad_audio =DVR_FALSE;
2291 AmTsPlayer_disableADMix(player->handle);
2292 }
hualing chen266b9502020-04-04 17:39:39 +08002293
hualing chen86e7d482020-01-16 15:13:33 +08002294 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002295 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2296 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2297 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002298 player->cur_segment_id = UINT64_MAX;
2299 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002300 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08002301 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08002302 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002303 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002304}
2305/**\brief Start play audio
2306 * \param[in] handle playback handle
2307 * \param[in] params audio playback params,contains fmt and pid...
2308 * \retval DVR_SUCCESS On success
2309 * \return Error code
2310 */
hualing chen2aba4022020-03-02 13:49:55 +08002311
hualing chendf118dd2020-05-21 15:49:11 +08002312int 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 +08002313 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002314
2315 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002316 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002317 return DVR_FAILURE;
2318 }
hualing chen86e7d482020-01-16 15:13:33 +08002319 _start_playback_thread(handle);
2320 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002321 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002322 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002323
hualing chendf118dd2020-05-21 15:49:11 +08002324 if (VALID_PID(adparam->pid)) {
2325 player->has_ad_audio = DVR_TRUE;
2326 DVR_PB_DG(1, "start ad audio");
2327 AmTsPlayer_setADParams(player->handle, adparam);
2328 AmTsPlayer_enableADMix(player->handle);
2329 }
hualing chen969fe7b2021-05-26 15:13:17 +08002330 if (VALID_PID(param->pid)) {
2331 DVR_PB_DG(1, "start audio");
2332 player->has_audio = DVR_TRUE;
2333 AmTsPlayer_setAudioParams(player->handle, param);
2334 AmTsPlayer_startAudioDecoding(player->handle);
2335 }
hualing chendf118dd2020-05-21 15:49:11 +08002336
hualing chen86e7d482020-01-16 15:13:33 +08002337 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002338 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
2339 player->cmd.state = DVR_PLAYBACK_STATE_START;
2340 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002341 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002342 pthread_mutex_unlock(&player->lock);
2343 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002344}
2345/**\brief Stop play audio
2346 * \param[in] handle playback handle
2347 * \retval DVR_SUCCESS On success
2348 * \return Error code
2349 */
hualing chen040df222020-01-17 13:35:02 +08002350int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2351 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002352
2353 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002354 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002355 return DVR_FAILURE;
2356 }
2357
hualing chen2aba4022020-03-02 13:49:55 +08002358 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002359 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002360 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2361 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002362 //destory thread
2363 _stop_playback_thread(handle);
2364 } else {
2365 //do nothing.video is playing
2366 }
hualing chen7a56cba2020-04-14 14:09:27 +08002367 DVR_PB_DG(1, "lock");
2368 pthread_mutex_lock(&player->lock);
2369
hualing chenf00cdc82020-06-10 14:23:35 +08002370 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002371 player->has_audio = DVR_FALSE;
2372 AmTsPlayer_stopAudioDecoding(player->handle);
2373 }
hualing chen87072a82020-03-12 16:20:12 +08002374
hualing chendf118dd2020-05-21 15:49:11 +08002375 if (player->has_ad_audio) {
2376 player->has_ad_audio =DVR_FALSE;
2377 AmTsPlayer_disableADMix(player->handle);
2378 }
2379
hualing chen87072a82020-03-12 16:20:12 +08002380 player->cmd.last_cmd = player->cmd.cur_cmd;
2381 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2382
hualing chen4b7c15d2020-04-07 16:13:48 +08002383 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002384 pthread_mutex_unlock(&player->lock);
2385 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002386}
2387/**\brief Start play video
2388 * \param[in] handle playback handle
2389 * \param[in] params video playback params,contains fmt and pid...
2390 * \retval DVR_SUCCESS On success
2391 * \return Error code
2392 */
hualing chen2aba4022020-03-02 13:49:55 +08002393int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002394 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002395
2396 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002397 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002398 return DVR_FAILURE;
2399 }
2400
hualing chen86e7d482020-01-16 15:13:33 +08002401 _start_playback_thread(handle);
2402 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002403 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002404 pthread_mutex_lock(&player->lock);
2405 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002406 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002407 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002408 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002409
2410 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002411 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002412 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002413 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002414 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2415 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002416 }
2417 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002418 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2419 player->cmd.state = DVR_PLAYBACK_STATE_START;
2420 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002421 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002422 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002423 return DVR_SUCCESS;
2424}
2425/**\brief Stop play video
2426 * \param[in] handle playback handle
2427 * \retval DVR_SUCCESS On success
2428 * \return Error code
2429 */
hualing chen040df222020-01-17 13:35:02 +08002430int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2431 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002432
2433 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002434 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002435 return DVR_FAILURE;
2436 }
2437
hualing chen86e7d482020-01-16 15:13:33 +08002438 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002439 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2440 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002441 //destory thread
2442 _stop_playback_thread(handle);
2443 } else {
2444 //do nothing.audio is playing
2445 }
hualing chen7a56cba2020-04-14 14:09:27 +08002446
2447 DVR_PB_DG(1, "lock");
2448 pthread_mutex_lock(&player->lock);
2449
hualing chen87072a82020-03-12 16:20:12 +08002450 player->has_video = DVR_FALSE;
2451
2452 AmTsPlayer_stopVideoDecoding(player->handle);
2453 //playback_device_video_stop(player->handle);
2454
2455 player->cmd.last_cmd = player->cmd.cur_cmd;
2456 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2457
hualing chen4b7c15d2020-04-07 16:13:48 +08002458 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002459 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002460 return DVR_SUCCESS;
2461}
2462/**\brief Pause play
2463 * \param[in] handle playback handle
2464 * \param[in] flush whether its internal buffers should be flushed
2465 * \retval DVR_SUCCESS On success
2466 * \return Error code
2467 */
hualing chen040df222020-01-17 13:35:02 +08002468int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2469 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002470 UNDVRUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002471 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002472 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002473 return DVR_FAILURE;
2474 }
hualing chenf00cdc82020-06-10 14:23:35 +08002475 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
2476 DVR_PB_DG(1, "player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002477 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002478 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002479 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002480 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002481 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002482 if (player->has_video)
2483 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002484 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002485 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002486
2487 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002488 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2489 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2490 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2491 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002492 } else {
2493 player->cmd.last_cmd = player->cmd.cur_cmd;
2494 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2495 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2496 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002497 }
hualing chen86e7d482020-01-16 15:13:33 +08002498 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002499 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002500
hualing chen86e7d482020-01-16 15:13:33 +08002501 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002502}
2503
hualing chen5cbe1a62020-02-10 16:36:36 +08002504//not add lock
2505static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2506{
2507 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2508
hualing chena540a7e2020-03-27 16:44:05 +08002509 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002510 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002511 return DVR_FAILURE;
2512 }
2513
hualing chen5cbe1a62020-02-10 16:36:36 +08002514 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002515 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002516 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002517 am_tsplayer_video_params vparams;
2518 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002519 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002520 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002521
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002522 memset(&vparams, 0, sizeof(vparams));
2523 memset(&aparams, 0, sizeof(aparams));
2524
hualing chendf118dd2020-05-21 15:49:11 +08002525 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002526 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002527 pthread_mutex_unlock(&player->lock);
2528
2529 switch (cmd) {
2530 case DVR_PLAYBACK_CMD_AVRESTART:
2531 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002532 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002533 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002534 break;
2535 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002536 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2537 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002538 break;
2539 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002540 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002541 break;
2542 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002543 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002544 break;
2545 case DVR_PLAYBACK_CMD_ARESTART:
2546 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002547 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002548 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002549 break;
2550 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002551 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002552 break;
2553 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002554 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002555 break;
2556 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002557 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2558 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2559 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002560 break;
2561 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002562 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2563 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002564 break;
2565 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002566 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2567 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002568 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002569 break;
2570 case DVR_PLAYBACK_CMD_STOP:
2571 break;
2572 case DVR_PLAYBACK_CMD_START:
2573 break;
2574 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002575 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2576 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002577 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002578 break;
2579 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002580 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2581 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002582 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002583 break;
2584 case DVR_PLAYBACK_CMD_FF:
2585 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002586 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002587 break;
2588 default:
2589 break;
2590 }
2591 return DVR_SUCCESS;
2592}
2593
2594/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002595 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002596 * \retval DVR_SUCCESS On success
2597 * \return Error code
2598 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002599int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2600 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002601 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002602 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002603 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002604 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002605 return DVR_FAILURE;
2606 }
2607
hualing chena991aa82021-08-16 10:21:15 +08002608 if (dvr_playback_check_limit(handle)) {
2609 //get id and pos to check if we can seek to this pos
hualing chen7ea70a72021-09-09 11:25:13 +08002610 DVR_PB_DG(1, "player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002611 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2612 if (segmentid != player->cur_segment_id ||
2613 (segmentid == player->cur_segment_id &&
2614 pos > _dvr_get_cur_time(handle))) {
2615 //first to seek new pos and to resume
2616 DVR_PB_DG(1, "seek new pos and to resume");
2617 dvr_playback_seek(handle, segmentid, pos);
2618 }
hualing chen7ea70a72021-09-09 11:25:13 +08002619 } else {
2620 DVR_PB_DG(1, "player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002621 }
hualing chena991aa82021-08-16 10:21:15 +08002622
hualing chen5cbe1a62020-02-10 16:36:36 +08002623 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002624 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002625 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002626 player->first_frame = 0;
2627 if (player->has_video)
2628 AmTsPlayer_pauseVideoDecoding(player->handle);
2629 if (player->has_audio)
2630 AmTsPlayer_pauseAudioDecoding(player->handle);
2631
hualing chen266b9502020-04-04 17:39:39 +08002632 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002633 DVR_PB_DG(1, "dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002634 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2635 AmTsPlayer_resumeVideoDecoding(player->handle);
2636 }
2637 if (player->has_audio) {
2638 AmTsPlayer_resumeAudioDecoding(player->handle);
2639 }
2640 //check is has audio param,if has audio .we need start audio,
2641 //we will stop audio when ff fb, if reach end, we will pause.so we need
2642 //start audio when resume play
2643
2644 am_tsplayer_video_params vparams;
2645 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002646 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002647 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002648
2649 memset(&vparams, 0, sizeof(vparams));
2650 memset(&aparams, 0, sizeof(aparams));
hualing chendf118dd2020-05-21 15:49:11 +08002651 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002652 //valid audio pid, start audio
hualing chen969fe7b2021-05-26 15:13:17 +08002653 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2654 player->has_ad_audio = DVR_TRUE;
2655 DVR_PB_DG(1, "start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08002656 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08002657 AmTsPlayer_setADParams(player->handle, &adparams);
2658 AmTsPlayer_enableADMix(player->handle);
2659 }
2660
hualing chenc70a8df2020-05-12 19:23:11 +08002661 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 +08002662 player->has_audio = DVR_TRUE;
hualing chen1679f812021-11-08 15:17:46 +08002663 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen266b9502020-04-04 17:39:39 +08002664 AmTsPlayer_setAudioParams(player->handle, &aparams);
2665 AmTsPlayer_startAudioDecoding(player->handle);
2666 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002667 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 +08002668 }
hualing chendf118dd2020-05-21 15:49:11 +08002669
hualing chen87072a82020-03-12 16:20:12 +08002670 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2671 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2672 player->cmd.state = DVR_PLAYBACK_STATE_START;
2673 player->state = DVR_PLAYBACK_STATE_START;
2674 } else {
2675 player->cmd.last_cmd = player->cmd.cur_cmd;
2676 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2677 player->cmd.state = DVR_PLAYBACK_STATE_START;
2678 player->state = DVR_PLAYBACK_STATE_START;
2679 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002680 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002681 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002682 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
hualing chen1ffd85b2021-08-16 15:18:43 +08002683 player->first_frame = 0;
2684 if (player->has_video)
2685 AmTsPlayer_pauseVideoDecoding(player->handle);
2686 if (player->has_audio)
2687 AmTsPlayer_pauseAudioDecoding(player->handle);
2688
hualing chene41f4372020-06-06 16:29:17 +08002689 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002690 DVR_PB_DG(1, "dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002691 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002692 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002693 }
hualing chen041c4092020-04-05 15:11:50 +08002694 if (player->has_audio)
2695 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002696 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002697 player->cmd.state = DVR_PLAYBACK_STATE_START;
2698 player->state = DVR_PLAYBACK_STATE_START;
hualing chen9811b212020-10-29 11:21:44 +08002699 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2700 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002701 } else {
2702 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2703 {
hualing chen1679f812021-11-08 15:17:46 +08002704 DVR_PB_DG(1, "lock ---\r\n");
hualing chen041c4092020-04-05 15:11:50 +08002705 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002706 player->first_frame = 0;
2707 if (player->has_video)
2708 AmTsPlayer_pauseVideoDecoding(player->handle);
2709 if (player->has_audio)
2710 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002711 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002712 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002713 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2714 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002715 if (player->has_video) {
2716 AmTsPlayer_resumeVideoDecoding(player->handle);
2717 }
2718 if (player->has_audio)
2719 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen1679f812021-11-08 15:17:46 +08002720 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen041c4092020-04-05 15:11:50 +08002721 pthread_mutex_unlock(&player->lock);
2722 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002723 }
2724 return DVR_SUCCESS;
2725}
2726
hualing chena540a7e2020-03-27 16:44:05 +08002727static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2728
2729 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2730 DVR_PlaybackSegmentInfo_t *segment = NULL;
2731 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2732 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2733
2734 list_for_each_entry(segment, &player->segment_list, head)
2735 {
2736 if (segment->segment_id == segment_id) {
2737 cur_segment = segment;
2738 }
2739 if (segment->segment_id == set_seg_id) {
2740 set_segment = segment;
2741 }
2742 if (cur_segment != NULL && set_segment != NULL) {
2743 break;
2744 }
2745 }
2746 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002747 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002748 return DVR_TRUE;
2749 }
2750 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2751 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2752 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2753 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002754 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 +08002755 return DVR_TRUE;
2756 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002757 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002758 return DVR_FALSE;
2759}
2760
hualing chen03fd4942021-07-15 15:56:41 +08002761/**\brief set limit
2762 * \param[in] handle playback handle
2763 * \param[in] rec start time ms
2764 * \param[in] rec limit time ms
2765 * \retval DVR_SUCCESS On success
2766 * \return Error code
2767 */
hualing chen7ea70a72021-09-09 11:25:13 +08002768int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08002769{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2770
2771 if (player == NULL) {
2772 DVR_PB_DG(1, "player is NULL");
2773 return DVR_FAILURE;
2774 }
hualing chen7ea70a72021-09-09 11:25:13 +08002775 _dvr_getClock_sec();
hualing chen1679f812021-11-08 15:17:46 +08002776 DVR_PB_DG(1, "lock time %lu limit: %u player->state:%d", time, limit, player->state);
hualing chen03fd4942021-07-15 15:56:41 +08002777 pthread_mutex_lock(&player->lock);
2778 player->rec_start = time;
2779 player->limit = limit;
hualing chen1679f812021-11-08 15:17:46 +08002780 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen03fd4942021-07-15 15:56:41 +08002781 pthread_mutex_unlock(&player->lock);
2782 return DVR_SUCCESS;
2783}
2784
hualing chen5cbe1a62020-02-10 16:36:36 +08002785/**\brief seek
2786 * \param[in] handle playback handle
2787 * \param[in] time_offset time offset base cur segment
2788 * \retval DVR_SUCCESS On success
2789 * \return Error code
2790 */
hualing chencc91e1c2020-02-28 13:26:17 +08002791int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002792 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002793 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08002794 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002795 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002796 return DVR_FAILURE;
2797 }
2798
hualing chen4b7c15d2020-04-07 16:13:48 +08002799 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 +08002800 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002801
hualing chen86e7d482020-01-16 15:13:33 +08002802 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002803 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002804 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002805
hualing chen5cbe1a62020-02-10 16:36:36 +08002806 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08002807 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002808 if (ret ==DVR_FAILURE) {
hualing chen1679f812021-11-08 15:17:46 +08002809 DVR_PB_DG(1, "unlock seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002810 pthread_mutex_unlock(&player->lock);
2811 return DVR_FAILURE;
2812 }
2813 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2814 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002815 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002816 time_offset = _dvr_get_end_time(handle);
2817 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002818 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002819 time_offset = _dvr_get_end_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08002820 ret = DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08002821 }
2822 }
2823
hualing chen03fd4942021-07-15 15:56:41 +08002824 DVR_PB_DG(1, "seek open id[%lld]flag[0x%x] time_offset %u",
2825 player->cur_segment.segment_id,
2826 player->cur_segment.flags,
2827 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08002828 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002829 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2830 //forward playback.not seek end of file
2831 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2832 //default -2000ms
2833 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2834 }
hualing chen86e7d482020-01-16 15:13:33 +08002835 }
hualing chen8a657f32021-08-30 13:12:49 +08002836 if (player->need_seek_start == DVR_TRUE) {
2837 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
2838 }
hualing chen2aba4022020-03-02 13:49:55 +08002839 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002840 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002841 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002842 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002843 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 +08002844 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002845 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002846
hualing chen2aba4022020-03-02 13:49:55 +08002847 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002848
2849 player->last_send_time_id = UINT64_MAX;
hualing chen03fd4942021-07-15 15:56:41 +08002850 player->last_segment_tatol = 0LL;
2851 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08002852 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002853 player->fffb_current = _dvr_time_getClock();
2854 player->fffb_start = player->fffb_current;
2855 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2856 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002857 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002858 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002859 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002860 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002861 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002862 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002863 }
hualing chen86e7d482020-01-16 15:13:33 +08002864 //stop play
hualing chen03fd4942021-07-15 15:56:41 +08002865 DVR_PB_DG(0, "seek stop play, not inject data has video[%d]audio[%d]",
2866 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08002867
hualing chen266b9502020-04-04 17:39:39 +08002868 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08002869 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08002870 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08002871 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002872 }
2873
2874 if (player->has_audio) {
2875 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002876 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002877 }
hualing chendf118dd2020-05-21 15:49:11 +08002878 if (player->has_ad_audio) {
2879 player->has_ad_audio =DVR_FALSE;
2880 AmTsPlayer_disableADMix(player->handle);
2881 }
2882
hualing chen86e7d482020-01-16 15:13:33 +08002883 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002884 am_tsplayer_video_params vparams;
2885 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002886 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002887
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002888 memset(&vparams, 0, sizeof(vparams));
2889 memset(&aparams, 0, sizeof(aparams));
2890
hualing chen040df222020-01-17 13:35:02 +08002891 player->cur_segment_id = segment_id;
2892
2893 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002894 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002895 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002896 //start audio and video
Zhiqiang Han9adc9722020-11-11 18:38:10 +08002897 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08002898 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002899 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 +08002900 pthread_mutex_unlock(&player->lock);
2901 return -1;
2902 }
2903 //add
hualing chen040df222020-01-17 13:35:02 +08002904 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002905 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002906 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002907 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08002908 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002909 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002910 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002911 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002912 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002913 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002914 }
hualing chen2aba4022020-03-02 13:49:55 +08002915 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08002916 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08002917 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002918 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
2919 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
2920 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2921 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2922 AmTsPlayer_stopFast(player->handle);
2923 }
hualing chen266b9502020-04-04 17:39:39 +08002924 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08002925 } else {
2926 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08002927 }
hualing chene41f4372020-06-06 16:29:17 +08002928 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08002929 player->has_ad_audio = DVR_TRUE;
2930 DVR_PB_DG(1, "start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08002931 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chendf118dd2020-05-21 15:49:11 +08002932 AmTsPlayer_setADParams(player->handle, &adparams);
2933 AmTsPlayer_enableADMix(player->handle);
2934 }
hualing chen969fe7b2021-05-26 15:13:17 +08002935 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
2936 DVR_PB_DG(1, "start audio seek");
hualing chen1679f812021-11-08 15:17:46 +08002937 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08002938 AmTsPlayer_setAudioParams(player->handle, &aparams);
2939 AmTsPlayer_startAudioDecoding(player->handle);
2940 player->has_audio = DVR_TRUE;
2941 }
hualing chen86e7d482020-01-16 15:13:33 +08002942 }
hualing chen1ffd85b2021-08-16 15:18:43 +08002943 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen2aba4022020-03-02 13:49:55 +08002944 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2945 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen30423862021-04-16 14:39:12 +08002946 player->seek_pause = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002947 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002948 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2949 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002950 player->speed > 1.0f||
2951 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002952 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002953 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002954 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002955 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002956 player->cmd.last_cmd = player->cmd.cur_cmd;
2957 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2958 player->cmd.state = DVR_PLAYBACK_STATE_START;
2959 player->state = DVR_PLAYBACK_STATE_START;
2960 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002961 player->last_send_time_id = UINT64_MAX;
2962 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002963 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002964
2965 return DVR_SUCCESS;
2966}
hualing chen5cbe1a62020-02-10 16:36:36 +08002967
hualing chen5cbe1a62020-02-10 16:36:36 +08002968static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2969 //get cur time of segment
2970 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002971
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002972 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002973 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002974 return DVR_FAILURE;
2975 }
2976
hualing chen31140872020-03-25 12:29:26 +08002977 int64_t cache = 0;//defalut es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08002978 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002979 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2980 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen21a40372021-10-29 11:07:26 +08002981 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002982 pthread_mutex_unlock(&player->segment_lock);
hualing chenfbf8e022020-06-15 13:43:11 +08002983 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 +08002984 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2985 cache = 0;
2986 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002987 int cur_time = (int)(cur > cache ? cur - cache : 0);
2988 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002989}
2990
hualing chen969fe7b2021-05-26 15:13:17 +08002991static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
2992 //get cur time of segment
2993 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2994
hualing chen03fd4942021-07-15 15:56:41 +08002995 if (player == NULL || player->handle == 0) {
hualing chen969fe7b2021-05-26 15:13:17 +08002996 DVR_PB_DG(1, "player is NULL");
2997 return DVR_FAILURE;
2998 }
2999
3000 int64_t cache = 0;//defalut es buf cache 500ms
3001 int cur_time = 0;
hualing chen969fe7b2021-05-26 15:13:17 +08003002 pthread_mutex_lock(&player->segment_lock);
hualing chen21a40372021-10-29 11:07:26 +08003003 loff_t pos = segment_tell_position(player->r_handle) - player->ts_cache_len;
hualing chen969fe7b2021-05-26 15:13:17 +08003004 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen21a40372021-10-29 11:07:26 +08003005 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen969fe7b2021-05-26 15:13:17 +08003006 pthread_mutex_unlock(&player->segment_lock);
hualing chen21a40372021-10-29 11:07:26 +08003007 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);
hualing chen969fe7b2021-05-26 15:13:17 +08003008 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3009 cache = 0;
3010 }
3011 if (cur > cache) {
3012 cur_time = (int)(cur - cache);
3013 *id = player->cur_segment_id;
3014 } else if (player->last_segment_tatol > 0) {
hualing chen8a657f32021-08-30 13:12:49 +08003015
3016 if (player->last_segment_tatol > (cache - cur))
3017 cur_time = (int)(player->last_segment_tatol - (cache - cur));
3018 else
3019 cur_time = (int)(player->last_segment_tatol - cur);
3020
hualing chen969fe7b2021-05-26 15:13:17 +08003021 *id = player->last_segment_id;
3022 DVR_PB_DG(1, "get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_tatol);
3023 } else {
3024 cur_time = 0;
3025 *id = player->cur_segment_id;
3026 }
3027
3028 return cur_time;
3029}
3030
hualing chencc91e1c2020-02-28 13:26:17 +08003031//get current segment current pcr time of read pos
3032static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3033 //get cur time of segment
3034 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003035
3036 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 chen2aba4022020-03-02 13:49:55 +08003041 pthread_mutex_lock(&player->segment_lock);
3042 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003043 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08003044 pthread_mutex_unlock(&player->segment_lock);
3045 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003046}
3047
hualing chen03fd4942021-07-15 15:56:41 +08003048DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3049{
3050 //check is set limit info
3051 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3052
3053 if (player == NULL) {
3054 DVR_PB_DG(1, "player is NULL");
3055 return DVR_FALSE;
3056 }
3057 if (player->rec_start > 0 || player->limit > 0) {
3058 return DVR_TRUE;
3059 }
3060 return DVR_FALSE;
3061}
3062
3063/**\brief set DVR playback calculate expired time len
3064 * \param[in] handle, DVR playback session handle
3065 * \return DVR_SUCCESS on success
3066 * \return error code on failure
3067 */
hualing chen7ea70a72021-09-09 11:25:13 +08003068uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003069{
3070 //calculate expired time to play
3071 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003072 uint32_t cur_time;
3073 uint32_t tmp_time;
3074 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003075 if (player == NULL) {
3076 DVR_PB_DG(1, "player is NULL");
3077 return expired;
3078 }
hualing chen7ea70a72021-09-09 11:25:13 +08003079 if (player->rec_start == 0 || player->limit == 0) {
3080 DVR_PB_DG(1, "rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003081 return expired;
3082 }
3083 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003084 cur_time = _dvr_getClock_sec();
3085 if ((cur_time - player->rec_start) > player->limit) {
3086 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3087 expired = *(int*)&tmp_time;
3088 DVR_PB_DG(1, "cur_time:%u, rec start:%u limit:%d c_r_diff:%u expired:%u tmp_time:%u",
hualing chen03fd4942021-07-15 15:56:41 +08003089 cur_time,
3090 player->rec_start,
3091 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003092 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3093 }
hualing chen03fd4942021-07-15 15:56:41 +08003094 return expired;
3095}
3096
3097/**\brief set DVR playback obsolete time
3098 * \param[in] handle, DVR playback session handle
3099 * \param[in] obsolete, obsolete len
3100 * \return DVR_SUCCESS on success
3101 * \return error code on failure
3102 */
3103int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3104{
3105 int expired = 0;
3106 //calculate expired time to play
3107 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3108
3109 if (player == NULL) {
3110 DVR_PB_DG(1, "player is NULL");
3111 return DVR_FALSE;
3112 }
3113 //get system time
hualing chen1679f812021-11-08 15:17:46 +08003114 DVR_PB_DG(1, "lock ---\r\n");
hualing chen03fd4942021-07-15 15:56:41 +08003115 pthread_mutex_lock(&player->lock);
3116 player->obsolete = obsolete;
hualing chen1679f812021-11-08 15:17:46 +08003117 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen03fd4942021-07-15 15:56:41 +08003118 pthread_mutex_unlock(&player->lock);
3119 return expired;
3120}
3121
3122/**\brief update DVR playback newest segment duration
3123 * \param[in] handle, DVR playback session handle
3124 * \param[in] segmentid, newest segment id
3125 * \param[in] dur dur time ms
3126 * \return DVR_SUCCESS on success
3127 * \return error code on failure
3128 */
3129int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3130uint64_t segmentid, int dur)
3131{
3132 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3133 DVR_PlaybackSegmentInfo_t *segment;
3134 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3135
3136 if (player == NULL) {
3137 DVR_PB_DG(1, " player is NULL");
3138 return DVR_FAILURE;
3139 }
3140 //update the newest segment duration on timeshift mode
3141 list_for_each_entry(segment, &player->segment_list, head)
3142 {
3143 if (segment->segment_id == segmentid) {
3144 segment->duration = dur;
3145 break;
3146 }
3147 pre_segment = segment;
3148 }
3149
3150 return DVR_SUCCESS;
3151}
3152
hualing chen7ea70a72021-09-09 11:25:13 +08003153static uint32_t dvr_playback_calculate_last_valid_segment(
3154 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003155{
hualing chen7ea70a72021-09-09 11:25:13 +08003156 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003157 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003158 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003159 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003160 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003161 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3162
3163 if (player == NULL) {
3164 DVR_PB_DG(1, "player is NULL");
3165 return DVR_FAILURE;
3166 }
3167 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003168 if (expired == 0) {
3169 *segmentid = player->cur_segment_id;
3170 *pos = 0;
3171 return DVR_SUCCESS;
3172 }
hualing chen03fd4942021-07-15 15:56:41 +08003173 DVR_PlaybackSegmentInfo_t *pseg;
3174 list_for_each_entry_reverse(pseg, &player->segment_list, head) {
3175 segment_id = pseg->segment_id;
3176
3177 if ((player->obsolete + pre_off + pseg->duration) > expired)
3178 break;
3179
3180 last_segment_id = pseg->segment_id;
3181 pre_off += pseg->duration;
3182 }
3183
3184 if (last_segment_id == segment_id) {
3185 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3186 off = expired;
3187 } else if (player->obsolete >= expired) {
3188 off = 0;
3189 } else {
3190 off = expired - pre_off - player->obsolete;
3191 }
3192 *segmentid = segment_id;
3193 *pos = off;
3194 return DVR_SUCCESS;
3195}
3196
hualing chen4b7c15d2020-04-07 16:13:48 +08003197#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003198//start replay
3199static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3200
3201 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3202 //calculate pcr seek time
3203 int t_diff = 0;
3204 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003205 uint64_t segmentid = 0;
3206 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003207 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003208 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003209 return DVR_FAILURE;
3210 }
3211
hualing chen5cbe1a62020-02-10 16:36:36 +08003212 if (player->fffb_start == -1) {
3213 //set fffb start time ms
3214 player->fffb_start = _dvr_time_getClock();
3215 player->fffb_current = player->fffb_start;
3216 //get segment current time pos
3217 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08003218 DVR_PB_DG(1, "calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
3219 player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003220 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08003221 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003222 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003223 } else {
3224 player->fffb_current = _dvr_time_getClock();
3225 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003226 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003227 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003228 if (seek_time <= 0) {
3229 //need seek to pre one segment
3230 seek_time = 0;
3231 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003232 //seek segment pos
3233 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003234 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003235 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003236 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3237 //set seek time to 0;
hualing chen03fd4942021-07-15 15:56:41 +08003238 DVR_PB_DG(1, "segment seek to 0 at fb mode [%d]id[%lld]",
3239 seek_time,
3240 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003241 seek_time = 0;
3242 }
hualing chen03fd4942021-07-15 15:56:41 +08003243 if (IS_FB(player->speed)
3244 && dvr_playback_check_limit(handle)) {
3245 //fb case.check expired time
3246 //get id and pos to check if we can seek to this pos
3247 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3248 //case cur id < segment id
3249 if (player->cur_segment_id < segmentid) {
3250 //expired ts data is player,return error
3251 //
3252 pthread_mutex_unlock(&player->segment_lock);
3253 return 0;
3254 } else if (player->cur_segment_id == segmentid) {
3255 //id is same,compare seek pos
3256 if (seek_time < pos) {
3257 //expired ts data is player,return error
3258 //
3259 pthread_mutex_unlock(&player->segment_lock);
3260 return 0;
3261 }
3262 }
3263 //case can play
3264 }
hualing chen041c4092020-04-05 15:11:50 +08003265 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
3266 seek_time = 0;
3267 }
hualing chen2aba4022020-03-02 13:49:55 +08003268 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003269 } else {
3270 //
hualing chen4b7c15d2020-04-07 16:13:48 +08003271 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003272 }
hualing chen03fd4942021-07-15 15:56:41 +08003273 DVR_PB_DG(1, "calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
3274 seek_time,
3275 player->speed,
3276 player->cur_segment_id,
3277 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003278 }
hualing chen2aba4022020-03-02 13:49:55 +08003279 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003280}
3281
3282
3283//start replay
3284static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3285 //
3286 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003287
3288 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003289 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003290 return DVR_FAILURE;
3291 }
3292
hualing chen5cbe1a62020-02-10 16:36:36 +08003293 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003294 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003295 DVR_PB_DG(1, "fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003296 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003297 AmTsPlayer_stopVideoDecoding(player->handle);
3298 }
3299 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003300 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003301 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003302 AmTsPlayer_stopAudioDecoding(player->handle);
3303 }
hualing chendf118dd2020-05-21 15:49:11 +08003304 if (player->has_ad_audio) {
3305 DVR_PB_DG(1, "fffb stop audio");
3306 player->has_ad_audio =DVR_FALSE;
3307 AmTsPlayer_disableADMix(player->handle);
3308 }
hualing chen2aba4022020-03-02 13:49:55 +08003309
hualing chen5cbe1a62020-02-10 16:36:36 +08003310 //start video and audio
3311
hualing chen2aba4022020-03-02 13:49:55 +08003312 am_tsplayer_video_params vparams;
3313 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003314 am_tsplayer_audio_params adparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003315
3316 memset(&vparams, 0, sizeof(vparams));
3317 memset(&aparams, 0, sizeof(aparams));
3318
hualing chen87072a82020-03-12 16:20:12 +08003319 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003320
3321 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08003322 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08003323 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003324 //start audio and video
3325 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
3326 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08003327 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003328 return -1;
3329 }
3330
3331 if (VALID_PID(vparams.pid)) {
3332 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08003333 DVR_PB_DG(1, "fffb start video");
hualing chen0888c032020-12-18 17:54:57 +08003334 //DVR_PB_DG(1, "fffb start video and save last frame");
3335 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003336 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003337 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
3338 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003339 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003340 AmTsPlayer_startVideoDecoding(player->handle);
3341 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003342 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003343 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003344 }
hualing chen31140872020-03-25 12:29:26 +08003345 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08003346 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08003347 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003348 return 0;
3349}
3350
3351static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3352 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003353 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003354 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003355 return DVR_FAILURE;
3356 }
3357
3358 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08003359 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003360 pthread_mutex_lock(&player->lock);
3361
hualing chen2aba4022020-03-02 13:49:55 +08003362 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003363 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 +08003364
hualing chen87072a82020-03-12 16:20:12 +08003365 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3366 //seek time set 0
3367 seek_time = 0;
3368 }
hualing chen041c4092020-04-05 15:11:50 +08003369 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003370 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3371 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003372 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003373 pthread_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003374 DVR_PB_DG(1, "unlock");
hualing chen87072a82020-03-12 16:20:12 +08003375 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003376 //send event here and pause
3377 DVR_Play_Notify_t notify;
3378 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003379 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003380 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003381 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08003382 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 +08003383 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003384 return DVR_SUCCESS;
3385 }
hualing chen2932d372020-04-29 13:44:00 +08003386 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003387 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003388 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003389 }
3390 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003391 _dvr_playback_fffb_replay(handle);
3392
3393 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003394 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003395
hualing chen5cbe1a62020-02-10 16:36:36 +08003396 return DVR_SUCCESS;
3397}
3398
hualing chen87072a82020-03-12 16:20:12 +08003399//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003400static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003401 //
3402 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003403
3404 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003405 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003406 return DVR_FAILURE;
3407 }
3408
hualing chen5cbe1a62020-02-10 16:36:36 +08003409 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003410 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003411 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003412 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003413 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003414 }
3415
3416 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003417 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003418 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003419 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003420 //start video and audio
3421
hualing chen2aba4022020-03-02 13:49:55 +08003422 am_tsplayer_video_params vparams;
3423 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003424 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08003425 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003426
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003427 memset(&vparams, 0, sizeof(vparams));
3428 memset(&aparams, 0, sizeof(aparams));
3429
hualing chen5cbe1a62020-02-10 16:36:36 +08003430 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08003431 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08003432 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003433 //start audio and video
3434 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003435 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08003436 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003437 return -1;
3438 }
3439
3440 if (VALID_PID(vparams.pid)) {
3441 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003442 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003443 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003444 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003445 }
hualing chen266b9502020-04-04 17:39:39 +08003446 else {
hualing chen2aba4022020-03-02 13:49:55 +08003447 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003448 }
hualing chen2aba4022020-03-02 13:49:55 +08003449 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003450 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003451 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003452 }
hualing chena540a7e2020-03-27 16:44:05 +08003453
3454 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08003455 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08003456 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003457 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003458 } else {
hualing chendf118dd2020-05-21 15:49:11 +08003459 if (VALID_PID(adparams.pid)) {
3460 player->has_ad_audio = DVR_TRUE;
3461 DVR_PB_DG(1, "start ad audio");
3462 AmTsPlayer_setADParams(player->handle, &adparams);
3463 AmTsPlayer_enableADMix(player->handle);
3464 }
hualing chen969fe7b2021-05-26 15:13:17 +08003465 if (VALID_PID(aparams.pid)) {
3466 player->has_audio = DVR_TRUE;
3467 DVR_PB_DG(1, "start audio");
3468 AmTsPlayer_setAudioParams(player->handle, &aparams);
3469 AmTsPlayer_startAudioDecoding(player->handle);
3470 }
hualing chendf118dd2020-05-21 15:49:11 +08003471
hualing chen7a56cba2020-04-14 14:09:27 +08003472 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08003473 AmTsPlayer_stopFast(player->handle);
3474 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3475 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3476 }
hualing chen2aba4022020-03-02 13:49:55 +08003477 player->cmd.last_cmd = player->cmd.cur_cmd;
3478 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003479 player->cmd.state = DVR_PLAYBACK_STATE_START;
3480 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08003481 return 0;
3482}
3483
3484
hualing chenb31a6c62020-01-13 17:27:00 +08003485/**\brief Set play speed
3486 * \param[in] handle playback handle
3487 * \param[in] speed playback speed
3488 * \retval DVR_SUCCESS On success
3489 * \return Error code
3490 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003491int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3492
3493 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003494
3495 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003496 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003497 return DVR_FAILURE;
3498 }
3499
hualing chena540a7e2020-03-27 16:44:05 +08003500 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003501 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003502 return DVR_FAILURE;
3503 }
hualing chenf00cdc82020-06-10 14:23:35 +08003504 if (speed.speed.speed == player->cmd.speed.speed.speed) {
3505 DVR_PB_DG(1, " func: eq speed [%d]", speed.speed.speed);
3506 return DVR_SUCCESS;
3507 }
hualing chen1679f812021-11-08 15:17:46 +08003508 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
3509
hualing chen5cbe1a62020-02-10 16:36:36 +08003510 pthread_mutex_lock(&player->lock);
3511 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3512 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3513 player->cmd.last_cmd = player->cmd.cur_cmd;
3514 }
hualing chene41f4372020-06-06 16:29:17 +08003515
hualing chen31140872020-03-25 12:29:26 +08003516 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003517 IS_KERNEL_SPEED(speed.speed.speed) ) {
3518 //case 1. not start play.only set speed
3519 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3520 //only set speed.and return;
3521 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3522 player->cmd.speed.speed = speed.speed;
3523 player->speed = (float)speed.speed.speed/(float)100;
3524 player->fffb_play = DVR_FALSE;
3525 pthread_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003526 DVR_PB_DG(1, "unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003527 return DVR_SUCCESS;
3528 }
3529 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003530 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3531 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003532 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003533 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3534 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003535 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003536 AmTsPlayer_stopFast(player->handle);
3537 pthread_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003538 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003539 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
hualing chen1679f812021-11-08 15:17:46 +08003540 DVR_PB_DG(1, "lock ---\r\n");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003541 pthread_mutex_lock(&player->lock);
3542 } else {
3543 //set play speed and if audio is start, stop audio.
3544 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003545 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003546 AmTsPlayer_stopAudioDecoding(player->handle);
3547 player->has_audio = DVR_FALSE;
3548 }
hualing chenb96aa2c2020-04-15 14:13:53 +08003549 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003550 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003551 }
hualing chenbcada022020-04-22 14:27:01 +08003552 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003553 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003554 player->cmd.speed.speed = speed.speed;
3555 player->speed = (float)speed.speed.speed/(float)100;
hualing chen1679f812021-11-08 15:17:46 +08003556 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen31140872020-03-25 12:29:26 +08003557 pthread_mutex_unlock(&player->lock);
3558 return DVR_SUCCESS;
3559 }
hualing chen31140872020-03-25 12:29:26 +08003560 //case 3 fffb mode
3561 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3562 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3563 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003564 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003565 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003566 player->cmd.speed.speed = speed.speed;
3567 player->speed = (float)speed.speed.speed/(float)100;
3568 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003569 player->fffb_play = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08003570 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen31140872020-03-25 12:29:26 +08003571 pthread_mutex_unlock(&player->lock);
3572 return DVR_SUCCESS;
3573 }
3574 }
3575 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003576 IS_KERNEL_SPEED(speed.speed.speed)) {
3577 //case 1. cur speed is kernel support speed,set kernel speed.
3578 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003579 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003580 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3581 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003582 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003583 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08003584 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003585 } else {
3586 //set play speed and if audio is start, stop audio.
3587 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003588 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003589 AmTsPlayer_stopAudioDecoding(player->handle);
3590 player->has_audio = DVR_FALSE;
3591 }
hualing chenf00cdc82020-06-10 14:23:35 +08003592 DVR_PB_DG(1, "start fast");
3593 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003594 }
hualing chena540a7e2020-03-27 16:44:05 +08003595 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003596 player->cmd.speed.speed = speed.speed;
3597 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003598 player->fffb_play = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08003599 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen31140872020-03-25 12:29:26 +08003600 pthread_mutex_unlock(&player->lock);
3601 return DVR_SUCCESS;
3602 }
3603 //case 2 fffb mode
3604 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3605 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3606 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003607 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003608 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003609 player->cmd.speed.speed = speed.speed;
3610 player->speed = (float)speed.speed.speed/(float)100;
3611 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08003612 player->fffb_play = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08003613 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen31140872020-03-25 12:29:26 +08003614 pthread_mutex_unlock(&player->lock);
3615 return DVR_SUCCESS;
3616 }
hualing chen31140872020-03-25 12:29:26 +08003617 }
hualing chena540a7e2020-03-27 16:44:05 +08003618 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3619 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003620 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003621 } else {
hualing chen31140872020-03-25 12:29:26 +08003622 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003623 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3624 else
3625 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003626 player->fffb_play = DVR_TRUE;
3627 }
3628 DVR_Bool_t init_last_time = DVR_FALSE;
3629 if (player->speed > 0.0f && speed.speed.speed < 0) {
3630 init_last_time = DVR_TRUE;
3631 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3632 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003633 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003634 player->cmd.speed.mode = speed.mode;
3635 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003636 player->speed = (float)speed.speed.speed/(float)100;
3637 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003638 _dvr_init_fffb_t(handle);
3639 if (init_last_time == DVR_TRUE)
3640 player->last_send_time_id = UINT64_MAX;
3641
hualing chen87072a82020-03-12 16:20:12 +08003642 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003643 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3644 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003645 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003646 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003647 _dvr_playback_replay(handle, DVR_FALSE);
3648 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3649 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
3650 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08003651 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003652 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003653 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08003654 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003655 return DVR_SUCCESS;
3656}
hualing chen2932d372020-04-29 13:44:00 +08003657
hualing chenb31a6c62020-01-13 17:27:00 +08003658/**\brief Get playback status
3659 * \param[in] handle playback handle
3660 * \param[out] p_status playback status
3661 * \retval DVR_SUCCESS On success
3662 * \return Error code
3663 */
hualing chen2932d372020-04-29 13:44:00 +08003664static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3665 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003666//
3667 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003668 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003669 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003670 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003671 return DVR_FAILURE;
3672 }
hualing chen1679f812021-11-08 15:17:46 +08003673 if (is_lock ==DVR_TRUE) {
3674 DVR_PB_DG(1, "lock");
hualing chen2932d372020-04-29 13:44:00 +08003675 pthread_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003676 }
3677
hualing chen5cbe1a62020-02-10 16:36:36 +08003678 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003679 //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 +08003680 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3681 player->state == DVR_PLAYBACK_STATE_START) {
3682 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3683 }
hualing chen041c4092020-04-05 15:11:50 +08003684
hualing chencc91e1c2020-02-28 13:26:17 +08003685 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003686 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003687
3688 if (CONTROL_SPEED_ENABLE == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08003689 if (player->con_spe.ply_sta == 0) {
3690 DVR_PB_DG(1, "player dur[%u] sta[%u] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08003691 player->con_spe.ply_dur,
3692 player->con_spe.ply_sta,
3693 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003694 player->con_spe.ply_sta = p_status->time_cur;
3695 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3696 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
hualing chen7ea70a72021-09-09 11:25:13 +08003697 DVR_PB_DG(1, "player dur[%u] sta[%u] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003698 player->con_spe.ply_dur,
3699 player->con_spe.ply_sta,
3700 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003701 player->con_spe.ply_sta = p_status->time_cur;
3702 }
3703
3704 if (player->con_spe.sys_sta == 0) {
3705 player->con_spe.sys_sta = _dvr_time_getClock();
3706 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3707 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3708 player->con_spe.sys_sta = _dvr_time_getClock();
3709 }
3710 }
3711
hualing chen4b7c15d2020-04-07 16:13:48 +08003712 if (player->last_send_time_id == UINT64_MAX) {
3713 player->last_send_time_id = player->cur_segment_id;
3714 player->last_cur_time = p_status->time_cur;
3715 }
3716 if (player->last_send_time_id == player->cur_segment_id) {
3717 if (player->speed > 0.0f ) {
3718 //ff
3719 if (p_status->time_cur < player->last_cur_time ) {
hualing chen03fd4942021-07-15 15:56:41 +08003720 DVR_PB_DG(1, "get ff time error last[%d]cur[%d]diff[%d]",
3721 player->last_cur_time,
3722 p_status->time_cur,
3723 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08003724 p_status->time_cur = player->last_cur_time;
3725 } else {
3726 player->last_cur_time = p_status->time_cur;
3727 }
hualing chene41f4372020-06-06 16:29:17 +08003728 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003729 //fb
3730 if (p_status->time_cur > player->last_cur_time ) {
hualing chen03fd4942021-07-15 15:56:41 +08003731 DVR_PB_DG(1, "get fb time error last[%d]cur[%d]diff[%d]",
3732 player->last_cur_time,
3733 p_status->time_cur,
3734 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08003735 p_status->time_cur = player->last_cur_time;
3736 } else {
3737 player->last_cur_time = p_status->time_cur;
3738 }
3739 }
hualing chend241c7a2021-06-22 13:34:27 +08003740 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003741 player->last_cur_time = p_status->time_cur;
3742 }
hualing chen969fe7b2021-05-26 15:13:17 +08003743 player->last_send_time_id = segment_id;
3744 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003745
hualing chen5cbe1a62020-02-10 16:36:36 +08003746 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003747 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003748 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08003749 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 +08003750 _dvr_playback_state_toString(player->state),
3751 _dvr_playback_state_toString(p_status->state),
3752 p_status->time_cur, p_status->time_end,
3753 p_status->segment_id,player->play_flag,
3754 player->speed,
3755 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08003756 if (is_lock ==DVR_TRUE) {
3757 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen2932d372020-04-29 13:44:00 +08003758 pthread_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003759 }
hualing chen2932d372020-04-29 13:44:00 +08003760 return DVR_SUCCESS;
3761}
3762
3763
3764/**\brief Get playback status
3765 * \param[in] handle playback handle
3766 * \param[out] p_status playback status
3767 * \retval DVR_SUCCESS On success
3768 * \return Error code
3769 */
3770int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3771 DVR_PlaybackStatus_t *p_status) {
3772//
3773 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3774
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003775 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3776
hualing chen2932d372020-04-29 13:44:00 +08003777 if (player == NULL) {
3778 DVR_PB_DG(1, "player is NULL");
3779 return DVR_FAILURE;
3780 }
hualing chen1679f812021-11-08 15:17:46 +08003781 DVR_PB_DG(1, "lock---");
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003782 pthread_mutex_lock(&player->lock);
3783 if (!player->has_video && !player->has_audio)
3784 p_status->time_cur = 0;
hualing chen1679f812021-11-08 15:17:46 +08003785 DVR_PB_DG(1, "unlock---");
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003786 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08003787
hualing chenb31a6c62020-01-13 17:27:00 +08003788 return DVR_SUCCESS;
3789}
3790
hualing chen040df222020-01-17 13:35:02 +08003791void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
3792 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003793 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
3794 DVR_PB_DG(1, "segment flag: %d", segment->flags);
3795 DVR_PB_DG(1, "segment location: [%s]", segment->location);
3796 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
3797 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
3798 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3799 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 +08003800 }
hualing chenb31a6c62020-01-13 17:27:00 +08003801}
3802
hualing chen5cbe1a62020-02-10 16:36:36 +08003803int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003804 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003805
hualing chena540a7e2020-03-27 16:44:05 +08003806 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003807 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003808 return DVR_FAILURE;
3809 }
3810
hualing chen040df222020-01-17 13:35:02 +08003811 DVR_PlaybackSegmentInfo_t *segment;
3812 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003813 {
hualing chen040df222020-01-17 13:35:02 +08003814 if (segment_id >= 0) {
3815 if (segment->segment_id == segment_id) {
3816 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003817 break;
3818 }
3819 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003820 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003821 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003822 }
3823 }
3824 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003825}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003826
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003827int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003828{
3829 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3830 DVR_RETURN_IF_FALSE(player);
3831 DVR_RETURN_IF_FALSE(func);
3832
hualing chen4b7c15d2020-04-07 16:13:48 +08003833 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003834 pthread_mutex_lock(&player->lock);
3835
3836 player->dec_func = func;
3837 player->dec_userdata = userdata;
3838
3839 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003840 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003841 return DVR_SUCCESS;
3842}
3843
3844int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3845{
3846 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3847 DVR_RETURN_IF_FALSE(player);
3848 DVR_RETURN_IF_FALSE(p_secure_buf);
3849 DVR_RETURN_IF_FALSE(len);
3850
hualing chen4b7c15d2020-04-07 16:13:48 +08003851 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003852 pthread_mutex_lock(&player->lock);
3853
3854 player->is_secure_mode = 1;
3855 player->secure_buffer = p_secure_buf;
3856 player->secure_buffer_size = len;
3857
3858 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003859 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003860 return DVR_SUCCESS;
3861}