blob: f17bad4a63cea8a9c2925cdd4f83017115213471 [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <poll.h>
11#include <errno.h>
12#include <signal.h>
13#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080014#include <errno.h>
hualing chen03fd4942021-07-15 15:56:41 +080015#include "dvr_utils.h"
16#include "dvr_types.h"
hualing chenb31a6c62020-01-13 17:27:00 +080017#include "dvr_playback.h"
Yahui Han1fbf3292021-11-08 18:17:19 +080018#include "am_crypt.h"
hualing chenb31a6c62020-01-13 17:27:00 +080019
Wentao MA96f68962022-06-15 19:45:35 +080020#define PB_LOG_TAG "libdvr-playback"
21#define DVR_PB_DEBUG(...) DVR_LOG_PRINT(LOG_LV_DEBUG, PB_LOG_TAG, __VA_ARGS__)
22#define DVR_PB_INFO(...) DVR_LOG_PRINT(LOG_LV_INFO, PB_LOG_TAG, __VA_ARGS__)
23#define DVR_PB_WARN(...) DVR_LOG_PRINT(LOG_LV_WARN, PB_LOG_TAG, __VA_ARGS__)
24#define DVR_PB_ERROR(...) DVR_LOG_PRINT(LOG_LV_ERROR, PB_LOG_TAG, __VA_ARGS__)
25#define DVR_PB_FATAL(...) DVR_LOG_PRINT(LOG_LV_FATAL, PB_LOG_TAG, __VA_ARGS__)
hualing chena540a7e2020-03-27 16:44:05 +080026
hualing chenb31a6c62020-01-13 17:27:00 +080027#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080028
hualing chend241c7a2021-06-22 13:34:27 +080029#define CONTROL_SPEED_ENABLE 0
hualing chena540a7e2020-03-27 16:44:05 +080030
31#define FF_SPEED (2.0f)
32#define FB_SPEED (-1.0f)
33#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080034#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080035
36#define IS_KERNEL_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_X1) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
37#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
38
hualing chenb31a6c62020-01-13 17:27:00 +080039
hualing chenb5cd42e2020-04-15 17:03:34 +080040#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080041#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080042//if tsplayer delay time < 200 and no data can read, we will pause
43#define MIN_TSPLAYER_DELAY_TIME (200)
44
hualing chen041c4092020-04-05 15:11:50 +080045#define MAX_CACHE_TIME (30000)
hualing chen43a89bc2022-01-19 14:31:20 +080046//used pcr to control avsync,default not used
47//#define AVSYNC_USED_PCR 1
hualing chena540a7e2020-03-27 16:44:05 +080048static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080049//
50static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chen99508642021-10-18 15:41:17 +080051static 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 +080052static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
53static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080054static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080055static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080056static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
57 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080058static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen7ea70a72021-09-09 11:25:13 +080059static uint32_t dvr_playback_calculate_last_valid_segment(
60 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos);
hualing chen87072a82020-03-12 16:20:12 +080061
hualing chenbcada022020-04-22 14:27:01 +080062
hualing chena5f03222021-12-02 11:22:35 +080063
hualing chenbcada022020-04-22 14:27:01 +080064static char* _cmd_toString(int cmd)
65{
66
67 char *string[DVR_PLAYBACK_CMD_NONE+1]={
68 "start",
69 "stop",
70 "vstart",
71 "astart",
72 "vstop",
73 "astop",
74 "vrestart",
75 "arestart",
76 "avrestart",
77 "vstopastart",
78 "astopvstart",
79 "vstoparestart",
80 "astopvrestart",
81 "vstartarestart",
82 "astartvrestart",
83 "pause",
84 "resume",
85 "seek",
86 "ff",
87 "fb",
88 "NONE"
89 };
90
91 if (cmd > DVR_PLAYBACK_CMD_NONE) {
92 return "unkown";
93 } else {
94 return string[cmd];
95 }
96}
97
98
hualing chen6d24aa92020-03-23 18:43:47 +080099static char* _dvr_playback_state_toString(int stat)
100{
101 char *string[DVR_PLAYBACK_STATE_FB+1]={
102 "start",
hualing chen6d24aa92020-03-23 18:43:47 +0800103 "stop",
hualing chen31140872020-03-25 12:29:26 +0800104 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +0800105 "ff",
106 "fb"
107 };
108
109 if (stat > DVR_PLAYBACK_STATE_FB) {
110 return "unkown";
111 } else {
112 return string[stat];
113 }
114}
hualing chena540a7e2020-03-27 16:44:05 +0800115
116static DVR_Bool_t _dvr_support_speed(int speed) {
117
118 DVR_Bool_t ret = DVR_FALSE;
119
120 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800121 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800122 case PLAYBACK_SPEED_FBX2:
123 case PLAYBACK_SPEED_FBX4:
124 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800125 case PLAYBACK_SPEED_FBX16:
126 case PLAYBACK_SPEED_FBX12:
127 case PLAYBACK_SPEED_FBX32:
128 case PLAYBACK_SPEED_FBX48:
129 case PLAYBACK_SPEED_FBX64:
130 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800131 case PLAYBACK_SPEED_S2:
132 case PLAYBACK_SPEED_S4:
133 case PLAYBACK_SPEED_S8:
134 case PLAYBACK_SPEED_X1:
135 case PLAYBACK_SPEED_X2:
136 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800137 case PLAYBACK_SPEED_X3:
138 case PLAYBACK_SPEED_X5:
139 case PLAYBACK_SPEED_X6:
140 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800141 case PLAYBACK_SPEED_X8:
142 case PLAYBACK_SPEED_X12:
143 case PLAYBACK_SPEED_X16:
144 case PLAYBACK_SPEED_X32:
145 case PLAYBACK_SPEED_X48:
146 case PLAYBACK_SPEED_X64:
147 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800148 ret = DVR_TRUE;
149 break;
150 default:
Wentao MA96f68962022-06-15 19:45:35 +0800151 DVR_PB_INFO("not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800152 break;
153 }
154 return ret;
155}
hualing chen6e4bfa52020-03-13 14:37:11 +0800156void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
157{
Wentao MA96f68962022-06-15 19:45:35 +0800158 DVR_PB_INFO("in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800159 DVR_Playback_t *player = NULL;
160 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800161 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800162 DVR_PB_INFO("play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800163 }
164 switch (event->type) {
165 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
166 {
Wentao MA96f68962022-06-15 19:45:35 +0800167 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800168 event->event.video_format.frame_width,
169 event->event.video_format.frame_height,
170 event->event.video_format.frame_rate);
171 break;
172 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800173 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
174 {
Wentao MA96f68962022-06-15 19:45:35 +0800175 DVR_PB_INFO("[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800176 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800177 break;
178 }
179 default:
180 break;
181 }
182}
hualing chen2aba4022020-03-02 13:49:55 +0800183void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
184{
hualing chen6e4bfa52020-03-13 14:37:11 +0800185 DVR_Playback_t *player = NULL;
186 if (user_data != NULL) {
187 player = (DVR_Playback_t *) user_data;
Wentao MA96f68962022-06-15 19:45:35 +0800188 DVR_PB_INFO("play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800189 }
hualing chen2aba4022020-03-02 13:49:55 +0800190 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800191 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
192 {
Wentao MA96f68962022-06-15 19:45:35 +0800193 DVR_PB_INFO("[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800194 event->event.video_format.frame_width,
195 event->event.video_format.frame_height,
196 event->event.video_format.frame_rate);
197 break;
198 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800199 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
200 {
Wentao MA96f68962022-06-15 19:45:35 +0800201 DVR_PB_INFO("[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chene41f4372020-06-06 16:29:17 +0800202 if (player->first_trans_ok == DVR_FALSE) {
203 player->first_trans_ok = DVR_TRUE;
204 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
205 }
hualing chen30423862021-04-16 14:39:12 +0800206 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800207 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800208 player->seek_pause = DVR_FALSE;
209 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800210 break;
211 }
hualing chen487ae6d2020-07-22 10:34:11 +0800212 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
Wentao MA96f68962022-06-15 19:45:35 +0800213 DVR_PB_INFO("[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
hualing chen487ae6d2020-07-22 10:34:11 +0800214 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
215 player->first_trans_ok = DVR_TRUE;
216 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
217 }
218 if (player != NULL && player->has_video == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +0800219 DVR_PB_INFO("[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
hualing chen487ae6d2020-07-22 10:34:11 +0800220 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800221 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800222 }
223 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800224 default:
Wentao MA96f68962022-06-15 19:45:35 +0800225 DVR_PB_INFO("[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800226 break;
227 }
228 if (player&&player->player_callback_func) {
Wentao MA96f68962022-06-15 19:45:35 +0800229 DVR_PB_INFO("player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800230 player->player_callback_func(player->player_callback_userdata, event);
231 } else if (player == NULL){
Wentao MA96f68962022-06-15 19:45:35 +0800232 DVR_PB_INFO("player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800233 } else {
Wentao MA96f68962022-06-15 19:45:35 +0800234 DVR_PB_INFO("player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800235 }
236}
hualing chencc91e1c2020-02-28 13:26:17 +0800237
hualing chen5cbe1a62020-02-10 16:36:36 +0800238//convert video and audio fmt
239static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
240 int format = 0;
241 if (is_audio == DVR_FALSE) {
242 //for video fmt
243 switch (fmt)
244 {
245 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800246 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800247 break;
248 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800249 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800250 break;
251 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800252 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800253 break;
254 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800255 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800256 break;
hualing chena540a7e2020-03-27 16:44:05 +0800257 case DVR_VIDEO_FORMAT_VP9:
258 format = AV_VIDEO_CODEC_VP9;
259 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800260 }
261 } else {
262 //for audio fmt
263 switch (fmt)
264 {
265 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800266 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800267 break;
268 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800269 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800270 break;
271 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800272 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800273 break;
274 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800275 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800276 break;
hualing chena540a7e2020-03-27 16:44:05 +0800277 case DVR_AUDIO_FORMAT_AAC:
278 format = AV_AUDIO_CODEC_AAC;
279 break;
280 case DVR_AUDIO_FORMAT_LATM:
281 format = AV_AUDIO_CODEC_LATM;
282 break;
283 case DVR_AUDIO_FORMAT_PCM:
284 format = AV_AUDIO_CODEC_PCM;
285 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800286 case DVR_AUDIO_FORMAT_AC4:
287 format = AV_AUDIO_CODEC_AC4;
288 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800289 }
290 }
291 return format;
292}
hualing chen040df222020-01-17 13:35:02 +0800293static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800294{
hualing chen040df222020-01-17 13:35:02 +0800295 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800296
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800297 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800298 return -1;
299
hualing chena540a7e2020-03-27 16:44:05 +0800300 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800301}
hualing chena540a7e2020-03-27 16:44:05 +0800302
hualing chen7ea70a72021-09-09 11:25:13 +0800303
304//get sys time sec
305static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800306{
307 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800308 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800309 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800310 s = (uint32_t)(ts.tv_sec);
Wentao MA96f68962022-06-15 19:45:35 +0800311 DVR_PB_INFO("n:%u", s);
hualing chen7ea70a72021-09-09 11:25:13 +0800312 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800313}
hualing chen86e7d482020-01-16 15:13:33 +0800314
hualing chen7ea70a72021-09-09 11:25:13 +0800315//get sys time ms
316static uint32_t _dvr_time_getClock(void)
317{
318 struct timespec ts;
319 uint32_t ms;
320 clock_gettime(CLOCK_REALTIME, &ts);
321 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
322 return ms;
323}
hualing chenb31a6c62020-01-13 17:27:00 +0800324
325//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800326static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800327{
hualing chen040df222020-01-17 13:35:02 +0800328 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800329
hualing chena540a7e2020-03-27 16:44:05 +0800330
331 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800332 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800333 return DVR_FAILURE;
334 }
335
hualing chen86e7d482020-01-16 15:13:33 +0800336 struct timespec ts;
337 clock_gettime(CLOCK_MONOTONIC, &ts);
338 //ms为毫秒,换算成秒
339 ts.tv_sec += ms/1000;
340 //在outtime的基础上,增加ms毫秒
341 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
342 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
343 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
344 //us的值有可能超过1秒,
345 ts.tv_sec += us / 1000000;
346 us = us % 1000000;
347 ts.tv_nsec = us * 1000;//换算成纳秒
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800348
349 int val = dvr_mutex_save(&player->lock);
350 pthread_cond_timedwait(&player->cond, &player->lock.lock, &ts);
351 dvr_mutex_restore(&player->lock, val);
hualing chen86e7d482020-01-16 15:13:33 +0800352 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800353}
hualing chen31140872020-03-25 12:29:26 +0800354//get tsplay delay time ms
355static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
356 DVR_Playback_t *player = (DVR_Playback_t *) handle;
357 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800358 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800359 DVR_PB_INFO("tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800360 return 0;
361 }
362 AmTsPlayer_getDelayTime(player->handle, &cache);
Wentao MA96f68962022-06-15 19:45:35 +0800363 DVR_PB_INFO("tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800364 return cache;
365}
hualing chenb31a6c62020-01-13 17:27:00 +0800366//send signal
hualing chen040df222020-01-17 13:35:02 +0800367static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800368{
hualing chen87072a82020-03-12 16:20:12 +0800369 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800370
371 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800372 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800373 return DVR_FAILURE;
374 }
Wentao MA96f68962022-06-15 19:45:35 +0800375 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800376 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800377 pthread_cond_signal(&player->cond);
Wentao MA96f68962022-06-15 19:45:35 +0800378 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +0800379 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800380 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800381}
382
hualing chen2932d372020-04-29 13:44:00 +0800383//send playback event, need check is need lock first
384static 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 +0800385
386 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800387
388 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800389 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800390 return DVR_FAILURE;
391 }
392
hualing chencc91e1c2020-02-28 13:26:17 +0800393 switch (evt) {
394 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800395 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800396 break;
397 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
398 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800399 DVR_PB_INFO("trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800400 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800401 break;
402 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
403 break;
404 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
405 break;
406 case DVR_PLAYBACK_EVENT_NO_KEY:
407 break;
408 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800409 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800410 DVR_PB_INFO("reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800411 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800412 break;
413 case DVR_PLAYBACK_EVENT_REACHED_END:
414 //GET STATE
Wentao MA96f68962022-06-15 19:45:35 +0800415 DVR_PB_INFO("reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800416 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800417 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800418 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800419 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800420 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800421 default:
422 break;
423 }
424 if (player->openParams.event_fn != NULL)
425 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800426 return DVR_SUCCESS;
427}
hualing chen2932d372020-04-29 13:44:00 +0800428static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800429{
430 DVR_Play_Notify_t notify;
431 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
432 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
433 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800434 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800435 return DVR_SUCCESS;
436}
437
hualing chen2932d372020-04-29 13:44:00 +0800438static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800439{
440 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800441
hualing chene3797f02021-01-13 14:53:28 +0800442 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800443 if (CONTROL_SPEED_ENABLE == 0)
444 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800445 }
hualing chena540a7e2020-03-27 16:44:05 +0800446 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800447 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800448 return DVR_FAILURE;
449 }
450
hualing chen03fd4942021-07-15 15:56:41 +0800451 if (player->send_time == 0) {
hualing chend241c7a2021-06-22 13:34:27 +0800452 if (CONTROL_SPEED_ENABLE == 0)
453 player->send_time = _dvr_time_getClock() + 500;
454 else
455 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800456 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen56c0a162022-01-27 17:01:50 +0800457 if ((player->send_time - _dvr_time_getClock()) > 1000) {
458 player->send_time = _dvr_time_getClock() + 500;
Wentao MA96f68962022-06-15 19:45:35 +0800459 DVR_PB_INFO("player send time occur system time changed!!!!!");
hualing chen56c0a162022-01-27 17:01:50 +0800460 } else {
461 return DVR_SUCCESS;
462 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800463 }
hualing chend241c7a2021-06-22 13:34:27 +0800464 if (CONTROL_SPEED_ENABLE == 0)
465 player->send_time = _dvr_time_getClock() + 500;
466 else
467 player->send_time = _dvr_time_getClock() + 20;
468
hualing chen6e4bfa52020-03-13 14:37:11 +0800469 DVR_Play_Notify_t notify;
470 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
471 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
472 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800473 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800474 return DVR_SUCCESS;
475}
476
hualing chencc91e1c2020-02-28 13:26:17 +0800477//check is ongoing segment
478static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
479
480 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800481 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800482
483 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800484 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800485 return DVR_FAILURE;
486 }
hualing chen87072a82020-03-12 16:20:12 +0800487 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800488 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800489 return DVR_FALSE;
490 }
hualing chencc91e1c2020-02-28 13:26:17 +0800491 return DVR_TRUE;
492}
hualing chen4b7c15d2020-04-07 16:13:48 +0800493
494
495static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
496 DVR_Playback_t *player = (DVR_Playback_t *) handle;
497 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800498 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800499 player->fffb_current = player->fffb_start;
500 //get segment current time pos
501 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800502 player->next_fffb_time = _dvr_time_getClock();
503
504 return DVR_SUCCESS;
505}
506
hualing chen2aba4022020-03-02 13:49:55 +0800507static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
508 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800509 player->fffb_start = _dvr_time_getClock();
Wentao MA96f68962022-06-15 19:45:35 +0800510 DVR_PB_INFO(" player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800511 player->fffb_current = player->fffb_start;
512 //get segment current time pos
513 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800514
hualing chen2aba4022020-03-02 13:49:55 +0800515 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800516 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800517 return DVR_SUCCESS;
518}
hualing chencc91e1c2020-02-28 13:26:17 +0800519//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800520static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
521
522 DVR_Playback_t *player = (DVR_Playback_t *) handle;
523 DVR_PlaybackSegmentInfo_t *segment;
524 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
525
hualing chena540a7e2020-03-27 16:44:05 +0800526 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800527 DVR_PB_INFO(" player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800528 return DVR_FAILURE;
529 }
530
hualing chen87072a82020-03-12 16:20:12 +0800531 int found = 0;
532 int found_eq_id = 0;
533 list_for_each_entry(segment, &player->segment_list, head)
534 {
535 if (player->segment_is_open == DVR_FALSE) {
536 //get first segment from list, case segment is not open
537 if (!IS_FB(player->speed))
538 found = 1;
539 } else if (segment->segment_id == segmentid) {
540 //find cur segment, we need get next one
541 found_eq_id = 1;
542 if (!IS_FB(player->speed)) {
543 found = 1;
544 continue;
545 } else {
546 //if is fb mode.we need used pre segment
547 if (pre_segment != NULL) {
548 found = 1;
549 } else {
550 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800551 DVR_PB_INFO("not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800552 return DVR_FAILURE;
553 }
554 }
555 }
556 if (found == 1) {
557 found = 2;
558 break;
559 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800560 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800561 }
562 if (found != 2) {
563 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800564 DVR_PB_INFO("not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800565 return DVR_FAILURE;
566 }
Wentao MA96f68962022-06-15 19:45:35 +0800567 DVR_PB_INFO("found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800568 return DVR_SUCCESS;
569}
570
571//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800572static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800573
hualing chen040df222020-01-17 13:35:02 +0800574 DVR_Playback_t *player = (DVR_Playback_t *) handle;
575 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800576 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800577 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800578 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800579 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800580 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800581 return DVR_FAILURE;
582 }
583
hualing chen03fd4942021-07-15 15:56:41 +0800584 if (IS_FB(player->speed)
585 && dvr_playback_check_limit(handle)) {
586 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
587 //case cur id < segment id
588 if (player->cur_segment_id <= segmentid) {
589 //expired ts data is player,return error
Wentao MA96f68962022-06-15 19:45:35 +0800590 DVR_PB_INFO("reach start segment ,return error");
hualing chen03fd4942021-07-15 15:56:41 +0800591 return DVR_FAILURE;
592 }
Wentao MA96f68962022-06-15 19:45:35 +0800593 DVR_PB_INFO("has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800594 }
595
hualing chen86e7d482020-01-16 15:13:33 +0800596 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800597 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800598
hualing chen040df222020-01-17 13:35:02 +0800599 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800600 {
hualing chencc91e1c2020-02-28 13:26:17 +0800601 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800602 //get first segment from list, case segment is not open
603 if (!IS_FB(player->speed))
604 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800605 } else if (segment->segment_id == player->cur_segment_id) {
606 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800607 found_eq_id = 1;
608 if (!IS_FB(player->speed)) {
609 found = 1;
610 continue;
611 } else {
612 //if is fb mode.we need used pre segment
613 if (pre_segment != NULL) {
614 found = 1;
615 } else {
616 //not find next id.
Wentao MA96f68962022-06-15 19:45:35 +0800617 DVR_PB_INFO("not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800618 return DVR_FAILURE;
619 }
620 }
hualing chen86e7d482020-01-16 15:13:33 +0800621 }
622 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800623 if (IS_FB(player->speed)) {
624 //used pre segment
625 segment = pre_segment;
626 }
hualing chencc91e1c2020-02-28 13:26:17 +0800627 //save segment info
628 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800629 if (player->r_handle)
630 player->last_segment_tatol = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800631 player->last_segment.segment_id = player->cur_segment.segment_id;
632 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800633 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
634 //pids
635 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
636
hualing chen5cbe1a62020-02-10 16:36:36 +0800637 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800638 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800639 player->cur_segment_id = segment->segment_id;
640 player->cur_segment.segment_id = segment->segment_id;
641 player->cur_segment.flags = segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800642 DVR_PB_INFO("set cur id cur flag[0x%x]segment->flags flag[0x%x] id [%lld]", player->cur_segment.flags, segment->flags, segment->segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800643 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800644 //pids
hualing chen040df222020-01-17 13:35:02 +0800645 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800646 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800647 break;
hualing chen86e7d482020-01-16 15:13:33 +0800648 }
hualing chen2aba4022020-03-02 13:49:55 +0800649 pre_segment = segment;
650 }
651 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
652 //used the last one segment to open
653 //get segment info
654 player->segment_is_open = DVR_TRUE;
655 player->cur_segment_id = pre_segment->segment_id;
656 player->cur_segment.segment_id = pre_segment->segment_id;
657 player->cur_segment.flags = pre_segment->flags;
Wentao MA96f68962022-06-15 19:45:35 +0800658 DVR_PB_INFO("set cur id fb last one cur flag[0x%x]segment->flags flag[0x%x] id [%lld]", player->cur_segment.flags, pre_segment->flags, pre_segment->segment_id);
hualing chen2aba4022020-03-02 13:49:55 +0800659 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
660 //pids
661 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
662 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800663 }
664 if (found != 2) {
665 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800666 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800667 }
668 return DVR_SUCCESS;
669}
hualing chen040df222020-01-17 13:35:02 +0800670//open next segment to play,if reach list end return errro.
671static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800672{
hualing chen040df222020-01-17 13:35:02 +0800673 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800674 Segment_OpenParams_t params;
675 int ret = DVR_SUCCESS;
676
hualing chena540a7e2020-03-27 16:44:05 +0800677 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800678 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800679 return DVR_FAILURE;
680 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800681 pthread_mutex_lock(&player->segment_lock);
hualing chen926a8ec2021-12-20 20:38:24 +0800682retry:
hualing chena540a7e2020-03-27 16:44:05 +0800683 ret = _dvr_get_next_segmentId(handle);
684 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800685 DVR_PB_INFO("not found segment info");
hualing chen4b7c15d2020-04-07 16:13:48 +0800686 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800687 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800688 }
689
690 if (player->r_handle != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800691 DVR_PB_INFO("close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800692 segment_close(player->r_handle);
693 player->r_handle = NULL;
694 }
695
696 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800697 //cp chur segment path to location
698 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800699 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800700 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800701 DVR_PB_INFO("open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen4b7c15d2020-04-07 16:13:48 +0800702
hualing chen86e7d482020-01-16 15:13:33 +0800703 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800704 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800705 DVR_PB_INFO("open segment error");
hualing chen926a8ec2021-12-20 20:38:24 +0800706 goto retry;
hualing chen4b7c15d2020-04-07 16:13:48 +0800707 }
Wentao MA01de0e62022-01-10 18:48:23 +0800708 // Keep the start segment_id when the first segment_open is called during a playback
709 if (player->first_start_id == UINT64_MAX) {
710 player->first_start_id = player->cur_segment.segment_id;
711 }
hualing chen87072a82020-03-12 16:20:12 +0800712 pthread_mutex_unlock(&player->segment_lock);
713 int total = _dvr_get_end_time( handle);
714 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800715 if (IS_FB(player->speed)) {
716 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800717 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800718 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +0800719 DVR_PB_INFO("seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800720 }
hualing chen87072a82020-03-12 16:20:12 +0800721 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800722 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +0800723 DVR_PB_INFO("next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800724 return ret;
725}
726
hualing chen5cbe1a62020-02-10 16:36:36 +0800727//open next segment to play,if reach list end return errro.
728static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
729{
730 DVR_Playback_t *player = (DVR_Playback_t *) handle;
731 Segment_OpenParams_t params;
732 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800733 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800734 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800735 return DVR_FAILURE;
736 }
hualing chencc91e1c2020-02-28 13:26:17 +0800737 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800738 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800739 }
hualing chencc91e1c2020-02-28 13:26:17 +0800740 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800741 if (id < 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800742 DVR_PB_INFO("not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800743 return DVR_FAILURE;
744 }
Wentao MA96f68962022-06-15 19:45:35 +0800745 DVR_PB_INFO("start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800746 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800747
748 DVR_PlaybackSegmentInfo_t *segment;
749
750 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800751
hualing chen5cbe1a62020-02-10 16:36:36 +0800752 list_for_each_entry(segment, &player->segment_list, head)
753 {
Wentao MA96f68962022-06-15 19:45:35 +0800754 DVR_PB_INFO("see 1 location [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800755 if (segment->segment_id == segment_id) {
756 found = 1;
757 }
758 if (found == 1) {
Wentao MA96f68962022-06-15 19:45:35 +0800759 DVR_PB_INFO("found [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800760 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800761 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800762 player->cur_segment_id = segment->segment_id;
763 player->cur_segment.segment_id = segment->segment_id;
764 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800765 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800766 //pids
767 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +0800768 DVR_PB_INFO("cur found location [%s]id[%lld]flag[%x]", player->cur_segment.location, player->cur_segment.segment_id,player->cur_segment.flags);
hualing chencc91e1c2020-02-28 13:26:17 +0800769 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800770 }
771 }
hualing chencc91e1c2020-02-28 13:26:17 +0800772 if (found == 0) {
Wentao MA96f68962022-06-15 19:45:35 +0800773 DVR_PB_INFO("not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800774 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800775 return DVR_FAILURE;
776 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800777 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800778 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800779 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800780 params.segment_id = (uint64_t)player->cur_segment.segment_id;
781 params.mode = SEGMENT_MODE_READ;
Wentao MA96f68962022-06-15 19:45:35 +0800782 DVR_PB_INFO("open segment location[%s][%lld]cur flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen2aba4022020-03-02 13:49:55 +0800783 if (player->r_handle != NULL) {
784 segment_close(player->r_handle);
785 player->r_handle = NULL;
786 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800787 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800788 if (ret == DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +0800789 DVR_PB_INFO("segment opne error");
hualing chen4b7c15d2020-04-07 16:13:48 +0800790 }
Wentao MA01de0e62022-01-10 18:48:23 +0800791 // Keep the start segment_id when the first segment_open is called during a playback
792 if (player->first_start_id == UINT64_MAX) {
793 player->first_start_id = player->cur_segment.segment_id;
794 }
hualing chen2aba4022020-03-02 13:49:55 +0800795 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800796 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800797
Wentao MA96f68962022-06-15 19:45:35 +0800798 DVR_PB_INFO("player->dur [%d]cur id [%lld]cur flag [0x%x]\r\n", player->dur,player->cur_segment.segment_id, player->cur_segment.flags);
hualing chen5cbe1a62020-02-10 16:36:36 +0800799 return ret;
800}
801
802
803//get play info by segment id
804static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
805 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800806 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800807 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800808
809 DVR_Playback_t *player = (DVR_Playback_t *) handle;
810 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800811 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800812 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800813 return DVR_FAILURE;
814 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800815
816 int found = 0;
817
818 list_for_each_entry(segment, &player->segment_list, head)
819 {
hualing chen87072a82020-03-12 16:20:12 +0800820 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800821 //get first segment from list
822 found = 1;
823 }
824 if (segment->segment_id == segment_id) {
825 found = 1;
826 }
827 if (found == 1) {
828 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800829 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800830 player->cur_segment_id = segment->segment_id;
Wentao MA96f68962022-06-15 19:45:35 +0800831 DVR_PB_INFO("get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800832 player->cur_segment.segment_id = segment->segment_id;
833 player->cur_segment.flags = segment->flags;
834 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800835 player->cur_segment.pids.video.pid = segment->pids.video.pid;
836 player->cur_segment.pids.video.format = segment->pids.video.format;
837 player->cur_segment.pids.video.type = segment->pids.video.type;
838 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
839 player->cur_segment.pids.audio.format = segment->pids.audio.format;
840 player->cur_segment.pids.audio.type = segment->pids.audio.type;
841 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
842 player->cur_segment.pids.ad.format = segment->pids.ad.format;
843 player->cur_segment.pids.ad.type = segment->pids.ad.type;
844 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800845 //
hualing chen2aba4022020-03-02 13:49:55 +0800846 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800847 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800848 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800849 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800850 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
851 adparam->pid =segment->pids.ad.pid;
Wentao MA96f68962022-06-15 19:45:35 +0800852 DVR_PB_INFO("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 +0800853 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800854 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800855 }
856 }
hualing chencc91e1c2020-02-28 13:26:17 +0800857 if (found != 2) {
858 //list is null or reache list end
Wentao MA96f68962022-06-15 19:45:35 +0800859 DVR_PB_INFO("get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800860 return DVR_FAILURE;
861 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800862
863 return DVR_SUCCESS;
864}
hualing chencc91e1c2020-02-28 13:26:17 +0800865static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
866 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800867 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800868 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800869 return DVR_FAILURE;
870 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800871
hualing chencc91e1c2020-02-28 13:26:17 +0800872 //compare cur segment
873 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
874 {
875 //check video pids, stop or restart
hualing chen99508642021-10-18 15:41:17 +0800876 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800877 //check sub audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800878 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800879 //check audio pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800880 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 1);
Wentao MA96f68962022-06-15 19:45:35 +0800881 DVR_PB_INFO(":last apid: %d set apid: %d", player->last_segment.pids.audio.pid,player->cur_segment.pids.audio.pid);
hualing chencc91e1c2020-02-28 13:26:17 +0800882 //check pcr pids stop or restart
hualing chen99508642021-10-18 15:41:17 +0800883 _do_check_pid_info(handle, player->last_segment.pids, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800884 }
hualing chena540a7e2020-03-27 16:44:05 +0800885 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800886}
hualing chen5cbe1a62020-02-10 16:36:36 +0800887
hualing chend241c7a2021-06-22 13:34:27 +0800888static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
889{
890 DVR_Playback_t *player = (DVR_Playback_t *) handle;
891 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800892 DVR_PB_INFO("player is NULL");
hualing chend241c7a2021-06-22 13:34:27 +0800893 return DVR_TRUE;
894 }
895 char buf[10];
896 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
Wentao MA96f68962022-06-15 19:45:35 +0800897 DVR_PB_INFO("player get prop[%d][%s]", atoi(buf), buf);
hualing chend241c7a2021-06-22 13:34:27 +0800898
899 if (atoi(buf) != 1) {
900 //return DVR_TRUE;
901 }
902
Wentao MA96f68962022-06-15 19:45:35 +0800903 DVR_PB_INFO(":play speed: %f ply dur: %u sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800904 player->speed,
905 player->con_spe.ply_dur,
906 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800907
908 if (player->speed != 1.0f)
909 return DVR_TRUE;
910
911 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800912 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800913 return DVR_FALSE;
914
915 return DVR_TRUE;
916}
917
hualing chencc91e1c2020-02-28 13:26:17 +0800918static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
919{
920 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800921 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800922 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800923 return DVR_FAILURE;
924 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800925 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
Wentao MA96f68962022-06-15 19:45:35 +0800926 DVR_PB_INFO("vendor is amlogic. no used segment flag to hide or show av");
hualing chenf43b8ba2020-07-28 13:11:42 +0800927 return DVR_SUCCESS;
928 }
Wentao MA96f68962022-06-15 19:45:35 +0800929 DVR_PB_INFO("flag[0x%x]id[%lld]last[0x%x][%llu]",
hualing chen03fd4942021-07-15 15:56:41 +0800930 player->cur_segment.flags,
931 player->cur_segment.segment_id,
932 player->last_segment.flags,
933 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800934 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
935 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800936 //enable display
Wentao MA96f68962022-06-15 19:45:35 +0800937 DVR_PB_INFO("unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800938 AmTsPlayer_showVideo(player->handle);
939 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800940 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
941 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800942 //disable display
Wentao MA96f68962022-06-15 19:45:35 +0800943 DVR_PB_INFO("mute");
hualing chen2aba4022020-03-02 13:49:55 +0800944 AmTsPlayer_hideVideo(player->handle);
945 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800946 }
947 return DVR_SUCCESS;
948}
hualing chene3797f02021-01-13 14:53:28 +0800949/*
950if decodec sucess first time.
951sucess: return true
952fail: return false
953*/
hualing chena540a7e2020-03-27 16:44:05 +0800954static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
955 DVR_Playback_t *player = (DVR_Playback_t *) handle;
956 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +0800957 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800958 return DVR_TRUE;
959 }
hualing chene3797f02021-01-13 14:53:28 +0800960 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800961 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800962 } else {
963 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800964 }
965}
hualing chen86e7d482020-01-16 15:13:33 +0800966static void* _dvr_playback_thread(void *arg)
967{
hualing chen040df222020-01-17 13:35:02 +0800968 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800969 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800970 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800971 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800972 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800973
hualing chen39628212020-05-14 10:35:13 +0800974 #define MAX_REACHEND_TIMEOUT (3000)
975 int reach_end_timeout = 0;//ms
976 int cache_time = 0;
hualing chenb9a1a2c2021-12-31 11:27:59 +0800977 int timeout = 200;//ms
hualing chen40dd5462021-11-26 19:56:20 +0800978 int check_no_data_time = 4;
hualing chen2aba4022020-03-02 13:49:55 +0800979 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800980 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800981 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800982 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
hualing chen40dd5462021-11-26 19:56:20 +0800983 int first_write = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800984 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800985 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800986 DVR_Bool_t goto_rewrite = DVR_FALSE;
yinming ding0ce94922021-09-08 15:09:15 +0800987 char prop_buf[10];
988
989 memset(prop_buf, 0 ,sizeof(prop_buf));
990 dvr_prop_read("vendor.tv.libdvr.writetm", prop_buf, sizeof(prop_buf));
Wentao MA96f68962022-06-15 19:45:35 +0800991 DVR_PB_INFO("---vendor.tv.libdvr.writetm get prop[%d][%s]block_size[%d]", atoi(prop_buf), prop_buf, player->openParams.block_size);
yinming ding0ce94922021-09-08 15:09:15 +0800992 if (atoi(prop_buf) > 0)
993 write_timeout_ms = atoi(prop_buf);
hualing chen03fd4942021-07-15 15:56:41 +0800994
hualing chen56c0a162022-01-27 17:01:50 +0800995
996 memset(prop_buf, 0 ,sizeof(prop_buf));
997 dvr_prop_read("vendor.tv.libdvr.waittm", prop_buf, sizeof(prop_buf));
Wentao MA96f68962022-06-15 19:45:35 +0800998 DVR_PB_INFO("---vendor.tv.libdvr.waittm get prop[%d][%s]block_size[%d]", atoi(prop_buf), prop_buf, player->openParams.block_size);
hualing chen56c0a162022-01-27 17:01:50 +0800999 if (atoi(prop_buf) > 0)
1000 timeout = atoi(prop_buf);
1001
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001002 if (player->is_secure_mode) {
1003 if (dec_buf_size > player->secure_buffer_size) {
Wentao MA96f68962022-06-15 19:45:35 +08001004 DVR_PB_INFO("playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001005 return NULL;
1006 }
1007 }
hualing chen86e7d482020-01-16 15:13:33 +08001008 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001009 if (!buf) {
Wentao MA96f68962022-06-15 19:45:35 +08001010 DVR_PB_INFO("Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001011 return NULL;
1012 }
hualing chen2aba4022020-03-02 13:49:55 +08001013 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1014 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001015
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001016 dec_bufs.buf_data = malloc(dec_buf_size);
1017 if (!dec_bufs.buf_data) {
Wentao MA96f68962022-06-15 19:45:35 +08001018 DVR_PB_INFO("Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +08001019 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001020 return NULL;
1021 }
1022 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1023 dec_bufs.buf_size = dec_buf_size;
1024
hualing chencc91e1c2020-02-28 13:26:17 +08001025 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001026 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
1027 }
hualing chen86e7d482020-01-16 15:13:33 +08001028
hualing chen86e7d482020-01-16 15:13:33 +08001029 if (ret != DVR_SUCCESS) {
1030 if (buf != NULL) {
1031 free(buf);
1032 buf = NULL;
1033 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001034 free(dec_bufs.buf_data);
Wentao MA96f68962022-06-15 19:45:35 +08001035 DVR_PB_INFO("get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001036 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001037 }
Wentao MA96f68962022-06-15 19:45:35 +08001038 DVR_PB_INFO("--player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001039 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001040 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1041 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1042 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1043 player->first_trans_ok = DVR_TRUE;
1044 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1045 }
hualing chencc91e1c2020-02-28 13:26:17 +08001046 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001047 //set video show
1048 AmTsPlayer_showVideo(player->handle);
hualing chen40dd5462021-11-26 19:56:20 +08001049 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON)
1050 check_no_data_time = 8;
hualing chen86e7d482020-01-16 15:13:33 +08001051 int trick_stat = 0;
1052 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001053
hualing chen86e7d482020-01-16 15:13:33 +08001054 //check trick stat
Wentao MA96f68962022-06-15 19:45:35 +08001055 //DVR_PB_INFO("lock check_no_data_time:%d", check_no_data_time);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001056 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001057
hualing chen2aba4022020-03-02 13:49:55 +08001058 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1059 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001060 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001061 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001062 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001063 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001064 {
hualing chen2aba4022020-03-02 13:49:55 +08001065 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1066 if (trick_stat > 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001067 DVR_PB_INFO("trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001068 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001069 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 +08001070 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001071 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001072 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001073 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
1074 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +08001075 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
1076 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
Wentao MA96f68962022-06-15 19:45:35 +08001077 DVR_PB_INFO("pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
hualing chen03fd4942021-07-15 15:56:41 +08001078 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001079 //need change to pause state
1080 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1081 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +08001082 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001083 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001084 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001085 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001086 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001087 AmTsPlayer_pauseVideoDecoding(player->handle);
1088 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001089 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001090 DVR_PB_INFO("clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001091 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001092 }
1093 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1094 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001095 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001096 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001097 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001098 DVR_PB_INFO("fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001099 player->speed,
1100 player->fffb_current,
1101 _dvr_time_getClock(),
1102 _dvr_playback_state_toString(player->state),
1103 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001104 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001105 //dvr_mutex_unlock(&player->lock);
1106 //dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001107 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001108 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001109 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001110 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001111 } else if (_dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001112 DVR_PB_INFO("fffb timeout-to pause video---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001113 player->speed,
1114 player->fffb_current,
1115 _dvr_time_getClock(),
1116 _dvr_playback_state_toString(player->state),
1117 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001118 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001119 //dvr_mutex_unlock(&player->lock);
1120 //dvr_mutex_lock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001121 AmTsPlayer_pauseVideoDecoding(player->handle);
1122 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001123 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001124 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001125 continue;
hualing chen2aba4022020-03-02 13:49:55 +08001126 }
Wentao MA96f68962022-06-15 19:45:35 +08001127 DVR_PB_INFO("fffb play-------speed[%f][%d][%d][%s][%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001128 player->speed,
1129 goto_rewrite,
1130 real_read,
1131 _dvr_playback_state_toString(player->state),
1132 player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08001133 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001134 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001135 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1136 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001137 DVR_PB_INFO("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001138 dvr_mutex_unlock(&player->lock);
1139
hualing chen2aba4022020-03-02 13:49:55 +08001140 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001141 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001142 dvr_mutex_lock(&player->lock);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001143 player->fffb_play = DVR_FALSE;
hualing chen1ffd85b2021-08-16 15:18:43 +08001144 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1145 //on pause state,user seek to new pos,we need pause and wait
1146 //user to resume
Wentao MA96f68962022-06-15 19:45:35 +08001147 DVR_PB_INFO("pause, when got first frame event when user seek end");
hualing chen1ffd85b2021-08-16 15:18:43 +08001148 player->first_frame = 0;
1149 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1150 AmTsPlayer_pauseVideoDecoding(player->handle);
1151 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001152 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001153 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001154 //for first into fffb when reset speed
1155 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1156 _dvr_time_getClock() < player->next_fffb_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001157 DVR_PB_INFO("fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001158 player->speed,
1159 player->fffb_current,
1160 _dvr_time_getClock(),
1161 _dvr_playback_state_toString(player->state),
1162 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001163 //used timeout wait need lock first,so we unlock and lock
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001164 //dvr_mutex_unlock(&player->lock);
1165 //dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001166 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001167 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001168 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001169 continue;
1170 }
Wentao MA96f68962022-06-15 19:45:35 +08001171 DVR_PB_INFO("fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001172 player->speed,
1173 goto_rewrite,
1174 real_read,
1175 _dvr_playback_state_toString(player->state),
1176 player->cmd.cur_cmd,
1177 player->fffb_play);
Wentao MA96f68962022-06-15 19:45:35 +08001178 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001179 dvr_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001180 goto_rewrite = DVR_FALSE;
1181 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001182 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001183 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1184 player->first_frame = 0;
1185 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001186 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001187 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001188 }
hualing chenb31a6c62020-01-13 17:27:00 +08001189 }
hualing chen86e7d482020-01-16 15:13:33 +08001190
hualing chen30423862021-04-16 14:39:12 +08001191 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1192 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001193 //check is need send time send end
Wentao MA96f68962022-06-15 19:45:35 +08001194 DVR_PB_INFO("pause, continue");
1195 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001196 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001197 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001198 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001199 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001200 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001201 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08001202 continue;
1203 }
hualing chen266b9502020-04-04 17:39:39 +08001204 //when seek action is done. we need drop write timeout data.
1205 if (player->drop_ts == DVR_TRUE) {
1206 goto_rewrite = DVR_FALSE;
1207 real_read = 0;
1208 player->drop_ts = DVR_FALSE;
1209 }
hualing chen2aba4022020-03-02 13:49:55 +08001210 if (goto_rewrite == DVR_TRUE) {
1211 goto_rewrite = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001212 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001213 dvr_mutex_unlock(&player->lock);
hualing chen3bcf3be2021-12-22 20:15:01 +08001214 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Wentao MA96f68962022-06-15 19:45:35 +08001215 //DVR_PB_INFO("rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001216 goto rewrite;
1217 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001218 //.check is need send time send end
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001219 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001220 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001221 dvr_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001222 pthread_mutex_lock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001223 //DVR_PB_INFO("start read");
hualing chen87072a82020-03-12 16:20:12 +08001224 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001225 real_read = real_read + read;
1226 player->ts_cache_len = real_read;
Wentao MA96f68962022-06-15 19:45:35 +08001227 //DVR_PB_INFO("start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001228 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001229 //DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001230 dvr_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001231 if (read < 0 && errno == EIO) {
1232 //EIO ERROR, EXIT THRAD
Wentao MA96f68962022-06-15 19:45:35 +08001233 DVR_PB_INFO("read error.EIO error, exit thread");
hualing chenb5cd42e2020-04-15 17:03:34 +08001234 DVR_Play_Notify_t notify;
1235 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1236 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001237 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001238 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001239 goto end;
1240 } else if (read < 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001241 DVR_PB_INFO("read error.:%d EIO:%d", errno, EIO);
hualing chenb5cd42e2020-04-15 17:03:34 +08001242 }
hualing chen87072a82020-03-12 16:20:12 +08001243 //if on fb mode and read file end , we need calculate pos to retry read.
1244 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08001245 DVR_PB_INFO("recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
hualing chen03fd4942021-07-15 15:56:41 +08001246 read,
1247 real_read,
1248 buf_len,
1249 player->speed,
1250 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001251 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
Wentao MA96f68962022-06-15 19:45:35 +08001252 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001253 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001254 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Wentao MA96f68962022-06-15 19:45:35 +08001255 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001256 dvr_mutex_unlock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001257 continue;
1258 }
Wentao MA96f68962022-06-15 19:45:35 +08001259 //DVR_PB_INFO("read ts [%d]buf_len[%d]speed[%f]real_read:%d", read, buf_len, player->speed, real_read);
hualing chen86e7d482020-01-16 15:13:33 +08001260 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001261 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001262 #define MIN_CACHE_TIME (3000)
1263 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001264 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001265 if (_cache_time > MIN_CACHE_TIME) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001266 //dvr_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001267 /*if cache time > 20s , we think get time is error,*/
1268 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
Wentao MA96f68962022-06-15 19:45:35 +08001269 DVR_PB_INFO("read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1270 DVR_PB_INFO("read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1271 DVR_PB_INFO("read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
hualing chene3797f02021-01-13 14:53:28 +08001272 }
hualing chen1679f812021-11-08 15:17:46 +08001273 //_dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001274 //dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001275 // DVR_PB_INFO("read end but cache time is %d > %d, to sleep end and continue", _cache_time, MIN_CACHE_TIME);
hualing chene41f4372020-06-06 16:29:17 +08001276 //continue;
1277 }
hualing chen969fe7b2021-05-26 15:13:17 +08001278
hualing chen040df222020-01-17 13:35:02 +08001279 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001280 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001281 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001282
1283 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chen1679f812021-11-08 15:17:46 +08001284
1285 if (ret != DVR_SUCCESS && delay < MIN_TSPLAYER_DELAY_TIME) {
1286 player->noData++;
Wentao MA96f68962022-06-15 19:45:35 +08001287 DVR_PB_INFO("playback nodata[%d]", player->noData);
hualing chen40dd5462021-11-26 19:56:20 +08001288 if (player->noData == check_no_data_time) {
Wentao MA96f68962022-06-15 19:45:35 +08001289 DVR_PB_INFO("playback send nodata event nodata[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001290 //send event here and pause
1291 DVR_Play_Notify_t notify;
1292 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1293 notify.event = DVR_PLAYBACK_EVENT_NODATA;
Wentao MA96f68962022-06-15 19:45:35 +08001294 DVR_PB_INFO("send event DVR_PLAYBACK_EVENT_NODATA--");
hualing chene3797f02021-01-13 14:53:28 +08001295 //get play statue not here
1296 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1297 }
1298 }
1299 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001300 if ((ret != DVR_SUCCESS &&
hualing chen03fd4942021-07-15 15:56:41 +08001301 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001302 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001303 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001304 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1305 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001306 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001307 DVR_Play_Notify_t notify;
1308 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1309 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1310 //get play statue not here
1311 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001312 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001313 //continue,timeshift mode, when read end,need wait cur recording segment
Wentao MA96f68962022-06-15 19:45:35 +08001314 DVR_PB_INFO("playback is send end delay:[%d]reach_end_timeout[%d]ms", delay, reach_end_timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001315 dvr_mutex_lock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001316 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001317 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08001318 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001319 } else if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001320 DVR_PB_INFO("delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001321 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08001322 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001323 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08001324 delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chena540a7e2020-03-27 16:44:05 +08001325 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001326 if (delay < cache_time) {
1327 //delay time is changed and then has data to play, so not start timeout
hualing chen1679f812021-11-08 15:17:46 +08001328 reach_end_timeout = 0;
hualing chen39628212020-05-14 10:35:13 +08001329 } else {
1330 reach_end_timeout = reach_end_timeout + timeout;
1331 }
1332 cache_time = delay;
hualing chen31140872020-03-25 12:29:26 +08001333 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001334 }
hualing chen39628212020-05-14 10:35:13 +08001335 reach_end_timeout = 0;
1336 cache_time = 0;
hualing chen2932d372020-04-29 13:44:00 +08001337 //change next segment success case
1338 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001339 dvr_mutex_lock(&player->lock);
hualing chen40dd5462021-11-26 19:56:20 +08001340 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001341 DVR_PB_INFO("_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001342 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1343 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001344 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001345 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001346 real_read = real_read + read;
1347 player->ts_cache_len = real_read;
1348 pthread_mutex_unlock(&player->segment_lock);
1349
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001350 dvr_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001351 }//read len 0 check end
hualing chen40dd5462021-11-26 19:56:20 +08001352 if (player->noData >= check_no_data_time) {
hualing chene3797f02021-01-13 14:53:28 +08001353 player->noData = 0;
Wentao MA96f68962022-06-15 19:45:35 +08001354 DVR_PB_INFO("playback send data event resume[%d]", player->noData);
hualing chene3797f02021-01-13 14:53:28 +08001355 //send event here and pause
1356 DVR_Play_Notify_t notify;
1357 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1358 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
Wentao MA96f68962022-06-15 19:45:35 +08001359 DVR_PB_INFO("----send event DVR_PLAYBACK_EVENT_DATARESUME");
hualing chene3797f02021-01-13 14:53:28 +08001360 //get play statue not here
1361 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001362 }
hualing chen39628212020-05-14 10:35:13 +08001363 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001364 //real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001365 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001366 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001367
hualing chena540a7e2020-03-27 16:44:05 +08001368 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001369 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001370 DVR_PB_INFO("error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001371 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001372 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001373 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001374 }
hualing chen266b9502020-04-04 17:39:39 +08001375 //if need write whole block size, we need check read buf len is eq block size.
1376 if (b_writed_whole_block == DVR_TRUE) {
1377 //buf_len is block size value.
1378 if (real_read < buf_len) {
1379 //coontinue to read data from file
Wentao MA96f68962022-06-15 19:45:35 +08001380 DVR_PB_INFO("read buf len[%d] is < block size [%d]", real_read, buf_len);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001381 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001382 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1383 dvr_mutex_unlock(&player->lock);
1384 DVR_PB_INFO("read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001385 continue;
1386 } else if (real_read > buf_len) {
Wentao MA96f68962022-06-15 19:45:35 +08001387 DVR_PB_INFO("read buf len[%d] is > block size [%d],this error occur", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001388 }
1389 }
1390
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001391 //if (player->is_secure_mode && player->dec_func) {
1392 if (player->dec_func) {
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001393 DVR_CryptoParams_t crypto_params;
1394
1395 memset(&crypto_params, 0, sizeof(crypto_params));
1396 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1397 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1398 crypto_params.segment_id = player->cur_segment.segment_id;
hualing chen1f26ffa2020-11-03 10:39:20 +08001399 crypto_params.offset = segment_tell_position(player->r_handle) - wbufs.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001400 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
Wentao MA96f68962022-06-15 19:45:35 +08001401 DVR_PB_INFO("offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001402 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1403 crypto_params.input_buffer.addr = (size_t)buf;
1404 crypto_params.input_buffer.size = real_read;
1405
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001406 if (player->is_secure_mode) {
1407 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1408 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1409 crypto_params.output_buffer.size = dec_buf_size;
1410 ret = player->dec_func(&crypto_params, player->dec_userdata);
1411 wbufs.buf_data = player->secure_buffer;
1412 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
1413 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001414 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001415 }
1416 wbufs.buf_size = crypto_params.output_size;
1417 } else { // only for NAGRA
1418 crypto_params.output_buffer.type = crypto_params.input_buffer.type;
1419 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1420 crypto_params.output_buffer.size = crypto_params.input_buffer.size;
1421 ret = player->dec_func(&crypto_params, player->dec_userdata);
1422 wbufs.buf_data = (uint8_t*)crypto_params.output_buffer.addr;
1423 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1424 if (ret != DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08001425 DVR_PB_INFO("decrypt failed");
weishi.zhang0a6d5c82021-12-13 14:05:31 +08001426 }
1427 wbufs.buf_size = crypto_params.output_buffer.size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001428 }
Yahui Han1fbf3292021-11-08 18:17:19 +08001429 } else if (player->cryptor) {
Yahui Han63b23b42021-12-07 15:37:46 +08001430 int len = real_read;
Yahui Han1fbf3292021-11-08 18:17:19 +08001431 am_crypt_des_crypt(player->cryptor, dec_bufs.buf_data, buf, &len, 1);
1432 wbufs.buf_data = dec_bufs.buf_data;
1433 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
1434 wbufs.buf_size = len;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001435 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001436rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001437 if (player->drop_ts == DVR_TRUE) {
1438 //need drop ts data when seek occur.we need read next loop,drop this ts data
1439 goto_rewrite = DVR_FALSE;
1440 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001441 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001442 player->drop_ts = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08001443 DVR_PB_INFO("----drop ts");
hualing chenbcada022020-04-22 14:27:01 +08001444 continue;
1445 }
hualing chen21a40372021-10-29 11:07:26 +08001446
1447 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001448 player->ts_cache_len = real_read;
hualing chenb9a02922021-12-14 11:29:47 +08001449 //used for printf first write data time.
1450 //to check change channel kpi.
1451 if (first_write == 0) {
1452 first_write++;
Wentao MA96f68962022-06-15 19:45:35 +08001453 DVR_PB_INFO("----firsr write ts data");
hualing chenb9a02922021-12-14 11:29:47 +08001454 }
1455
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001456 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1457 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001458 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001459 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001460 real_read = 0;
1461 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001462 if (CONTROL_SPEED_ENABLE == 1) {
1463check0:
1464 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001465 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001466 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001467 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001468 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1469 goto check0;
1470 }
1471 }
Wentao MA96f68962022-06-15 19:45:35 +08001472 //DVR_PB_INFO("write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001473 continue;
hualing chen87072a82020-03-12 16:20:12 +08001474 } else {
hualing chen21a40372021-10-29 11:07:26 +08001475 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08001476 DVR_PB_INFO("write time out write_success:%d wbufs.buf_size:%d systime:%u",
hualing chen03fd4942021-07-15 15:56:41 +08001477 write_success,
1478 wbufs.buf_size,
1479 _dvr_time_getClock());
1480
hualing chena540a7e2020-03-27 16:44:05 +08001481 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001482 if (CONTROL_SPEED_ENABLE == 1) {
1483check1:
1484 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001485 dvr_mutex_lock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001486 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001487 dvr_mutex_unlock(&player->lock);
hualing chend241c7a2021-06-22 13:34:27 +08001488 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1489 goto check1;
1490 }
1491 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001492 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001493 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001494 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001495 if (!player->is_running) {
Wentao MA96f68962022-06-15 19:45:35 +08001496 DVR_PB_INFO("playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001497 break;
1498 }
hualing chen2aba4022020-03-02 13:49:55 +08001499 goto_rewrite = DVR_TRUE;
1500 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001501 }
1502 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001503end:
Wentao MA96f68962022-06-15 19:45:35 +08001504 DVR_PB_INFO("playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001505 free(buf);
1506 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001507 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001508}
1509
1510
hualing chen040df222020-01-17 13:35:02 +08001511static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001512{
hualing chen040df222020-01-17 13:35:02 +08001513 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001514
1515 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001516 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001517 return DVR_FAILURE;
1518 }
Wentao MA96f68962022-06-15 19:45:35 +08001519 DVR_PB_INFO("start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001520 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001521 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001522 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001523 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001524 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001525 if (rc < 0)
1526 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001527 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001528}
1529
1530
hualing chen040df222020-01-17 13:35:02 +08001531static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001532{
hualing chen040df222020-01-17 13:35:02 +08001533 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001534
1535 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001536 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001537 return DVR_FAILURE;
1538 }
1539
Wentao MA96f68962022-06-15 19:45:35 +08001540 DVR_PB_INFO("stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001541 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001542 {
1543 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001544 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001545 pthread_join(player->playback_thread, NULL);
1546 }
1547 if (player->r_handle) {
1548 segment_close(player->r_handle);
1549 player->r_handle = NULL;
1550 }
Wentao MA96f68962022-06-15 19:45:35 +08001551 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001552 return 0;
1553}
1554
hualing chen1679f812021-11-08 15:17:46 +08001555static int getFakePid()
1556{
1557 char fake_pid_prop[] = "vendor.tv.dtv.fake_pid";
1558 char buf[32];
1559 int pid = 0xffff;
1560
1561 dvr_prop_read(fake_pid_prop, buf, sizeof(buf));
1562
1563 if (sscanf(buf, "%i", &pid) != 1)
1564 {
Wentao MA96f68962022-06-15 19:45:35 +08001565 DVR_PB_INFO("get fake pid error");
hualing chen1679f812021-11-08 15:17:46 +08001566 pid = 0xffff;
1567 }
1568 return pid;
1569}
1570
1571void dvr_playback_change_seek_state(DVR_PlaybackHandle_t handle,int pid) {
1572
1573 DVR_ASSERT(handle);
1574 DVR_Playback_t *player = (DVR_Playback_t *) handle;
1575 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001576 DVR_PB_INFO("player is NULL");
hualing chen1679f812021-11-08 15:17:46 +08001577 return ;
1578 }
1579 if (player->need_seek_start == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08001580 DVR_PB_INFO("player need_seek_start is false");
hualing chen1679f812021-11-08 15:17:46 +08001581 return ;
1582 }
1583
hualing chena5f03222021-12-02 11:22:35 +08001584 if (pid != player->fake_pid) {
hualing chen1679f812021-11-08 15:17:46 +08001585 player->need_seek_start = DVR_FALSE;
1586 }
Wentao MA96f68962022-06-15 19:45:35 +08001587 DVR_PB_INFO("player player->need_seek_start=%d", player->need_seek_start);
hualing chen1679f812021-11-08 15:17:46 +08001588}
1589
hualing chenb31a6c62020-01-13 17:27:00 +08001590/**\brief Open an dvr palyback
1591 * \param[out] p_handle dvr playback addr
1592 * \param[in] params dvr playback open parameters
1593 * \retval DVR_SUCCESS On success
1594 * \return Error code
1595 */
hualing chen040df222020-01-17 13:35:02 +08001596int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001597
hualing chen040df222020-01-17 13:35:02 +08001598 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001599 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001600
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001601 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001602
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001603 dvr_mutex_init(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001604 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001605 pthread_condattr_init(&cattr);
1606 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1607 pthread_cond_init(&player->cond, &cattr);
1608 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001609
hualing chen5cbe1a62020-02-10 16:36:36 +08001610 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001611 INIT_LIST_HEAD(&player->segment_list);
1612 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1613 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001614 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001615 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001616 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001617 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001618 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001619 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001620
hualing chen86e7d482020-01-16 15:13:33 +08001621 //store open params
hualing chen040df222020-01-17 13:35:02 +08001622 player->openParams.dmx_dev_id = params->dmx_dev_id;
1623 player->openParams.block_size = params->block_size;
Wentao MA96f68962022-06-15 19:45:35 +08001624 DVR_PB_INFO("playback open block_size:[%d]",params->block_size);
hualing chen86e7d482020-01-16 15:13:33 +08001625 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001626 player->openParams.event_fn = params->event_fn;
1627 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001628 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001629 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001630
hualing chen5cbe1a62020-02-10 16:36:36 +08001631 player->has_pids = params->has_pids;
1632
hualing chen2aba4022020-03-02 13:49:55 +08001633 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001634
1635 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1636 //for test get callback
1637 if (0 && player->player_callback_func == NULL) {
1638 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1639 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
Wentao MA96f68962022-06-15 19:45:35 +08001640 DVR_PB_INFO("playback open get callback[%p][%p][%p][%p]",
hualing chen03fd4942021-07-15 15:56:41 +08001641 player->player_callback_func,
1642 player->player_callback_userdata,
1643 _dvr_tsplayer_callback_test,
1644 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001645 }
1646 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001647
hualing chen86e7d482020-01-16 15:13:33 +08001648 //init has audio and video
1649 player->has_video = DVR_FALSE;
1650 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001651 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001652 player->last_segment_id = 0LL;
1653 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001654
hualing chen5cbe1a62020-02-10 16:36:36 +08001655 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001656 player->fffb_current = 0;
1657 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001658 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001659 //seek time
1660 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001661 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001662
Yahui Han1fbf3292021-11-08 18:17:19 +08001663 //allocate cryptor if have clearkey
1664 if (params->keylen > 0) {
1665 player->cryptor = am_crypt_des_open((uint8_t *)params->clearkey,
hualing chen002e5b92022-02-23 17:51:21 +08001666 (uint8_t *)params->cleariv,
1667 params->keylen * 8);
Yahui Han1fbf3292021-11-08 18:17:19 +08001668 if (!player->cryptor) {
Wentao MA96f68962022-06-15 19:45:35 +08001669 DVR_INFO("%s , open des cryptor failed!!!\n", __func__);
Yahui Han1fbf3292021-11-08 18:17:19 +08001670 }
1671 } else {
1672 player->cryptor = NULL;
1673 }
1674
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001675 //init secure stuff
1676 player->dec_func = NULL;
1677 player->dec_userdata = NULL;
1678 player->is_secure_mode = 0;
1679 player->secure_buffer = NULL;
1680 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001681 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001682
hualing chen4b7c15d2020-04-07 16:13:48 +08001683 player->fffb_play = DVR_FALSE;
1684
1685 player->last_send_time_id = UINT64_MAX;
1686 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001687 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001688
hualing chend241c7a2021-06-22 13:34:27 +08001689 //speed con init
1690 if (CONTROL_SPEED_ENABLE == 1) {
1691 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001692 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001693 player->con_spe.sys_dur = 0;
1694 player->con_spe.sys_sta = 0;
1695 }
1696
hualing chen03fd4942021-07-15 15:56:41 +08001697 //limit info
1698 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001699 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001700 //need seek to start pos
1701 player->first_start_time = 0;
Wentao MA01de0e62022-01-10 18:48:23 +08001702 player->first_start_id = UINT64_MAX;
1703 player->check_cache_flag = DVR_TRUE;
hualing chen8a657f32021-08-30 13:12:49 +08001704 player->need_seek_start = DVR_TRUE;
hualing chena5f03222021-12-02 11:22:35 +08001705 //fake_pid init
1706 player->fake_pid = getFakePid();
hualing chen86e7d482020-01-16 15:13:33 +08001707 *p_handle = player;
1708 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001709}
1710
1711/**\brief Close an dvr palyback
1712 * \param[in] handle playback handle
1713 * \retval DVR_SUCCESS On success
1714 * \return Error code
1715 */
hualing chen040df222020-01-17 13:35:02 +08001716int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001717
hualing chen86e7d482020-01-16 15:13:33 +08001718 DVR_ASSERT(handle);
Wentao MA96f68962022-06-15 19:45:35 +08001719 DVR_PB_INFO(":into");
hualing chen040df222020-01-17 13:35:02 +08001720 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001721 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001722 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001723 return DVR_FAILURE;
1724 }
1725
hualing chencc91e1c2020-02-28 13:26:17 +08001726 if (player->state != DVR_PLAYBACK_STATE_STOP)
1727 {
Wentao MA96f68962022-06-15 19:45:35 +08001728 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Yahui Han1fbf3292021-11-08 18:17:19 +08001729 if (player->cryptor) {
1730 am_crypt_des_close(player->cryptor);
1731 player->cryptor = NULL;
1732 }
hualing chencc91e1c2020-02-28 13:26:17 +08001733 dvr_playback_stop(handle, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08001734 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
hualing chenb96aa2c2020-04-15 14:13:53 +08001735 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001736 DVR_PB_INFO(":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001737 }
Wentao MA96f68962022-06-15 19:45:35 +08001738 DVR_PB_INFO(":into");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001739 dvr_mutex_destroy(&player->lock);
Zhiqiang Hanc9513462022-06-21 09:55:23 +08001740 pthread_mutex_destroy(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001741 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001742
1743 if (player) {
1744 free(player);
1745 player = NULL;
1746 }
Wentao MA96f68962022-06-15 19:45:35 +08001747 DVR_PB_INFO(":end");
hualing chen86e7d482020-01-16 15:13:33 +08001748 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001749}
1750
hualing chenb31a6c62020-01-13 17:27:00 +08001751/**\brief Start play audio and video, used start auido api and start video api
1752 * \param[in] handle playback handle
1753 * \param[in] params audio playback params,contains fmt and pid...
1754 * \retval DVR_SUCCESS On success
1755 * \return Error code
1756 */
hualing chen040df222020-01-17 13:35:02 +08001757int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1758 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001759 am_tsplayer_video_params vparams;
1760 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001761 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001762
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001763 memset(&vparams, 0, sizeof(vparams));
1764 memset(&aparams, 0, sizeof(aparams));
1765
hualing chena540a7e2020-03-27 16:44:05 +08001766 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001767 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001768 return DVR_FAILURE;
1769 }
hualing chencc91e1c2020-02-28 13:26:17 +08001770 uint64_t segment_id = player->cur_segment_id;
Wentao MA96f68962022-06-15 19:45:35 +08001771 DVR_PB_INFO("[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001772
hualing chena540a7e2020-03-27 16:44:05 +08001773 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001774 //can used start api to resume playback
1775 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1776 return dvr_playback_resume(handle);
1777 }
hualing chen87072a82020-03-12 16:20:12 +08001778 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001779 //if flag is puased and not decodec first frame. if user resume, we need
1780 //clear flag and set trickmode none
1781 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001782 DVR_PB_INFO("[%p]clear pause live flag and clear trick mode", handle);
hualing chen9b434f02020-06-10 15:06:54 +08001783 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1784 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1785 }
Wentao MA96f68962022-06-15 19:45:35 +08001786 DVR_PB_INFO("stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001787 return DVR_SUCCESS;
1788 }
hualing chen86e7d482020-01-16 15:13:33 +08001789 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001790 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001791 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08001792 DVR_PB_INFO("lock flag:0x%x", flag);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001793 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001794 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001795 //start audio and video
hualing chena5f03222021-12-02 11:22:35 +08001796 if (vparams.pid != player->fake_pid && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001797 //audio abnd video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08001798 DVR_PB_ERROR("unlock dvr play back start error, not found audio and video info [0x%x]", vparams.pid);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001799 dvr_mutex_unlock(&player->lock);
hualing chencc91e1c2020-02-28 13:26:17 +08001800 DVR_Play_Notify_t notify;
1801 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1802 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1803 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1804 notify.info.transition_failed_data.segment_id = segment_id;
1805 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001806 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001807 return -1;
1808 }
hualing chen31140872020-03-25 12:29:26 +08001809
hualing chencc91e1c2020-02-28 13:26:17 +08001810 {
hualing chen86e7d482020-01-16 15:13:33 +08001811 if (VALID_PID(vparams.pid)) {
1812 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001813 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001814 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08001815 DVR_PB_INFO("set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001816 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1817 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001818 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
Wentao MA96f68962022-06-15 19:45:35 +08001819 DVR_PB_INFO("set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001820 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001821 } else {
Wentao MA96f68962022-06-15 19:45:35 +08001822 DVR_PB_INFO("set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001823 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001824 }
hualing chena93bbbc2020-12-22 17:23:42 +08001825 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001826 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08001827 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001828 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001829 }
hualing chena540a7e2020-03-27 16:44:05 +08001830
Wentao MA96f68962022-06-15 19:45:35 +08001831 DVR_PB_INFO("player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
hualing chen4b7c15d2020-04-07 16:13:48 +08001832 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001833 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1834 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1835 player->cmd.state = DVR_PLAYBACK_STATE_START;
1836 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001837 } else {
1838 player->cmd.last_cmd = player->cmd.cur_cmd;
1839 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001840 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001841 //set fast play
Wentao MA96f68962022-06-15 19:45:35 +08001842 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08001843 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001844 } else {
hualing chendf118dd2020-05-21 15:49:11 +08001845 if (VALID_PID(adparams.pid)) {
1846 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08001847 DVR_PB_INFO("start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08001848 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chendf118dd2020-05-21 15:49:11 +08001849 AmTsPlayer_setADParams(player->handle, &adparams);
1850 AmTsPlayer_enableADMix(player->handle);
1851 }
hualing chen969fe7b2021-05-26 15:13:17 +08001852 if (VALID_PID(aparams.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001853 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08001854 player->has_audio = DVR_TRUE;
hualing chen1679f812021-11-08 15:17:46 +08001855 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08001856 AmTsPlayer_setAudioParams(player->handle, &aparams);
1857 AmTsPlayer_startAudioDecoding(player->handle);
1858 }
hualing chen31140872020-03-25 12:29:26 +08001859 }
hualing chencc91e1c2020-02-28 13:26:17 +08001860 player->cmd.state = DVR_PLAYBACK_STATE_START;
1861 player->state = DVR_PLAYBACK_STATE_START;
1862 }
hualing chen86e7d482020-01-16 15:13:33 +08001863 }
hualing chen43a89bc2022-01-19 14:31:20 +08001864#ifdef AVSYNC_USED_PCR
1865 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08001866 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08001867 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
1868 }
1869#endif
Wentao MA96f68962022-06-15 19:45:35 +08001870 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001871 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001872 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001873 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001874}
hualing chen040df222020-01-17 13:35:02 +08001875/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001876 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001877 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001878 * \retval DVR_SUCCESS On success
1879 * \return Error code
1880 */
hualing chen040df222020-01-17 13:35:02 +08001881int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1882 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001883
hualing chena540a7e2020-03-27 16:44:05 +08001884 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001885 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001886 return DVR_FAILURE;
1887 }
1888
Wentao MA96f68962022-06-15 19:45:35 +08001889 DVR_PB_INFO("add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001890 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001891
hualing chen040df222020-01-17 13:35:02 +08001892 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1893 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001894
hualing chen86e7d482020-01-16 15:13:33 +08001895 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001896 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001897 //cp location
hualing chen040df222020-01-17 13:35:02 +08001898 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001899
Wentao MA96f68962022-06-15 19:45:35 +08001900 DVR_PB_INFO("add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001901 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001902
1903 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001904 segment->pids.video.pid = info->pids.video.pid;
1905 segment->pids.video.format = info->pids.video.format;
1906 segment->pids.video.type = info->pids.video.type;
1907
hualing chen2aba4022020-03-02 13:49:55 +08001908 segment->pids.audio.pid = info->pids.audio.pid;
1909 segment->pids.audio.format = info->pids.audio.format;
1910 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001911
hualing chen2aba4022020-03-02 13:49:55 +08001912 segment->pids.ad.pid = info->pids.ad.pid;
1913 segment->pids.ad.format = info->pids.ad.format;
1914 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001915
1916 segment->pids.pcr.pid = info->pids.pcr.pid;
1917
Wentao MA96f68962022-06-15 19:45:35 +08001918 DVR_PB_INFO("lock pid [0x%x][0x%x][0x%x][0x%x]", segment->pids.video.pid,segment->pids.audio.pid, info->pids.video.pid,info->pids.audio.pid);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001919 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001920 list_add_tail(&segment->head, &player->segment_list);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001921 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08001922 DVR_PB_DEBUG("unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001923
hualing chen5cbe1a62020-02-10 16:36:36 +08001924 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001925}
hualing chen040df222020-01-17 13:35:02 +08001926/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001927 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001928 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001929 * \retval DVR_SUCCESS On success
1930 * \return Error code
1931 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001932int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001933 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001934 DVR_PB_INFO("remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001935 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001936 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001937 return DVR_FAILURE;
1938 }
1939
hualing chencc91e1c2020-02-28 13:26:17 +08001940 if (segment_id == player->cur_segment_id) {
Wentao MA96f68962022-06-15 19:45:35 +08001941 DVR_PB_INFO("not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001942 return DVR_FAILURE;
1943 }
Wentao MA96f68962022-06-15 19:45:35 +08001944 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001945 dvr_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001946 DVR_PlaybackSegmentInfo_t *segment = NULL;
1947 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1948 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001949 {
hualing chen040df222020-01-17 13:35:02 +08001950 if (segment->segment_id == segment_id) {
1951 list_del(&segment->head);
1952 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001953 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001954 }
hualing chen86e7d482020-01-16 15:13:33 +08001955 }
Wentao MA96f68962022-06-15 19:45:35 +08001956 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001957 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001958
1959 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001960}
hualing chen040df222020-01-17 13:35:02 +08001961/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001962 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001963 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001964 * \retval DVR_SUCCESS On success
1965 * \return Error code
1966 */
hualing chen040df222020-01-17 13:35:02 +08001967int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001968 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001969 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MA96f68962022-06-15 19:45:35 +08001970 DVR_PB_INFO("update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001971 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08001972 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001973 return DVR_FAILURE;
1974 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001975 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
Wentao MA96f68962022-06-15 19:45:35 +08001976 DVR_PB_INFO("vendor is amlogic. not hide or show av and update segment");
hualing chenf43b8ba2020-07-28 13:11:42 +08001977 return DVR_SUCCESS;
1978 }
hualing chena540a7e2020-03-27 16:44:05 +08001979
hualing chen040df222020-01-17 13:35:02 +08001980 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08001981 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08001982 dvr_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001983 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001984 {
hualing chen040df222020-01-17 13:35:02 +08001985 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001986 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001987 }
hualing chen86e7d482020-01-16 15:13:33 +08001988 // if encramble to free, only set flag and return;
1989
1990 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001991 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001992 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1993 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001994 //disable display, mute
Wentao MA96f68962022-06-15 19:45:35 +08001995 DVR_PB_INFO("mute av");
hualing chen2aba4022020-03-02 13:49:55 +08001996 AmTsPlayer_hideVideo(player->handle);
1997 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001998 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1999 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08002000 //enable display, unmute
Wentao MA96f68962022-06-15 19:45:35 +08002001 DVR_PB_INFO("unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08002002 AmTsPlayer_showVideo(player->handle);
2003 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08002004 } else {
2005 //do nothing
2006 }
2007 } else {
2008 //do nothing
2009 }
2010 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08002011 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08002012 }
Wentao MA96f68962022-06-15 19:45:35 +08002013 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002014 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002015 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002016}
2017
2018
hualing chen99508642021-10-18 15:41:17 +08002019static 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 +08002020 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08002021 DVR_StreamInfo_t set_pid;
hualing chen99508642021-10-18 15:41:17 +08002022 DVR_StreamInfo_t now_pid;
hualing chen275379e2021-06-15 17:57:21 +08002023
2024 if (type == 0) {
2025 set_pid = set_pids.video;
hualing chen99508642021-10-18 15:41:17 +08002026 now_pid = now_pids.video;
hualing chen275379e2021-06-15 17:57:21 +08002027 } else if (type == 1) {
2028 set_pid = set_pids.audio;
hualing chen99508642021-10-18 15:41:17 +08002029 now_pid = now_pids.audio;
hualing chen275379e2021-06-15 17:57:21 +08002030 } else if (type == 2) {
2031 set_pid = set_pids.ad;
hualing chen99508642021-10-18 15:41:17 +08002032 now_pid = now_pids.ad;
hualing chen275379e2021-06-15 17:57:21 +08002033 } else {
2034 set_pid = set_pids.pcr;
hualing chen99508642021-10-18 15:41:17 +08002035 now_pid = now_pids.pcr;
hualing chen275379e2021-06-15 17:57:21 +08002036 }
2037
hualing chena540a7e2020-03-27 16:44:05 +08002038 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002039 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002040 return DVR_FAILURE;
2041 }
Wentao MA96f68962022-06-15 19:45:35 +08002042 DVR_PB_INFO(" do check");
hualing chen86e7d482020-01-16 15:13:33 +08002043 if (now_pid.pid == set_pid.pid) {
2044 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08002045 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08002046 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08002047 if (VALID_PID(now_pid.pid)) {
2048 //stop now stream
2049 if (type == 0) {
2050 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08002051 if (player->has_video == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002052 DVR_PB_INFO("stop video");
hualing chenc70a8df2020-05-12 19:23:11 +08002053 AmTsPlayer_stopVideoDecoding(player->handle);
2054 player->has_video = DVR_FALSE;
2055 }
hualing chen86e7d482020-01-16 15:13:33 +08002056 } else if (type == 1) {
2057 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08002058 if (player->has_audio == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08002059 DVR_PB_INFO("stop audio");
hualing chenc70a8df2020-05-12 19:23:11 +08002060 AmTsPlayer_stopAudioDecoding(player->handle);
2061 player->has_audio = DVR_FALSE;
2062 }
hualing chen86e7d482020-01-16 15:13:33 +08002063 } else if (type == 2) {
2064 //stop sub audio
Wentao MA96f68962022-06-15 19:45:35 +08002065 DVR_PB_INFO("stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08002066 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002067 } else if (type == 3) {
2068 //pcr
2069 }
2070 }
2071 if (VALID_PID(set_pid.pid)) {
2072 //start
2073 if (type == 0) {
2074 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08002075 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08002076 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08002077 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002078 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002079 DVR_PB_INFO("start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08002080 AmTsPlayer_setVideoParams(player->handle, &vparams);
2081 AmTsPlayer_startVideoDecoding(player->handle);
2082 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08002083 } else if (type == 1) {
2084 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002085 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08002086 if (VALID_PID(set_pids.ad.pid)) {
2087 am_tsplayer_audio_params adparams;
2088 adparams.pid = set_pids.ad.pid;
2089 adparams.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08002090 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",adparams.pid, adparams.codectype);
hualing chen275379e2021-06-15 17:57:21 +08002091 AmTsPlayer_setADParams(player->handle, &adparams);
2092 AmTsPlayer_enableADMix(player->handle);
2093 }
2094
hualing chenc70a8df2020-05-12 19:23:11 +08002095 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002096
2097 memset(&aparams, 0, sizeof(aparams));
2098
hualing chenc70a8df2020-05-12 19:23:11 +08002099 aparams.pid = set_pid.pid;
2100 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
2101 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002102 DVR_PB_INFO("start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chenc70a8df2020-05-12 19:23:11 +08002103 AmTsPlayer_setAudioParams(player->handle, &aparams);
2104 AmTsPlayer_startAudioDecoding(player->handle);
2105 //playback_device_audio_start(player->handle,&aparams);
2106 }
hualing chen86e7d482020-01-16 15:13:33 +08002107 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002108 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen99508642021-10-18 15:41:17 +08002109 if (set_pids.audio.pid == now_pids.audio.pid) {
2110 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002111 DVR_PB_INFO("stop audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002112 AmTsPlayer_stopAudioDecoding(player->handle);
2113 }
hualing chenc70a8df2020-05-12 19:23:11 +08002114 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002115
2116 memset(&aparams, 0, sizeof(aparams));
hualing chenc70a8df2020-05-12 19:23:11 +08002117 aparams.pid = set_pid.pid;
2118 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
2119 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002120 DVR_PB_INFO("start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
hualing chenc70a8df2020-05-12 19:23:11 +08002121 AmTsPlayer_setADParams(player->handle, &aparams);
2122 AmTsPlayer_enableADMix(player->handle);
hualing chen99508642021-10-18 15:41:17 +08002123
2124 if (set_pids.audio.pid == now_pids.audio.pid) {
2125 am_tsplayer_audio_params aparams;
2126
2127 memset(&aparams, 0, sizeof(aparams));
2128
2129 aparams.pid = set_pids.audio.pid;
2130 aparams.codectype= _dvr_convert_stream_fmt(set_pids.audio.format, DVR_TRUE);
2131 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002132 DVR_PB_INFO("restart audio when start ad");
hualing chen99508642021-10-18 15:41:17 +08002133 AmTsPlayer_setAudioParams(player->handle, &aparams);
2134 AmTsPlayer_startAudioDecoding(player->handle);
2135 }
hualing chenc70a8df2020-05-12 19:23:11 +08002136 }
hualing chen86e7d482020-01-16 15:13:33 +08002137 } else if (type == 3) {
2138 //pcr
Wentao MA96f68962022-06-15 19:45:35 +08002139 DVR_PB_INFO("start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08002140 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002141 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002142 //audio and video all close
2143 if (!player->has_audio && !player->has_video) {
2144 player->state = DVR_PLAYBACK_STATE_STOP;
2145 }
hualing chen43a89bc2022-01-19 14:31:20 +08002146 } else if (type == 2) {
2147 //case disable ad
Wentao MA96f68962022-06-15 19:45:35 +08002148 DVR_PB_INFO("restart audio when stop ad");
hualing chen43a89bc2022-01-19 14:31:20 +08002149 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
Wentao MA6d045b32022-02-18 18:47:25 +08002150 if (VALID_PID(now_pids.audio.pid)) {
2151 //stop audio if audio pid not change
Wentao MA96f68962022-06-15 19:45:35 +08002152 DVR_PB_INFO("stop audio when stop ad pid [0x%x]", now_pids.audio.pid);
Wentao MA6d045b32022-02-18 18:47:25 +08002153 AmTsPlayer_stopAudioDecoding(player->handle);
2154 am_tsplayer_audio_params aparams;
hualing chen43a89bc2022-01-19 14:31:20 +08002155
Wentao MA6d045b32022-02-18 18:47:25 +08002156 memset(&aparams, 0, sizeof(aparams));
hualing chen43a89bc2022-01-19 14:31:20 +08002157
Wentao MA6d045b32022-02-18 18:47:25 +08002158 aparams.pid = now_pids.audio.pid;
2159 aparams.codectype= _dvr_convert_stream_fmt(now_pids.audio.format, DVR_TRUE);
2160 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002161 DVR_PB_INFO("restart audio when stop ad");
Wentao MA6d045b32022-02-18 18:47:25 +08002162 AmTsPlayer_setAudioParams(player->handle, &aparams);
2163 AmTsPlayer_startAudioDecoding(player->handle);
hualing chen43a89bc2022-01-19 14:31:20 +08002164 }
Wentao MA6d045b32022-02-18 18:47:25 +08002165 }
hualing chen86e7d482020-01-16 15:13:33 +08002166 }
2167 }
2168 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08002169}
hualing chena5f03222021-12-02 11:22:35 +08002170/**\brief dvr play back only update segment pids info
2171 * only update pid info not to start stop codec.
2172 * \param[in] handle playback handle
2173 * \param[in] segment_id need updated pids segment id
2174 * \param[in] p_pids need updated pids
2175 * \retval DVR_SUCCESS On success
2176 * \return Error code
2177 */
2178int dvr_playback_only_update_segment_pids(DVR_PlaybackHandle_t handle, uint64_t segment_id, DVR_PlaybackPids_t *p_pids) {
2179 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2180 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002181 DVR_PB_INFO("player is NULL");
hualing chena5f03222021-12-02 11:22:35 +08002182 return DVR_FAILURE;
2183 }
2184
2185 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002186 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002187 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002188 DVR_PB_INFO("get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
hualing chena5f03222021-12-02 11:22:35 +08002189 list_for_each_entry(segment, &player->segment_list, head)
2190 {
2191 if (segment->segment_id == segment_id) {
2192 if (player->cur_segment_id == segment_id) {
2193 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
2194 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
2195 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002196 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002197 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002198 return 0;
2199 }
2200 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
2201 }
2202 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002203 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002204 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002205 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chena5f03222021-12-02 11:22:35 +08002206 break;
2207 }
2208 }
Wentao MA96f68962022-06-15 19:45:35 +08002209 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002210 dvr_mutex_unlock(&player->lock);
hualing chena5f03222021-12-02 11:22:35 +08002211 return DVR_SUCCESS;
2212}
2213
hualing chen5cbe1a62020-02-10 16:36:36 +08002214/**\brief dvr play back update segment pids
2215 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08002216 * add pid stream and stop remove pid stream.
2217 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08002218 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002219 * \retval DVR_SUCCESS On success
2220 * \return Error code
2221 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002222int 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 +08002223 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002224 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002225 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002226 return DVR_FAILURE;
2227 }
2228
hualing chen040df222020-01-17 13:35:02 +08002229 DVR_PlaybackSegmentInfo_t *segment;
Wentao MA96f68962022-06-15 19:45:35 +08002230 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002231 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002232 DVR_PB_INFO("get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08002233
hualing chen040df222020-01-17 13:35:02 +08002234 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002235 {
hualing chen040df222020-01-17 13:35:02 +08002236 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002237
2238 if (player->cur_segment_id == segment_id) {
2239 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
2240 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
2241 //do nothing when ff fb
Wentao MA96f68962022-06-15 19:45:35 +08002242 DVR_PB_INFO("unlock now is ff fb, not to update cur segment info\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002243 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002244 return 0;
2245 }
2246
2247 //if segment is on going segment,we need stop start stream
2248 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
Wentao MA96f68962022-06-15 19:45:35 +08002249 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002250 dvr_mutex_unlock(&player->lock);
hualing chen8a657f32021-08-30 13:12:49 +08002251 if (segment->pids.audio.pid != p_pids->audio.pid &&
2252 segment->pids.audio.pid == 0x1fff) {
hualing chena5f03222021-12-02 11:22:35 +08002253 //not used this to seek to start pos.we will
2254 //add uopdate only api. if need seek to start
2255 //pos, we will call only update api and used seek api
2256 //to start and stop av codec
2257 if (0 && player->need_seek_start == DVR_TRUE) {
hualing chen8a657f32021-08-30 13:12:49 +08002258 player->need_seek_start = DVR_FALSE;
2259 pthread_mutex_lock(&player->segment_lock);
2260 player->drop_ts = DVR_TRUE;
2261 player->ts_cache_len = 0;
2262 if (player->first_start_time > 0)
2263 player->first_start_time = player->first_start_time - 1;
2264 segment_seek(player->r_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002265 DVR_PB_ERROR("unlock segment update need seek time_offset %llu [0x%x][0x%x]", player->first_start_time, segment->pids.audio.pid, segment->pids.ad.pid);
hualing chen8a657f32021-08-30 13:12:49 +08002266 pthread_mutex_unlock(&player->segment_lock);
2267 }
2268 }
hualing chen1679f812021-11-08 15:17:46 +08002269 //check video pids, stop or restart
2270 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 0);
2271 //check sub audio pids stop or restart
2272 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 2);
2273 //check audio pids stop or restart
2274 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 1);
2275 //check pcr pids stop or restart
2276 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids, *p_pids, 3);
2277
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002278 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002279 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2280 //if state is pause, we need process at resume api. we only record change info
2281 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2282 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2283 if (VALID_PID(segment->pids.video.pid)
2284 && VALID_PID(p_pids->video.pid)
2285 && segment->pids.video.pid != p_pids->video.pid) {
2286 //restart video
2287 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
2288 }
2289 if (!VALID_PID(segment->pids.video.pid)
2290 && VALID_PID(p_pids->video.pid)
2291 && segment->pids.video.pid != p_pids->video.pid) {
2292 //start video
2293 v_cmd = DVR_PLAYBACK_CMD_VSTART;
2294 }
2295 if (VALID_PID(segment->pids.video.pid)
2296 && !VALID_PID(p_pids->video.pid)
2297 && segment->pids.video.pid != p_pids->video.pid) {
2298 //stop video
2299 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
2300 }
2301 if (VALID_PID(segment->pids.audio.pid)
2302 && VALID_PID(p_pids->audio.pid)
2303 && segment->pids.audio.pid != p_pids->audio.pid) {
2304 //restart audio
2305 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
2306 }
2307 if (!VALID_PID(segment->pids.audio.pid)
2308 && VALID_PID(p_pids->audio.pid)
2309 && segment->pids.audio.pid != p_pids->audio.pid) {
2310 //start audio
2311 a_cmd = DVR_PLAYBACK_CMD_ASTART;
2312 }
2313 if (VALID_PID(segment->pids.audio.pid)
2314 && !VALID_PID(p_pids->audio.pid)
2315 && segment->pids.audio.pid != p_pids->audio.pid) {
2316 //stop audio
2317 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
2318 }
2319 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2320 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2321 //do nothing
2322 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2323 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2324 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2325 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2326 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2327 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
2328 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2329 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2330 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2331 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2332 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2333 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2334 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2335 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
2336 } else {
2337 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2338 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
2339 }
2340
2341 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2342 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2343 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2344 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
2345 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2346 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2347 //not occur this case
2348 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2349 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2350 } else {
2351 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2352 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
2353 }
2354
2355 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2356 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2357 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2358 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
2359 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2360 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
2361 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2362 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
2363 } else {
2364 //not occur this case
2365 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2366 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2367 }
2368 }
2369 }
hualing chene10666f2020-04-14 13:58:37 +08002370 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002371 }
hualing chen86e7d482020-01-16 15:13:33 +08002372 //save pids info
Wentao MA96f68962022-06-15 19:45:35 +08002373 DVR_PB_INFO(":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002374 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
Wentao MA96f68962022-06-15 19:45:35 +08002375 DVR_PB_INFO(":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002376 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002377 }
hualing chen86e7d482020-01-16 15:13:33 +08002378 }
Wentao MA96f68962022-06-15 19:45:35 +08002379 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002380 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002381 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002382}
2383/**\brief Stop play, will stop video and audio
2384 * \param[in] handle playback handle
2385 * \param[in] clear is clear last frame
2386 * \retval DVR_SUCCESS On success
2387 * \return Error code
2388 */
hualing chen040df222020-01-17 13:35:02 +08002389int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2390 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002391 DVR_UNUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002392 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002393 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002394 return DVR_FAILURE;
2395 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002396 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002397 DVR_PB_INFO(":playback is stoped");
hualing chenb96aa2c2020-04-15 14:13:53 +08002398 return DVR_SUCCESS;
2399 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002400 if (player->state == DVR_PLAYBACK_STATE_STOP) {
Wentao MA96f68962022-06-15 19:45:35 +08002401 DVR_PB_INFO(":playback is stoped");
Ke Gong3c0caba2020-04-21 22:58:18 -07002402 return DVR_SUCCESS;
2403 }
hualing chen87072a82020-03-12 16:20:12 +08002404 _stop_playback_thread(handle);
Wentao MA96f68962022-06-15 19:45:35 +08002405 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002406 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002407 DVR_PB_INFO(":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002408 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002409 if (player->has_video) {
2410 AmTsPlayer_resumeVideoDecoding(player->handle);
2411 }
2412 if (player->has_audio) {
2413 AmTsPlayer_resumeAudioDecoding(player->handle);
2414 }
2415 if (player->has_video) {
2416 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002417 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002418 AmTsPlayer_stopVideoDecoding(player->handle);
2419 }
2420 if (player->has_audio) {
2421 player->has_audio = DVR_FALSE;
2422 AmTsPlayer_stopAudioDecoding(player->handle);
2423 }
hualing chendf118dd2020-05-21 15:49:11 +08002424 if (player->has_ad_audio) {
2425 player->has_ad_audio =DVR_FALSE;
2426 AmTsPlayer_disableADMix(player->handle);
2427 }
hualing chen266b9502020-04-04 17:39:39 +08002428
hualing chen86e7d482020-01-16 15:13:33 +08002429 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002430 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2431 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2432 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002433 player->cur_segment_id = UINT64_MAX;
2434 player->segment_is_open = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08002435 DVR_PB_DEBUG("unlock");
2436 DVR_PB_INFO("player->state %s", _dvr_playback_state_toString(player->state));
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002437 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002438 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002439}
2440/**\brief Start play audio
2441 * \param[in] handle playback handle
2442 * \param[in] params audio playback params,contains fmt and pid...
2443 * \retval DVR_SUCCESS On success
2444 * \return Error code
2445 */
hualing chen2aba4022020-03-02 13:49:55 +08002446
hualing chendf118dd2020-05-21 15:49:11 +08002447int 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 +08002448 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002449
2450 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002451 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002452 return DVR_FAILURE;
2453 }
hualing chen86e7d482020-01-16 15:13:33 +08002454 _start_playback_thread(handle);
2455 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002456 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002457 dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002458
hualing chendf118dd2020-05-21 15:49:11 +08002459 if (VALID_PID(adparam->pid)) {
2460 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002461 DVR_PB_INFO("start ad audio");
hualing chendf118dd2020-05-21 15:49:11 +08002462 AmTsPlayer_setADParams(player->handle, adparam);
2463 AmTsPlayer_enableADMix(player->handle);
2464 }
hualing chen969fe7b2021-05-26 15:13:17 +08002465 if (VALID_PID(param->pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08002466 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08002467 player->has_audio = DVR_TRUE;
2468 AmTsPlayer_setAudioParams(player->handle, param);
2469 AmTsPlayer_startAudioDecoding(player->handle);
2470 }
hualing chendf118dd2020-05-21 15:49:11 +08002471
hualing chen86e7d482020-01-16 15:13:33 +08002472 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002473 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
2474 player->cmd.state = DVR_PLAYBACK_STATE_START;
2475 player->state = DVR_PLAYBACK_STATE_START;
Wentao MA96f68962022-06-15 19:45:35 +08002476 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002477 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002478 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002479}
2480/**\brief Stop play audio
2481 * \param[in] handle playback handle
2482 * \retval DVR_SUCCESS On success
2483 * \return Error code
2484 */
hualing chen040df222020-01-17 13:35:02 +08002485int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2486 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002487
2488 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002489 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002490 return DVR_FAILURE;
2491 }
2492
hualing chen2aba4022020-03-02 13:49:55 +08002493 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002494 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002495 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2496 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002497 //destory thread
2498 _stop_playback_thread(handle);
2499 } else {
2500 //do nothing.video is playing
2501 }
Wentao MA96f68962022-06-15 19:45:35 +08002502 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002503 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002504
hualing chenf00cdc82020-06-10 14:23:35 +08002505 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002506 player->has_audio = DVR_FALSE;
2507 AmTsPlayer_stopAudioDecoding(player->handle);
2508 }
hualing chen87072a82020-03-12 16:20:12 +08002509
hualing chendf118dd2020-05-21 15:49:11 +08002510 if (player->has_ad_audio) {
2511 player->has_ad_audio =DVR_FALSE;
2512 AmTsPlayer_disableADMix(player->handle);
2513 }
2514
hualing chen87072a82020-03-12 16:20:12 +08002515 player->cmd.last_cmd = player->cmd.cur_cmd;
2516 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2517
Wentao MA96f68962022-06-15 19:45:35 +08002518 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002519 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002520 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002521}
2522/**\brief Start play video
2523 * \param[in] handle playback handle
2524 * \param[in] params video playback params,contains fmt and pid...
2525 * \retval DVR_SUCCESS On success
2526 * \return Error code
2527 */
hualing chen2aba4022020-03-02 13:49:55 +08002528int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002529 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002530
2531 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002532 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002533 return DVR_FAILURE;
2534 }
2535
hualing chen86e7d482020-01-16 15:13:33 +08002536 _start_playback_thread(handle);
2537 //start audio and video
Wentao MA96f68962022-06-15 19:45:35 +08002538 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002539 dvr_mutex_lock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002540 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002541 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002542 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002543 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002544
2545 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002546 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002547 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
Wentao MA96f68962022-06-15 19:45:35 +08002548 DVR_PB_INFO("settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002549 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2550 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002551 }
2552 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002553 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2554 player->cmd.state = DVR_PLAYBACK_STATE_START;
2555 player->state = DVR_PLAYBACK_STATE_START;
Wentao MA96f68962022-06-15 19:45:35 +08002556 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002557 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002558 return DVR_SUCCESS;
2559}
2560/**\brief Stop play video
2561 * \param[in] handle playback handle
2562 * \retval DVR_SUCCESS On success
2563 * \return Error code
2564 */
hualing chen040df222020-01-17 13:35:02 +08002565int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2566 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002567
2568 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002569 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002570 return DVR_FAILURE;
2571 }
2572
hualing chen86e7d482020-01-16 15:13:33 +08002573 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002574 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2575 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002576 //destory thread
2577 _stop_playback_thread(handle);
2578 } else {
2579 //do nothing.audio is playing
2580 }
hualing chen7a56cba2020-04-14 14:09:27 +08002581
Wentao MA96f68962022-06-15 19:45:35 +08002582 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002583 dvr_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002584
hualing chen87072a82020-03-12 16:20:12 +08002585 player->has_video = DVR_FALSE;
2586
2587 AmTsPlayer_stopVideoDecoding(player->handle);
2588 //playback_device_video_stop(player->handle);
2589
2590 player->cmd.last_cmd = player->cmd.cur_cmd;
2591 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2592
Wentao MA96f68962022-06-15 19:45:35 +08002593 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002594 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002595 return DVR_SUCCESS;
2596}
2597/**\brief Pause play
2598 * \param[in] handle playback handle
2599 * \param[in] flush whether its internal buffers should be flushed
2600 * \retval DVR_SUCCESS On success
2601 * \return Error code
2602 */
hualing chen040df222020-01-17 13:35:02 +08002603int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2604 DVR_Playback_t *player = (DVR_Playback_t *) handle;
Wentao MAe8ba5172022-08-09 11:18:17 +08002605 DVR_UNUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002606 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002607 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002608 return DVR_FAILURE;
2609 }
hualing chenf00cdc82020-06-10 14:23:35 +08002610 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
Wentao MA96f68962022-06-15 19:45:35 +08002611 DVR_PB_INFO("player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002612 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002613 }
Wentao MA96f68962022-06-15 19:45:35 +08002614 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002615 dvr_mutex_lock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002616 DVR_PB_DEBUG("get lock");
hualing chen266b9502020-04-04 17:39:39 +08002617 if (player->has_video)
2618 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002619 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002620 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002621
2622 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002623 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2624 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2625 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2626 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002627 } else {
2628 player->cmd.last_cmd = player->cmd.cur_cmd;
2629 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2630 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2631 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002632 }
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002633 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08002634 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002635
hualing chen86e7d482020-01-16 15:13:33 +08002636 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002637}
2638
hualing chen5cbe1a62020-02-10 16:36:36 +08002639//not add lock
2640static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2641{
2642 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2643
hualing chena540a7e2020-03-27 16:44:05 +08002644 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002645 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002646 return DVR_FAILURE;
2647 }
2648
hualing chen5cbe1a62020-02-10 16:36:36 +08002649 //get video params and audio params
Wentao MA96f68962022-06-15 19:45:35 +08002650 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002651 dvr_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002652 am_tsplayer_video_params vparams;
2653 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002654 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002655 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002656
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002657 memset(&vparams, 0, sizeof(vparams));
2658 memset(&aparams, 0, sizeof(aparams));
2659
hualing chendf118dd2020-05-21 15:49:11 +08002660 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
Wentao MA96f68962022-06-15 19:45:35 +08002661 DVR_PB_INFO("unlock cmd: %d", cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002662 dvr_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002663
2664 switch (cmd) {
2665 case DVR_PLAYBACK_CMD_AVRESTART:
2666 //av restart
Wentao MA96f68962022-06-15 19:45:35 +08002667 DVR_PB_INFO("do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002668 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002669 break;
2670 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002671 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2672 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002673 break;
2674 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002675 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002676 break;
2677 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002678 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002679 break;
2680 case DVR_PLAYBACK_CMD_ARESTART:
2681 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002682 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002683 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002684 break;
2685 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002686 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002687 break;
2688 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002689 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002690 break;
2691 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002692 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2693 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2694 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002695 break;
2696 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002697 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2698 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002699 break;
2700 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002701 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2702 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002703 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002704 break;
2705 case DVR_PLAYBACK_CMD_STOP:
2706 break;
2707 case DVR_PLAYBACK_CMD_START:
2708 break;
2709 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002710 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2711 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002712 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002713 break;
2714 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002715 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2716 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002717 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002718 break;
2719 case DVR_PLAYBACK_CMD_FF:
2720 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002721 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002722 break;
2723 default:
2724 break;
2725 }
2726 return DVR_SUCCESS;
2727}
2728
2729/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002730 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002731 * \retval DVR_SUCCESS On success
2732 * \return Error code
2733 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002734int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2735 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002736 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002737 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002738 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002739 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002740 return DVR_FAILURE;
2741 }
2742
hualing chena991aa82021-08-16 10:21:15 +08002743 if (dvr_playback_check_limit(handle)) {
2744 //get id and pos to check if we can seek to this pos
Wentao MA96f68962022-06-15 19:45:35 +08002745 DVR_PB_INFO("player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002746 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2747 if (segmentid != player->cur_segment_id ||
2748 (segmentid == player->cur_segment_id &&
2749 pos > _dvr_get_cur_time(handle))) {
2750 //first to seek new pos and to resume
Wentao MA96f68962022-06-15 19:45:35 +08002751 DVR_PB_INFO("seek new pos and to resume");
hualing chena991aa82021-08-16 10:21:15 +08002752 dvr_playback_seek(handle, segmentid, pos);
2753 }
hualing chen7ea70a72021-09-09 11:25:13 +08002754 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002755 DVR_PB_INFO("player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002756 }
hualing chena991aa82021-08-16 10:21:15 +08002757
hualing chen5cbe1a62020-02-10 16:36:36 +08002758 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
Wentao MA96f68962022-06-15 19:45:35 +08002759 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002760 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002761 player->first_frame = 0;
2762 if (player->has_video)
2763 AmTsPlayer_pauseVideoDecoding(player->handle);
2764 if (player->has_audio)
2765 AmTsPlayer_pauseAudioDecoding(player->handle);
2766
hualing chen266b9502020-04-04 17:39:39 +08002767 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002768 DVR_PB_INFO("dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002769 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2770 AmTsPlayer_resumeVideoDecoding(player->handle);
2771 }
2772 if (player->has_audio) {
2773 AmTsPlayer_resumeAudioDecoding(player->handle);
2774 }
2775 //check is has audio param,if has audio .we need start audio,
2776 //we will stop audio when ff fb, if reach end, we will pause.so we need
2777 //start audio when resume play
2778
2779 am_tsplayer_video_params vparams;
2780 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002781 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002782 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002783
2784 memset(&vparams, 0, sizeof(vparams));
2785 memset(&aparams, 0, sizeof(aparams));
hualing chendf118dd2020-05-21 15:49:11 +08002786 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002787 //valid audio pid, start audio
hualing chen969fe7b2021-05-26 15:13:17 +08002788 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2789 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08002790 DVR_PB_INFO("start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08002791 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08002792 AmTsPlayer_setADParams(player->handle, &adparams);
2793 AmTsPlayer_enableADMix(player->handle);
2794 }
2795
hualing chenc70a8df2020-05-12 19:23:11 +08002796 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 +08002797 player->has_audio = DVR_TRUE;
hualing chen1679f812021-11-08 15:17:46 +08002798 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen266b9502020-04-04 17:39:39 +08002799 AmTsPlayer_setAudioParams(player->handle, &aparams);
2800 AmTsPlayer_startAudioDecoding(player->handle);
2801 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002802 DVR_PB_INFO("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 +08002803 }
hualing chendf118dd2020-05-21 15:49:11 +08002804
hualing chen87072a82020-03-12 16:20:12 +08002805 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2806 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2807 player->cmd.state = DVR_PLAYBACK_STATE_START;
2808 player->state = DVR_PLAYBACK_STATE_START;
2809 } else {
2810 player->cmd.last_cmd = player->cmd.cur_cmd;
2811 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2812 player->cmd.state = DVR_PLAYBACK_STATE_START;
2813 player->state = DVR_PLAYBACK_STATE_START;
2814 }
Wentao MA96f68962022-06-15 19:45:35 +08002815 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002816 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002817 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
Wentao MA96f68962022-06-15 19:45:35 +08002818 DVR_PB_INFO("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002819 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002820 player->first_frame = 0;
2821 if (player->has_video)
2822 AmTsPlayer_pauseVideoDecoding(player->handle);
2823 if (player->has_audio)
2824 AmTsPlayer_pauseAudioDecoding(player->handle);
2825
hualing chene41f4372020-06-06 16:29:17 +08002826 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08002827 DVR_PB_INFO("dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002828 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002829 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002830 }
hualing chen041c4092020-04-05 15:11:50 +08002831 if (player->has_audio)
2832 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002833 DVR_PB_INFO("set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen9811b212020-10-29 11:21:44 +08002834 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2835 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chend1686e52022-01-05 17:10:42 +08002836 player->cmd.state = DVR_PLAYBACK_STATE_START;
2837 player->state = DVR_PLAYBACK_STATE_START;
Wentao MA96f68962022-06-15 19:45:35 +08002838 DVR_PB_INFO("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002839 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002840 } else {
2841 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2842 {
Wentao MA96f68962022-06-15 19:45:35 +08002843 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002844 dvr_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002845 player->first_frame = 0;
2846 if (player->has_video)
2847 AmTsPlayer_pauseVideoDecoding(player->handle);
2848 if (player->has_audio)
2849 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002850 //clear flag
Wentao MA96f68962022-06-15 19:45:35 +08002851 DVR_PB_INFO("clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002852 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2853 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002854 if (player->has_video) {
2855 AmTsPlayer_resumeVideoDecoding(player->handle);
2856 }
2857 if (player->has_audio)
2858 AmTsPlayer_resumeAudioDecoding(player->handle);
Wentao MA96f68962022-06-15 19:45:35 +08002859 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002860 dvr_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002861 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002862 }
2863 return DVR_SUCCESS;
2864}
2865
hualing chena540a7e2020-03-27 16:44:05 +08002866static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2867
2868 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2869 DVR_PlaybackSegmentInfo_t *segment = NULL;
2870 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2871 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2872
2873 list_for_each_entry(segment, &player->segment_list, head)
2874 {
2875 if (segment->segment_id == segment_id) {
2876 cur_segment = segment;
2877 }
2878 if (segment->segment_id == set_seg_id) {
2879 set_segment = segment;
2880 }
2881 if (cur_segment != NULL && set_segment != NULL) {
2882 break;
2883 }
2884 }
2885 if (cur_segment == NULL || set_segment == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002886 DVR_PB_INFO("set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002887 return DVR_TRUE;
2888 }
2889 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2890 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2891 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2892 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
Wentao MA96f68962022-06-15 19:45:35 +08002893 DVR_PB_INFO("cur v[%d]a[%d] set v[%d]a[%d]",cur_segment->pids.video.pid,cur_segment->pids.audio.pid,set_segment->pids.video.pid,set_segment->pids.audio.pid);
hualing chena540a7e2020-03-27 16:44:05 +08002894 return DVR_TRUE;
2895 }
Wentao MA96f68962022-06-15 19:45:35 +08002896 DVR_PB_INFO("play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002897 return DVR_FALSE;
2898}
2899
hualing chen03fd4942021-07-15 15:56:41 +08002900/**\brief set limit
2901 * \param[in] handle playback handle
2902 * \param[in] rec start time ms
2903 * \param[in] rec limit time ms
2904 * \retval DVR_SUCCESS On success
2905 * \return Error code
2906 */
hualing chen7ea70a72021-09-09 11:25:13 +08002907int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08002908{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2909
2910 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002911 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08002912 return DVR_FAILURE;
2913 }
hualing chen7ea70a72021-09-09 11:25:13 +08002914 _dvr_getClock_sec();
Wentao MA96f68962022-06-15 19:45:35 +08002915 DVR_PB_INFO("lock time %lu limit: %u player->state:%d", time, limit, player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002916 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002917 player->rec_start = time;
2918 player->limit = limit;
Wentao MA96f68962022-06-15 19:45:35 +08002919 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002920 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08002921 return DVR_SUCCESS;
2922}
2923
hualing chen5cbe1a62020-02-10 16:36:36 +08002924/**\brief seek
2925 * \param[in] handle playback handle
2926 * \param[in] time_offset time offset base cur segment
2927 * \retval DVR_SUCCESS On success
2928 * \return Error code
2929 */
hualing chencc91e1c2020-02-28 13:26:17 +08002930int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002931 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002932 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08002933 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08002934 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002935 return DVR_FAILURE;
2936 }
2937
Wentao MA96f68962022-06-15 19:45:35 +08002938 DVR_PB_INFO("lock segment_id %llu cur id %llu time_offset %u cur end: %d player->state:%d", segment_id,player->cur_segment_id, (uint32_t)time_offset, _dvr_get_end_time(handle), player->state);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002939 dvr_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002940
hualing chen86e7d482020-01-16 15:13:33 +08002941 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002942 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
Wentao MA96f68962022-06-15 19:45:35 +08002943 DVR_PB_INFO("player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002944
hualing chen5cbe1a62020-02-10 16:36:36 +08002945 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08002946 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002947 if (ret ==DVR_FAILURE) {
Wentao MA96f68962022-06-15 19:45:35 +08002948 DVR_PB_INFO("unlock seek error at open segment");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08002949 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002950 return DVR_FAILURE;
2951 }
2952 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2953 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
Wentao MA96f68962022-06-15 19:45:35 +08002954 DVR_PB_INFO("is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002955 time_offset = _dvr_get_end_time(handle);
2956 } else {
Wentao MA96f68962022-06-15 19:45:35 +08002957 DVR_PB_INFO("is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002958 time_offset = _dvr_get_end_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08002959 ret = DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08002960 }
2961 }
2962
Wentao MA96f68962022-06-15 19:45:35 +08002963 DVR_PB_INFO("seek open id[%lld]flag[0x%x] time_offset %u",
hualing chen03fd4942021-07-15 15:56:41 +08002964 player->cur_segment.segment_id,
2965 player->cur_segment.flags,
2966 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08002967 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002968 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2969 //forward playback.not seek end of file
2970 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2971 //default -2000ms
2972 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2973 }
hualing chen86e7d482020-01-16 15:13:33 +08002974 }
Wentao MA01de0e62022-01-10 18:48:23 +08002975 // Seek can be regarded as a new playback, so keep the start segment_id for it also
hualing chen8a657f32021-08-30 13:12:49 +08002976 if (player->need_seek_start == DVR_TRUE) {
2977 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
Wentao MA01de0e62022-01-10 18:48:23 +08002978 player->first_start_id = player->cur_segment.segment_id;
hualing chen8a657f32021-08-30 13:12:49 +08002979 }
hualing chen2aba4022020-03-02 13:49:55 +08002980 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002981 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002982 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002983 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
Wentao MA96f68962022-06-15 19:45:35 +08002984 DVR_PB_ERROR("seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08002985 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002986 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002987
hualing chen2aba4022020-03-02 13:49:55 +08002988 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002989
2990 player->last_send_time_id = UINT64_MAX;
hualing chen03fd4942021-07-15 15:56:41 +08002991 player->last_segment_tatol = 0LL;
2992 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08002993 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002994 player->fffb_current = _dvr_time_getClock();
2995 player->fffb_start = player->fffb_current;
2996 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2997 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002998 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002999 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003000 //only seek file,not start
Wentao MA96f68962022-06-15 19:45:35 +08003001 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003002 dvr_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08003003 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08003004 }
hualing chen86e7d482020-01-16 15:13:33 +08003005 //stop play
Wentao MA96f68962022-06-15 19:45:35 +08003006 DVR_PB_ERROR("seek stop play, not inject data has video[%d]audio[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003007 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08003008
hualing chen266b9502020-04-04 17:39:39 +08003009 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08003010 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003011 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003012 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003013 }
3014
hualing chen40dd5462021-11-26 19:56:20 +08003015
hualing chen266b9502020-04-04 17:39:39 +08003016 if (player->has_audio) {
3017 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003018 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08003019 }
hualing chendf118dd2020-05-21 15:49:11 +08003020 if (player->has_ad_audio) {
3021 player->has_ad_audio =DVR_FALSE;
3022 AmTsPlayer_disableADMix(player->handle);
3023 }
3024
hualing chen86e7d482020-01-16 15:13:33 +08003025 //start play
hualing chen2aba4022020-03-02 13:49:55 +08003026 am_tsplayer_video_params vparams;
3027 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003028 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08003029
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003030 memset(&vparams, 0, sizeof(vparams));
3031 memset(&aparams, 0, sizeof(aparams));
3032
hualing chen040df222020-01-17 13:35:02 +08003033 player->cur_segment_id = segment_id;
3034
3035 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08003036 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08003037 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08003038 //start audio and video
hualing chena5f03222021-12-02 11:22:35 +08003039 if (vparams.pid != player->fake_pid && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
3040 //audio and video pid is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003041 DVR_PB_ERROR("unlock seek start dvr play back start error, not found audio and video info [0x%x]", vparams.pid);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003042 dvr_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08003043 return -1;
3044 }
Wentao MA96f68962022-06-15 19:45:35 +08003045 DVR_PB_ERROR("seek start[0x%x]", vparams.pid);
hualing chen86e7d482020-01-16 15:13:33 +08003046 //add
hualing chen040df222020-01-17 13:35:02 +08003047 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08003048 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003049 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08003050 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08003051 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08003052 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08003053 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003054 //if is pause state. we need set trick mode.
Wentao MA96f68962022-06-15 19:45:35 +08003055 DVR_PB_INFO("seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003056 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08003057 }
Wentao MA96f68962022-06-15 19:45:35 +08003058 DVR_PB_INFO("start video");
hualing chen2aba4022020-03-02 13:49:55 +08003059 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003060 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003061 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08003062 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
3063 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
3064 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
3065 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
3066 AmTsPlayer_stopFast(player->handle);
3067 }
hualing chen266b9502020-04-04 17:39:39 +08003068 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08003069 } else {
3070 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08003071 }
hualing chene41f4372020-06-06 16:29:17 +08003072 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08003073 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003074 DVR_PB_INFO("start ad audio");
hualing chen1679f812021-11-08 15:17:46 +08003075 dvr_playback_change_seek_state(handle, adparams.pid);
hualing chendf118dd2020-05-21 15:49:11 +08003076 AmTsPlayer_setADParams(player->handle, &adparams);
3077 AmTsPlayer_enableADMix(player->handle);
3078 }
hualing chen969fe7b2021-05-26 15:13:17 +08003079 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
Wentao MA96f68962022-06-15 19:45:35 +08003080 DVR_PB_INFO("start audio seek");
hualing chen1679f812021-11-08 15:17:46 +08003081 dvr_playback_change_seek_state(handle, aparams.pid);
hualing chen969fe7b2021-05-26 15:13:17 +08003082 AmTsPlayer_setAudioParams(player->handle, &aparams);
3083 AmTsPlayer_startAudioDecoding(player->handle);
3084 player->has_audio = DVR_TRUE;
3085 }
hualing chen43a89bc2022-01-19 14:31:20 +08003086#ifdef AVSYNC_USED_PCR
3087 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003088 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003089 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3090 }
3091#endif
hualing chen86e7d482020-01-16 15:13:33 +08003092 }
hualing chen1ffd85b2021-08-16 15:18:43 +08003093 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen2aba4022020-03-02 13:49:55 +08003094 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
3095 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chena5f03222021-12-02 11:22:35 +08003096 if (VALID_PID(aparams.pid) || VALID_PID(vparams.pid))
3097 player->seek_pause = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003098 DVR_PB_INFO("set state pause in seek vpid[0x%x]apid[0x%x]",vparams.pid, aparams.pid);
hualing chen87072a82020-03-12 16:20:12 +08003099 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3100 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08003101 player->speed > 1.0f||
3102 player->speed <= -1.0f) {
Wentao MA96f68962022-06-15 19:45:35 +08003103 DVR_PB_INFO("not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08003104 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08003105 } else {
Wentao MA96f68962022-06-15 19:45:35 +08003106 DVR_PB_INFO("set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08003107 player->cmd.last_cmd = player->cmd.cur_cmd;
3108 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
3109 player->cmd.state = DVR_PLAYBACK_STATE_START;
3110 player->state = DVR_PLAYBACK_STATE_START;
3111 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003112 player->last_send_time_id = UINT64_MAX;
Wentao MA96f68962022-06-15 19:45:35 +08003113 DVR_PB_DEBUG("unlock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003114 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003115
3116 return DVR_SUCCESS;
3117}
hualing chen5cbe1a62020-02-10 16:36:36 +08003118
Wentao MAac5ea062022-08-11 11:44:27 +08003119// Get current playback time position of the ongoing segment.
3120// Notice the return value may be negative. This is because previous segment's
3121// data cached in demux buffer need to be considered.
hualing chen5cbe1a62020-02-10 16:36:36 +08003122static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
3123 //get cur time of segment
3124 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003125
Gong Ke2a0ebbe2021-05-25 15:22:50 +08003126 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003127 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003128 return DVR_FAILURE;
3129 }
3130
hualing chen31140872020-03-25 12:29:26 +08003131 int64_t cache = 0;//defalut es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08003132 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003133 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
hualing chena5f03222021-12-02 11:22:35 +08003134 uint64_t cur = 0;
3135 if (player->ts_cache_len > 0 && pos < 0) {
3136 //this case is open new segment end,but cache data is last segment.
3137 //we need used last segment len to send play time.
3138 cur = 0;
3139 } else {
3140 cur = segment_tell_position_time(player->r_handle, pos);
3141 }
hualing chen21a40372021-10-29 11:07:26 +08003142 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08003143 pthread_mutex_unlock(&player->segment_lock);
Wentao MA96f68962022-06-15 19:45:35 +08003144 DVR_PB_INFO("get cur time [%lld] cache:%lld cur id [%lld]last id [%lld] pb cache len [%d] [%lld]", cur, cache, player->cur_segment_id,player->last_send_time_id, player->ts_cache_len, pos);
hualing chen87072a82020-03-12 16:20:12 +08003145 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3146 cache = 0;
3147 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003148 int cur_time = (int)(cur > cache ? cur - cache : 0);
3149 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08003150}
3151
Wentao MAac5ea062022-08-11 11:44:27 +08003152// Get current playback time position of the ongoing segment.
3153// Notice the return value may be negative. This is because previous segment's
3154// data cached in demux buffer need to be considered.
hualing chen969fe7b2021-05-26 15:13:17 +08003155static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
3156 //get cur time of segment
3157 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3158
hualing chen03fd4942021-07-15 15:56:41 +08003159 if (player == NULL || player->handle == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003160 DVR_PB_INFO("player is NULL");
hualing chen969fe7b2021-05-26 15:13:17 +08003161 return DVR_FAILURE;
3162 }
3163
3164 int64_t cache = 0;//defalut es buf cache 500ms
3165 int cur_time = 0;
hualing chen969fe7b2021-05-26 15:13:17 +08003166 pthread_mutex_lock(&player->segment_lock);
hualing chena5f03222021-12-02 11:22:35 +08003167 loff_t tmp_pos = segment_tell_position(player->r_handle);
3168 loff_t pos = tmp_pos - player->ts_cache_len;
3169 uint64_t cur = 0;
3170 if (player->ts_cache_len > 0 && (tmp_pos < player->ts_cache_len)) {
3171 //this case is open new segment end,but cache data is last segment.
3172 //we need used last segment len to send play time.
3173 cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003174 DVR_PB_INFO("change segment [%lld][%lld]",
hualing chen926a8ec2021-12-20 20:38:24 +08003175 player->last_segment_id, player->cur_segment_id);
hualing chena5f03222021-12-02 11:22:35 +08003176 } else {
3177 cur = segment_tell_position_time(player->r_handle, pos);
3178 }
hualing chen21a40372021-10-29 11:07:26 +08003179 AmTsPlayer_getDelayTime(player->handle, &cache);
Wentao MAaf716972021-12-28 13:28:52 +08003180
hualing chen969fe7b2021-05-26 15:13:17 +08003181 pthread_mutex_unlock(&player->segment_lock);
Wentao MA01de0e62022-01-10 18:48:23 +08003182
3183 // The idea here is to work around a weakness of AmTsPlayer_getDelayTime at
3184 // starting phase of a playback in a short period of 20ms or less. During the
3185 // said period, getDelayTime does NOT work as expect to return real cache
3186 // length because demux isn't actually running to provide valid pts to
3187 // TsPlayer. "cache==0" implies the situation that playback is NOT actually
3188 // started. Under such conditions a '0' cache size may NOT reflect actual data
3189 // length remaining in TsPlayer cache, therefore corresponding libdvr 'cur' is
3190 // useless if data in TsPlayer cache is not considered, so it needs to be
3191 // reset to a previos valid state. To make the reset operation stricter, extra
3192 // AmTsPlayer_getPts invocations on both video/audio are introduced to test if
3193 // TsPlayer can get valid pts which indicates the actual running status of
3194 // demux. (JIRA issue: SWPL-68740)
3195 if (player->first_start_id != UINT64_MAX && cache == 0
3196 && player->check_cache_flag == DVR_TRUE ) {
3197 uint64_t pts_a=0;
3198 uint64_t pts_v=0;
3199 AmTsPlayer_getPts(player->handle, TS_STREAM_AUDIO, &pts_a);
3200 AmTsPlayer_getPts(player->handle, TS_STREAM_VIDEO, &pts_v);
3201 if ((int64_t)pts_a <= 0 && (int64_t)pts_v <= 0) {
3202 // Identified the wired situation and just return previous valid state
3203 cur = player->first_start_time;
3204 *id = player->first_start_id;
3205 return cur;
3206 }
3207 }
3208 if (cache != 0) {
3209 // Do NOT permit to enter 'if' code block above any more
3210 player->check_cache_flag=DVR_FALSE;
3211 }
3212
Wentao MA96f68962022-06-15 19:45:35 +08003213 DVR_PB_INFO("***get play cur time [%lld] cache:%lld cur id [%lld]"
3214 " last id [%lld] pb cache len [%d] pos [%lld][%lld]",
hualing chen926a8ec2021-12-20 20:38:24 +08003215 cur,
3216 cache,
3217 player->cur_segment_id,
3218 player->last_send_time_id,
3219 player->ts_cache_len,
3220 pos,
3221 tmp_pos);
hualing chen969fe7b2021-05-26 15:13:17 +08003222 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3223 cache = 0;
3224 }
3225 if (cur > cache) {
3226 cur_time = (int)(cur - cache);
3227 *id = player->cur_segment_id;
3228 } else if (player->last_segment_tatol > 0) {
hualing chend1686e52022-01-05 17:10:42 +08003229 //if at fb mode,we not used last id to replace cur id if cache > cur time.
3230 //this case only used for normal speed or ff speed
3231 if (!IS_FB(player->speed) && player->last_segment_id <= player->cur_segment_id) {
3232 if (player->last_segment_tatol > (cache - cur))
3233 cur_time = (int)(player->last_segment_tatol - (cache - cur));
3234 else
3235 cur_time = (int)(player->last_segment_tatol - cur);
hualing chen8a657f32021-08-30 13:12:49 +08003236
hualing chend1686e52022-01-05 17:10:42 +08003237 *id = player->last_segment_id;
3238 } else {//fb mode
3239 cur_time = (int)(cur);
3240 *id = player->cur_segment_id;
3241 }
Wentao MA96f68962022-06-15 19:45:35 +08003242 DVR_PB_INFO("get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_tatol);
hualing chen969fe7b2021-05-26 15:13:17 +08003243 } else {
3244 cur_time = 0;
3245 *id = player->cur_segment_id;
3246 }
hualing chen969fe7b2021-05-26 15:13:17 +08003247 return cur_time;
3248}
3249
hualing chencc91e1c2020-02-28 13:26:17 +08003250//get current segment current pcr time of read pos
3251static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
3252 //get cur time of segment
3253 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003254
3255 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003256 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003257 return DVR_FAILURE;
3258 }
3259
hualing chen2aba4022020-03-02 13:49:55 +08003260 pthread_mutex_lock(&player->segment_lock);
3261 uint64_t end = segment_tell_total_time(player->r_handle);
Wentao MA96f68962022-06-15 19:45:35 +08003262 DVR_PB_INFO("get total time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08003263 pthread_mutex_unlock(&player->segment_lock);
3264 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08003265}
3266
hualing chen03fd4942021-07-15 15:56:41 +08003267DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
3268{
3269 //check is set limit info
3270 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3271
3272 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003273 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003274 return DVR_FALSE;
3275 }
3276 if (player->rec_start > 0 || player->limit > 0) {
3277 return DVR_TRUE;
3278 }
3279 return DVR_FALSE;
3280}
3281
3282/**\brief set DVR playback calculate expired time len
3283 * \param[in] handle, DVR playback session handle
3284 * \return DVR_SUCCESS on success
3285 * \return error code on failure
3286 */
hualing chen7ea70a72021-09-09 11:25:13 +08003287uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08003288{
3289 //calculate expired time to play
3290 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08003291 uint32_t cur_time;
3292 uint32_t tmp_time;
3293 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003294 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003295 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003296 return expired;
3297 }
hualing chen7ea70a72021-09-09 11:25:13 +08003298 if (player->rec_start == 0 || player->limit == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003299 DVR_PB_INFO("rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08003300 return expired;
3301 }
3302 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08003303 cur_time = _dvr_getClock_sec();
3304 if ((cur_time - player->rec_start) > player->limit) {
3305 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
3306 expired = *(int*)&tmp_time;
Wentao MA96f68962022-06-15 19:45:35 +08003307 DVR_PB_INFO("cur_time:%u, rec start:%u limit:%d c_r_diff:%u expired:%u tmp_time:%u",
hualing chen03fd4942021-07-15 15:56:41 +08003308 cur_time,
3309 player->rec_start,
3310 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003311 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3312 }
hualing chen03fd4942021-07-15 15:56:41 +08003313 return expired;
3314}
3315
3316/**\brief set DVR playback obsolete time
3317 * \param[in] handle, DVR playback session handle
3318 * \param[in] obsolete, obsolete len
3319 * \return DVR_SUCCESS on success
3320 * \return error code on failure
3321 */
3322int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3323{
3324 int expired = 0;
3325 //calculate expired time to play
3326 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3327
3328 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003329 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003330 return DVR_FALSE;
3331 }
3332 //get system time
Wentao MA96f68962022-06-15 19:45:35 +08003333 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003334 dvr_mutex_lock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003335 player->obsolete = obsolete;
Wentao MA96f68962022-06-15 19:45:35 +08003336 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003337 dvr_mutex_unlock(&player->lock);
hualing chen03fd4942021-07-15 15:56:41 +08003338 return expired;
3339}
3340
3341/**\brief update DVR playback newest segment duration
3342 * \param[in] handle, DVR playback session handle
3343 * \param[in] segmentid, newest segment id
3344 * \param[in] dur dur time ms
3345 * \return DVR_SUCCESS on success
3346 * \return error code on failure
3347 */
3348int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3349uint64_t segmentid, int dur)
3350{
3351 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3352 DVR_PlaybackSegmentInfo_t *segment;
3353 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3354
3355 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003356 DVR_PB_INFO(" player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003357 return DVR_FAILURE;
3358 }
3359 //update the newest segment duration on timeshift mode
3360 list_for_each_entry(segment, &player->segment_list, head)
3361 {
3362 if (segment->segment_id == segmentid) {
3363 segment->duration = dur;
3364 break;
3365 }
3366 pre_segment = segment;
3367 }
3368
3369 return DVR_SUCCESS;
3370}
3371
hualing chen7ea70a72021-09-09 11:25:13 +08003372static uint32_t dvr_playback_calculate_last_valid_segment(
3373 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003374{
hualing chen7ea70a72021-09-09 11:25:13 +08003375 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003376 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003377 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003378 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003379 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003380 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3381
3382 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003383 DVR_PB_INFO("player is NULL");
hualing chen03fd4942021-07-15 15:56:41 +08003384 return DVR_FAILURE;
3385 }
3386 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003387 if (expired == 0) {
3388 *segmentid = player->cur_segment_id;
3389 *pos = 0;
3390 return DVR_SUCCESS;
3391 }
hualing chen03fd4942021-07-15 15:56:41 +08003392 DVR_PlaybackSegmentInfo_t *pseg;
3393 list_for_each_entry_reverse(pseg, &player->segment_list, head) {
3394 segment_id = pseg->segment_id;
3395
3396 if ((player->obsolete + pre_off + pseg->duration) > expired)
3397 break;
3398
3399 last_segment_id = pseg->segment_id;
3400 pre_off += pseg->duration;
3401 }
3402
3403 if (last_segment_id == segment_id) {
3404 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3405 off = expired;
3406 } else if (player->obsolete >= expired) {
3407 off = 0;
3408 } else {
3409 off = expired - pre_off - player->obsolete;
3410 }
3411 *segmentid = segment_id;
3412 *pos = off;
3413 return DVR_SUCCESS;
3414}
3415
hualing chen4b7c15d2020-04-07 16:13:48 +08003416#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003417//start replay
3418static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3419
3420 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3421 //calculate pcr seek time
3422 int t_diff = 0;
3423 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003424 uint64_t segmentid = 0;
3425 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003426 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003427 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003428 return DVR_FAILURE;
3429 }
3430
hualing chen5cbe1a62020-02-10 16:36:36 +08003431 if (player->fffb_start == -1) {
3432 //set fffb start time ms
3433 player->fffb_start = _dvr_time_getClock();
3434 player->fffb_current = player->fffb_start;
3435 //get segment current time pos
3436 player->fffb_start_pcr = _dvr_get_cur_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003437 DVR_PB_INFO("calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
hualing chen03fd4942021-07-15 15:56:41 +08003438 player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003439 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08003440 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003441 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003442 } else {
3443 player->fffb_current = _dvr_time_getClock();
3444 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003445 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003446 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003447 if (seek_time <= 0) {
3448 //need seek to pre one segment
3449 seek_time = 0;
3450 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003451 //seek segment pos
3452 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003453 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003454 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003455 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3456 //set seek time to 0;
Wentao MA96f68962022-06-15 19:45:35 +08003457 DVR_PB_INFO("segment seek to 0 at fb mode [%d]id[%lld]",
hualing chen03fd4942021-07-15 15:56:41 +08003458 seek_time,
3459 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003460 seek_time = 0;
3461 }
hualing chen03fd4942021-07-15 15:56:41 +08003462 if (IS_FB(player->speed)
3463 && dvr_playback_check_limit(handle)) {
3464 //fb case.check expired time
3465 //get id and pos to check if we can seek to this pos
3466 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3467 //case cur id < segment id
3468 if (player->cur_segment_id < segmentid) {
3469 //expired ts data is player,return error
3470 //
3471 pthread_mutex_unlock(&player->segment_lock);
3472 return 0;
3473 } else if (player->cur_segment_id == segmentid) {
3474 //id is same,compare seek pos
3475 if (seek_time < pos) {
3476 //expired ts data is player,return error
3477 //
3478 pthread_mutex_unlock(&player->segment_lock);
3479 return 0;
3480 }
3481 }
3482 //case can play
3483 }
hualing chen041c4092020-04-05 15:11:50 +08003484 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
3485 seek_time = 0;
3486 }
hualing chen2aba4022020-03-02 13:49:55 +08003487 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003488 } else {
3489 //
Wentao MA96f68962022-06-15 19:45:35 +08003490 DVR_PB_INFO("segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003491 }
Wentao MA96f68962022-06-15 19:45:35 +08003492 DVR_PB_INFO("calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003493 seek_time,
3494 player->speed,
3495 player->cur_segment_id,
3496 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003497 }
hualing chen2aba4022020-03-02 13:49:55 +08003498 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003499}
3500
3501
3502//start replay
3503static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3504 //
3505 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003506
3507 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003508 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003509 return DVR_FAILURE;
3510 }
3511
hualing chen5cbe1a62020-02-10 16:36:36 +08003512 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003513 if (player->has_video) {
Wentao MA96f68962022-06-15 19:45:35 +08003514 DVR_PB_INFO("fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003515 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003516 AmTsPlayer_stopVideoDecoding(player->handle);
3517 }
3518 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003519 DVR_PB_INFO("fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003520 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003521 AmTsPlayer_stopAudioDecoding(player->handle);
3522 }
hualing chendf118dd2020-05-21 15:49:11 +08003523 if (player->has_ad_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003524 DVR_PB_INFO("fffb stop audio");
hualing chendf118dd2020-05-21 15:49:11 +08003525 player->has_ad_audio =DVR_FALSE;
3526 AmTsPlayer_disableADMix(player->handle);
3527 }
hualing chen2aba4022020-03-02 13:49:55 +08003528
hualing chen5cbe1a62020-02-10 16:36:36 +08003529 //start video and audio
3530
hualing chen2aba4022020-03-02 13:49:55 +08003531 am_tsplayer_video_params vparams;
3532 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003533 am_tsplayer_audio_params adparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003534
3535 memset(&vparams, 0, sizeof(vparams));
3536 memset(&aparams, 0, sizeof(aparams));
3537
hualing chen87072a82020-03-12 16:20:12 +08003538 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003539
3540 //get segment info and audio video pid fmt ;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003541 //dvr_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08003542 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003543 //start audio and video
3544 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
3545 //audio abnd video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003546 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003547 return -1;
3548 }
3549
3550 if (VALID_PID(vparams.pid)) {
3551 player->has_video = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003552 DVR_PB_INFO("fffb start video");
3553 //DVR_PB_INFO("fffb start video and save last frame");
hualing chen0888c032020-12-18 17:54:57 +08003554 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003555 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003556 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
3557 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003558 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003559 AmTsPlayer_startVideoDecoding(player->handle);
3560 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003561 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003562 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003563 }
hualing chen31140872020-03-25 12:29:26 +08003564 //fffb mode need stop fast;
Wentao MA96f68962022-06-15 19:45:35 +08003565 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003566 AmTsPlayer_stopFast(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003567 return 0;
3568}
3569
3570static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3571 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003572 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003573 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003574 return DVR_FAILURE;
3575 }
3576
3577 player->first_frame = 0;
Wentao MA96f68962022-06-15 19:45:35 +08003578 DVR_PB_INFO("lock speed [%f]", player->speed);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003579 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003580
hualing chen2aba4022020-03-02 13:49:55 +08003581 int seek_time = _dvr_playback_calculate_seekpos(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003582 DVR_PB_INFO("get lock speed [%f]id [%lld]seek_time[%d]", player->speed, player->cur_segment_id, seek_time);
hualing chen041c4092020-04-05 15:11:50 +08003583
hualing chen87072a82020-03-12 16:20:12 +08003584 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3585 //seek time set 0
3586 seek_time = 0;
3587 }
hualing chen041c4092020-04-05 15:11:50 +08003588 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003589 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3590 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003591 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003592 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003593 DVR_PB_DEBUG("unlock");
hualing chen87072a82020-03-12 16:20:12 +08003594 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003595 //send event here and pause
3596 DVR_Play_Notify_t notify;
3597 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003598 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003599 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003600 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
Wentao MA96f68962022-06-15 19:45:35 +08003601 DVR_PB_INFO("*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08003602 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003603 return DVR_SUCCESS;
3604 }
hualing chen2932d372020-04-29 13:44:00 +08003605 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003606 _dvr_init_fffb_time(handle);
Wentao MA96f68962022-06-15 19:45:35 +08003607 DVR_PB_INFO("*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003608 }
3609 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003610 _dvr_playback_fffb_replay(handle);
3611
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003612 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003613 DVR_PB_DEBUG("unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003614
hualing chen5cbe1a62020-02-10 16:36:36 +08003615 return DVR_SUCCESS;
3616}
3617
hualing chen87072a82020-03-12 16:20:12 +08003618//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003619static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003620 //
3621 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003622
3623 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003624 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003625 return DVR_FAILURE;
3626 }
3627
hualing chen5cbe1a62020-02-10 16:36:36 +08003628 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003629 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003630 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003631 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003632 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003633 }
3634
3635 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003636 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003637 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003638 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003639 //start video and audio
3640
hualing chen2aba4022020-03-02 13:49:55 +08003641 am_tsplayer_video_params vparams;
3642 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003643 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08003644 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003645
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003646 memset(&vparams, 0, sizeof(vparams));
3647 memset(&aparams, 0, sizeof(aparams));
3648
hualing chen5cbe1a62020-02-10 16:36:36 +08003649 //get segment info and audio video pid fmt ;
Wentao MA96f68962022-06-15 19:45:35 +08003650 DVR_PB_INFO("into");
hualing chendf118dd2020-05-21 15:49:11 +08003651 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003652 //start audio and video
3653 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003654 //audio and video pis is all invalid, return error.
Wentao MA96f68962022-06-15 19:45:35 +08003655 DVR_PB_ERROR("dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003656 return -1;
3657 }
3658
3659 if (VALID_PID(vparams.pid)) {
3660 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003661 if (trick == DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003662 DVR_PB_INFO("settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003663 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003664 }
hualing chen266b9502020-04-04 17:39:39 +08003665 else {
hualing chen2aba4022020-03-02 13:49:55 +08003666 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003667 }
hualing chen2aba4022020-03-02 13:49:55 +08003668 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003669 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003670 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003671 }
hualing chena540a7e2020-03-27 16:44:05 +08003672
3673 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
Wentao MA96f68962022-06-15 19:45:35 +08003674 DVR_PB_INFO("start fast");
hualing chen31140872020-03-25 12:29:26 +08003675 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003676 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003677 } else {
hualing chendf118dd2020-05-21 15:49:11 +08003678 if (VALID_PID(adparams.pid)) {
3679 player->has_ad_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003680 DVR_PB_INFO("start ad audio");
hualing chendf118dd2020-05-21 15:49:11 +08003681 AmTsPlayer_setADParams(player->handle, &adparams);
3682 AmTsPlayer_enableADMix(player->handle);
3683 }
hualing chen969fe7b2021-05-26 15:13:17 +08003684 if (VALID_PID(aparams.pid)) {
3685 player->has_audio = DVR_TRUE;
Wentao MA96f68962022-06-15 19:45:35 +08003686 DVR_PB_INFO("start audio");
hualing chen969fe7b2021-05-26 15:13:17 +08003687 AmTsPlayer_setAudioParams(player->handle, &aparams);
3688 AmTsPlayer_startAudioDecoding(player->handle);
3689 }
hualing chendf118dd2020-05-21 15:49:11 +08003690
Wentao MA96f68962022-06-15 19:45:35 +08003691 DVR_PB_INFO("stop fast");
hualing chen31140872020-03-25 12:29:26 +08003692 AmTsPlayer_stopFast(player->handle);
3693 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3694 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3695 }
hualing chen43a89bc2022-01-19 14:31:20 +08003696#ifdef AVSYNC_USED_PCR
3697 if (player && VALID_PID(player->cur_segment.pids.pcr.pid)) {
Wentao MA96f68962022-06-15 19:45:35 +08003698 DVR_PB_INFO("start set pcr [%d]", player->cur_segment.pids.pcr.pid);
hualing chen43a89bc2022-01-19 14:31:20 +08003699 AmTsPlayer_setPcrPid(player->handle, player->cur_segment.pids.pcr.pid);
3700 }
3701#endif
hualing chen2aba4022020-03-02 13:49:55 +08003702 player->cmd.last_cmd = player->cmd.cur_cmd;
3703 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003704 player->cmd.state = DVR_PLAYBACK_STATE_START;
3705 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08003706 return 0;
3707}
3708
3709
hualing chenb31a6c62020-01-13 17:27:00 +08003710/**\brief Set play speed
3711 * \param[in] handle playback handle
3712 * \param[in] speed playback speed
3713 * \retval DVR_SUCCESS On success
3714 * \return Error code
3715 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003716int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3717
3718 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003719
3720 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003721 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003722 return DVR_FAILURE;
3723 }
3724
hualing chena540a7e2020-03-27 16:44:05 +08003725 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
Wentao MA96f68962022-06-15 19:45:35 +08003726 DVR_PB_INFO(" func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003727 return DVR_FAILURE;
3728 }
hualing chenf00cdc82020-06-10 14:23:35 +08003729 if (speed.speed.speed == player->cmd.speed.speed.speed) {
Wentao MA96f68962022-06-15 19:45:35 +08003730 DVR_PB_INFO(" func: eq speed [%d]", speed.speed.speed);
hualing chenf00cdc82020-06-10 14:23:35 +08003731 return DVR_SUCCESS;
3732 }
Wentao MA96f68962022-06-15 19:45:35 +08003733 DVR_PB_INFO("lock func: speed [%d]", speed.speed.speed);
hualing chen1679f812021-11-08 15:17:46 +08003734
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003735 dvr_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003736 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3737 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3738 player->cmd.last_cmd = player->cmd.cur_cmd;
3739 }
hualing chene41f4372020-06-06 16:29:17 +08003740
hualing chen31140872020-03-25 12:29:26 +08003741 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003742 IS_KERNEL_SPEED(speed.speed.speed) ) {
3743 //case 1. not start play.only set speed
3744 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3745 //only set speed.and return;
3746 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3747 player->cmd.speed.speed = speed.speed;
3748 player->speed = (float)speed.speed.speed/(float)100;
3749 player->fffb_play = DVR_FALSE;
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003750 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003751 DVR_PB_DEBUG("unlock");
hualing chenf00cdc82020-06-10 14:23:35 +08003752 return DVR_SUCCESS;
3753 }
3754 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003755 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3756 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003757 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003758 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3759 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003760 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003761 AmTsPlayer_stopFast(player->handle);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003762 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08003763 DVR_PB_DEBUG("unlock ---\r\n");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003764 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
Wentao MA96f68962022-06-15 19:45:35 +08003765 DVR_PB_DEBUG("lock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003766 dvr_mutex_lock(&player->lock);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003767 } else {
3768 //set play speed and if audio is start, stop audio.
3769 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003770 DVR_PB_INFO("fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003771 AmTsPlayer_stopAudioDecoding(player->handle);
3772 player->has_audio = DVR_FALSE;
3773 }
Wentao MA96f68962022-06-15 19:45:35 +08003774 DVR_PB_INFO("start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003775 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003776 }
hualing chenbcada022020-04-22 14:27:01 +08003777 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003778 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003779 player->cmd.speed.speed = speed.speed;
3780 player->speed = (float)speed.speed.speed/(float)100;
Wentao MA96f68962022-06-15 19:45:35 +08003781 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003782 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003783 return DVR_SUCCESS;
3784 }
hualing chen31140872020-03-25 12:29:26 +08003785 //case 3 fffb mode
3786 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3787 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3788 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003789 DVR_PB_INFO("set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003790 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003791 player->cmd.speed.speed = speed.speed;
3792 player->speed = (float)speed.speed.speed/(float)100;
3793 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003794 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003795 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003796 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003797 return DVR_SUCCESS;
3798 }
3799 }
3800 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003801 IS_KERNEL_SPEED(speed.speed.speed)) {
3802 //case 1. cur speed is kernel support speed,set kernel speed.
3803 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003804 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003805 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3806 // resume audio and stop fast play
Wentao MA96f68962022-06-15 19:45:35 +08003807 DVR_PB_INFO("stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003808 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08003809 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003810 } else {
3811 //set play speed and if audio is start, stop audio.
3812 if (player->has_audio) {
Wentao MA96f68962022-06-15 19:45:35 +08003813 DVR_PB_INFO("fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003814 AmTsPlayer_stopAudioDecoding(player->handle);
3815 player->has_audio = DVR_FALSE;
3816 }
Wentao MA96f68962022-06-15 19:45:35 +08003817 DVR_PB_INFO("start fast");
hualing chenf00cdc82020-06-10 14:23:35 +08003818 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003819 }
hualing chena540a7e2020-03-27 16:44:05 +08003820 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003821 player->cmd.speed.speed = speed.speed;
3822 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003823 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003824 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003825 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003826 return DVR_SUCCESS;
3827 }
3828 //case 2 fffb mode
3829 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3830 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3831 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003832 DVR_PB_INFO("set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003833 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003834 player->cmd.speed.speed = speed.speed;
3835 player->speed = (float)speed.speed.speed/(float)100;
3836 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08003837 player->fffb_play = DVR_FALSE;
Wentao MA96f68962022-06-15 19:45:35 +08003838 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003839 dvr_mutex_unlock(&player->lock);
hualing chen31140872020-03-25 12:29:26 +08003840 return DVR_SUCCESS;
3841 }
hualing chen31140872020-03-25 12:29:26 +08003842 }
hualing chena540a7e2020-03-27 16:44:05 +08003843 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3844 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003845 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003846 } else {
hualing chen31140872020-03-25 12:29:26 +08003847 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003848 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3849 else
3850 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003851 player->fffb_play = DVR_TRUE;
3852 }
3853 DVR_Bool_t init_last_time = DVR_FALSE;
3854 if (player->speed > 0.0f && speed.speed.speed < 0) {
3855 init_last_time = DVR_TRUE;
3856 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3857 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003858 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003859 player->cmd.speed.mode = speed.mode;
3860 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003861 player->speed = (float)speed.speed.speed/(float)100;
3862 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003863 _dvr_init_fffb_t(handle);
3864 if (init_last_time == DVR_TRUE)
3865 player->last_send_time_id = UINT64_MAX;
3866
hualing chen87072a82020-03-12 16:20:12 +08003867 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003868 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3869 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003870 //restart play at normal speed exit ff fb
Wentao MA96f68962022-06-15 19:45:35 +08003871 DVR_PB_INFO("set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003872 _dvr_playback_replay(handle, DVR_FALSE);
3873 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3874 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
3875 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
Wentao MA96f68962022-06-15 19:45:35 +08003876 DVR_PB_INFO("set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003877 }
Wentao MA96f68962022-06-15 19:45:35 +08003878 DVR_PB_INFO("unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003879 dvr_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003880 return DVR_SUCCESS;
3881}
hualing chen2932d372020-04-29 13:44:00 +08003882
hualing chenb31a6c62020-01-13 17:27:00 +08003883/**\brief Get playback status
3884 * \param[in] handle playback handle
3885 * \param[out] p_status playback status
3886 * \retval DVR_SUCCESS On success
3887 * \return Error code
3888 */
hualing chen2932d372020-04-29 13:44:00 +08003889static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3890 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003891//
3892 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003893 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003894 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08003895 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003896 return DVR_FAILURE;
3897 }
hualing chen1679f812021-11-08 15:17:46 +08003898 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003899 DVR_PB_DEBUG("lock");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003900 dvr_mutex_lock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003901 }
3902
hualing chen5cbe1a62020-02-10 16:36:36 +08003903 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003904 //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 +08003905 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3906 player->state == DVR_PLAYBACK_STATE_START) {
3907 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3908 }
hualing chen041c4092020-04-05 15:11:50 +08003909
hualing chencc91e1c2020-02-28 13:26:17 +08003910 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003911 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003912
3913 if (CONTROL_SPEED_ENABLE == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08003914 if (player->con_spe.ply_sta == 0) {
Wentao MA96f68962022-06-15 19:45:35 +08003915 DVR_PB_INFO("player dur[%u] sta[%u] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08003916 player->con_spe.ply_dur,
3917 player->con_spe.ply_sta,
3918 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003919 player->con_spe.ply_sta = p_status->time_cur;
3920 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3921 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
Wentao MA96f68962022-06-15 19:45:35 +08003922 DVR_PB_INFO("player dur[%u] sta[%u] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003923 player->con_spe.ply_dur,
3924 player->con_spe.ply_sta,
3925 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003926 player->con_spe.ply_sta = p_status->time_cur;
3927 }
3928
3929 if (player->con_spe.sys_sta == 0) {
3930 player->con_spe.sys_sta = _dvr_time_getClock();
3931 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3932 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3933 player->con_spe.sys_sta = _dvr_time_getClock();
3934 }
3935 }
3936
hualing chen4b7c15d2020-04-07 16:13:48 +08003937 if (player->last_send_time_id == UINT64_MAX) {
3938 player->last_send_time_id = player->cur_segment_id;
3939 player->last_cur_time = p_status->time_cur;
3940 }
3941 if (player->last_send_time_id == player->cur_segment_id) {
3942 if (player->speed > 0.0f ) {
3943 //ff
3944 if (p_status->time_cur < player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08003945 DVR_PB_INFO("get ff time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003946 player->last_cur_time,
3947 p_status->time_cur,
3948 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08003949 p_status->time_cur = player->last_cur_time;
3950 } else {
3951 player->last_cur_time = p_status->time_cur;
3952 }
hualing chene41f4372020-06-06 16:29:17 +08003953 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003954 //fb
3955 if (p_status->time_cur > player->last_cur_time ) {
Wentao MA96f68962022-06-15 19:45:35 +08003956 DVR_PB_INFO("get fb time error last[%d]cur[%d]diff[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003957 player->last_cur_time,
3958 p_status->time_cur,
3959 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08003960 p_status->time_cur = player->last_cur_time;
3961 } else {
3962 player->last_cur_time = p_status->time_cur;
3963 }
3964 }
hualing chend241c7a2021-06-22 13:34:27 +08003965 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003966 player->last_cur_time = p_status->time_cur;
3967 }
hualing chen969fe7b2021-05-26 15:13:17 +08003968 player->last_send_time_id = segment_id;
3969 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003970
hualing chen5cbe1a62020-02-10 16:36:36 +08003971 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003972 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003973 p_status->flags = player->cur_segment.flags;
Wentao MA96f68962022-06-15 19:45:35 +08003974 DVR_PB_INFO("player real state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]is_lock[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003975 _dvr_playback_state_toString(player->state),
3976 _dvr_playback_state_toString(p_status->state),
3977 p_status->time_cur, p_status->time_end,
3978 p_status->segment_id,player->play_flag,
3979 player->speed,
3980 is_lock);
hualing chen1679f812021-11-08 15:17:46 +08003981 if (is_lock ==DVR_TRUE) {
Wentao MA96f68962022-06-15 19:45:35 +08003982 DVR_PB_DEBUG("unlock ---\r\n");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08003983 dvr_mutex_unlock(&player->lock);
hualing chen1679f812021-11-08 15:17:46 +08003984 }
hualing chen2932d372020-04-29 13:44:00 +08003985 return DVR_SUCCESS;
3986}
3987
3988
3989/**\brief Get playback status
3990 * \param[in] handle playback handle
3991 * \param[out] p_status playback status
3992 * \retval DVR_SUCCESS On success
3993 * \return Error code
3994 */
3995int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3996 DVR_PlaybackStatus_t *p_status) {
3997//
3998 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3999
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004000 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
4001
hualing chen2932d372020-04-29 13:44:00 +08004002 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004003 DVR_PB_INFO("player is NULL");
hualing chen2932d372020-04-29 13:44:00 +08004004 return DVR_FAILURE;
4005 }
Wentao MA96f68962022-06-15 19:45:35 +08004006 DVR_PB_DEBUG("lock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004007 dvr_mutex_lock(&player->lock);
Zhiqiang Han9adc9722020-11-11 18:38:10 +08004008 if (!player->has_video && !player->has_audio)
4009 p_status->time_cur = 0;
Wentao MA96f68962022-06-15 19:45:35 +08004010 DVR_PB_DEBUG("unlock---");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004011 dvr_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08004012
hualing chenb31a6c62020-01-13 17:27:00 +08004013 return DVR_SUCCESS;
4014}
4015
hualing chen040df222020-01-17 13:35:02 +08004016void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
4017 if (segment != NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004018 DVR_PB_INFO("segment id: %lld", segment->segment_id);
4019 DVR_PB_INFO("segment flag: %d", segment->flags);
4020 DVR_PB_INFO("segment location: [%s]", segment->location);
4021 DVR_PB_INFO("segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
4022 DVR_PB_INFO("segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
4023 DVR_PB_INFO("segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
4024 DVR_PB_INFO("segment sub apid: 0x%x sub afmt:0x%x", segment->pids.ad.pid,segment->pids.ad.format);
hualing chen86e7d482020-01-16 15:13:33 +08004025 }
hualing chenb31a6c62020-01-13 17:27:00 +08004026}
4027
hualing chen5cbe1a62020-02-10 16:36:36 +08004028int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08004029 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08004030
hualing chena540a7e2020-03-27 16:44:05 +08004031 if (player == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +08004032 DVR_PB_INFO("player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08004033 return DVR_FAILURE;
4034 }
4035
hualing chen040df222020-01-17 13:35:02 +08004036 DVR_PlaybackSegmentInfo_t *segment;
4037 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08004038 {
hualing chen040df222020-01-17 13:35:02 +08004039 if (segment_id >= 0) {
4040 if (segment->segment_id == segment_id) {
4041 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08004042 break;
4043 }
4044 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08004045 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08004046 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08004047 }
4048 }
4049 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08004050}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004051
pengfei.liu27cc4ec2020-04-03 16:28:16 +08004052int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004053{
4054 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4055 DVR_RETURN_IF_FALSE(player);
4056 DVR_RETURN_IF_FALSE(func);
4057
Wentao MA96f68962022-06-15 19:45:35 +08004058 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004059 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004060
4061 player->dec_func = func;
4062 player->dec_userdata = userdata;
4063
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004064 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004065 DVR_PB_INFO("out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004066 return DVR_SUCCESS;
4067}
4068
4069int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
4070{
4071 DVR_Playback_t *player = (DVR_Playback_t *) handle;
4072 DVR_RETURN_IF_FALSE(player);
4073 DVR_RETURN_IF_FALSE(p_secure_buf);
4074 DVR_RETURN_IF_FALSE(len);
4075
Wentao MA96f68962022-06-15 19:45:35 +08004076 DVR_PB_INFO("in ");
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004077 dvr_mutex_lock(&player->lock);
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004078
4079 player->is_secure_mode = 1;
4080 player->secure_buffer = p_secure_buf;
4081 player->secure_buffer_size = len;
4082
Zhiqiang Hanf9c0e272022-06-14 13:54:03 +08004083 dvr_mutex_unlock(&player->lock);
Wentao MA96f68962022-06-15 19:45:35 +08004084 DVR_PB_INFO("out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08004085 return DVR_SUCCESS;
4086}