blob: eb76076a2f24d507cf130e9423b1c089815b40fa [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
hualing chena5f03222021-12-02 11:22:35 +080058
hualing chenbcada022020-04-22 14:27:01 +080059static char* _cmd_toString(int cmd)
60{
61
62 char *string[DVR_PLAYBACK_CMD_NONE+1]={
63 "start",
64 "stop",
65 "vstart",
66 "astart",
67 "vstop",
68 "astop",
69 "vrestart",
70 "arestart",
71 "avrestart",
72 "vstopastart",
73 "astopvstart",
74 "vstoparestart",
75 "astopvrestart",
76 "vstartarestart",
77 "astartvrestart",
78 "pause",
79 "resume",
80 "seek",
81 "ff",
82 "fb",
83 "NONE"
84 };
85
86 if (cmd > DVR_PLAYBACK_CMD_NONE) {
87 return "unkown";
88 } else {
89 return string[cmd];
90 }
91}
92
93
hualing chen6d24aa92020-03-23 18:43:47 +080094static char* _dvr_playback_state_toString(int stat)
95{
96 char *string[DVR_PLAYBACK_STATE_FB+1]={
97 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080098 "stop",
hualing chen31140872020-03-25 12:29:26 +080099 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +0800100 "ff",
101 "fb"
102 };
103
104 if (stat > DVR_PLAYBACK_STATE_FB) {
105 return "unkown";
106 } else {
107 return string[stat];
108 }
109}
hualing chena540a7e2020-03-27 16:44:05 +0800110
111static DVR_Bool_t _dvr_support_speed(int speed) {
112
113 DVR_Bool_t ret = DVR_FALSE;
114
115 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800116 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800117 case PLAYBACK_SPEED_FBX2:
118 case PLAYBACK_SPEED_FBX4:
119 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800120 case PLAYBACK_SPEED_FBX16:
121 case PLAYBACK_SPEED_FBX12:
122 case PLAYBACK_SPEED_FBX32:
123 case PLAYBACK_SPEED_FBX48:
124 case PLAYBACK_SPEED_FBX64:
125 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800126 case PLAYBACK_SPEED_S2:
127 case PLAYBACK_SPEED_S4:
128 case PLAYBACK_SPEED_S8:
129 case PLAYBACK_SPEED_X1:
130 case PLAYBACK_SPEED_X2:
131 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800132 case PLAYBACK_SPEED_X3:
133 case PLAYBACK_SPEED_X5:
134 case PLAYBACK_SPEED_X6:
135 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800136 case PLAYBACK_SPEED_X8:
137 case PLAYBACK_SPEED_X12:
138 case PLAYBACK_SPEED_X16:
139 case PLAYBACK_SPEED_X32:
140 case PLAYBACK_SPEED_X48:
141 case PLAYBACK_SPEED_X64:
142 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800143 ret = DVR_TRUE;
144 break;
145 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800146 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800147 break;
148 }
149 return ret;
150}
hualing chen6e4bfa52020-03-13 14:37:11 +0800151void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
152{
hualing chen4b7c15d2020-04-07 16:13:48 +0800153 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800154 DVR_Playback_t *player = NULL;
155 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800156 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800157 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800158 }
159 switch (event->type) {
160 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
161 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800162 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800163 event->event.video_format.frame_width,
164 event->event.video_format.frame_height,
165 event->event.video_format.frame_rate);
166 break;
167 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800168 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
169 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800170 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800171 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800172 break;
173 }
174 default:
175 break;
176 }
177}
hualing chen2aba4022020-03-02 13:49:55 +0800178void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
179{
hualing chen6e4bfa52020-03-13 14:37:11 +0800180 DVR_Playback_t *player = NULL;
181 if (user_data != NULL) {
182 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800183 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800184 }
hualing chen2aba4022020-03-02 13:49:55 +0800185 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800186 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
187 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800188 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800189 event->event.video_format.frame_width,
190 event->event.video_format.frame_height,
191 event->event.video_format.frame_rate);
192 break;
193 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800194 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
195 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800196 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chene41f4372020-06-06 16:29:17 +0800197 if (player->first_trans_ok == DVR_FALSE) {
198 player->first_trans_ok = DVR_TRUE;
199 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
200 }
hualing chen30423862021-04-16 14:39:12 +0800201 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800202 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800203 player->seek_pause = DVR_FALSE;
204 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800205 break;
206 }
hualing chen487ae6d2020-07-22 10:34:11 +0800207 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
hualing chen1679f812021-11-08 15:17:46 +0800208 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
hualing chen487ae6d2020-07-22 10:34:11 +0800209 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
210 player->first_trans_ok = DVR_TRUE;
211 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
212 }
213 if (player != NULL && player->has_video == DVR_FALSE) {
214 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
215 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800216 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800217 }
218 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800219 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800220 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800221 break;
222 }
223 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800224 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800225 player->player_callback_func(player->player_callback_userdata, event);
226 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800227 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800228 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800229 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800230 }
231}
hualing chencc91e1c2020-02-28 13:26:17 +0800232
hualing chen5cbe1a62020-02-10 16:36:36 +0800233//convert video and audio fmt
234static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
235 int format = 0;
236 if (is_audio == DVR_FALSE) {
237 //for video fmt
238 switch (fmt)
239 {
240 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800241 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800242 break;
243 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800244 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800245 break;
246 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800247 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800248 break;
249 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800250 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800251 break;
hualing chena540a7e2020-03-27 16:44:05 +0800252 case DVR_VIDEO_FORMAT_VP9:
253 format = AV_VIDEO_CODEC_VP9;
254 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800255 }
256 } else {
257 //for audio fmt
258 switch (fmt)
259 {
260 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800261 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800262 break;
263 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800264 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800265 break;
266 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800267 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800268 break;
269 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800270 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800271 break;
hualing chena540a7e2020-03-27 16:44:05 +0800272 case DVR_AUDIO_FORMAT_AAC:
273 format = AV_AUDIO_CODEC_AAC;
274 break;
275 case DVR_AUDIO_FORMAT_LATM:
276 format = AV_AUDIO_CODEC_LATM;
277 break;
278 case DVR_AUDIO_FORMAT_PCM:
279 format = AV_AUDIO_CODEC_PCM;
280 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800281 case DVR_AUDIO_FORMAT_AC4:
282 format = AV_AUDIO_CODEC_AC4;
283 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800284 }
285 }
286 return format;
287}
hualing chen040df222020-01-17 13:35:02 +0800288static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800289{
hualing chen040df222020-01-17 13:35:02 +0800290 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800291
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800292 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800293 return -1;
294
hualing chena540a7e2020-03-27 16:44:05 +0800295 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800296}
hualing chena540a7e2020-03-27 16:44:05 +0800297
hualing chen7ea70a72021-09-09 11:25:13 +0800298
299//get sys time sec
300static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800301{
302 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800303 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800304 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800305 s = (uint32_t)(ts.tv_sec);
306 DVR_PB_DG(1, "n:%u", s);
307 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800308}
hualing chen86e7d482020-01-16 15:13:33 +0800309
hualing chen7ea70a72021-09-09 11:25:13 +0800310//get sys time ms
311static uint32_t _dvr_time_getClock(void)
312{
313 struct timespec ts;
314 uint32_t ms;
315 clock_gettime(CLOCK_REALTIME, &ts);
316 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
317 return ms;
318}
hualing chenb31a6c62020-01-13 17:27:00 +0800319
320//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800321static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800322{
hualing chen040df222020-01-17 13:35:02 +0800323 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800324
hualing chena540a7e2020-03-27 16:44:05 +0800325
326 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800327 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800328 return DVR_FAILURE;
329 }
330
hualing chen86e7d482020-01-16 15:13:33 +0800331 struct timespec ts;
332 clock_gettime(CLOCK_MONOTONIC, &ts);
333 //ms为毫秒,换算成秒
334 ts.tv_sec += ms/1000;
335 //在outtime的基础上,增加ms毫秒
336 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
337 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
338 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
339 //us的值有可能超过1秒,
340 ts.tv_sec += us / 1000000;
341 us = us % 1000000;
342 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800343 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
344 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800345}
hualing chen31140872020-03-25 12:29:26 +0800346//get tsplay delay time ms
347static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
348 DVR_Playback_t *player = (DVR_Playback_t *) handle;
349 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800350 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800351 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800352 return 0;
353 }
354 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800355 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800356 return cache;
357}
hualing chenb31a6c62020-01-13 17:27:00 +0800358//send signal
hualing chen040df222020-01-17 13:35:02 +0800359static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800360{
hualing chen87072a82020-03-12 16:20:12 +0800361 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800362
363 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800364 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800365 return DVR_FAILURE;
366 }
hualing chen1679f812021-11-08 15:17:46 +0800367 DVR_PB_DG(1, "lock---");
hualing chen87072a82020-03-12 16:20:12 +0800368 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800369 pthread_cond_signal(&player->cond);
hualing chen1679f812021-11-08 15:17:46 +0800370 DVR_PB_DG(1, "unlock---");
hualing chen87072a82020-03-12 16:20:12 +0800371 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800372 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800373}
374
hualing chen2932d372020-04-29 13:44:00 +0800375//send playback event, need check is need lock first
376static 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 +0800377
378 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800379
380 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800381 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800382 return DVR_FAILURE;
383 }
384
hualing chencc91e1c2020-02-28 13:26:17 +0800385 switch (evt) {
386 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800387 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800388 break;
389 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
390 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800391 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800392 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800393 break;
394 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
395 break;
396 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
397 break;
398 case DVR_PLAYBACK_EVENT_NO_KEY:
399 break;
400 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800401 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800402 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800403 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800404 break;
405 case DVR_PLAYBACK_EVENT_REACHED_END:
406 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800407 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800408 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800409 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800410 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800411 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800412 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800413 default:
414 break;
415 }
416 if (player->openParams.event_fn != NULL)
417 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800418 return DVR_SUCCESS;
419}
hualing chen2932d372020-04-29 13:44:00 +0800420static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800421{
422 DVR_Play_Notify_t notify;
423 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
424 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
425 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800426 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800427 return DVR_SUCCESS;
428}
429
hualing chen2932d372020-04-29 13:44:00 +0800430static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800431{
432 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800433
hualing chene3797f02021-01-13 14:53:28 +0800434 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800435 if (CONTROL_SPEED_ENABLE == 0)
436 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800437 }
hualing chena540a7e2020-03-27 16:44:05 +0800438 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800439 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800440 return DVR_FAILURE;
441 }
442
hualing chen03fd4942021-07-15 15:56:41 +0800443 if (player->send_time == 0) {
hualing chend241c7a2021-06-22 13:34:27 +0800444 if (CONTROL_SPEED_ENABLE == 0)
445 player->send_time = _dvr_time_getClock() + 500;
446 else
447 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800448 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800449 return DVR_SUCCESS;
450 }
hualing chend241c7a2021-06-22 13:34:27 +0800451 if (CONTROL_SPEED_ENABLE == 0)
452 player->send_time = _dvr_time_getClock() + 500;
453 else
454 player->send_time = _dvr_time_getClock() + 20;
455
hualing chen6e4bfa52020-03-13 14:37:11 +0800456 DVR_Play_Notify_t notify;
457 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
458 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
459 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800460 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800461 return DVR_SUCCESS;
462}
463
hualing chencc91e1c2020-02-28 13:26:17 +0800464//check is ongoing segment
465static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
466
467 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800468 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800469
470 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800471 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800472 return DVR_FAILURE;
473 }
hualing chen87072a82020-03-12 16:20:12 +0800474 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800475 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800476 return DVR_FALSE;
477 }
hualing chencc91e1c2020-02-28 13:26:17 +0800478 return DVR_TRUE;
479}
hualing chen4b7c15d2020-04-07 16:13:48 +0800480
481
482static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
483 DVR_Playback_t *player = (DVR_Playback_t *) handle;
484 player->fffb_start = _dvr_time_getClock();
hualing chen7ea70a72021-09-09 11:25:13 +0800485 DVR_PB_DG(1, " player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800486 player->fffb_current = player->fffb_start;
487 //get segment current time pos
488 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800489 player->next_fffb_time = _dvr_time_getClock();
490
491 return DVR_SUCCESS;
492}
493
hualing chen2aba4022020-03-02 13:49:55 +0800494static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
495 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800496 player->fffb_start = _dvr_time_getClock();
hualing chen7ea70a72021-09-09 11:25:13 +0800497 DVR_PB_DG(1, " player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800498 player->fffb_current = player->fffb_start;
499 //get segment current time pos
500 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800501
hualing chen2aba4022020-03-02 13:49:55 +0800502 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800503 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800504 return DVR_SUCCESS;
505}
hualing chencc91e1c2020-02-28 13:26:17 +0800506//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800507static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
508
509 DVR_Playback_t *player = (DVR_Playback_t *) handle;
510 DVR_PlaybackSegmentInfo_t *segment;
511 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
512
hualing chena540a7e2020-03-27 16:44:05 +0800513 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800514 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800515 return DVR_FAILURE;
516 }
517
hualing chen87072a82020-03-12 16:20:12 +0800518 int found = 0;
519 int found_eq_id = 0;
520 list_for_each_entry(segment, &player->segment_list, head)
521 {
522 if (player->segment_is_open == DVR_FALSE) {
523 //get first segment from list, case segment is not open
524 if (!IS_FB(player->speed))
525 found = 1;
526 } else if (segment->segment_id == segmentid) {
527 //find cur segment, we need get next one
528 found_eq_id = 1;
529 if (!IS_FB(player->speed)) {
530 found = 1;
531 continue;
532 } else {
533 //if is fb mode.we need used pre segment
534 if (pre_segment != NULL) {
535 found = 1;
536 } else {
537 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800538 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800539 return DVR_FAILURE;
540 }
541 }
542 }
543 if (found == 1) {
544 found = 2;
545 break;
546 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800547 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800548 }
549 if (found != 2) {
550 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800551 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800552 return DVR_FAILURE;
553 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800554 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800555 return DVR_SUCCESS;
556}
557
558//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800559static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800560
hualing chen040df222020-01-17 13:35:02 +0800561 DVR_Playback_t *player = (DVR_Playback_t *) handle;
562 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800563 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800564 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800565 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800566 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800567 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800568 return DVR_FAILURE;
569 }
570
hualing chen03fd4942021-07-15 15:56:41 +0800571 if (IS_FB(player->speed)
572 && dvr_playback_check_limit(handle)) {
573 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
574 //case cur id < segment id
575 if (player->cur_segment_id <= segmentid) {
576 //expired ts data is player,return error
577 DVR_PB_DG(1, "reach start segment ,return error");
578 return DVR_FAILURE;
579 }
hualing chen7ea70a72021-09-09 11:25:13 +0800580 DVR_PB_DG(1, "has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800581 }
582
hualing chen86e7d482020-01-16 15:13:33 +0800583 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800584 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800585
hualing chen040df222020-01-17 13:35:02 +0800586 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800587 {
hualing chencc91e1c2020-02-28 13:26:17 +0800588 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800589 //get first segment from list, case segment is not open
590 if (!IS_FB(player->speed))
591 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800592 } else if (segment->segment_id == player->cur_segment_id) {
593 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800594 found_eq_id = 1;
595 if (!IS_FB(player->speed)) {
596 found = 1;
597 continue;
598 } else {
599 //if is fb mode.we need used pre segment
600 if (pre_segment != NULL) {
601 found = 1;
602 } else {
603 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800604 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800605 return DVR_FAILURE;
606 }
607 }
hualing chen86e7d482020-01-16 15:13:33 +0800608 }
609 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800610 if (IS_FB(player->speed)) {
611 //used pre segment
612 segment = pre_segment;
613 }
hualing chencc91e1c2020-02-28 13:26:17 +0800614 //save segment info
615 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800616 if (player->r_handle)
617 player->last_segment_tatol = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800618 player->last_segment.segment_id = player->cur_segment.segment_id;
619 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800620 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
621 //pids
622 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
623
hualing chen5cbe1a62020-02-10 16:36:36 +0800624 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800625 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800626 player->cur_segment_id = segment->segment_id;
627 player->cur_segment.segment_id = segment->segment_id;
628 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800629 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 +0800630 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800631 //pids
hualing chen040df222020-01-17 13:35:02 +0800632 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800633 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800634 break;
hualing chen86e7d482020-01-16 15:13:33 +0800635 }
hualing chen2aba4022020-03-02 13:49:55 +0800636 pre_segment = segment;
637 }
638 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
639 //used the last one segment to open
640 //get segment info
641 player->segment_is_open = DVR_TRUE;
642 player->cur_segment_id = pre_segment->segment_id;
643 player->cur_segment.segment_id = pre_segment->segment_id;
644 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800645 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 +0800646 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
647 //pids
648 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
649 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800650 }
651 if (found != 2) {
652 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800653 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800654 }
655 return DVR_SUCCESS;
656}
hualing chen040df222020-01-17 13:35:02 +0800657//open next segment to play,if reach list end return errro.
658static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800659{
hualing chen040df222020-01-17 13:35:02 +0800660 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800661 Segment_OpenParams_t params;
662 int ret = DVR_SUCCESS;
663
hualing chena540a7e2020-03-27 16:44:05 +0800664 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800665 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800666 return DVR_FAILURE;
667 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800668 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800669retry:
hualing chena540a7e2020-03-27 16:44:05 +0800670 ret = _dvr_get_next_segmentId(handle);
671 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800672 DVR_PB_DG(1, "not found segment info");
673 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800674 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800675 }
676
677 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800678 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800679 segment_close(player->r_handle);
680 player->r_handle = NULL;
681 }
682
683 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800684 //cp chur segment path to location
685 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800686 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800687 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800688 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
689
hualing chen86e7d482020-01-16 15:13:33 +0800690 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800691 if (ret == DVR_FAILURE) {
692 DVR_PB_DG(1, "open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800693 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800694 }
hualing chen87072a82020-03-12 16:20:12 +0800695 pthread_mutex_unlock(&player->segment_lock);
696 int total = _dvr_get_end_time( handle);
697 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800698 if (IS_FB(player->speed)) {
699 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800700 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800701 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800702 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800703 }
hualing chen87072a82020-03-12 16:20:12 +0800704 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800705 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800706 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800707 return ret;
708}
709
hualing chen5cbe1a62020-02-10 16:36:36 +0800710//open next segment to play,if reach list end return errro.
711static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
712{
713 DVR_Playback_t *player = (DVR_Playback_t *) handle;
714 Segment_OpenParams_t params;
715 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800716 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800717 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800718 return DVR_FAILURE;
719 }
hualing chencc91e1c2020-02-28 13:26:17 +0800720 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800721 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800722 }
hualing chencc91e1c2020-02-28 13:26:17 +0800723 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800724 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800725 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800726 return DVR_FAILURE;
727 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800728 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800729 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800730
731 DVR_PlaybackSegmentInfo_t *segment;
732
733 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800734
hualing chen5cbe1a62020-02-10 16:36:36 +0800735 list_for_each_entry(segment, &player->segment_list, head)
736 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800737 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 +0800738 if (segment->segment_id == segment_id) {
739 found = 1;
740 }
741 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800742 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 +0800743 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800744 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800745 player->cur_segment_id = segment->segment_id;
746 player->cur_segment.segment_id = segment->segment_id;
747 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800748 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800749 //pids
750 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800751 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 +0800752 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800753 }
754 }
hualing chencc91e1c2020-02-28 13:26:17 +0800755 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800756 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800757 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800758 return DVR_FAILURE;
759 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800760 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800761 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800762 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800763 params.segment_id = (uint64_t)player->cur_segment.segment_id;
764 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800765 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 +0800766 if (player->r_handle != NULL) {
767 segment_close(player->r_handle);
768 player->r_handle = NULL;
769 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800770 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800771 if (ret == DVR_FAILURE) {
772 DVR_PB_DG(1, "segment opne error");
773 }
hualing chen2aba4022020-03-02 13:49:55 +0800774 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800775 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800776
hualing chen4b7c15d2020-04-07 16:13:48 +0800777 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 +0800778 return ret;
779}
780
781
782//get play info by segment id
783static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
784 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800785 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800786 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800787
788 DVR_Playback_t *player = (DVR_Playback_t *) handle;
789 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800790 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800791 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800792 return DVR_FAILURE;
793 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800794
795 int found = 0;
796
797 list_for_each_entry(segment, &player->segment_list, head)
798 {
hualing chen87072a82020-03-12 16:20:12 +0800799 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800800 //get first segment from list
801 found = 1;
802 }
803 if (segment->segment_id == segment_id) {
804 found = 1;
805 }
806 if (found == 1) {
807 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800808 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800809 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800810 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800811 player->cur_segment.segment_id = segment->segment_id;
812 player->cur_segment.flags = segment->flags;
813 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800814 player->cur_segment.pids.video.pid = segment->pids.video.pid;
815 player->cur_segment.pids.video.format = segment->pids.video.format;
816 player->cur_segment.pids.video.type = segment->pids.video.type;
817 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
818 player->cur_segment.pids.audio.format = segment->pids.audio.format;
819 player->cur_segment.pids.audio.type = segment->pids.audio.type;
820 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
821 player->cur_segment.pids.ad.format = segment->pids.ad.format;
822 player->cur_segment.pids.ad.type = segment->pids.ad.type;
823 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800824 //
hualing chen2aba4022020-03-02 13:49:55 +0800825 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800826 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800827 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800828 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800829 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
830 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800831 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 +0800832 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800833 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800834 }
835 }
hualing chencc91e1c2020-02-28 13:26:17 +0800836 if (found != 2) {
837 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800838 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800839 return DVR_FAILURE;
840 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800841
842 return DVR_SUCCESS;
843}
hualing chencc91e1c2020-02-28 13:26:17 +0800844static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
845 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800846 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800847 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800848 return DVR_FAILURE;
849 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800850
hualing chencc91e1c2020-02-28 13:26:17 +0800851 //compare cur segment
852 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
853 {
854 //check video 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, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800856 //check sub 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, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800858 //check audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800859 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 1);
hualing chene3797f02021-01-13 14:53:28 +0800860 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 +0800861 //check pcr pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800862 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800863 }
hualing chena540a7e2020-03-27 16:44:05 +0800864 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800865}
hualing chen5cbe1a62020-02-10 16:36:36 +0800866
hualing chend241c7a2021-06-22 13:34:27 +0800867static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
868{
869 DVR_Playback_t *player = (DVR_Playback_t *) handle;
870 if (player == NULL) {
871 DVR_PB_DG(1, "player is NULL");
872 return DVR_TRUE;
873 }
874 char buf[10];
875 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
876 DVR_PB_DG(1, "player get prop[%d][%s]", atoi(buf), buf);
877
878 if (atoi(buf) != 1) {
879 //return DVR_TRUE;
880 }
881
hualing chen7ea70a72021-09-09 11:25:13 +0800882 DVR_PB_DG(1, ":play speed: %f ply dur: %u sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800883 player->speed,
884 player->con_spe.ply_dur,
885 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800886
887 if (player->speed != 1.0f)
888 return DVR_TRUE;
889
890 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800891 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800892 return DVR_FALSE;
893
894 return DVR_TRUE;
895}
896
hualing chencc91e1c2020-02-28 13:26:17 +0800897static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
898{
899 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800900 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800901 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800902 return DVR_FAILURE;
903 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800904 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
905 DVR_PB_DG(1, "vendor is amlogic. no used segment flag to hide or show av");
906 return DVR_SUCCESS;
907 }
hualing chen03fd4942021-07-15 15:56:41 +0800908 DVR_PB_DG(1, "flag[0x%x]id[%lld]last[0x%x][%llu]",
909 player->cur_segment.flags,
910 player->cur_segment.segment_id,
911 player->last_segment.flags,
912 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800913 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
914 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800915 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800916 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800917 AmTsPlayer_showVideo(player->handle);
918 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800919 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
920 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800921 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800922 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800923 AmTsPlayer_hideVideo(player->handle);
924 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800925 }
926 return DVR_SUCCESS;
927}
hualing chene3797f02021-01-13 14:53:28 +0800928/*
929if decodec sucess first time.
930sucess: return true
931fail: return false
932*/
hualing chena540a7e2020-03-27 16:44:05 +0800933static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
934 DVR_Playback_t *player = (DVR_Playback_t *) handle;
935 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800936 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800937 return DVR_TRUE;
938 }
hualing chene3797f02021-01-13 14:53:28 +0800939 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800940 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800941 } else {
942 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800943 }
944}
hualing chen86e7d482020-01-16 15:13:33 +0800945static void* _dvr_playback_thread(void *arg)
946{
hualing chen040df222020-01-17 13:35:02 +0800947 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800948 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800949 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800950 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800951 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800952
hualing chen39628212020-05-14 10:35:13 +0800953 #define MAX_REACHEND_TIMEOUT (3000)
954 int reach_end_timeout = 0;//ms
955 int cache_time = 0;
hualing chena5f03222021-12-02 11:22:35 +0800956 int timeout = 100;//ms
hualing chen40dd5462021-11-26 19:56:20 +0800957 int check_no_data_time = 4;
hualing chen2aba4022020-03-02 13:49:55 +0800958 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800959 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800960 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800961 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +0800962 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800963 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800964 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800965 DVR_Bool_t goto_rewrite = DVR_FALSE;
yinming ding0ce94922021-09-08 15:09:15 +0800966 char prop_buf[10];
967
968 memset(prop_buf, 0 ,sizeof(prop_buf));
969 dvr_prop_read("vendor.tv.libdvr.writetm", prop_buf, sizeof(prop_buf));
hualing chena5f03222021-12-02 11:22:35 +0800970 DVR_PB_DG(1, "---vendor.tv.libdvr.writetm get prop[%d][%s]block_size[%d]", atoi(prop_buf), prop_buf, player->openParams.block_size);
yinming ding0ce94922021-09-08 15:09:15 +0800971 if (atoi(prop_buf) > 0)
972 write_timeout_ms = atoi(prop_buf);
hualing chen03fd4942021-07-15 15:56:41 +0800973
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800974 if (player->is_secure_mode) {
975 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800976 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800977 return NULL;
978 }
979 }
hualing chen86e7d482020-01-16 15:13:33 +0800980 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800981 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800982 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800983 return NULL;
984 }
hualing chen2aba4022020-03-02 13:49:55 +0800985 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
986 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800987
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800988 dec_bufs.buf_data = malloc(dec_buf_size);
989 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800990 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800991 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800992 return NULL;
993 }
994 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
995 dec_bufs.buf_size = dec_buf_size;
996
hualing chencc91e1c2020-02-28 13:26:17 +0800997 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800998 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
999 }
hualing chen86e7d482020-01-16 15:13:33 +08001000
hualing chen86e7d482020-01-16 15:13:33 +08001001 if (ret != DVR_SUCCESS) {
1002 if (buf != NULL) {
1003 free(buf);
1004 buf = NULL;
1005 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001006 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +08001007 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001008 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001009 }
hualing chen1679f812021-11-08 15:17:46 +08001010 DVR_PB_DG(1, "--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001011 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001012 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1013 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1014 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1015 player->first_trans_ok = DVR_TRUE;
1016 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1017 }
hualing chencc91e1c2020-02-28 13:26:17 +08001018 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001019 //set video show
1020 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001021 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1022 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001023 int trick_stat = 0;
1024 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001025
hualing chen86e7d482020-01-16 15:13:33 +08001026 //check trick stat
hualing chen926a8ec2021-12-20 20:38:24 +08001027 //DVR_PB_DG(1, "lock check_no_data_time:%d", check_no_data_time);
hualing chencc91e1c2020-02-28 13:26:17 +08001028 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001029
hualing chen2aba4022020-03-02 13:49:55 +08001030 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1031 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001032 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001033 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001034 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001035 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001036 {
hualing chen2aba4022020-03-02 13:49:55 +08001037 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1038 if (trick_stat > 0) {
hualing chen03fd4942021-07-15 15:56:41 +08001039 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
1040 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001041 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 +08001042 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001043 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001044 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001045 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
1046 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +08001047 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
1048 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chen03fd4942021-07-15 15:56:41 +08001049 DVR_PB_DG(1, "pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
1050 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001051 //need change to pause state
1052 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1053 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +08001054 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001055 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001056 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001057 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001058 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001059 AmTsPlayer_pauseVideoDecoding(player->handle);
1060 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001061 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001062 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001063 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001064 }
1065 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1066 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001067 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001068 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001069 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen7ea70a72021-09-09 11:25:13 +08001070 DVR_PB_DG(1, "fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001071 player->speed,
1072 player->fffb_current,
1073 _dvr_time_getClock(),
1074 _dvr_playback_state_toString(player->state),
1075 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001076 //used timeout wait need lock first,so we unlock and lock
1077 //pthread_mutex_unlock(&player->lock);
1078 //pthread_mutex_lock(&player->lock);
1079 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001080 DVR_PB_DG(1, "unlock---");
hualing chen2aba4022020-03-02 13:49:55 +08001081 pthread_mutex_unlock(&player->lock);
1082 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001083 } else if (_dvr_time_getClock() < player->next_fffb_time) {
hualing chen7ea70a72021-09-09 11:25:13 +08001084 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 +08001085 player->speed,
1086 player->fffb_current,
1087 _dvr_time_getClock(),
1088 _dvr_playback_state_toString(player->state),
1089 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001090 //used timeout wait need lock first,so we unlock and lock
1091 //pthread_mutex_unlock(&player->lock);
1092 //pthread_mutex_lock(&player->lock);
1093 AmTsPlayer_pauseVideoDecoding(player->handle);
1094 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001095 DVR_PB_DG(1, "unlock---");
hualing chenb5cd42e2020-04-15 17:03:34 +08001096 pthread_mutex_unlock(&player->lock);
1097 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001098 }
hualing chen03fd4942021-07-15 15:56:41 +08001099 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d][%s][%d]",
1100 player->speed,
1101 goto_rewrite,
1102 real_read,
1103 _dvr_playback_state_toString(player->state),
1104 player->cmd.cur_cmd);
hualing chen1679f812021-11-08 15:17:46 +08001105 DVR_PB_DG(1, "unlock---");
hualing chen2aba4022020-03-02 13:49:55 +08001106 pthread_mutex_unlock(&player->lock);
1107 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001108 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001109 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1110 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001111 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001112 player->fffb_play = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08001113 DVR_PB_DG(1, "lock---");
hualing chen2aba4022020-03-02 13:49:55 +08001114 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08001115 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1116 //on pause state,user seek to new pos,we need pause and wait
1117 //user to resume
1118 DVR_PB_DG(1, "pause, when got first frame event when user seek end");
1119 player->first_frame = 0;
1120 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1121 AmTsPlayer_pauseVideoDecoding(player->handle);
1122 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001123 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001124 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001125 //for first into fffb when reset speed
1126 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1127 _dvr_time_getClock() < player->next_fffb_time) {
hualing chen7ea70a72021-09-09 11:25:13 +08001128 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 +08001129 player->speed,
1130 player->fffb_current,
1131 _dvr_time_getClock(),
1132 _dvr_playback_state_toString(player->state),
1133 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001134 //used timeout wait need lock first,so we unlock and lock
1135 //pthread_mutex_unlock(&player->lock);
1136 //pthread_mutex_lock(&player->lock);
1137 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001138 DVR_PB_DG(1, "unlock---");
hualing chen4b7c15d2020-04-07 16:13:48 +08001139 pthread_mutex_unlock(&player->lock);
1140 continue;
1141 }
hualing chen03fd4942021-07-15 15:56:41 +08001142 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
1143 player->speed,
1144 goto_rewrite,
1145 real_read,
1146 _dvr_playback_state_toString(player->state),
1147 player->cmd.cur_cmd,
1148 player->fffb_play);
hualing chen1679f812021-11-08 15:17:46 +08001149 DVR_PB_DG(1, "unlock---");
hualing chen4b7c15d2020-04-07 16:13:48 +08001150 pthread_mutex_unlock(&player->lock);
1151 goto_rewrite = DVR_FALSE;
1152 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001153 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001154 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1155 player->first_frame = 0;
1156 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1157 pthread_mutex_lock(&player->lock);
1158 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001159 }
hualing chenb31a6c62020-01-13 17:27:00 +08001160 }
hualing chen86e7d482020-01-16 15:13:33 +08001161
hualing chen30423862021-04-16 14:39:12 +08001162 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1163 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001164 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001165 DVR_PB_DG(1, "pause, continue");
hualing chen1679f812021-11-08 15:17:46 +08001166 DVR_PB_DG(1, "unlock---");
1167 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001168 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen1679f812021-11-08 15:17:46 +08001169 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001170 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001171 DVR_PB_DG(1, "unlock---");
hualing chen87072a82020-03-12 16:20:12 +08001172 pthread_mutex_unlock(&player->lock);
1173 continue;
1174 }
hualing chen266b9502020-04-04 17:39:39 +08001175 //when seek action is done. we need drop write timeout data.
1176 if (player->drop_ts == DVR_TRUE) {
1177 goto_rewrite = DVR_FALSE;
1178 real_read = 0;
1179 player->drop_ts = DVR_FALSE;
1180 }
hualing chen2aba4022020-03-02 13:49:55 +08001181 if (goto_rewrite == DVR_TRUE) {
1182 goto_rewrite = DVR_FALSE;
hualing chen926a8ec2021-12-20 20:38:24 +08001183 //DVR_PB_DG(1, "unlock---");
hualing chen2aba4022020-03-02 13:49:55 +08001184 pthread_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001185 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001186 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001187 goto rewrite;
1188 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001189 //.check is need send time send end
hualing chen1679f812021-11-08 15:17:46 +08001190 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001191 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen1679f812021-11-08 15:17:46 +08001192 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001193 pthread_mutex_lock(&player->segment_lock);
hualing chene41f4372020-06-06 16:29:17 +08001194 //DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001195 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001196 real_read = real_read + read;
1197 player->ts_cache_len = real_read;
hualing chenfbf8e022020-06-15 13:43:11 +08001198 //DVR_PB_DG(1, "start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001199 pthread_mutex_unlock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +08001200 //DVR_PB_DG(1, "unlock---");
hualing chen87072a82020-03-12 16:20:12 +08001201 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001202 if (read < 0 && errno == EIO) {
1203 //EIO ERROR, EXIT THRAD
1204 DVR_PB_DG(1, "read error.EIO error, exit thread");
1205 DVR_Play_Notify_t notify;
1206 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1207 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001208 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001209 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001210 goto end;
1211 } else if (read < 0) {
1212 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1213 }
hualing chen87072a82020-03-12 16:20:12 +08001214 //if on fb mode and read file end , we need calculate pos to retry read.
1215 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen03fd4942021-07-15 15:56:41 +08001216 DVR_PB_DG(1, "recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
1217 read,
1218 real_read,
1219 buf_len,
1220 player->speed,
1221 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001222 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
hualing chen1679f812021-11-08 15:17:46 +08001223 DVR_PB_DG(1, "lock---");
hualing chen87072a82020-03-12 16:20:12 +08001224 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001225 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chen1679f812021-11-08 15:17:46 +08001226 DVR_PB_DG(1, "unlock---");
hualing chen2aba4022020-03-02 13:49:55 +08001227 pthread_mutex_unlock(&player->lock);
1228 continue;
1229 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001230 //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 +08001231 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001232 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001233 #define MIN_CACHE_TIME (3000)
1234 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001235 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001236 if (_cache_time > MIN_CACHE_TIME) {
hualing chen1679f812021-11-08 15:17:46 +08001237 //pthread_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001238 /*if cache time > 20s , we think get time is error,*/
1239 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
1240 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1241 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1242 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1243 }
hualing chen1679f812021-11-08 15:17:46 +08001244 //_dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
1245 //pthread_mutex_unlock(&player->lock);
1246 // 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 +08001247 //continue;
1248 }
hualing chen969fe7b2021-05-26 15:13:17 +08001249
hualing chen040df222020-01-17 13:35:02 +08001250 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001251 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001252 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001253
1254 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen1679f812021-11-08 15:17:46 +08001255
1256 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1257 player->noData++;
1258 DVR_PB_DG(1, "playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001259 if (player->noData == check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001260 DVR_PB_DG(1, "playback send nodata event nodata[%d]", player->noData);
1261 //send event here and pause
1262 DVR_Play_Notify_t notify;
1263 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1264 notify.event = DVR_PLAYBACK_EVENT_NODATA;
hualing chen1679f812021-11-08 15:17:46 +08001265 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001266 //get play statue not here
1267 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1268 }
1269 }
1270 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001271 if ((ret != DVR_SUCCESS &&
hualing chen03fd4942021-07-15 15:56:41 +08001272 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001273 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001274 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001275 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1276 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001277 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001278 DVR_Play_Notify_t notify;
1279 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1280 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1281 //get play statue not here
1282 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001283 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001284 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001285 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 +08001286 pthread_mutex_lock(&player->lock);
1287 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1288 pthread_mutex_unlock(&player->lock);
1289 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001290 } else if (ret != DVR_SUCCESS) {
hualing chen1679f812021-11-08 15:17:46 +08001291 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
1292 pthread_mutex_lock(&player->lock);
1293 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1294 pthread_mutex_unlock(&player->lock);
1295 delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chena540a7e2020-03-27 16:44:05 +08001296 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001297 if (delay < cache_time) {
1298 //delay time is changed and then has data to play, so not start timeout
hualing chen1679f812021-11-08 15:17:46 +08001299 reach_end_timeout = 0;
hualing chen39628212020-05-14 10:35:13 +08001300 } else {
1301 reach_end_timeout = reach_end_timeout + timeout;
1302 }
1303 cache_time = delay;
hualing chen31140872020-03-25 12:29:26 +08001304 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001305 }
hualing chen39628212020-05-14 10:35:13 +08001306 reach_end_timeout = 0;
1307 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001308 //change next segment success case
1309 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen40dd5462021-11-26 19:56:20 +08001310 pthread_mutex_lock(&player->lock);
1311 player->noData = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001312 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001313 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1314 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001315 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001316 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001317 real_read = real_read + read;
1318 player->ts_cache_len = real_read;
1319 pthread_mutex_unlock(&player->segment_lock);
1320
hualing chen87072a82020-03-12 16:20:12 +08001321 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001322 }//read len 0 check end
hualing chen40dd5462021-11-26 19:56:20 +08001323 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001324 player->noData = 0;
1325 DVR_PB_DG(1, "playback send data event resume[%d]", player->noData);
1326 //send event here and pause
1327 DVR_Play_Notify_t notify;
1328 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1329 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
hualing chen1679f812021-11-08 15:17:46 +08001330 DVR_PB_DG(1, "----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001331 //get play statue not here
1332 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001333 }
hualing chen39628212020-05-14 10:35:13 +08001334 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001335 //real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001336 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001337 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001338
hualing chena540a7e2020-03-27 16:44:05 +08001339 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001340 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001341 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001342 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001343 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001344 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001345 }
hualing chen266b9502020-04-04 17:39:39 +08001346 //if need write whole block size, we need check read buf len is eq block size.
1347 if (b_writed_whole_block == DVR_TRUE) {
1348 //buf_len is block size value.
1349 if (real_read < buf_len) {
1350 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001351 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001352 pthread_mutex_lock(&player->lock);
1353 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1354 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001355 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001356 continue;
1357 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001358 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 +08001359 }
1360 }
1361
Yahui Han1fbf3292021-11-08 18:17:19 +08001362 if (player->is_secure_mode && player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001363 DVR_CryptoParams_t crypto_params;
1364
1365 memset(&crypto_params, 0, sizeof(crypto_params));
1366 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1367 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1368 crypto_params.segment_id = player->cur_segment.segment_id;
hualing chen1f26ffa2020-11-03 10:39:20 +08001369 crypto_params.offset = segment_tell_position(player->r_handle) - wbufs.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001370 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
1371 DVR_PB_DG(1, "offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001372 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1373 crypto_params.input_buffer.addr = (size_t)buf;
1374 crypto_params.input_buffer.size = real_read;
1375
Yahui Han1fbf3292021-11-08 18:17:19 +08001376 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1377 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1378 crypto_params.output_buffer.size = dec_buf_size;
1379 ret = player->dec_func(&crypto_params, player->dec_userdata);
1380 wbufs.buf_data = player->secure_buffer;
1381 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001382 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001383 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001384 }
pengfei.liufda2a972020-04-09 14:47:15 +08001385 wbufs.buf_size = crypto_params.output_size;
Yahui Han1fbf3292021-11-08 18:17:19 +08001386 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001387 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001388 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
1389 wbufs.buf_data = dec_bufs.buf_data;
1390 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1391 wbufs.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001392 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001393rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001394 if (player->drop_ts == DVR_TRUE) {
1395 //need drop ts data when seek occur.we need read next loop,drop this ts data
1396 goto_rewrite = DVR_FALSE;
1397 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001398 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001399 player->drop_ts = DVR_FALSE;
hualing chena5f03222021-12-02 11:22:35 +08001400 DVR_PB_DG(1, "----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001401 continue;
1402 }
hualing chen21a40372021-10-29 11:07:26 +08001403
1404 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001405 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001406 //used for printf first write data time.
1407 //to check change channel kpi.
1408 if (first_write == 0) {
1409 first_write++;
1410 DVR_PB_DG(1, "----firsr write ts data");
1411 }
1412
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001413 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1414 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001415 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001416 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001417 real_read = 0;
1418 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001419 if (CONTROL_SPEED_ENABLE == 1) {
1420check0:
1421 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1422 pthread_mutex_lock(&player->lock);
1423 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1424 pthread_mutex_unlock(&player->lock);
1425 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1426 goto check0;
1427 }
1428 }
hualing chen5605eed2020-05-26 18:18:06 +08001429 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001430 continue;
hualing chen87072a82020-03-12 16:20:12 +08001431 } else {
hualing chen21a40372021-10-29 11:07:26 +08001432 pthread_mutex_unlock(&player->segment_lock);
hualing chen7ea70a72021-09-09 11:25:13 +08001433 DVR_PB_DG(1, "write time out write_success:%d wbufs.buf_size:%d systime:%u",
hualing chen03fd4942021-07-15 15:56:41 +08001434 write_success,
1435 wbufs.buf_size,
1436 _dvr_time_getClock());
1437
hualing chena540a7e2020-03-27 16:44:05 +08001438 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001439 if (CONTROL_SPEED_ENABLE == 1) {
1440check1:
1441 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1442 pthread_mutex_lock(&player->lock);
1443 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1444 pthread_mutex_unlock(&player->lock);
1445 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1446 goto check1;
1447 }
1448 }
hualing chencc91e1c2020-02-28 13:26:17 +08001449 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001450 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001451 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001452 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001453 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001454 break;
1455 }
hualing chen2aba4022020-03-02 13:49:55 +08001456 goto_rewrite = DVR_TRUE;
1457 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001458 }
1459 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001460end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001461 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001462 free(buf);
1463 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001464 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001465}
1466
1467
hualing chen040df222020-01-17 13:35:02 +08001468static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001469{
hualing chen040df222020-01-17 13:35:02 +08001470 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001471
1472 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001473 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001474 return DVR_FAILURE;
1475 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001476 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001477 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001478 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001479 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001480 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001481 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001482 if (rc < 0)
1483 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001484 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001485}
1486
1487
hualing chen040df222020-01-17 13:35:02 +08001488static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001489{
hualing chen040df222020-01-17 13:35:02 +08001490 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001491
1492 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001493 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001494 return DVR_FAILURE;
1495 }
1496
hualing chen4b7c15d2020-04-07 16:13:48 +08001497 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001498 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001499 {
1500 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001501 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001502 pthread_join(player->playback_thread, NULL);
1503 }
1504 if (player->r_handle) {
1505 segment_close(player->r_handle);
1506 player->r_handle = NULL;
1507 }
hualing chen7a56cba2020-04-14 14:09:27 +08001508 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001509 return 0;
1510}
1511
hualing chen1679f812021-11-08 15:17:46 +08001512static int getFakePid()
1513{
1514 char fake_pid_prop[] = "vendor.tv.dtv.fake_pid";
1515 char buf[32];
1516 int pid = 0xffff;
1517
1518 dvr_prop_read(fake_pid_prop, buf, sizeof(buf));
1519
1520 if (sscanf(buf, "%i", &pid) != 1)
1521 {
1522 DVR_PB_DG(1, "get fake pid error");
1523 pid = 0xffff;
1524 }
1525 return pid;
1526}
1527
1528void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1529
1530 DVR_ASSERT(handle);
1531 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1532 if (player == NULL) {
1533 DVR_PB_DG(1, "player is NULL");
1534 return ;
1535 }
1536 if (player->need_seek_start == DVR_FALSE) {
1537 DVR_PB_DG(1, "player need_seek_start is false");
1538 return ;
1539 }
1540
hualing chena5f03222021-12-02 11:22:35 +08001541 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001542 player->need_seek_start = DVR_FALSE;
1543 }
1544 DVR_PB_DG(1, "player player->need_seek_start=%d", player->need_seek_start);
1545}
1546
hualing chenb31a6c62020-01-13 17:27:00 +08001547/**\brief Open an dvr palyback
1548 * \param[out] p_handle dvr playback addr
1549 * \param[in] params dvr playback open parameters
1550 * \retval DVR_SUCCESS On success
1551 * \return Error code
1552 */
hualing chen040df222020-01-17 13:35:02 +08001553int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001554
hualing chen040df222020-01-17 13:35:02 +08001555 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001556 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001557
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001558 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001559
hualing chen86e7d482020-01-16 15:13:33 +08001560 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001561 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001562 pthread_condattr_init(&cattr);
1563 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1564 pthread_cond_init(&player->cond, &cattr);
1565 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001566
hualing chen5cbe1a62020-02-10 16:36:36 +08001567 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001568 INIT_LIST_HEAD(&player->segment_list);
1569 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1570 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001571 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001572 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001573 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001574 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001575 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001576 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001577
hualing chen86e7d482020-01-16 15:13:33 +08001578 //store open params
hualing chen040df222020-01-17 13:35:02 +08001579 player->openParams.dmx_dev_id = params->dmx_dev_id;
1580 player->openParams.block_size = params->block_size;
hualing chena5f03222021-12-02 11:22:35 +08001581 DVR_PB_DG(1, "playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001582 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001583 player->openParams.event_fn = params->event_fn;
1584 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001585 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001586 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001587
hualing chen5cbe1a62020-02-10 16:36:36 +08001588 player->has_pids = params->has_pids;
1589
hualing chen2aba4022020-03-02 13:49:55 +08001590 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001591
1592 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1593 //for test get callback
1594 if (0 && player->player_callback_func == NULL) {
1595 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1596 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen03fd4942021-07-15 15:56:41 +08001597 DVR_PB_DG(1, "playback open get callback[%p][%p][%p][%p]",
1598 player->player_callback_func,
1599 player->player_callback_userdata,
1600 _dvr_tsplayer_callback_test,
1601 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001602 }
1603 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001604
hualing chen86e7d482020-01-16 15:13:33 +08001605 //init has audio and video
1606 player->has_video = DVR_FALSE;
1607 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001608 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001609 player->last_segment_id = 0LL;
1610 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001611
hualing chen5cbe1a62020-02-10 16:36:36 +08001612 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001613 player->fffb_current = 0;
1614 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001615 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001616 //seek time
1617 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001618 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001619
Yahui Han1fbf3292021-11-08 18:17:19 +08001620 //allocate cryptor if have clearkey
1621 if (params->keylen > 0) {
1622 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
1623 (uint8_t *)params->cleariv,
1624 params->keylen * 8);
1625 if (!player->cryptor) {
1626 DVR_DEBUG(1, "%s , open des cryptor failed!!!\n", __func__);
1627 }
1628 } else {
1629 player->cryptor = NULL;
1630 }
1631
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001632 //init secure stuff
1633 player->dec_func = NULL;
1634 player->dec_userdata = NULL;
1635 player->is_secure_mode = 0;
1636 player->secure_buffer = NULL;
1637 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001638 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001639
hualing chen4b7c15d2020-04-07 16:13:48 +08001640 player->fffb_play = DVR_FALSE;
1641
1642 player->last_send_time_id = UINT64_MAX;
1643 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001644 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001645
hualing chend241c7a2021-06-22 13:34:27 +08001646 //speed con init
1647 if (CONTROL_SPEED_ENABLE == 1) {
1648 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001649 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001650 player->con_spe.sys_dur = 0;
1651 player->con_spe.sys_sta = 0;
1652 }
1653
hualing chen03fd4942021-07-15 15:56:41 +08001654 //limit info
1655 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001656 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001657 //need seek to start pos
1658 player->first_start_time = 0;
1659 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001660 //fake_pid init
1661 player->fake_pid = getFakePid();
hualing chen86e7d482020-01-16 15:13:33 +08001662 *p_handle = player;
1663 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001664}
1665
1666/**\brief Close an dvr palyback
1667 * \param[in] handle playback handle
1668 * \retval DVR_SUCCESS On success
1669 * \return Error code
1670 */
hualing chen040df222020-01-17 13:35:02 +08001671int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001672
hualing chen86e7d482020-01-16 15:13:33 +08001673 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001674 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001675 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001676 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001677 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001678 return DVR_FAILURE;
1679 }
1680
hualing chencc91e1c2020-02-28 13:26:17 +08001681 if (player->state != DVR_PLAYBACK_STATE_STOP)
1682 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001683 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001684 if (player->cryptor) {
1685 am_crypt_des_close(player->cryptor);
1686 player->cryptor = NULL;
1687 }
hualing chencc91e1c2020-02-28 13:26:17 +08001688 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001689 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1690 } else {
1691 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001692 }
hualing chen7a56cba2020-04-14 14:09:27 +08001693 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001694 pthread_mutex_destroy(&player->lock);
1695 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001696
1697 if (player) {
1698 free(player);
1699 player = NULL;
1700 }
hualing chen7a56cba2020-04-14 14:09:27 +08001701 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001702 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001703}
1704
hualing chenb31a6c62020-01-13 17:27:00 +08001705/**\brief Start play audio and video, used start auido api and start video api
1706 * \param[in] handle playback handle
1707 * \param[in] params audio playback params,contains fmt and pid...
1708 * \retval DVR_SUCCESS On success
1709 * \return Error code
1710 */
hualing chen040df222020-01-17 13:35:02 +08001711int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1712 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001713 am_tsplayer_video_params vparams;
1714 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001715 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001716
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001717 memset(&vparams, 0, sizeof(vparams));
1718 memset(&aparams, 0, sizeof(aparams));
1719
hualing chena540a7e2020-03-27 16:44:05 +08001720 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001721 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001722 return DVR_FAILURE;
1723 }
hualing chencc91e1c2020-02-28 13:26:17 +08001724 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001725 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001726
hualing chena540a7e2020-03-27 16:44:05 +08001727 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001728 //can used start api to resume playback
1729 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1730 return dvr_playback_resume(handle);
1731 }
hualing chen87072a82020-03-12 16:20:12 +08001732 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001733 //if flag is puased and not decodec first frame. if user resume, we need
1734 //clear flag and set trickmode none
1735 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1736 DVR_PB_DG(1, "[%p]clear pause live flag and clear trick mode", handle);
1737 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1738 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1739 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001740 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001741 return DVR_SUCCESS;
1742 }
hualing chen86e7d482020-01-16 15:13:33 +08001743 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001744 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001745 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001746 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001747 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001748 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001749 //start audio and video
hualing chena5f03222021-12-02 11:22:35 +08001750 if (vparams.pid != player->fake_pid && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001751 //audio abnd video pis is all invalid, return error.
hualing chena5f03222021-12-02 11:22:35 +08001752 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info [0x%x]", vparams.pid);
hualing chencc91e1c2020-02-28 13:26:17 +08001753 pthread_mutex_unlock(&player->lock);
1754 DVR_Play_Notify_t notify;
1755 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1756 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1757 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1758 notify.info.transition_failed_data.segment_id = segment_id;
1759 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001760 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001761 return -1;
1762 }
hualing chen31140872020-03-25 12:29:26 +08001763
hualing chencc91e1c2020-02-28 13:26:17 +08001764 {
hualing chen86e7d482020-01-16 15:13:33 +08001765 if (VALID_PID(vparams.pid)) {
1766 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001767 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001768 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001769 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001770 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1771 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001772 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001773 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001774 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001775 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001776 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001777 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001778 }
hualing chena93bbbc2020-12-22 17:23:42 +08001779 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001780 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08001781 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001782 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001783 }
hualing chena540a7e2020-03-27 16:44:05 +08001784
hualing chen4b7c15d2020-04-07 16:13:48 +08001785 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1786 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001787 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1788 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1789 player->cmd.state = DVR_PLAYBACK_STATE_START;
1790 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001791 } else {
1792 player->cmd.last_cmd = player->cmd.cur_cmd;
1793 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001794 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001795 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001796 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001797 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001798 } else {
hualing chendf118dd2020-05-21 15:49:11 +08001799 if (VALID_PID(adparams.pid)) {
1800 player->has_ad_audio = DVR_TRUE;
1801 DVR_PB_DG(1, "start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08001802 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chendf118dd2020-05-21 15:49:11 +08001803 AmTsPlayer_setADParams(player->handle, &adparams);
1804 AmTsPlayer_enableADMix(player->handle);
1805 }
hualing chen969fe7b2021-05-26 15:13:17 +08001806 if (VALID_PID(aparams.pid)) {
1807 DVR_PB_DG(1, "start audio");
1808 player->has_audio = DVR_TRUE;
hualing chen1679f812021-11-08 15:17:46 +08001809 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08001810 AmTsPlayer_setAudioParams(player->handle, &aparams);
1811 AmTsPlayer_startAudioDecoding(player->handle);
1812 }
hualing chen31140872020-03-25 12:29:26 +08001813 }
hualing chencc91e1c2020-02-28 13:26:17 +08001814 player->cmd.state = DVR_PLAYBACK_STATE_START;
1815 player->state = DVR_PLAYBACK_STATE_START;
1816 }
hualing chen86e7d482020-01-16 15:13:33 +08001817 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001818 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001819 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001820 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001821 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001822}
hualing chen040df222020-01-17 13:35:02 +08001823/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001824 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001825 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001826 * \retval DVR_SUCCESS On success
1827 * \return Error code
1828 */
hualing chen040df222020-01-17 13:35:02 +08001829int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1830 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001831
hualing chena540a7e2020-03-27 16:44:05 +08001832 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001833 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001834 return DVR_FAILURE;
1835 }
1836
hualing chen4b7c15d2020-04-07 16:13:48 +08001837 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001838 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001839
hualing chen040df222020-01-17 13:35:02 +08001840 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1841 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001842
hualing chen86e7d482020-01-16 15:13:33 +08001843 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001844 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001845 //cp location
hualing chen040df222020-01-17 13:35:02 +08001846 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001847
hualing chen4b7c15d2020-04-07 16:13:48 +08001848 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 +08001849 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001850
1851 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001852 segment->pids.video.pid = info->pids.video.pid;
1853 segment->pids.video.format = info->pids.video.format;
1854 segment->pids.video.type = info->pids.video.type;
1855
hualing chen2aba4022020-03-02 13:49:55 +08001856 segment->pids.audio.pid = info->pids.audio.pid;
1857 segment->pids.audio.format = info->pids.audio.format;
1858 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001859
hualing chen2aba4022020-03-02 13:49:55 +08001860 segment->pids.ad.pid = info->pids.ad.pid;
1861 segment->pids.ad.format = info->pids.ad.format;
1862 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001863
1864 segment->pids.pcr.pid = info->pids.pcr.pid;
1865
hualing chen4b7c15d2020-04-07 16:13:48 +08001866 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 +08001867 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001868 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001869 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001870 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001871
hualing chen5cbe1a62020-02-10 16:36:36 +08001872 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001873}
hualing chen040df222020-01-17 13:35:02 +08001874/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001875 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001876 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001877 * \retval DVR_SUCCESS On success
1878 * \return Error code
1879 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001880int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001881 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001882 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001883 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001884 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001885 return DVR_FAILURE;
1886 }
1887
hualing chencc91e1c2020-02-28 13:26:17 +08001888 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001889 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001890 return DVR_FAILURE;
1891 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001892 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001893 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001894 DVR_PlaybackSegmentInfo_t *segment = NULL;
1895 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1896 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001897 {
hualing chen040df222020-01-17 13:35:02 +08001898 if (segment->segment_id == segment_id) {
1899 list_del(&segment->head);
1900 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001901 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001902 }
hualing chen86e7d482020-01-16 15:13:33 +08001903 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001904 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001905 pthread_mutex_unlock(&player->lock);
1906
1907 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001908}
hualing chen040df222020-01-17 13:35:02 +08001909/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001910 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001911 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001912 * \retval DVR_SUCCESS On success
1913 * \return Error code
1914 */
hualing chen040df222020-01-17 13:35:02 +08001915int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001916 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001917 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001918 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001919 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001920 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001921 return DVR_FAILURE;
1922 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001923 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
1924 DVR_PB_DG(1, "vendor is amlogic. not hide or show av and update segment");
1925 return DVR_SUCCESS;
1926 }
hualing chena540a7e2020-03-27 16:44:05 +08001927
hualing chen040df222020-01-17 13:35:02 +08001928 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001929 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001930 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001931 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001932 {
hualing chen040df222020-01-17 13:35:02 +08001933 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001934 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001935 }
hualing chen86e7d482020-01-16 15:13:33 +08001936 // if encramble to free, only set flag and return;
1937
1938 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001939 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001940 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1941 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001942 //disable display, mute
hualing chen703f3572021-01-06 12:51:34 +08001943 DVR_PB_DG(1, "mute av");
hualing chen2aba4022020-03-02 13:49:55 +08001944 AmTsPlayer_hideVideo(player->handle);
1945 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001946 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1947 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001948 //enable display, unmute
hualing chen703f3572021-01-06 12:51:34 +08001949 DVR_PB_DG(1, "unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08001950 AmTsPlayer_showVideo(player->handle);
1951 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001952 } else {
1953 //do nothing
1954 }
1955 } else {
1956 //do nothing
1957 }
1958 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001959 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001960 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001961 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001962 pthread_mutex_unlock(&player->lock);
1963 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001964}
1965
1966
hualing chen99508642021-10-18 15:41:17 +08001967static 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 +08001968 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08001969 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08001970 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08001971
1972 if (type == 0) {
1973 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08001974 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08001975 } else if (type == 1) {
1976 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08001977 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08001978 } else if (type == 2) {
1979 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08001980 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08001981 } else {
1982 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08001983 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08001984 }
1985
hualing chena540a7e2020-03-27 16:44:05 +08001986 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001987 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001988 return DVR_FAILURE;
1989 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001990 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001991 if (now_pid.pid == set_pid.pid) {
1992 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001993 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001994 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001995 if (VALID_PID(now_pid.pid)) {
1996 //stop now stream
1997 if (type == 0) {
1998 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001999 if (player->has_video == DVR_TRUE) {
2000 DVR_PB_DG(1, "stop video");
2001 AmTsPlayer_stopVideoDecoding(player->handle);
2002 player->has_video = DVR_FALSE;
2003 }
hualing chen86e7d482020-01-16 15:13:33 +08002004 } else if (type == 1) {
2005 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002006 if (player->has_audio == DVR_TRUE) {
2007 DVR_PB_DG(1, "stop audio");
2008 AmTsPlayer_stopAudioDecoding(player->handle);
2009 player->has_audio = DVR_FALSE;
2010 }
hualing chen86e7d482020-01-16 15:13:33 +08002011 } else if (type == 2) {
2012 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08002013 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002014 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002015 } else if (type == 3) {
2016 //pcr
2017 }
2018 }
2019 if (VALID_PID(set_pid.pid)) {
2020 //start
2021 if (type == 0) {
2022 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08002023 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08002024 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08002025 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002026 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002027 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08002028 AmTsPlayer_setVideoParams(player->handle, &vparams);
2029 AmTsPlayer_startVideoDecoding(player->handle);
2030 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08002031 } else if (type == 1) {
2032 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002033 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002034 if (VALID_PID(set_pids.ad.pid)) {
2035 am_tsplayer_audio_params adparams;
2036 adparams.pid = set_pids.ad.pid;
2037 adparams.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
2038 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",adparams.pid, adparams.codectype);
2039 AmTsPlayer_setADParams(player->handle, &adparams);
2040 AmTsPlayer_enableADMix(player->handle);
2041 }
2042
hualing chenc70a8df2020-05-12 19:23:11 +08002043 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002044
2045 memset(&aparams, 0, sizeof(aparams));
2046
hualing chenc70a8df2020-05-12 19:23:11 +08002047 aparams.pid = set_pid.pid;
2048 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
2049 player->has_audio = DVR_TRUE;
2050 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
2051 AmTsPlayer_setAudioParams(player->handle, &aparams);
2052 AmTsPlayer_startAudioDecoding(player->handle);
2053 //playback_device_audio_start(player->handle,&aparams);
2054 }
hualing chen86e7d482020-01-16 15:13:33 +08002055 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002056 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002057 if (set_pids.audio.pid == now_pids.audio.pid) {
2058 //stop audio if audio pid not change
2059 DVR_PB_DG(1, "stop audio when start ad");
2060 AmTsPlayer_stopAudioDecoding(player->handle);
2061 }
hualing chenc70a8df2020-05-12 19:23:11 +08002062 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002063
2064 memset(&aparams, 0, sizeof(aparams));
hualing chenc70a8df2020-05-12 19:23:11 +08002065 aparams.pid = set_pid.pid;
2066 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
2067 player->has_audio = DVR_TRUE;
2068 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
2069 AmTsPlayer_setADParams(player->handle, &aparams);
2070 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002071
2072 if (set_pids.audio.pid == now_pids.audio.pid) {
2073 am_tsplayer_audio_params aparams;
2074
2075 memset(&aparams, 0, sizeof(aparams));
2076
2077 aparams.pid = set_pids.audio.pid;
2078 aparams.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
2079 player->has_audio = DVR_TRUE;
2080 DVR_PB_DG(1, "restart audio when start ad");
2081 AmTsPlayer_setAudioParams(player->handle, &aparams);
2082 AmTsPlayer_startAudioDecoding(player->handle);
2083 }
hualing chenc70a8df2020-05-12 19:23:11 +08002084 }
hualing chen86e7d482020-01-16 15:13:33 +08002085 } else if (type == 3) {
2086 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08002087 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002088 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002089 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002090 //audio and video all close
2091 if (!player->has_audio && !player->has_video) {
2092 player->state = DVR_PLAYBACK_STATE_STOP;
2093 }
hualing chen86e7d482020-01-16 15:13:33 +08002094 }
2095 }
2096 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002097}
hualing chena5f03222021-12-02 11:22:35 +08002098/**\brief dvr play back only update segment pids info
2099 * only update pid info not to start stop codec.
2100 * \param[in] handle playback handle
2101 * \param[in] segment_id need updated pids segment id
2102 * \param[in] p_pids need updated pids
2103 * \retval DVR_SUCCESS On success
2104 * \return Error code
2105 */
2106int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2107 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2108 if (player == NULL) {
2109 DVR_PB_DG(1, "player is NULL");
2110 return DVR_FAILURE;
2111 }
2112
2113 DVR_PlaybackSegmentInfo_t *segment;
2114 DVR_PB_DG(1, "lock");
2115 pthread_mutex_lock(&player->lock);
2116 DVR_PB_DG(1, "get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
2117 list_for_each_entry(segment, &player->segment_list, head)
2118 {
2119 if (segment->segment_id == segment_id) {
2120 if (player->cur_segment_id == segment_id) {
2121 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
2122 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
2123 //do nothing when ff fb
2124 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
2125 pthread_mutex_unlock(&player->lock);
2126 return 0;
2127 }
2128 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2129 }
2130 //save pids info
2131 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
2132 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
2133 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
2134 break;
2135 }
2136 }
2137 DVR_PB_DG(1, "unlock");
2138 pthread_mutex_unlock(&player->lock);
2139 return DVR_SUCCESS;
2140}
2141
hualing chen5cbe1a62020-02-10 16:36:36 +08002142/**\brief dvr play back update segment pids
2143 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002144 * add pid stream and stop remove pid stream.
2145 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002146 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002147 * \retval DVR_SUCCESS On success
2148 * \return Error code
2149 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002150int 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 +08002151 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002152 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002153 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002154 return DVR_FAILURE;
2155 }
2156
hualing chen040df222020-01-17 13:35:02 +08002157 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08002158 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002159 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002160 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 +08002161
hualing chen040df222020-01-17 13:35:02 +08002162 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002163 {
hualing chen040df222020-01-17 13:35:02 +08002164 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002165
2166 if (player->cur_segment_id == segment_id) {
2167 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
2168 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
2169 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002170 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08002171 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002172 return 0;
2173 }
2174
2175 //if segment is on going segment,we need stop start stream
2176 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen1679f812021-11-08 15:17:46 +08002177 DVR_PB_DG(1, "unlock ---\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08002178 pthread_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002179 if (segment->pids.audio.pid != p_pids->audio.pid &&
2180 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002181 //not used this to seek to start pos.we will
2182 //add uopdate only api. if need seek to start
2183 //pos, we will call only update api and used seek api
2184 //to start and stop av codec
2185 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002186 player->need_seek_start = DVR_FALSE;
2187 pthread_mutex_lock(&player->segment_lock);
2188 player->drop_ts = DVR_TRUE;
2189 player->ts_cache_len = 0;
2190 if (player->first_start_time > 0)
2191 player->first_start_time = player->first_start_time - 1;
2192 segment_seek(player->r_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
hualing chen1679f812021-11-08 15:17:46 +08002193 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 +08002194 pthread_mutex_unlock(&player->segment_lock);
2195 }
2196 }
hualing chen1679f812021-11-08 15:17:46 +08002197 //check video pids, stop or restart
2198 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
2199 //check sub audio pids stop or restart
2200 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
2201 //check audio pids stop or restart
2202 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
2203 //check pcr pids stop or restart
2204 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
2205
hualing chencc91e1c2020-02-28 13:26:17 +08002206 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002207 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2208 //if state is pause, we need process at resume api. we only record change info
2209 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2210 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2211 if (VALID_PID(segment->pids.video.pid)
2212 && VALID_PID(p_pids->video.pid)
2213 && segment->pids.video.pid != p_pids->video.pid) {
2214 //restart video
2215 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
2216 }
2217 if (!VALID_PID(segment->pids.video.pid)
2218 && VALID_PID(p_pids->video.pid)
2219 && segment->pids.video.pid != p_pids->video.pid) {
2220 //start video
2221 v_cmd = DVR_PLAYBACK_CMD_VSTART;
2222 }
2223 if (VALID_PID(segment->pids.video.pid)
2224 && !VALID_PID(p_pids->video.pid)
2225 && segment->pids.video.pid != p_pids->video.pid) {
2226 //stop video
2227 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
2228 }
2229 if (VALID_PID(segment->pids.audio.pid)
2230 && VALID_PID(p_pids->audio.pid)
2231 && segment->pids.audio.pid != p_pids->audio.pid) {
2232 //restart audio
2233 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
2234 }
2235 if (!VALID_PID(segment->pids.audio.pid)
2236 && VALID_PID(p_pids->audio.pid)
2237 && segment->pids.audio.pid != p_pids->audio.pid) {
2238 //start audio
2239 a_cmd = DVR_PLAYBACK_CMD_ASTART;
2240 }
2241 if (VALID_PID(segment->pids.audio.pid)
2242 && !VALID_PID(p_pids->audio.pid)
2243 && segment->pids.audio.pid != p_pids->audio.pid) {
2244 //stop audio
2245 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
2246 }
2247 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2248 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2249 //do nothing
2250 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2251 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2252 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2253 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2254 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2255 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
2256 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2257 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2258 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2259 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2260 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2261 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2262 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2263 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
2264 } else {
2265 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2266 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
2267 }
2268
2269 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2270 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2271 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2272 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
2273 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2274 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2275 //not occur this case
2276 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2277 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2278 } else {
2279 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2280 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
2281 }
2282
2283 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2284 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2285 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2286 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
2287 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2288 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
2289 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2290 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
2291 } else {
2292 //not occur this case
2293 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2294 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2295 }
2296 }
2297 }
hualing chene10666f2020-04-14 13:58:37 +08002298 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002299 }
hualing chen86e7d482020-01-16 15:13:33 +08002300 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08002301 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002302 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08002303 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002304 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002305 }
hualing chen86e7d482020-01-16 15:13:33 +08002306 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002307 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002308 pthread_mutex_unlock(&player->lock);
2309 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002310}
2311/**\brief Stop play, will stop video and audio
2312 * \param[in] handle playback handle
2313 * \param[in] clear is clear last frame
2314 * \retval DVR_SUCCESS On success
2315 * \return Error code
2316 */
hualing chen040df222020-01-17 13:35:02 +08002317int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2318 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002319 UNDVRUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002320 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002321 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002322 return DVR_FAILURE;
2323 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002324 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2325 DVR_PB_DG(1, ":playback is stoped");
2326 return DVR_SUCCESS;
2327 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002328 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2329 DVR_PB_DG(1, ":playback is stoped");
2330 return DVR_SUCCESS;
2331 }
hualing chen87072a82020-03-12 16:20:12 +08002332 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08002333 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002334 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002335 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002336 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002337 if (player->has_video) {
2338 AmTsPlayer_resumeVideoDecoding(player->handle);
2339 }
2340 if (player->has_audio) {
2341 AmTsPlayer_resumeAudioDecoding(player->handle);
2342 }
2343 if (player->has_video) {
2344 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002345 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002346 AmTsPlayer_stopVideoDecoding(player->handle);
2347 }
2348 if (player->has_audio) {
2349 player->has_audio = DVR_FALSE;
2350 AmTsPlayer_stopAudioDecoding(player->handle);
2351 }
hualing chendf118dd2020-05-21 15:49:11 +08002352 if (player->has_ad_audio) {
2353 player->has_ad_audio =DVR_FALSE;
2354 AmTsPlayer_disableADMix(player->handle);
2355 }
hualing chen266b9502020-04-04 17:39:39 +08002356
hualing chen86e7d482020-01-16 15:13:33 +08002357 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002358 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2359 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2360 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002361 player->cur_segment_id = UINT64_MAX;
2362 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002363 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08002364 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08002365 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002366 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002367}
2368/**\brief Start play audio
2369 * \param[in] handle playback handle
2370 * \param[in] params audio playback params,contains fmt and pid...
2371 * \retval DVR_SUCCESS On success
2372 * \return Error code
2373 */
hualing chen2aba4022020-03-02 13:49:55 +08002374
hualing chendf118dd2020-05-21 15:49:11 +08002375int 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 +08002376 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002377
2378 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002379 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002380 return DVR_FAILURE;
2381 }
hualing chen86e7d482020-01-16 15:13:33 +08002382 _start_playback_thread(handle);
2383 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002384 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002385 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002386
hualing chendf118dd2020-05-21 15:49:11 +08002387 if (VALID_PID(adparam->pid)) {
2388 player->has_ad_audio = DVR_TRUE;
2389 DVR_PB_DG(1, "start ad audio");
2390 AmTsPlayer_setADParams(player->handle, adparam);
2391 AmTsPlayer_enableADMix(player->handle);
2392 }
hualing chen969fe7b2021-05-26 15:13:17 +08002393 if (VALID_PID(param->pid)) {
2394 DVR_PB_DG(1, "start audio");
2395 player->has_audio = DVR_TRUE;
2396 AmTsPlayer_setAudioParams(player->handle, param);
2397 AmTsPlayer_startAudioDecoding(player->handle);
2398 }
hualing chendf118dd2020-05-21 15:49:11 +08002399
hualing chen86e7d482020-01-16 15:13:33 +08002400 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002401 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
2402 player->cmd.state = DVR_PLAYBACK_STATE_START;
2403 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002404 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002405 pthread_mutex_unlock(&player->lock);
2406 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002407}
2408/**\brief Stop play audio
2409 * \param[in] handle playback handle
2410 * \retval DVR_SUCCESS On success
2411 * \return Error code
2412 */
hualing chen040df222020-01-17 13:35:02 +08002413int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2414 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002415
2416 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002417 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002418 return DVR_FAILURE;
2419 }
2420
hualing chen2aba4022020-03-02 13:49:55 +08002421 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002422 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002423 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2424 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002425 //destory thread
2426 _stop_playback_thread(handle);
2427 } else {
2428 //do nothing.video is playing
2429 }
hualing chen7a56cba2020-04-14 14:09:27 +08002430 DVR_PB_DG(1, "lock");
2431 pthread_mutex_lock(&player->lock);
2432
hualing chenf00cdc82020-06-10 14:23:35 +08002433 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002434 player->has_audio = DVR_FALSE;
2435 AmTsPlayer_stopAudioDecoding(player->handle);
2436 }
hualing chen87072a82020-03-12 16:20:12 +08002437
hualing chendf118dd2020-05-21 15:49:11 +08002438 if (player->has_ad_audio) {
2439 player->has_ad_audio =DVR_FALSE;
2440 AmTsPlayer_disableADMix(player->handle);
2441 }
2442
hualing chen87072a82020-03-12 16:20:12 +08002443 player->cmd.last_cmd = player->cmd.cur_cmd;
2444 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2445
hualing chen4b7c15d2020-04-07 16:13:48 +08002446 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002447 pthread_mutex_unlock(&player->lock);
2448 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002449}
2450/**\brief Start play video
2451 * \param[in] handle playback handle
2452 * \param[in] params video playback params,contains fmt and pid...
2453 * \retval DVR_SUCCESS On success
2454 * \return Error code
2455 */
hualing chen2aba4022020-03-02 13:49:55 +08002456int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002457 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002458
2459 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002460 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002461 return DVR_FAILURE;
2462 }
2463
hualing chen86e7d482020-01-16 15:13:33 +08002464 _start_playback_thread(handle);
2465 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002466 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002467 pthread_mutex_lock(&player->lock);
2468 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002469 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002470 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002471 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002472
2473 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002474 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002475 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002476 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002477 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2478 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002479 }
2480 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002481 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2482 player->cmd.state = DVR_PLAYBACK_STATE_START;
2483 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002484 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002485 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002486 return DVR_SUCCESS;
2487}
2488/**\brief Stop play video
2489 * \param[in] handle playback handle
2490 * \retval DVR_SUCCESS On success
2491 * \return Error code
2492 */
hualing chen040df222020-01-17 13:35:02 +08002493int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2494 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002495
2496 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002497 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002498 return DVR_FAILURE;
2499 }
2500
hualing chen86e7d482020-01-16 15:13:33 +08002501 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002502 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2503 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002504 //destory thread
2505 _stop_playback_thread(handle);
2506 } else {
2507 //do nothing.audio is playing
2508 }
hualing chen7a56cba2020-04-14 14:09:27 +08002509
2510 DVR_PB_DG(1, "lock");
2511 pthread_mutex_lock(&player->lock);
2512
hualing chen87072a82020-03-12 16:20:12 +08002513 player->has_video = DVR_FALSE;
2514
2515 AmTsPlayer_stopVideoDecoding(player->handle);
2516 //playback_device_video_stop(player->handle);
2517
2518 player->cmd.last_cmd = player->cmd.cur_cmd;
2519 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2520
hualing chen4b7c15d2020-04-07 16:13:48 +08002521 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002522 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002523 return DVR_SUCCESS;
2524}
2525/**\brief Pause play
2526 * \param[in] handle playback handle
2527 * \param[in] flush whether its internal buffers should be flushed
2528 * \retval DVR_SUCCESS On success
2529 * \return Error code
2530 */
hualing chen040df222020-01-17 13:35:02 +08002531int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2532 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002533 UNDVRUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002534 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002535 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002536 return DVR_FAILURE;
2537 }
hualing chenf00cdc82020-06-10 14:23:35 +08002538 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
2539 DVR_PB_DG(1, "player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002540 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002541 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002542 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002543 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002544 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002545 if (player->has_video)
2546 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002547 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002548 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002549
2550 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002551 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2552 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2553 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2554 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002555 } else {
2556 player->cmd.last_cmd = player->cmd.cur_cmd;
2557 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2558 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2559 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002560 }
hualing chen86e7d482020-01-16 15:13:33 +08002561 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002562 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002563
hualing chen86e7d482020-01-16 15:13:33 +08002564 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002565}
2566
hualing chen5cbe1a62020-02-10 16:36:36 +08002567//not add lock
2568static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2569{
2570 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2571
hualing chena540a7e2020-03-27 16:44:05 +08002572 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002573 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002574 return DVR_FAILURE;
2575 }
2576
hualing chen5cbe1a62020-02-10 16:36:36 +08002577 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002578 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002579 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002580 am_tsplayer_video_params vparams;
2581 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002582 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002583 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002584
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002585 memset(&vparams, 0, sizeof(vparams));
2586 memset(&aparams, 0, sizeof(aparams));
2587
hualing chendf118dd2020-05-21 15:49:11 +08002588 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002589 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002590 pthread_mutex_unlock(&player->lock);
2591
2592 switch (cmd) {
2593 case DVR_PLAYBACK_CMD_AVRESTART:
2594 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002595 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002596 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002597 break;
2598 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002599 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2600 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002601 break;
2602 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002603 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002604 break;
2605 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002606 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002607 break;
2608 case DVR_PLAYBACK_CMD_ARESTART:
2609 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002610 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002611 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002612 break;
2613 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002614 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002615 break;
2616 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002617 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002618 break;
2619 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002620 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2621 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2622 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002623 break;
2624 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002625 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2626 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002627 break;
2628 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002629 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2630 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002631 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002632 break;
2633 case DVR_PLAYBACK_CMD_STOP:
2634 break;
2635 case DVR_PLAYBACK_CMD_START:
2636 break;
2637 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002638 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2639 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002640 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002641 break;
2642 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002643 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2644 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002645 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002646 break;
2647 case DVR_PLAYBACK_CMD_FF:
2648 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002649 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002650 break;
2651 default:
2652 break;
2653 }
2654 return DVR_SUCCESS;
2655}
2656
2657/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002658 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002659 * \retval DVR_SUCCESS On success
2660 * \return Error code
2661 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002662int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2663 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002664 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002665 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002666 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002667 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002668 return DVR_FAILURE;
2669 }
2670
hualing chena991aa82021-08-16 10:21:15 +08002671 if (dvr_playback_check_limit(handle)) {
2672 //get id and pos to check if we can seek to this pos
hualing chen7ea70a72021-09-09 11:25:13 +08002673 DVR_PB_DG(1, "player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002674 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2675 if (segmentid != player->cur_segment_id ||
2676 (segmentid == player->cur_segment_id &&
2677 pos > _dvr_get_cur_time(handle))) {
2678 //first to seek new pos and to resume
2679 DVR_PB_DG(1, "seek new pos and to resume");
2680 dvr_playback_seek(handle, segmentid, pos);
2681 }
hualing chen7ea70a72021-09-09 11:25:13 +08002682 } else {
2683 DVR_PB_DG(1, "player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002684 }
hualing chena991aa82021-08-16 10:21:15 +08002685
hualing chen5cbe1a62020-02-10 16:36:36 +08002686 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002687 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002688 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002689 player->first_frame = 0;
2690 if (player->has_video)
2691 AmTsPlayer_pauseVideoDecoding(player->handle);
2692 if (player->has_audio)
2693 AmTsPlayer_pauseAudioDecoding(player->handle);
2694
hualing chen266b9502020-04-04 17:39:39 +08002695 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002696 DVR_PB_DG(1, "dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002697 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2698 AmTsPlayer_resumeVideoDecoding(player->handle);
2699 }
2700 if (player->has_audio) {
2701 AmTsPlayer_resumeAudioDecoding(player->handle);
2702 }
2703 //check is has audio param,if has audio .we need start audio,
2704 //we will stop audio when ff fb, if reach end, we will pause.so we need
2705 //start audio when resume play
2706
2707 am_tsplayer_video_params vparams;
2708 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002709 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002710 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002711
2712 memset(&vparams, 0, sizeof(vparams));
2713 memset(&aparams, 0, sizeof(aparams));
hualing chendf118dd2020-05-21 15:49:11 +08002714 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002715 //valid audio pid, start audio
hualing chen969fe7b2021-05-26 15:13:17 +08002716 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2717 player->has_ad_audio = DVR_TRUE;
2718 DVR_PB_DG(1, "start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08002719 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08002720 AmTsPlayer_setADParams(player->handle, &adparams);
2721 AmTsPlayer_enableADMix(player->handle);
2722 }
2723
hualing chenc70a8df2020-05-12 19:23:11 +08002724 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 +08002725 player->has_audio = DVR_TRUE;
hualing chen1679f812021-11-08 15:17:46 +08002726 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen266b9502020-04-04 17:39:39 +08002727 AmTsPlayer_setAudioParams(player->handle, &aparams);
2728 AmTsPlayer_startAudioDecoding(player->handle);
2729 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002730 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 +08002731 }
hualing chendf118dd2020-05-21 15:49:11 +08002732
hualing chen87072a82020-03-12 16:20:12 +08002733 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2734 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2735 player->cmd.state = DVR_PLAYBACK_STATE_START;
2736 player->state = DVR_PLAYBACK_STATE_START;
2737 } else {
2738 player->cmd.last_cmd = player->cmd.cur_cmd;
2739 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2740 player->cmd.state = DVR_PLAYBACK_STATE_START;
2741 player->state = DVR_PLAYBACK_STATE_START;
2742 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002743 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002744 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002745 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
hualing chen1ffd85b2021-08-16 15:18:43 +08002746 player->first_frame = 0;
2747 if (player->has_video)
2748 AmTsPlayer_pauseVideoDecoding(player->handle);
2749 if (player->has_audio)
2750 AmTsPlayer_pauseAudioDecoding(player->handle);
2751
hualing chene41f4372020-06-06 16:29:17 +08002752 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002753 DVR_PB_DG(1, "dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002754 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002755 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002756 }
hualing chen041c4092020-04-05 15:11:50 +08002757 if (player->has_audio)
2758 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002759 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002760 player->cmd.state = DVR_PLAYBACK_STATE_START;
2761 player->state = DVR_PLAYBACK_STATE_START;
hualing chen9811b212020-10-29 11:21:44 +08002762 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2763 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002764 } else {
2765 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2766 {
hualing chen1679f812021-11-08 15:17:46 +08002767 DVR_PB_DG(1, "lock ---\r\n");
hualing chen041c4092020-04-05 15:11:50 +08002768 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002769 player->first_frame = 0;
2770 if (player->has_video)
2771 AmTsPlayer_pauseVideoDecoding(player->handle);
2772 if (player->has_audio)
2773 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002774 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002775 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002776 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2777 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002778 if (player->has_video) {
2779 AmTsPlayer_resumeVideoDecoding(player->handle);
2780 }
2781 if (player->has_audio)
2782 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen1679f812021-11-08 15:17:46 +08002783 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen041c4092020-04-05 15:11:50 +08002784 pthread_mutex_unlock(&player->lock);
2785 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002786 }
2787 return DVR_SUCCESS;
2788}
2789
hualing chena540a7e2020-03-27 16:44:05 +08002790static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2791
2792 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2793 DVR_PlaybackSegmentInfo_t *segment = NULL;
2794 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2795 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2796
2797 list_for_each_entry(segment, &player->segment_list, head)
2798 {
2799 if (segment->segment_id == segment_id) {
2800 cur_segment = segment;
2801 }
2802 if (segment->segment_id == set_seg_id) {
2803 set_segment = segment;
2804 }
2805 if (cur_segment != NULL && set_segment != NULL) {
2806 break;
2807 }
2808 }
2809 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002810 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002811 return DVR_TRUE;
2812 }
2813 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2814 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2815 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2816 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002817 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 +08002818 return DVR_TRUE;
2819 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002820 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002821 return DVR_FALSE;
2822}
2823
hualing chen03fd4942021-07-15 15:56:41 +08002824/**\brief set limit
2825 * \param[in] handle playback handle
2826 * \param[in] rec start time ms
2827 * \param[in] rec limit time ms
2828 * \retval DVR_SUCCESS On success
2829 * \return Error code
2830 */
hualing chen7ea70a72021-09-09 11:25:13 +08002831int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08002832{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2833
2834 if (player == NULL) {
2835 DVR_PB_DG(1, "player is NULL");
2836 return DVR_FAILURE;
2837 }
hualing chen7ea70a72021-09-09 11:25:13 +08002838 _dvr_getClock_sec();
hualing chen1679f812021-11-08 15:17:46 +08002839 DVR_PB_DG(1, "lock time %lu limit: %u player->state:%d", time, limit, player->state);
hualing chen03fd4942021-07-15 15:56:41 +08002840 pthread_mutex_lock(&player->lock);
2841 player->rec_start = time;
2842 player->limit = limit;
hualing chen1679f812021-11-08 15:17:46 +08002843 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen03fd4942021-07-15 15:56:41 +08002844 pthread_mutex_unlock(&player->lock);
2845 return DVR_SUCCESS;
2846}
2847
hualing chen5cbe1a62020-02-10 16:36:36 +08002848/**\brief seek
2849 * \param[in] handle playback handle
2850 * \param[in] time_offset time offset base cur segment
2851 * \retval DVR_SUCCESS On success
2852 * \return Error code
2853 */
hualing chencc91e1c2020-02-28 13:26:17 +08002854int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002855 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002856 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08002857 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002858 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002859 return DVR_FAILURE;
2860 }
2861
hualing chen4b7c15d2020-04-07 16:13:48 +08002862 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 +08002863 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002864
hualing chen86e7d482020-01-16 15:13:33 +08002865 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002866 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002867 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002868
hualing chen5cbe1a62020-02-10 16:36:36 +08002869 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08002870 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002871 if (ret ==DVR_FAILURE) {
hualing chen1679f812021-11-08 15:17:46 +08002872 DVR_PB_DG(1, "unlock seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002873 pthread_mutex_unlock(&player->lock);
2874 return DVR_FAILURE;
2875 }
2876 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2877 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002878 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002879 time_offset = _dvr_get_end_time(handle);
2880 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002881 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002882 time_offset = _dvr_get_end_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08002883 ret = DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08002884 }
2885 }
2886
hualing chen03fd4942021-07-15 15:56:41 +08002887 DVR_PB_DG(1, "seek open id[%lld]flag[0x%x] time_offset %u",
2888 player->cur_segment.segment_id,
2889 player->cur_segment.flags,
2890 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08002891 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002892 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2893 //forward playback.not seek end of file
2894 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2895 //default -2000ms
2896 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2897 }
hualing chen86e7d482020-01-16 15:13:33 +08002898 }
hualing chen8a657f32021-08-30 13:12:49 +08002899 if (player->need_seek_start == DVR_TRUE) {
2900 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
2901 }
hualing chen2aba4022020-03-02 13:49:55 +08002902 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002903 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002904 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002905 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002906 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 +08002907 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002908 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002909
hualing chen2aba4022020-03-02 13:49:55 +08002910 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002911
2912 player->last_send_time_id = UINT64_MAX;
hualing chen03fd4942021-07-15 15:56:41 +08002913 player->last_segment_tatol = 0LL;
2914 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08002915 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002916 player->fffb_current = _dvr_time_getClock();
2917 player->fffb_start = player->fffb_current;
2918 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2919 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002920 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002921 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002922 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002923 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002924 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002925 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002926 }
hualing chen86e7d482020-01-16 15:13:33 +08002927 //stop play
hualing chen03fd4942021-07-15 15:56:41 +08002928 DVR_PB_DG(0, "seek stop play, not inject data has video[%d]audio[%d]",
2929 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08002930
hualing chen266b9502020-04-04 17:39:39 +08002931 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08002932 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08002933 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08002934 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002935 }
2936
hualing chen40dd5462021-11-26 19:56:20 +08002937
hualing chen266b9502020-04-04 17:39:39 +08002938 if (player->has_audio) {
2939 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002940 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002941 }
hualing chendf118dd2020-05-21 15:49:11 +08002942 if (player->has_ad_audio) {
2943 player->has_ad_audio =DVR_FALSE;
2944 AmTsPlayer_disableADMix(player->handle);
2945 }
2946
hualing chen86e7d482020-01-16 15:13:33 +08002947 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002948 am_tsplayer_video_params vparams;
2949 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002950 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002951
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002952 memset(&vparams, 0, sizeof(vparams));
2953 memset(&aparams, 0, sizeof(aparams));
2954
hualing chen040df222020-01-17 13:35:02 +08002955 player->cur_segment_id = segment_id;
2956
2957 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002958 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002959 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002960 //start audio and video
hualing chena5f03222021-12-02 11:22:35 +08002961 if (vparams.pid != player->fake_pid && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
2962 //audio and video pid is all invalid, return error.
2963 DVR_PB_DG(0, "unlock seek start dvr play back start error, not found audio and video info [0x%x]", vparams.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002964 pthread_mutex_unlock(&player->lock);
2965 return -1;
2966 }
hualing chena5f03222021-12-02 11:22:35 +08002967 DVR_PB_DG(0, "seek start[0x%x]", vparams.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002968 //add
hualing chen040df222020-01-17 13:35:02 +08002969 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002970 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002971 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002972 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08002973 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002974 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002975 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002976 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002977 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002978 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002979 }
hualing chena5f03222021-12-02 11:22:35 +08002980 DVR_PB_DG(1, "start video");
hualing chen2aba4022020-03-02 13:49:55 +08002981 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08002982 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08002983 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002984 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
2985 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
2986 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2987 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2988 AmTsPlayer_stopFast(player->handle);
2989 }
hualing chen266b9502020-04-04 17:39:39 +08002990 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08002991 } else {
2992 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08002993 }
hualing chene41f4372020-06-06 16:29:17 +08002994 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08002995 player->has_ad_audio = DVR_TRUE;
2996 DVR_PB_DG(1, "start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08002997 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chendf118dd2020-05-21 15:49:11 +08002998 AmTsPlayer_setADParams(player->handle, &adparams);
2999 AmTsPlayer_enableADMix(player->handle);
3000 }
hualing chen969fe7b2021-05-26 15:13:17 +08003001 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
3002 DVR_PB_DG(1, "start audio seek");
hualing chen1679f812021-11-08 15:17:46 +08003003 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08003004 AmTsPlayer_setAudioParams(player->handle, &aparams);
3005 AmTsPlayer_startAudioDecoding(player->handle);
3006 player->has_audio = DVR_TRUE;
3007 }
hualing chen86e7d482020-01-16 15:13:33 +08003008 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003009 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen2aba4022020-03-02 13:49:55 +08003010 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
3011 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chena5f03222021-12-02 11:22:35 +08003012 if (VALID_PID(aparams.pid) || VALID_PID(vparams.pid))
3013 player->seek_pause = DVR_TRUE;
3014 DVR_PB_DG(1, "set state pause in seek vpid[0x%x]apid[0x%x]",vparams.pid, aparams.pid);
hualing chen87072a82020-03-12 16:20:12 +08003015 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3016 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08003017 player->speed > 1.0f||
3018 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003019 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003020 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003021 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003022 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003023 player->cmd.last_cmd = player->cmd.cur_cmd;
3024 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3025 player->cmd.state = DVR_PLAYBACK_STATE_START;
3026 player->state = DVR_PLAYBACK_STATE_START;
3027 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003028 player->last_send_time_id = UINT64_MAX;
3029 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08003030 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003031
3032 return DVR_SUCCESS;
3033}
hualing chen5cbe1a62020-02-10 16:36:36 +08003034
hualing chen5cbe1a62020-02-10 16:36:36 +08003035static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3036 //get cur time of segment
3037 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003038
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003039 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003040 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003041 return DVR_FAILURE;
3042 }
3043
hualing chen31140872020-03-25 12:29:26 +08003044 int64_t cache = 0;//defalut es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003045 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003046 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003047 uint64_t cur = 0;
3048 if (player->ts_cache_len > 0 && pos < 0) {
3049 //this case is open new segment end,but cache data is last segment.
3050 //we need used last segment len to send play time.
3051 cur = 0;
3052 } else {
3053 cur = segment_tell_position_time(player->r_handle, pos);
3054 }
hualing chen21a40372021-10-29 11:07:26 +08003055 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003056 pthread_mutex_unlock(&player->segment_lock);
hualing chenfbf8e022020-06-15 13:43:11 +08003057 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 +08003058 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3059 cache = 0;
3060 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003061 int cur_time = (int)(cur > cache ? cur - cache : 0);
3062 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003063}
3064
hualing chen969fe7b2021-05-26 15:13:17 +08003065static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3066 //get cur time of segment
3067 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3068
hualing chen03fd4942021-07-15 15:56:41 +08003069 if (player == NULL || player->handle == 0) {
hualing chen969fe7b2021-05-26 15:13:17 +08003070 DVR_PB_DG(1, "player is NULL");
3071 return DVR_FAILURE;
3072 }
3073
3074 int64_t cache = 0;//defalut es buf cache 500ms
3075 int cur_time = 0;
hualing chen969fe7b2021-05-26 15:13:17 +08003076 pthread_mutex_lock(&player->segment_lock);
hualing chena5f03222021-12-02 11:22:35 +08003077 loff_t tmp_pos = segment_tell_position(player->r_handle);
3078 loff_t pos = tmp_pos - player->ts_cache_len;
3079 uint64_t cur = 0;
3080 if (player->ts_cache_len > 0 && (tmp_pos < player->ts_cache_len)) {
3081 //this case is open new segment end,but cache data is last segment.
3082 //we need used last segment len to send play time.
3083 cur = 0;
hualing chen926a8ec2021-12-20 20:38:24 +08003084 DVR_PB_DG(1, "change segment [%lld][%lld]",
3085 player->last_segment_id, player->cur_segment_id);
hualing chena5f03222021-12-02 11:22:35 +08003086 } else {
3087 cur = segment_tell_position_time(player->r_handle, pos);
3088 }
hualing chen21a40372021-10-29 11:07:26 +08003089 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen969fe7b2021-05-26 15:13:17 +08003090 pthread_mutex_unlock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +08003091 DVR_PB_DG(1, "***get play cur time [%lld] cache:%lld cur id [%lld]\
3092 last id [%lld] pb cache len [%d] pos [%lld][%lld]",
3093 cur,
3094 cache,
3095 player->cur_segment_id,
3096 player->last_send_time_id,
3097 player->ts_cache_len,
3098 pos,
3099 tmp_pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003100 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3101 cache = 0;
3102 }
3103 if (cur > cache) {
3104 cur_time = (int)(cur - cache);
3105 *id = player->cur_segment_id;
3106 } else if (player->last_segment_tatol > 0) {
hualing chen8a657f32021-08-30 13:12:49 +08003107
3108 if (player->last_segment_tatol > (cache - cur))
3109 cur_time = (int)(player->last_segment_tatol - (cache - cur));
3110 else
3111 cur_time = (int)(player->last_segment_tatol - cur);
3112
hualing chen969fe7b2021-05-26 15:13:17 +08003113 *id = player->last_segment_id;
3114 DVR_PB_DG(1, "get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_tatol);
3115 } else {
3116 cur_time = 0;
3117 *id = player->cur_segment_id;
3118 }
3119
3120 return cur_time;
3121}
3122
hualing chencc91e1c2020-02-28 13:26:17 +08003123//get current segment current pcr time of read pos
3124static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3125 //get cur time of segment
3126 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003127
3128 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003129 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003130 return DVR_FAILURE;
3131 }
3132
hualing chen2aba4022020-03-02 13:49:55 +08003133 pthread_mutex_lock(&player->segment_lock);
3134 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003135 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08003136 pthread_mutex_unlock(&player->segment_lock);
3137 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003138}
3139
hualing chen03fd4942021-07-15 15:56:41 +08003140DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3141{
3142 //check is set limit info
3143 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3144
3145 if (player == NULL) {
3146 DVR_PB_DG(1, "player is NULL");
3147 return DVR_FALSE;
3148 }
3149 if (player->rec_start > 0 || player->limit > 0) {
3150 return DVR_TRUE;
3151 }
3152 return DVR_FALSE;
3153}
3154
3155/**\brief set DVR playback calculate expired time len
3156 * \param[in] handle, DVR playback session handle
3157 * \return DVR_SUCCESS on success
3158 * \return error code on failure
3159 */
hualing chen7ea70a72021-09-09 11:25:13 +08003160uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003161{
3162 //calculate expired time to play
3163 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003164 uint32_t cur_time;
3165 uint32_t tmp_time;
3166 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003167 if (player == NULL) {
3168 DVR_PB_DG(1, "player is NULL");
3169 return expired;
3170 }
hualing chen7ea70a72021-09-09 11:25:13 +08003171 if (player->rec_start == 0 || player->limit == 0) {
3172 DVR_PB_DG(1, "rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003173 return expired;
3174 }
3175 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003176 cur_time = _dvr_getClock_sec();
3177 if ((cur_time - player->rec_start) > player->limit) {
3178 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3179 expired = *(int*)&tmp_time;
3180 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 +08003181 cur_time,
3182 player->rec_start,
3183 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003184 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3185 }
hualing chen03fd4942021-07-15 15:56:41 +08003186 return expired;
3187}
3188
3189/**\brief set DVR playback obsolete time
3190 * \param[in] handle, DVR playback session handle
3191 * \param[in] obsolete, obsolete len
3192 * \return DVR_SUCCESS on success
3193 * \return error code on failure
3194 */
3195int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3196{
3197 int expired = 0;
3198 //calculate expired time to play
3199 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3200
3201 if (player == NULL) {
3202 DVR_PB_DG(1, "player is NULL");
3203 return DVR_FALSE;
3204 }
3205 //get system time
hualing chen1679f812021-11-08 15:17:46 +08003206 DVR_PB_DG(1, "lock ---\r\n");
hualing chen03fd4942021-07-15 15:56:41 +08003207 pthread_mutex_lock(&player->lock);
3208 player->obsolete = obsolete;
hualing chen1679f812021-11-08 15:17:46 +08003209 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen03fd4942021-07-15 15:56:41 +08003210 pthread_mutex_unlock(&player->lock);
3211 return expired;
3212}
3213
3214/**\brief update DVR playback newest segment duration
3215 * \param[in] handle, DVR playback session handle
3216 * \param[in] segmentid, newest segment id
3217 * \param[in] dur dur time ms
3218 * \return DVR_SUCCESS on success
3219 * \return error code on failure
3220 */
3221int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3222uint64_t segmentid, int dur)
3223{
3224 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3225 DVR_PlaybackSegmentInfo_t *segment;
3226 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3227
3228 if (player == NULL) {
3229 DVR_PB_DG(1, " player is NULL");
3230 return DVR_FAILURE;
3231 }
3232 //update the newest segment duration on timeshift mode
3233 list_for_each_entry(segment, &player->segment_list, head)
3234 {
3235 if (segment->segment_id == segmentid) {
3236 segment->duration = dur;
3237 break;
3238 }
3239 pre_segment = segment;
3240 }
3241
3242 return DVR_SUCCESS;
3243}
3244
hualing chen7ea70a72021-09-09 11:25:13 +08003245static uint32_t dvr_playback_calculate_last_valid_segment(
3246 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003247{
hualing chen7ea70a72021-09-09 11:25:13 +08003248 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003249 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003250 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003251 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003252 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003253 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3254
3255 if (player == NULL) {
3256 DVR_PB_DG(1, "player is NULL");
3257 return DVR_FAILURE;
3258 }
3259 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003260 if (expired == 0) {
3261 *segmentid = player->cur_segment_id;
3262 *pos = 0;
3263 return DVR_SUCCESS;
3264 }
hualing chen03fd4942021-07-15 15:56:41 +08003265 DVR_PlaybackSegmentInfo_t *pseg;
3266 list_for_each_entry_reverse(pseg, &player->segment_list, head) {
3267 segment_id = pseg->segment_id;
3268
3269 if ((player->obsolete + pre_off + pseg->duration) > expired)
3270 break;
3271
3272 last_segment_id = pseg->segment_id;
3273 pre_off += pseg->duration;
3274 }
3275
3276 if (last_segment_id == segment_id) {
3277 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3278 off = expired;
3279 } else if (player->obsolete >= expired) {
3280 off = 0;
3281 } else {
3282 off = expired - pre_off - player->obsolete;
3283 }
3284 *segmentid = segment_id;
3285 *pos = off;
3286 return DVR_SUCCESS;
3287}
3288
hualing chen4b7c15d2020-04-07 16:13:48 +08003289#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003290//start replay
3291static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3292
3293 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3294 //calculate pcr seek time
3295 int t_diff = 0;
3296 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003297 uint64_t segmentid = 0;
3298 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003299 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003300 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003301 return DVR_FAILURE;
3302 }
3303
hualing chen5cbe1a62020-02-10 16:36:36 +08003304 if (player->fffb_start == -1) {
3305 //set fffb start time ms
3306 player->fffb_start = _dvr_time_getClock();
3307 player->fffb_current = player->fffb_start;
3308 //get segment current time pos
3309 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08003310 DVR_PB_DG(1, "calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
3311 player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003312 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08003313 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003314 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003315 } else {
3316 player->fffb_current = _dvr_time_getClock();
3317 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003318 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003319 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003320 if (seek_time <= 0) {
3321 //need seek to pre one segment
3322 seek_time = 0;
3323 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003324 //seek segment pos
3325 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003326 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003327 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003328 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3329 //set seek time to 0;
hualing chen03fd4942021-07-15 15:56:41 +08003330 DVR_PB_DG(1, "segment seek to 0 at fb mode [%d]id[%lld]",
3331 seek_time,
3332 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003333 seek_time = 0;
3334 }
hualing chen03fd4942021-07-15 15:56:41 +08003335 if (IS_FB(player->speed)
3336 && dvr_playback_check_limit(handle)) {
3337 //fb case.check expired time
3338 //get id and pos to check if we can seek to this pos
3339 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3340 //case cur id < segment id
3341 if (player->cur_segment_id < segmentid) {
3342 //expired ts data is player,return error
3343 //
3344 pthread_mutex_unlock(&player->segment_lock);
3345 return 0;
3346 } else if (player->cur_segment_id == segmentid) {
3347 //id is same,compare seek pos
3348 if (seek_time < pos) {
3349 //expired ts data is player,return error
3350 //
3351 pthread_mutex_unlock(&player->segment_lock);
3352 return 0;
3353 }
3354 }
3355 //case can play
3356 }
hualing chen041c4092020-04-05 15:11:50 +08003357 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
3358 seek_time = 0;
3359 }
hualing chen2aba4022020-03-02 13:49:55 +08003360 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003361 } else {
3362 //
hualing chen4b7c15d2020-04-07 16:13:48 +08003363 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003364 }
hualing chen03fd4942021-07-15 15:56:41 +08003365 DVR_PB_DG(1, "calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
3366 seek_time,
3367 player->speed,
3368 player->cur_segment_id,
3369 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003370 }
hualing chen2aba4022020-03-02 13:49:55 +08003371 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003372}
3373
3374
3375//start replay
3376static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3377 //
3378 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003379
3380 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003381 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003382 return DVR_FAILURE;
3383 }
3384
hualing chen5cbe1a62020-02-10 16:36:36 +08003385 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003386 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003387 DVR_PB_DG(1, "fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003388 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003389 AmTsPlayer_stopVideoDecoding(player->handle);
3390 }
3391 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003392 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003393 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003394 AmTsPlayer_stopAudioDecoding(player->handle);
3395 }
hualing chendf118dd2020-05-21 15:49:11 +08003396 if (player->has_ad_audio) {
3397 DVR_PB_DG(1, "fffb stop audio");
3398 player->has_ad_audio =DVR_FALSE;
3399 AmTsPlayer_disableADMix(player->handle);
3400 }
hualing chen2aba4022020-03-02 13:49:55 +08003401
hualing chen5cbe1a62020-02-10 16:36:36 +08003402 //start video and audio
3403
hualing chen2aba4022020-03-02 13:49:55 +08003404 am_tsplayer_video_params vparams;
3405 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003406 am_tsplayer_audio_params adparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003407
3408 memset(&vparams, 0, sizeof(vparams));
3409 memset(&aparams, 0, sizeof(aparams));
3410
hualing chen87072a82020-03-12 16:20:12 +08003411 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003412
3413 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08003414 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08003415 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003416 //start audio and video
3417 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
3418 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08003419 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003420 return -1;
3421 }
3422
3423 if (VALID_PID(vparams.pid)) {
3424 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08003425 DVR_PB_DG(1, "fffb start video");
hualing chen0888c032020-12-18 17:54:57 +08003426 //DVR_PB_DG(1, "fffb start video and save last frame");
3427 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003428 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003429 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
3430 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003431 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003432 AmTsPlayer_startVideoDecoding(player->handle);
3433 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003434 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003435 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003436 }
hualing chen31140872020-03-25 12:29:26 +08003437 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08003438 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08003439 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003440 return 0;
3441}
3442
3443static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3444 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003445 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003446 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003447 return DVR_FAILURE;
3448 }
3449
3450 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08003451 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003452 pthread_mutex_lock(&player->lock);
3453
hualing chen2aba4022020-03-02 13:49:55 +08003454 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003455 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 +08003456
hualing chen87072a82020-03-12 16:20:12 +08003457 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3458 //seek time set 0
3459 seek_time = 0;
3460 }
hualing chen041c4092020-04-05 15:11:50 +08003461 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003462 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3463 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003464 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003465 pthread_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003466 DVR_PB_DG(1, "unlock");
hualing chen87072a82020-03-12 16:20:12 +08003467 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003468 //send event here and pause
3469 DVR_Play_Notify_t notify;
3470 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003471 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003472 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003473 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08003474 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 +08003475 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003476 return DVR_SUCCESS;
3477 }
hualing chen2932d372020-04-29 13:44:00 +08003478 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003479 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003480 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003481 }
3482 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003483 _dvr_playback_fffb_replay(handle);
3484
3485 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003486 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003487
hualing chen5cbe1a62020-02-10 16:36:36 +08003488 return DVR_SUCCESS;
3489}
3490
hualing chen87072a82020-03-12 16:20:12 +08003491//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003492static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003493 //
3494 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003495
3496 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003497 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003498 return DVR_FAILURE;
3499 }
3500
hualing chen5cbe1a62020-02-10 16:36:36 +08003501 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003502 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003503 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003504 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003505 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003506 }
3507
3508 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003509 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003510 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003511 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003512 //start video and audio
3513
hualing chen2aba4022020-03-02 13:49:55 +08003514 am_tsplayer_video_params vparams;
3515 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003516 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08003517 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003518
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003519 memset(&vparams, 0, sizeof(vparams));
3520 memset(&aparams, 0, sizeof(aparams));
3521
hualing chen5cbe1a62020-02-10 16:36:36 +08003522 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08003523 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08003524 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003525 //start audio and video
3526 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003527 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08003528 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003529 return -1;
3530 }
3531
3532 if (VALID_PID(vparams.pid)) {
3533 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003534 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003535 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003536 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003537 }
hualing chen266b9502020-04-04 17:39:39 +08003538 else {
hualing chen2aba4022020-03-02 13:49:55 +08003539 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003540 }
hualing chen2aba4022020-03-02 13:49:55 +08003541 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003542 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003543 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003544 }
hualing chena540a7e2020-03-27 16:44:05 +08003545
3546 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08003547 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08003548 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003549 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003550 } else {
hualing chendf118dd2020-05-21 15:49:11 +08003551 if (VALID_PID(adparams.pid)) {
3552 player->has_ad_audio = DVR_TRUE;
3553 DVR_PB_DG(1, "start ad audio");
3554 AmTsPlayer_setADParams(player->handle, &adparams);
3555 AmTsPlayer_enableADMix(player->handle);
3556 }
hualing chen969fe7b2021-05-26 15:13:17 +08003557 if (VALID_PID(aparams.pid)) {
3558 player->has_audio = DVR_TRUE;
3559 DVR_PB_DG(1, "start audio");
3560 AmTsPlayer_setAudioParams(player->handle, &aparams);
3561 AmTsPlayer_startAudioDecoding(player->handle);
3562 }
hualing chendf118dd2020-05-21 15:49:11 +08003563
hualing chen7a56cba2020-04-14 14:09:27 +08003564 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08003565 AmTsPlayer_stopFast(player->handle);
3566 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3567 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3568 }
hualing chen2aba4022020-03-02 13:49:55 +08003569 player->cmd.last_cmd = player->cmd.cur_cmd;
3570 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003571 player->cmd.state = DVR_PLAYBACK_STATE_START;
3572 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08003573 return 0;
3574}
3575
3576
hualing chenb31a6c62020-01-13 17:27:00 +08003577/**\brief Set play speed
3578 * \param[in] handle playback handle
3579 * \param[in] speed playback speed
3580 * \retval DVR_SUCCESS On success
3581 * \return Error code
3582 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003583int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3584
3585 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003586
3587 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003588 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003589 return DVR_FAILURE;
3590 }
3591
hualing chena540a7e2020-03-27 16:44:05 +08003592 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003593 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003594 return DVR_FAILURE;
3595 }
hualing chenf00cdc82020-06-10 14:23:35 +08003596 if (speed.speed.speed == player->cmd.speed.speed.speed) {
3597 DVR_PB_DG(1, " func: eq speed [%d]", speed.speed.speed);
3598 return DVR_SUCCESS;
3599 }
hualing chen1679f812021-11-08 15:17:46 +08003600 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
3601
hualing chen5cbe1a62020-02-10 16:36:36 +08003602 pthread_mutex_lock(&player->lock);
3603 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3604 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3605 player->cmd.last_cmd = player->cmd.cur_cmd;
3606 }
hualing chene41f4372020-06-06 16:29:17 +08003607
hualing chen31140872020-03-25 12:29:26 +08003608 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003609 IS_KERNEL_SPEED(speed.speed.speed) ) {
3610 //case 1. not start play.only set speed
3611 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3612 //only set speed.and return;
3613 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3614 player->cmd.speed.speed = speed.speed;
3615 player->speed = (float)speed.speed.speed/(float)100;
3616 player->fffb_play = DVR_FALSE;
3617 pthread_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003618 DVR_PB_DG(1, "unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003619 return DVR_SUCCESS;
3620 }
3621 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003622 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3623 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003624 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003625 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3626 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003627 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003628 AmTsPlayer_stopFast(player->handle);
3629 pthread_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003630 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003631 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
hualing chen1679f812021-11-08 15:17:46 +08003632 DVR_PB_DG(1, "lock ---\r\n");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003633 pthread_mutex_lock(&player->lock);
3634 } else {
3635 //set play speed and if audio is start, stop audio.
3636 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003637 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003638 AmTsPlayer_stopAudioDecoding(player->handle);
3639 player->has_audio = DVR_FALSE;
3640 }
hualing chenb96aa2c2020-04-15 14:13:53 +08003641 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003642 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003643 }
hualing chenbcada022020-04-22 14:27:01 +08003644 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003645 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003646 player->cmd.speed.speed = speed.speed;
3647 player->speed = (float)speed.speed.speed/(float)100;
hualing chen1679f812021-11-08 15:17:46 +08003648 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen31140872020-03-25 12:29:26 +08003649 pthread_mutex_unlock(&player->lock);
3650 return DVR_SUCCESS;
3651 }
hualing chen31140872020-03-25 12:29:26 +08003652 //case 3 fffb mode
3653 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3654 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3655 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003656 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003657 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003658 player->cmd.speed.speed = speed.speed;
3659 player->speed = (float)speed.speed.speed/(float)100;
3660 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003661 player->fffb_play = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08003662 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen31140872020-03-25 12:29:26 +08003663 pthread_mutex_unlock(&player->lock);
3664 return DVR_SUCCESS;
3665 }
3666 }
3667 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003668 IS_KERNEL_SPEED(speed.speed.speed)) {
3669 //case 1. cur speed is kernel support speed,set kernel speed.
3670 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003671 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003672 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3673 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003674 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003675 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08003676 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003677 } else {
3678 //set play speed and if audio is start, stop audio.
3679 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003680 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003681 AmTsPlayer_stopAudioDecoding(player->handle);
3682 player->has_audio = DVR_FALSE;
3683 }
hualing chenf00cdc82020-06-10 14:23:35 +08003684 DVR_PB_DG(1, "start fast");
3685 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003686 }
hualing chena540a7e2020-03-27 16:44:05 +08003687 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003688 player->cmd.speed.speed = speed.speed;
3689 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003690 player->fffb_play = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08003691 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen31140872020-03-25 12:29:26 +08003692 pthread_mutex_unlock(&player->lock);
3693 return DVR_SUCCESS;
3694 }
3695 //case 2 fffb mode
3696 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3697 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3698 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003699 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003700 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003701 player->cmd.speed.speed = speed.speed;
3702 player->speed = (float)speed.speed.speed/(float)100;
3703 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08003704 player->fffb_play = DVR_FALSE;
hualing chen1679f812021-11-08 15:17:46 +08003705 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen31140872020-03-25 12:29:26 +08003706 pthread_mutex_unlock(&player->lock);
3707 return DVR_SUCCESS;
3708 }
hualing chen31140872020-03-25 12:29:26 +08003709 }
hualing chena540a7e2020-03-27 16:44:05 +08003710 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3711 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003712 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003713 } else {
hualing chen31140872020-03-25 12:29:26 +08003714 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003715 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3716 else
3717 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003718 player->fffb_play = DVR_TRUE;
3719 }
3720 DVR_Bool_t init_last_time = DVR_FALSE;
3721 if (player->speed > 0.0f && speed.speed.speed < 0) {
3722 init_last_time = DVR_TRUE;
3723 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3724 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003725 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003726 player->cmd.speed.mode = speed.mode;
3727 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003728 player->speed = (float)speed.speed.speed/(float)100;
3729 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003730 _dvr_init_fffb_t(handle);
3731 if (init_last_time == DVR_TRUE)
3732 player->last_send_time_id = UINT64_MAX;
3733
hualing chen87072a82020-03-12 16:20:12 +08003734 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003735 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3736 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003737 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003738 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003739 _dvr_playback_replay(handle, DVR_FALSE);
3740 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3741 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
3742 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08003743 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003744 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003745 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08003746 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003747 return DVR_SUCCESS;
3748}
hualing chen2932d372020-04-29 13:44:00 +08003749
hualing chenb31a6c62020-01-13 17:27:00 +08003750/**\brief Get playback status
3751 * \param[in] handle playback handle
3752 * \param[out] p_status playback status
3753 * \retval DVR_SUCCESS On success
3754 * \return Error code
3755 */
hualing chen2932d372020-04-29 13:44:00 +08003756static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3757 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003758//
3759 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003760 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003761 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003762 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003763 return DVR_FAILURE;
3764 }
hualing chen1679f812021-11-08 15:17:46 +08003765 if (is_lock ==DVR_TRUE) {
3766 DVR_PB_DG(1, "lock");
hualing chen2932d372020-04-29 13:44:00 +08003767 pthread_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003768 }
3769
hualing chen5cbe1a62020-02-10 16:36:36 +08003770 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003771 //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 +08003772 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3773 player->state == DVR_PLAYBACK_STATE_START) {
3774 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3775 }
hualing chen041c4092020-04-05 15:11:50 +08003776
hualing chencc91e1c2020-02-28 13:26:17 +08003777 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003778 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003779
3780 if (CONTROL_SPEED_ENABLE == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08003781 if (player->con_spe.ply_sta == 0) {
3782 DVR_PB_DG(1, "player dur[%u] sta[%u] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08003783 player->con_spe.ply_dur,
3784 player->con_spe.ply_sta,
3785 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003786 player->con_spe.ply_sta = p_status->time_cur;
3787 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3788 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
hualing chen7ea70a72021-09-09 11:25:13 +08003789 DVR_PB_DG(1, "player dur[%u] sta[%u] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003790 player->con_spe.ply_dur,
3791 player->con_spe.ply_sta,
3792 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003793 player->con_spe.ply_sta = p_status->time_cur;
3794 }
3795
3796 if (player->con_spe.sys_sta == 0) {
3797 player->con_spe.sys_sta = _dvr_time_getClock();
3798 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3799 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3800 player->con_spe.sys_sta = _dvr_time_getClock();
3801 }
3802 }
3803
hualing chen4b7c15d2020-04-07 16:13:48 +08003804 if (player->last_send_time_id == UINT64_MAX) {
3805 player->last_send_time_id = player->cur_segment_id;
3806 player->last_cur_time = p_status->time_cur;
3807 }
3808 if (player->last_send_time_id == player->cur_segment_id) {
3809 if (player->speed > 0.0f ) {
3810 //ff
3811 if (p_status->time_cur < player->last_cur_time ) {
hualing chen03fd4942021-07-15 15:56:41 +08003812 DVR_PB_DG(1, "get ff time error last[%d]cur[%d]diff[%d]",
3813 player->last_cur_time,
3814 p_status->time_cur,
3815 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08003816 p_status->time_cur = player->last_cur_time;
3817 } else {
3818 player->last_cur_time = p_status->time_cur;
3819 }
hualing chene41f4372020-06-06 16:29:17 +08003820 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003821 //fb
3822 if (p_status->time_cur > player->last_cur_time ) {
hualing chen03fd4942021-07-15 15:56:41 +08003823 DVR_PB_DG(1, "get fb time error last[%d]cur[%d]diff[%d]",
3824 player->last_cur_time,
3825 p_status->time_cur,
3826 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08003827 p_status->time_cur = player->last_cur_time;
3828 } else {
3829 player->last_cur_time = p_status->time_cur;
3830 }
3831 }
hualing chend241c7a2021-06-22 13:34:27 +08003832 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003833 player->last_cur_time = p_status->time_cur;
3834 }
hualing chen969fe7b2021-05-26 15:13:17 +08003835 player->last_send_time_id = segment_id;
3836 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003837
hualing chen5cbe1a62020-02-10 16:36:36 +08003838 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003839 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003840 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08003841 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 +08003842 _dvr_playback_state_toString(player->state),
3843 _dvr_playback_state_toString(p_status->state),
3844 p_status->time_cur, p_status->time_end,
3845 p_status->segment_id,player->play_flag,
3846 player->speed,
3847 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08003848 if (is_lock ==DVR_TRUE) {
3849 DVR_PB_DG(1, "unlock ---\r\n");
hualing chen2932d372020-04-29 13:44:00 +08003850 pthread_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003851 }
hualing chen2932d372020-04-29 13:44:00 +08003852 return DVR_SUCCESS;
3853}
3854
3855
3856/**\brief Get playback status
3857 * \param[in] handle playback handle
3858 * \param[out] p_status playback status
3859 * \retval DVR_SUCCESS On success
3860 * \return Error code
3861 */
3862int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3863 DVR_PlaybackStatus_t *p_status) {
3864//
3865 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3866
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003867 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3868
hualing chen2932d372020-04-29 13:44:00 +08003869 if (player == NULL) {
3870 DVR_PB_DG(1, "player is NULL");
3871 return DVR_FAILURE;
3872 }
hualing chen1679f812021-11-08 15:17:46 +08003873 DVR_PB_DG(1, "lock---");
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003874 pthread_mutex_lock(&player->lock);
3875 if (!player->has_video && !player->has_audio)
3876 p_status->time_cur = 0;
hualing chen1679f812021-11-08 15:17:46 +08003877 DVR_PB_DG(1, "unlock---");
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003878 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08003879
hualing chenb31a6c62020-01-13 17:27:00 +08003880 return DVR_SUCCESS;
3881}
3882
hualing chen040df222020-01-17 13:35:02 +08003883void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
3884 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003885 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
3886 DVR_PB_DG(1, "segment flag: %d", segment->flags);
3887 DVR_PB_DG(1, "segment location: [%s]", segment->location);
3888 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
3889 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
3890 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3891 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 +08003892 }
hualing chenb31a6c62020-01-13 17:27:00 +08003893}
3894
hualing chen5cbe1a62020-02-10 16:36:36 +08003895int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003896 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003897
hualing chena540a7e2020-03-27 16:44:05 +08003898 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003899 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003900 return DVR_FAILURE;
3901 }
3902
hualing chen040df222020-01-17 13:35:02 +08003903 DVR_PlaybackSegmentInfo_t *segment;
3904 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003905 {
hualing chen040df222020-01-17 13:35:02 +08003906 if (segment_id >= 0) {
3907 if (segment->segment_id == segment_id) {
3908 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003909 break;
3910 }
3911 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003912 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003913 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003914 }
3915 }
3916 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003917}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003918
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003919int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003920{
3921 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3922 DVR_RETURN_IF_FALSE(player);
3923 DVR_RETURN_IF_FALSE(func);
3924
hualing chen4b7c15d2020-04-07 16:13:48 +08003925 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003926 pthread_mutex_lock(&player->lock);
3927
3928 player->dec_func = func;
3929 player->dec_userdata = userdata;
3930
3931 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003932 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003933 return DVR_SUCCESS;
3934}
3935
3936int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3937{
3938 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3939 DVR_RETURN_IF_FALSE(player);
3940 DVR_RETURN_IF_FALSE(p_secure_buf);
3941 DVR_RETURN_IF_FALSE(len);
3942
hualing chen4b7c15d2020-04-07 16:13:48 +08003943 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003944 pthread_mutex_lock(&player->lock);
3945
3946 player->is_secure_mode = 1;
3947 player->secure_buffer = p_secure_buf;
3948 player->secure_buffer_size = len;
3949
3950 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003951 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003952 return DVR_SUCCESS;
3953}