blob: 608e6f6428557e1a601e8c8b653a13a5a03acfd7 [file] [log] [blame]
hualing chenb31a6c62020-01-13 17:27:00 +08001#include <stdio.h>
2#include <stdlib.h>
3
hualing chen5cbe1a62020-02-10 16:36:36 +08004#include <string.h>
hualing chenb31a6c62020-01-13 17:27:00 +08005#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <poll.h>
11#include <errno.h>
12#include <signal.h>
13#include <pthread.h>
hualing chenb5cd42e2020-04-15 17:03:34 +080014#include <errno.h>
hualing chen03fd4942021-07-15 15:56:41 +080015#include "dvr_utils.h"
16#include "dvr_types.h"
hualing chenb31a6c62020-01-13 17:27:00 +080017#include "dvr_playback.h"
18
Gong Ke2a0ebbe2021-05-25 15:22:50 +080019#define DVR_PB_DG(_level, _fmt...) \
20 DVR_DEBUG_FL(_level, "playback", _fmt)
hualing chena540a7e2020-03-27 16:44:05 +080021
hualing chenb31a6c62020-01-13 17:27:00 +080022#define VALID_PID(_pid_) ((_pid_)>0 && (_pid_)<0x1fff)
hualing chena540a7e2020-03-27 16:44:05 +080023
hualing chend241c7a2021-06-22 13:34:27 +080024#define CONTROL_SPEED_ENABLE 0
hualing chena540a7e2020-03-27 16:44:05 +080025
26#define FF_SPEED (2.0f)
27#define FB_SPEED (-1.0f)
28#define IS_FFFB(_SPEED_) ((_SPEED_) > FF_SPEED && (_SPEED_) < FB_SPEED)
hualing chene41f4372020-06-06 16:29:17 +080029#define IS_FB(_SPEED_) ((_SPEED_) <= FB_SPEED)
hualing chena540a7e2020-03-27 16:44:05 +080030
31#define IS_KERNEL_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_X1) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
32#define IS_FAST_SPEED(_SPEED_) (((_SPEED_) == PLAYBACK_SPEED_X2) || ((_SPEED_) == PLAYBACK_SPEED_S2) || ((_SPEED_) == PLAYBACK_SPEED_S4) || ((_SPEED_) == PLAYBACK_SPEED_S8))
33
hualing chenb31a6c62020-01-13 17:27:00 +080034
hualing chenb5cd42e2020-04-15 17:03:34 +080035#define FFFB_SLEEP_TIME (1000)//500ms
hualing chene41f4372020-06-06 16:29:17 +080036#define FB_DEFAULT_LEFT_TIME (3000)
hualing chen31140872020-03-25 12:29:26 +080037//if tsplayer delay time < 200 and no data can read, we will pause
38#define MIN_TSPLAYER_DELAY_TIME (200)
39
hualing chen041c4092020-04-05 15:11:50 +080040#define MAX_CACHE_TIME (30000)
41
hualing chena540a7e2020-03-27 16:44:05 +080042static int write_success = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +080043//
44static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle);
hualing chen275379e2021-06-15 17:57:21 +080045static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_PlaybackPids_t pids, int type);
hualing chencc91e1c2020-02-28 13:26:17 +080046static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle);
47static int _dvr_get_end_time(DVR_PlaybackHandle_t handle);
hualing chen2aba4022020-03-02 13:49:55 +080048static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle);
hualing chen87072a82020-03-12 16:20:12 +080049static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) ;
hualing chen2932d372020-04-29 13:44:00 +080050static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
51 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock);
hualing chene41f4372020-06-06 16:29:17 +080052static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock);
hualing chen7ea70a72021-09-09 11:25:13 +080053static uint32_t dvr_playback_calculate_last_valid_segment(
54 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos);
hualing chen87072a82020-03-12 16:20:12 +080055
hualing chenbcada022020-04-22 14:27:01 +080056
57static char* _cmd_toString(int cmd)
58{
59
60 char *string[DVR_PLAYBACK_CMD_NONE+1]={
61 "start",
62 "stop",
63 "vstart",
64 "astart",
65 "vstop",
66 "astop",
67 "vrestart",
68 "arestart",
69 "avrestart",
70 "vstopastart",
71 "astopvstart",
72 "vstoparestart",
73 "astopvrestart",
74 "vstartarestart",
75 "astartvrestart",
76 "pause",
77 "resume",
78 "seek",
79 "ff",
80 "fb",
81 "NONE"
82 };
83
84 if (cmd > DVR_PLAYBACK_CMD_NONE) {
85 return "unkown";
86 } else {
87 return string[cmd];
88 }
89}
90
91
hualing chen6d24aa92020-03-23 18:43:47 +080092static char* _dvr_playback_state_toString(int stat)
93{
94 char *string[DVR_PLAYBACK_STATE_FB+1]={
95 "start",
hualing chen6d24aa92020-03-23 18:43:47 +080096 "stop",
hualing chen31140872020-03-25 12:29:26 +080097 "pause",
hualing chen6d24aa92020-03-23 18:43:47 +080098 "ff",
99 "fb"
100 };
101
102 if (stat > DVR_PLAYBACK_STATE_FB) {
103 return "unkown";
104 } else {
105 return string[stat];
106 }
107}
hualing chena540a7e2020-03-27 16:44:05 +0800108
109static DVR_Bool_t _dvr_support_speed(int speed) {
110
111 DVR_Bool_t ret = DVR_FALSE;
112
113 switch (speed) {
hualing chene41f4372020-06-06 16:29:17 +0800114 case PLAYBACK_SPEED_FBX1:
hualing chena540a7e2020-03-27 16:44:05 +0800115 case PLAYBACK_SPEED_FBX2:
116 case PLAYBACK_SPEED_FBX4:
117 case PLAYBACK_SPEED_FBX8:
hualing chen041c4092020-04-05 15:11:50 +0800118 case PLAYBACK_SPEED_FBX16:
119 case PLAYBACK_SPEED_FBX12:
120 case PLAYBACK_SPEED_FBX32:
121 case PLAYBACK_SPEED_FBX48:
122 case PLAYBACK_SPEED_FBX64:
123 case PLAYBACK_SPEED_FBX128:
hualing chena540a7e2020-03-27 16:44:05 +0800124 case PLAYBACK_SPEED_S2:
125 case PLAYBACK_SPEED_S4:
126 case PLAYBACK_SPEED_S8:
127 case PLAYBACK_SPEED_X1:
128 case PLAYBACK_SPEED_X2:
129 case PLAYBACK_SPEED_X4:
hualing chena540a7e2020-03-27 16:44:05 +0800130 case PLAYBACK_SPEED_X3:
131 case PLAYBACK_SPEED_X5:
132 case PLAYBACK_SPEED_X6:
133 case PLAYBACK_SPEED_X7:
hualing chen041c4092020-04-05 15:11:50 +0800134 case PLAYBACK_SPEED_X8:
135 case PLAYBACK_SPEED_X12:
136 case PLAYBACK_SPEED_X16:
137 case PLAYBACK_SPEED_X32:
138 case PLAYBACK_SPEED_X48:
139 case PLAYBACK_SPEED_X64:
140 case PLAYBACK_SPEED_X128:
hualing chena540a7e2020-03-27 16:44:05 +0800141 ret = DVR_TRUE;
142 break;
143 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800144 DVR_PB_DG(1, "not support speed is set [%d]", speed);
hualing chena540a7e2020-03-27 16:44:05 +0800145 break;
146 }
147 return ret;
148}
hualing chen6e4bfa52020-03-13 14:37:11 +0800149void _dvr_tsplayer_callback_test(void *user_data, am_tsplayer_event *event)
150{
hualing chen4b7c15d2020-04-07 16:13:48 +0800151 DVR_PB_DG(1, "in callback test ");
hualing chen6e4bfa52020-03-13 14:37:11 +0800152 DVR_Playback_t *player = NULL;
153 if (user_data != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800154 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800155 DVR_PB_DG(1, "play speed [%f] in callback test ", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800156 }
157 switch (event->type) {
158 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
159 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800160 DVR_PB_DG(1,"[evt] test AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800161 event->event.video_format.frame_width,
162 event->event.video_format.frame_height,
163 event->event.video_format.frame_rate);
164 break;
165 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800166 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
167 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800168 DVR_PB_DG(1, "[evt] test AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chena540a7e2020-03-27 16:44:05 +0800169 player->first_frame = 1;
hualing chen6e4bfa52020-03-13 14:37:11 +0800170 break;
171 }
172 default:
173 break;
174 }
175}
hualing chen2aba4022020-03-02 13:49:55 +0800176void _dvr_tsplayer_callback(void *user_data, am_tsplayer_event *event)
177{
hualing chen6e4bfa52020-03-13 14:37:11 +0800178 DVR_Playback_t *player = NULL;
179 if (user_data != NULL) {
180 player = (DVR_Playback_t *) user_data;
hualing chen4b7c15d2020-04-07 16:13:48 +0800181 DVR_PB_DG(1, "play speed [%f] in-- callback", player->speed);
hualing chen6e4bfa52020-03-13 14:37:11 +0800182 }
hualing chen2aba4022020-03-02 13:49:55 +0800183 switch (event->type) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800184 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
185 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800186 DVR_PB_DG(1,"[evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d\n",
hualing chen6e4bfa52020-03-13 14:37:11 +0800187 event->event.video_format.frame_width,
188 event->event.video_format.frame_height,
189 event->event.video_format.frame_rate);
190 break;
191 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800192 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
193 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800194 DVR_PB_DG(1, "[evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n");
hualing chene41f4372020-06-06 16:29:17 +0800195 if (player->first_trans_ok == DVR_FALSE) {
196 player->first_trans_ok = DVR_TRUE;
197 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
198 }
hualing chen30423862021-04-16 14:39:12 +0800199 if (player != NULL) {
hualing chena540a7e2020-03-27 16:44:05 +0800200 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800201 player->seek_pause = DVR_FALSE;
202 }
hualing chen6e4bfa52020-03-13 14:37:11 +0800203 break;
204 }
hualing chen487ae6d2020-07-22 10:34:11 +0800205 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
206 if (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE) {
207 player->first_trans_ok = DVR_TRUE;
208 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
209 }
210 if (player != NULL && player->has_video == DVR_FALSE) {
211 DVR_PB_DG(1, "[evt]AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO [%d]\n", event->type);
212 player->first_frame = 1;
hualing chen30423862021-04-16 14:39:12 +0800213 player->seek_pause = DVR_FALSE;
hualing chen487ae6d2020-07-22 10:34:11 +0800214 }
215 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800216 default:
hualing chen4b7c15d2020-04-07 16:13:48 +0800217 DVR_PB_DG(1, "[evt]unkown event [%d]\n", event->type);
hualing chen6e4bfa52020-03-13 14:37:11 +0800218 break;
219 }
220 if (player&&player->player_callback_func) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800221 DVR_PB_DG(1, "player is nonull, --call callback\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800222 player->player_callback_func(player->player_callback_userdata, event);
223 } else if (player == NULL){
hualing chen4b7c15d2020-04-07 16:13:48 +0800224 DVR_PB_DG(1, "player is null, get userdata error\n");
hualing chen6e4bfa52020-03-13 14:37:11 +0800225 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +0800226 DVR_PB_DG(1, "player callback is null, get callback error\n");
hualing chen2aba4022020-03-02 13:49:55 +0800227 }
228}
hualing chencc91e1c2020-02-28 13:26:17 +0800229
hualing chen5cbe1a62020-02-10 16:36:36 +0800230//convert video and audio fmt
231static int _dvr_convert_stream_fmt(int fmt, DVR_Bool_t is_audio) {
232 int format = 0;
233 if (is_audio == DVR_FALSE) {
234 //for video fmt
235 switch (fmt)
236 {
237 case DVR_VIDEO_FORMAT_MPEG1:
hualing chen2aba4022020-03-02 13:49:55 +0800238 format = AV_VIDEO_CODEC_MPEG1;
hualing chen5cbe1a62020-02-10 16:36:36 +0800239 break;
240 case DVR_VIDEO_FORMAT_MPEG2:
hualing chen2aba4022020-03-02 13:49:55 +0800241 format = AV_VIDEO_CODEC_MPEG2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800242 break;
243 case DVR_VIDEO_FORMAT_HEVC:
hualing chen2aba4022020-03-02 13:49:55 +0800244 format = AV_VIDEO_CODEC_H265;
hualing chen5cbe1a62020-02-10 16:36:36 +0800245 break;
246 case DVR_VIDEO_FORMAT_H264:
hualing chen2aba4022020-03-02 13:49:55 +0800247 format = AV_VIDEO_CODEC_H264;
hualing chen5cbe1a62020-02-10 16:36:36 +0800248 break;
hualing chena540a7e2020-03-27 16:44:05 +0800249 case DVR_VIDEO_FORMAT_VP9:
250 format = AV_VIDEO_CODEC_VP9;
251 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800252 }
253 } else {
254 //for audio fmt
255 switch (fmt)
256 {
257 case DVR_AUDIO_FORMAT_MPEG:
hualing chen2aba4022020-03-02 13:49:55 +0800258 format = AV_AUDIO_CODEC_MP2;
hualing chen5cbe1a62020-02-10 16:36:36 +0800259 break;
260 case DVR_AUDIO_FORMAT_AC3:
hualing chen2aba4022020-03-02 13:49:55 +0800261 format = AV_AUDIO_CODEC_AC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800262 break;
263 case DVR_AUDIO_FORMAT_EAC3:
hualing chen2aba4022020-03-02 13:49:55 +0800264 format = AV_AUDIO_CODEC_EAC3;
hualing chen5cbe1a62020-02-10 16:36:36 +0800265 break;
266 case DVR_AUDIO_FORMAT_DTS:
hualing chen2aba4022020-03-02 13:49:55 +0800267 format = AV_AUDIO_CODEC_DTS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800268 break;
hualing chena540a7e2020-03-27 16:44:05 +0800269 case DVR_AUDIO_FORMAT_AAC:
270 format = AV_AUDIO_CODEC_AAC;
271 break;
272 case DVR_AUDIO_FORMAT_LATM:
273 format = AV_AUDIO_CODEC_LATM;
274 break;
275 case DVR_AUDIO_FORMAT_PCM:
276 format = AV_AUDIO_CODEC_PCM;
277 break;
hualing chenee0e52b2021-04-09 16:58:44 +0800278 case DVR_AUDIO_FORMAT_AC4:
279 format = AV_AUDIO_CODEC_AC4;
280 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800281 }
282 }
283 return format;
284}
hualing chen040df222020-01-17 13:35:02 +0800285static int _dvr_playback_get_trick_stat(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800286{
hualing chen040df222020-01-17 13:35:02 +0800287 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800288
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800289 if (player == NULL || player->handle == (am_tsplayer_handle)NULL)
hualing chen86e7d482020-01-16 15:13:33 +0800290 return -1;
291
hualing chena540a7e2020-03-27 16:44:05 +0800292 return player->first_frame;
hualing chen86e7d482020-01-16 15:13:33 +0800293}
hualing chena540a7e2020-03-27 16:44:05 +0800294
hualing chen7ea70a72021-09-09 11:25:13 +0800295
296//get sys time sec
297static uint32_t _dvr_getClock_sec(void)
hualing chen5cbe1a62020-02-10 16:36:36 +0800298{
299 struct timespec ts;
hualing chen7ea70a72021-09-09 11:25:13 +0800300 uint32_t s;
hualing chen03fd4942021-07-15 15:56:41 +0800301 clock_gettime(CLOCK_REALTIME, &ts);
hualing chen7ea70a72021-09-09 11:25:13 +0800302 s = (uint32_t)(ts.tv_sec);
303 DVR_PB_DG(1, "n:%u", s);
304 return s;
hualing chen5cbe1a62020-02-10 16:36:36 +0800305}
hualing chen86e7d482020-01-16 15:13:33 +0800306
hualing chen7ea70a72021-09-09 11:25:13 +0800307//get sys time ms
308static uint32_t _dvr_time_getClock(void)
309{
310 struct timespec ts;
311 uint32_t ms;
312 clock_gettime(CLOCK_REALTIME, &ts);
313 ms = (uint32_t)(ts.tv_sec*1000+ts.tv_nsec/1000000);
314 return ms;
315}
hualing chenb31a6c62020-01-13 17:27:00 +0800316
317//timeout wait sibnal
hualing chen040df222020-01-17 13:35:02 +0800318static int _dvr_playback_timeoutwait(DVR_PlaybackHandle_t handle , int ms)
hualing chenb31a6c62020-01-13 17:27:00 +0800319{
hualing chen040df222020-01-17 13:35:02 +0800320 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +0800321
hualing chena540a7e2020-03-27 16:44:05 +0800322
323 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800324 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800325 return DVR_FAILURE;
326 }
327
hualing chen86e7d482020-01-16 15:13:33 +0800328 struct timespec ts;
329 clock_gettime(CLOCK_MONOTONIC, &ts);
330 //ms为毫秒,换算成秒
331 ts.tv_sec += ms/1000;
332 //在outtime的基础上,增加ms毫秒
333 //outtime.tv_nsec为纳秒,1微秒=1000纳秒
334 //tv_nsec此值再加上剩余的毫秒数 ms%1000,有可能超过1秒。需要特殊处理
335 uint64_t us = ts.tv_nsec/1000 + 1000 * (ms % 1000); //微秒
336 //us的值有可能超过1秒,
337 ts.tv_sec += us / 1000000;
338 us = us % 1000000;
339 ts.tv_nsec = us * 1000;//换算成纳秒
hualing chen86e7d482020-01-16 15:13:33 +0800340 pthread_cond_timedwait(&player->cond, &player->lock, &ts);
341 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800342}
hualing chen31140872020-03-25 12:29:26 +0800343//get tsplay delay time ms
344static int _dvr_playback_get_delaytime(DVR_PlaybackHandle_t handle ) {
345 DVR_Playback_t *player = (DVR_Playback_t *) handle;
346 int64_t cache = 0;
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800347 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800348 DVR_PB_DG(1, "tsplayer delay time error, handle is NULL");
hualing chen31140872020-03-25 12:29:26 +0800349 return 0;
350 }
351 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen4b7c15d2020-04-07 16:13:48 +0800352 DVR_PB_DG(1, "tsplayer cache time [%lld]ms", cache);
hualing chen31140872020-03-25 12:29:26 +0800353 return cache;
354}
hualing chenb31a6c62020-01-13 17:27:00 +0800355//send signal
hualing chen040df222020-01-17 13:35:02 +0800356static int _dvr_playback_sendSignal(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +0800357{
hualing chen87072a82020-03-12 16:20:12 +0800358 DVR_Playback_t *player = (DVR_Playback_t *) handle;\
hualing chena540a7e2020-03-27 16:44:05 +0800359
360 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800361 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800362 return DVR_FAILURE;
363 }
364
hualing chen87072a82020-03-12 16:20:12 +0800365 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +0800366 pthread_cond_signal(&player->cond);
hualing chen87072a82020-03-12 16:20:12 +0800367 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +0800368 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +0800369}
370
hualing chen2932d372020-04-29 13:44:00 +0800371//send playback event, need check is need lock first
372static 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 +0800373
374 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800375
376 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800377 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800378 return DVR_FAILURE;
379 }
380
hualing chencc91e1c2020-02-28 13:26:17 +0800381 switch (evt) {
382 case DVR_PLAYBACK_EVENT_ERROR:
hualing chen2932d372020-04-29 13:44:00 +0800383 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800384 break;
385 case DVR_PLAYBACK_EVENT_TRANSITION_OK:
386 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800387 DVR_PB_DG(1, "trans ok EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800388 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800389 break;
390 case DVR_PLAYBACK_EVENT_TRANSITION_FAILED:
391 break;
392 case DVR_PLAYBACK_EVENT_KEY_FAILURE:
393 break;
394 case DVR_PLAYBACK_EVENT_NO_KEY:
395 break;
396 case DVR_PLAYBACK_EVENT_REACHED_BEGIN:
hualing chen2aba4022020-03-02 13:49:55 +0800397 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800398 DVR_PB_DG(1, "reached begin EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800399 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800400 break;
401 case DVR_PLAYBACK_EVENT_REACHED_END:
402 //GET STATE
hualing chen4b7c15d2020-04-07 16:13:48 +0800403 DVR_PB_DG(1, "reached end EVENT");
hualing chen2932d372020-04-29 13:44:00 +0800404 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800405 break;
hualing chen6e4bfa52020-03-13 14:37:11 +0800406 case DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME:
hualing chen2932d372020-04-29 13:44:00 +0800407 _dvr_playback_get_status(handle, &(notify->play_status), is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800408 break;
hualing chencc91e1c2020-02-28 13:26:17 +0800409 default:
410 break;
411 }
412 if (player->openParams.event_fn != NULL)
413 player->openParams.event_fn(evt, (void*)notify, player->openParams.event_userdata);
hualing chencc91e1c2020-02-28 13:26:17 +0800414 return DVR_SUCCESS;
415}
hualing chen2932d372020-04-29 13:44:00 +0800416static int _dvr_playback_sent_transition_ok(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chencc91e1c2020-02-28 13:26:17 +0800417{
418 DVR_Play_Notify_t notify;
419 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
420 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_OK;
421 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800422 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_OK, &notify, is_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800423 return DVR_SUCCESS;
424}
425
hualing chen2932d372020-04-29 13:44:00 +0800426static int _dvr_playback_sent_playtime(DVR_PlaybackHandle_t handle, DVR_Bool_t is_lock)
hualing chen6e4bfa52020-03-13 14:37:11 +0800427{
428 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800429
hualing chene3797f02021-01-13 14:53:28 +0800430 if (player->openParams.is_notify_time == DVR_FALSE) {
hualing chend241c7a2021-06-22 13:34:27 +0800431 if (CONTROL_SPEED_ENABLE == 0)
432 return DVR_SUCCESS;
hualing chen4b7c15d2020-04-07 16:13:48 +0800433 }
hualing chena540a7e2020-03-27 16:44:05 +0800434 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800435 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800436 return DVR_FAILURE;
437 }
438
hualing chen03fd4942021-07-15 15:56:41 +0800439 if (player->send_time == 0) {
hualing chend241c7a2021-06-22 13:34:27 +0800440 if (CONTROL_SPEED_ENABLE == 0)
441 player->send_time = _dvr_time_getClock() + 500;
442 else
443 player->send_time = _dvr_time_getClock() + 20;
hualing chen0888c032020-12-18 17:54:57 +0800444 } else if (player->send_time >= _dvr_time_getClock()) {
hualing chen6e4bfa52020-03-13 14:37:11 +0800445 return DVR_SUCCESS;
446 }
hualing chend241c7a2021-06-22 13:34:27 +0800447 if (CONTROL_SPEED_ENABLE == 0)
448 player->send_time = _dvr_time_getClock() + 500;
449 else
450 player->send_time = _dvr_time_getClock() + 20;
451
hualing chen6e4bfa52020-03-13 14:37:11 +0800452 DVR_Play_Notify_t notify;
453 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
454 notify.event = DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME;
455 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +0800456 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_NOTIFY_PLAYTIME, &notify, is_lock);
hualing chen6e4bfa52020-03-13 14:37:11 +0800457 return DVR_SUCCESS;
458}
459
hualing chencc91e1c2020-02-28 13:26:17 +0800460//check is ongoing segment
461static int _dvr_check_segment_ongoing(DVR_PlaybackHandle_t handle) {
462
463 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen87072a82020-03-12 16:20:12 +0800464 int ret = DVR_FAILURE;
hualing chena540a7e2020-03-27 16:44:05 +0800465
466 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800467 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800468 return DVR_FAILURE;
469 }
hualing chen87072a82020-03-12 16:20:12 +0800470 ret = segment_ongoing(player->r_handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800471 if (ret != DVR_SUCCESS) {
hualing chencc91e1c2020-02-28 13:26:17 +0800472 return DVR_FALSE;
473 }
hualing chencc91e1c2020-02-28 13:26:17 +0800474 return DVR_TRUE;
475}
hualing chen4b7c15d2020-04-07 16:13:48 +0800476
477
478static int _dvr_init_fffb_t(DVR_PlaybackHandle_t handle) {
479 DVR_Playback_t *player = (DVR_Playback_t *) handle;
480 player->fffb_start = _dvr_time_getClock();
hualing chen7ea70a72021-09-09 11:25:13 +0800481 DVR_PB_DG(1, " player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800482 player->fffb_current = player->fffb_start;
483 //get segment current time pos
484 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +0800485 player->next_fffb_time = _dvr_time_getClock();
486
487 return DVR_SUCCESS;
488}
489
hualing chen2aba4022020-03-02 13:49:55 +0800490static int _dvr_init_fffb_time(DVR_PlaybackHandle_t handle) {
491 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +0800492 player->fffb_start = _dvr_time_getClock();
hualing chen7ea70a72021-09-09 11:25:13 +0800493 DVR_PB_DG(1, " player->fffb_start:%u", player->fffb_start);
hualing chen4b7c15d2020-04-07 16:13:48 +0800494 player->fffb_current = player->fffb_start;
495 //get segment current time pos
496 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +0800497
hualing chen2aba4022020-03-02 13:49:55 +0800498 player->next_fffb_time = _dvr_time_getClock();
hualing chen4b7c15d2020-04-07 16:13:48 +0800499 player->last_send_time_id = UINT64_MAX;
hualing chen2aba4022020-03-02 13:49:55 +0800500 return DVR_SUCCESS;
501}
hualing chencc91e1c2020-02-28 13:26:17 +0800502//get next segment id
hualing chen87072a82020-03-12 16:20:12 +0800503static int _dvr_has_next_segmentId(DVR_PlaybackHandle_t handle, int segmentid) {
504
505 DVR_Playback_t *player = (DVR_Playback_t *) handle;
506 DVR_PlaybackSegmentInfo_t *segment;
507 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
508
hualing chena540a7e2020-03-27 16:44:05 +0800509 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800510 DVR_PB_DG(1, " player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800511 return DVR_FAILURE;
512 }
513
hualing chen87072a82020-03-12 16:20:12 +0800514 int found = 0;
515 int found_eq_id = 0;
516 list_for_each_entry(segment, &player->segment_list, head)
517 {
518 if (player->segment_is_open == DVR_FALSE) {
519 //get first segment from list, case segment is not open
520 if (!IS_FB(player->speed))
521 found = 1;
522 } else if (segment->segment_id == segmentid) {
523 //find cur segment, we need get next one
524 found_eq_id = 1;
525 if (!IS_FB(player->speed)) {
526 found = 1;
527 continue;
528 } else {
529 //if is fb mode.we need used pre segment
530 if (pre_segment != NULL) {
531 found = 1;
532 } else {
533 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800534 DVR_PB_DG(1, "not has find next segment on fb mode");
hualing chen87072a82020-03-12 16:20:12 +0800535 return DVR_FAILURE;
536 }
537 }
538 }
539 if (found == 1) {
540 found = 2;
541 break;
542 }
hualing chenc7aa4c82021-02-03 15:41:37 +0800543 pre_segment = segment;
hualing chen87072a82020-03-12 16:20:12 +0800544 }
545 if (found != 2) {
546 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800547 DVR_PB_DG(1, "not found next segment return failure");
hualing chen87072a82020-03-12 16:20:12 +0800548 return DVR_FAILURE;
549 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800550 DVR_PB_DG(1, "found next segment return success");
hualing chen87072a82020-03-12 16:20:12 +0800551 return DVR_SUCCESS;
552}
553
554//get next segment id
hualing chen040df222020-01-17 13:35:02 +0800555static int _dvr_get_next_segmentId(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +0800556
hualing chen040df222020-01-17 13:35:02 +0800557 DVR_Playback_t *player = (DVR_Playback_t *) handle;
558 DVR_PlaybackSegmentInfo_t *segment;
hualing chen2aba4022020-03-02 13:49:55 +0800559 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
hualing chen03fd4942021-07-15 15:56:41 +0800560 uint64_t segmentid;
hualing chen7ea70a72021-09-09 11:25:13 +0800561 uint32_t pos;
hualing chena540a7e2020-03-27 16:44:05 +0800562 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800563 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800564 return DVR_FAILURE;
565 }
566
hualing chen03fd4942021-07-15 15:56:41 +0800567 if (IS_FB(player->speed)
568 && dvr_playback_check_limit(handle)) {
569 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
570 //case cur id < segment id
571 if (player->cur_segment_id <= segmentid) {
572 //expired ts data is player,return error
573 DVR_PB_DG(1, "reach start segment ,return error");
574 return DVR_FAILURE;
575 }
hualing chen7ea70a72021-09-09 11:25:13 +0800576 DVR_PB_DG(1, "has segment to fb play [%lld][%u]", segmentid, pos);
hualing chen03fd4942021-07-15 15:56:41 +0800577 }
578
hualing chen86e7d482020-01-16 15:13:33 +0800579 int found = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800580 int found_eq_id = 0;
hualing chena540a7e2020-03-27 16:44:05 +0800581
hualing chen040df222020-01-17 13:35:02 +0800582 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +0800583 {
hualing chencc91e1c2020-02-28 13:26:17 +0800584 if (player->segment_is_open == DVR_FALSE) {
hualing chen2aba4022020-03-02 13:49:55 +0800585 //get first segment from list, case segment is not open
586 if (!IS_FB(player->speed))
587 found = 1;
hualing chen040df222020-01-17 13:35:02 +0800588 } else if (segment->segment_id == player->cur_segment_id) {
589 //find cur segment, we need get next one
hualing chen2aba4022020-03-02 13:49:55 +0800590 found_eq_id = 1;
591 if (!IS_FB(player->speed)) {
592 found = 1;
593 continue;
594 } else {
595 //if is fb mode.we need used pre segment
596 if (pre_segment != NULL) {
597 found = 1;
598 } else {
599 //not find next id.
hualing chen4b7c15d2020-04-07 16:13:48 +0800600 DVR_PB_DG(1, "not find next segment on fb mode");
hualing chen2aba4022020-03-02 13:49:55 +0800601 return DVR_FAILURE;
602 }
603 }
hualing chen86e7d482020-01-16 15:13:33 +0800604 }
605 if (found == 1) {
hualing chen2aba4022020-03-02 13:49:55 +0800606 if (IS_FB(player->speed)) {
607 //used pre segment
608 segment = pre_segment;
609 }
hualing chencc91e1c2020-02-28 13:26:17 +0800610 //save segment info
611 player->last_segment_id = player->cur_segment_id;
hualing chen969fe7b2021-05-26 15:13:17 +0800612 if (player->r_handle)
613 player->last_segment_tatol = segment_tell_total_time(player->r_handle);
hualing chen87072a82020-03-12 16:20:12 +0800614 player->last_segment.segment_id = player->cur_segment.segment_id;
615 player->last_segment.flags = player->cur_segment.flags;
hualing chencc91e1c2020-02-28 13:26:17 +0800616 memcpy(player->last_segment.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
617 //pids
618 memcpy(&player->last_segment.pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
619
hualing chen5cbe1a62020-02-10 16:36:36 +0800620 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800621 player->segment_is_open = DVR_TRUE;
hualing chen040df222020-01-17 13:35:02 +0800622 player->cur_segment_id = segment->segment_id;
623 player->cur_segment.segment_id = segment->segment_id;
624 player->cur_segment.flags = segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800625 DVR_PB_DG(1, "set cur id cur flag[0x%x]segment->flags flag[0x%x] id [%lld]", player->cur_segment.flags, segment->flags, segment->segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800626 memcpy(player->cur_segment.location, segment->location, DVR_MAX_LOCATION_SIZE);
hualing chen86e7d482020-01-16 15:13:33 +0800627 //pids
hualing chen040df222020-01-17 13:35:02 +0800628 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen86e7d482020-01-16 15:13:33 +0800629 found = 2;
hualing chen2aba4022020-03-02 13:49:55 +0800630 break;
hualing chen86e7d482020-01-16 15:13:33 +0800631 }
hualing chen2aba4022020-03-02 13:49:55 +0800632 pre_segment = segment;
633 }
634 if (player->segment_is_open == DVR_FALSE && IS_FB(player->speed)) {
635 //used the last one segment to open
636 //get segment info
637 player->segment_is_open = DVR_TRUE;
638 player->cur_segment_id = pre_segment->segment_id;
639 player->cur_segment.segment_id = pre_segment->segment_id;
640 player->cur_segment.flags = pre_segment->flags;
hualing chen4b7c15d2020-04-07 16:13:48 +0800641 DVR_PB_DG(1, "set cur id fb last one cur flag[0x%x]segment->flags flag[0x%x] id [%lld]", player->cur_segment.flags, pre_segment->flags, pre_segment->segment_id);
hualing chen2aba4022020-03-02 13:49:55 +0800642 memcpy(player->cur_segment.location, pre_segment->location, DVR_MAX_LOCATION_SIZE);
643 //pids
644 memcpy(&player->cur_segment.pids, &pre_segment->pids, sizeof(DVR_PlaybackPids_t));
645 return DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800646 }
647 if (found != 2) {
648 //list is null or reache list end
hualing chen2aba4022020-03-02 13:49:55 +0800649 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800650 }
651 return DVR_SUCCESS;
652}
hualing chen040df222020-01-17 13:35:02 +0800653//open next segment to play,if reach list end return errro.
654static int _change_to_next_segment(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +0800655{
hualing chen040df222020-01-17 13:35:02 +0800656 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen86e7d482020-01-16 15:13:33 +0800657 Segment_OpenParams_t params;
658 int ret = DVR_SUCCESS;
659
hualing chena540a7e2020-03-27 16:44:05 +0800660 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800661 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800662 return DVR_FAILURE;
663 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800664 pthread_mutex_lock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +0800665
666 ret = _dvr_get_next_segmentId(handle);
667 if (ret == DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800668 DVR_PB_DG(1, "not found segment info");
669 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800670 return DVR_FAILURE;
hualing chen86e7d482020-01-16 15:13:33 +0800671 }
672
673 if (player->r_handle != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800674 DVR_PB_DG(1, "close segment");
hualing chen86e7d482020-01-16 15:13:33 +0800675 segment_close(player->r_handle);
676 player->r_handle = NULL;
677 }
678
679 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800680 //cp chur segment path to location
681 memcpy(params.location, player->cur_segment.location, DVR_MAX_LOCATION_SIZE);
hualing chen040df222020-01-17 13:35:02 +0800682 params.segment_id = (uint64_t)player->cur_segment.segment_id;
hualing chen86e7d482020-01-16 15:13:33 +0800683 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800684 DVR_PB_DG(1, "open segment location[%s]id[%lld]flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
685
hualing chen86e7d482020-01-16 15:13:33 +0800686 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800687 if (ret == DVR_FAILURE) {
688 DVR_PB_DG(1, "open segment error");
689 }
hualing chen87072a82020-03-12 16:20:12 +0800690 pthread_mutex_unlock(&player->segment_lock);
691 int total = _dvr_get_end_time( handle);
692 pthread_mutex_lock(&player->segment_lock);
hualing chen2aba4022020-03-02 13:49:55 +0800693 if (IS_FB(player->speed)) {
694 //seek end pos -FB_DEFAULT_LEFT_TIME
hualing chen5605eed2020-05-26 18:18:06 +0800695 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +0800696 segment_seek(player->r_handle, total - FB_DEFAULT_LEFT_TIME, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +0800697 DVR_PB_DG(1, "seek pos [%d]", total - FB_DEFAULT_LEFT_TIME);
hualing chen2aba4022020-03-02 13:49:55 +0800698 }
hualing chen87072a82020-03-12 16:20:12 +0800699 player->dur = total;
hualing chen2aba4022020-03-02 13:49:55 +0800700 pthread_mutex_unlock(&player->segment_lock);
hualing chen4b7c15d2020-04-07 16:13:48 +0800701 DVR_PB_DG(1, "next segment dur [%d] flag [0x%x]", player->dur, player->cur_segment.flags);
hualing chen86e7d482020-01-16 15:13:33 +0800702 return ret;
703}
704
hualing chen5cbe1a62020-02-10 16:36:36 +0800705//open next segment to play,if reach list end return errro.
706static int _dvr_open_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id)
707{
708 DVR_Playback_t *player = (DVR_Playback_t *) handle;
709 Segment_OpenParams_t params;
710 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +0800711 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800712 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800713 return DVR_FAILURE;
714 }
hualing chencc91e1c2020-02-28 13:26:17 +0800715 if (segment_id == player->cur_segment_id && player->segment_is_open == DVR_TRUE) {
hualing chen87072a82020-03-12 16:20:12 +0800716 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +0800717 }
hualing chencc91e1c2020-02-28 13:26:17 +0800718 uint64_t id = segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +0800719 if (id < 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800720 DVR_PB_DG(1, "not found segment info");
hualing chen5cbe1a62020-02-10 16:36:36 +0800721 return DVR_FAILURE;
722 }
hualing chen4b7c15d2020-04-07 16:13:48 +0800723 DVR_PB_DG(1, "start found segment[%lld]info", id);
hualing chen2aba4022020-03-02 13:49:55 +0800724 pthread_mutex_lock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +0800725
726 DVR_PlaybackSegmentInfo_t *segment;
727
728 int found = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800729
hualing chen5cbe1a62020-02-10 16:36:36 +0800730 list_for_each_entry(segment, &player->segment_list, head)
731 {
hualing chen4b7c15d2020-04-07 16:13:48 +0800732 DVR_PB_DG(1, "see 1 location [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800733 if (segment->segment_id == segment_id) {
734 found = 1;
735 }
736 if (found == 1) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800737 DVR_PB_DG(1, "found [%s]id[%lld]flag[%x]segment_id[%lld]", segment->location, segment->segment_id, segment->flags, segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800738 //get segment info
hualing chencc91e1c2020-02-28 13:26:17 +0800739 player->segment_is_open = DVR_TRUE;
hualing chen5cbe1a62020-02-10 16:36:36 +0800740 player->cur_segment_id = segment->segment_id;
741 player->cur_segment.segment_id = segment->segment_id;
742 player->cur_segment.flags = segment->flags;
hualing chen31140872020-03-25 12:29:26 +0800743 strncpy(player->cur_segment.location, segment->location, sizeof(segment->location));//DVR_MAX_LOCATION_SIZE
hualing chen5cbe1a62020-02-10 16:36:36 +0800744 //pids
745 memcpy(&player->cur_segment.pids, &segment->pids, sizeof(DVR_PlaybackPids_t));
hualing chen4b7c15d2020-04-07 16:13:48 +0800746 DVR_PB_DG(1, "cur found location [%s]id[%lld]flag[%x]", player->cur_segment.location, player->cur_segment.segment_id,player->cur_segment.flags);
hualing chencc91e1c2020-02-28 13:26:17 +0800747 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800748 }
749 }
hualing chencc91e1c2020-02-28 13:26:17 +0800750 if (found == 0) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800751 DVR_PB_DG(1, "not found segment info.error..");
hualing chen2aba4022020-03-02 13:49:55 +0800752 pthread_mutex_unlock(&player->segment_lock);
hualing chencc91e1c2020-02-28 13:26:17 +0800753 return DVR_FAILURE;
754 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800755 memset(params.location, 0, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +0800756 //cp cur segment path to location
hualing chen31140872020-03-25 12:29:26 +0800757 strncpy(params.location, player->cur_segment.location, sizeof(player->cur_segment.location));
hualing chen5cbe1a62020-02-10 16:36:36 +0800758 params.segment_id = (uint64_t)player->cur_segment.segment_id;
759 params.mode = SEGMENT_MODE_READ;
hualing chen4b7c15d2020-04-07 16:13:48 +0800760 DVR_PB_DG(1, "open segment location[%s][%lld]cur flag[0x%x]", params.location, params.segment_id, player->cur_segment.flags);
hualing chen2aba4022020-03-02 13:49:55 +0800761 if (player->r_handle != NULL) {
762 segment_close(player->r_handle);
763 player->r_handle = NULL;
764 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800765 ret = segment_open(&params, &(player->r_handle));
hualing chen4b7c15d2020-04-07 16:13:48 +0800766 if (ret == DVR_FAILURE) {
767 DVR_PB_DG(1, "segment opne error");
768 }
hualing chen2aba4022020-03-02 13:49:55 +0800769 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +0800770 player->dur = _dvr_get_end_time(handle);
hualing chencc91e1c2020-02-28 13:26:17 +0800771
hualing chen4b7c15d2020-04-07 16:13:48 +0800772 DVR_PB_DG(1, "player->dur [%d]cur id [%lld]cur flag [0x%x]\r\n", player->dur,player->cur_segment.segment_id, player->cur_segment.flags);
hualing chen5cbe1a62020-02-10 16:36:36 +0800773 return ret;
774}
775
776
777//get play info by segment id
778static int _dvr_playback_get_playinfo(DVR_PlaybackHandle_t handle,
779 uint64_t segment_id,
hualing chen2aba4022020-03-02 13:49:55 +0800780 am_tsplayer_video_params *vparam,
hualing chendf118dd2020-05-21 15:49:11 +0800781 am_tsplayer_audio_params *aparam, am_tsplayer_audio_params *adparam) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800782
783 DVR_Playback_t *player = (DVR_Playback_t *) handle;
784 DVR_PlaybackSegmentInfo_t *segment;
hualing chena540a7e2020-03-27 16:44:05 +0800785 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800786 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800787 return DVR_FAILURE;
788 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800789
790 int found = 0;
791
792 list_for_each_entry(segment, &player->segment_list, head)
793 {
hualing chen87072a82020-03-12 16:20:12 +0800794 if (segment_id == UINT64_MAX) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800795 //get first segment from list
796 found = 1;
797 }
798 if (segment->segment_id == segment_id) {
799 found = 1;
800 }
801 if (found == 1) {
802 //get segment info
hualing chen87072a82020-03-12 16:20:12 +0800803 if (player->cur_segment_id != UINT64_MAX)
hualing chen5cbe1a62020-02-10 16:36:36 +0800804 player->cur_segment_id = segment->segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +0800805 DVR_PB_DG(1, "get play info id [%lld]", player->cur_segment_id);
hualing chen5cbe1a62020-02-10 16:36:36 +0800806 player->cur_segment.segment_id = segment->segment_id;
807 player->cur_segment.flags = segment->flags;
808 //pids
hualing chen2aba4022020-03-02 13:49:55 +0800809 player->cur_segment.pids.video.pid = segment->pids.video.pid;
810 player->cur_segment.pids.video.format = segment->pids.video.format;
811 player->cur_segment.pids.video.type = segment->pids.video.type;
812 player->cur_segment.pids.audio.pid = segment->pids.audio.pid;
813 player->cur_segment.pids.audio.format = segment->pids.audio.format;
814 player->cur_segment.pids.audio.type = segment->pids.audio.type;
815 player->cur_segment.pids.ad.pid = segment->pids.ad.pid;
816 player->cur_segment.pids.ad.format = segment->pids.ad.format;
817 player->cur_segment.pids.ad.type = segment->pids.ad.type;
818 player->cur_segment.pids.pcr.pid = segment->pids.pcr.pid;
hualing chen5cbe1a62020-02-10 16:36:36 +0800819 //
hualing chen2aba4022020-03-02 13:49:55 +0800820 vparam->codectype = _dvr_convert_stream_fmt(segment->pids.video.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800821 vparam->pid = segment->pids.video.pid;
hualing chen2aba4022020-03-02 13:49:55 +0800822 aparam->codectype = _dvr_convert_stream_fmt(segment->pids.audio.format, DVR_TRUE);
hualing chen5cbe1a62020-02-10 16:36:36 +0800823 aparam->pid = segment->pids.audio.pid;
hualing chendf118dd2020-05-21 15:49:11 +0800824 adparam->codectype =_dvr_convert_stream_fmt(segment->pids.ad.format, DVR_TRUE);
825 adparam->pid =segment->pids.ad.pid;
hualing chen4b7c15d2020-04-07 16:13:48 +0800826 DVR_PB_DG(1, "get play info sucess[0x%x]apid[0x%x]vfmt[%d]afmt[%d]", vparam->pid, aparam->pid, vparam->codectype, aparam->codectype);
hualing chen5cbe1a62020-02-10 16:36:36 +0800827 found = 2;
hualing chencc91e1c2020-02-28 13:26:17 +0800828 break;
hualing chen5cbe1a62020-02-10 16:36:36 +0800829 }
830 }
hualing chencc91e1c2020-02-28 13:26:17 +0800831 if (found != 2) {
832 //list is null or reache list end
hualing chen4b7c15d2020-04-07 16:13:48 +0800833 DVR_PB_DG(1, "get play info fail");
hualing chencc91e1c2020-02-28 13:26:17 +0800834 return DVR_FAILURE;
835 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800836
837 return DVR_SUCCESS;
838}
hualing chencc91e1c2020-02-28 13:26:17 +0800839static int _dvr_replay_changed_pid(DVR_PlaybackHandle_t handle) {
840 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800841 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800842 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800843 return DVR_FAILURE;
844 }
hualing chen5cbe1a62020-02-10 16:36:36 +0800845
hualing chencc91e1c2020-02-28 13:26:17 +0800846 //compare cur segment
847 //if (player->cmd.state == DVR_PLAYBACK_STATE_START)
848 {
849 //check video pids, stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800850 _do_check_pid_info(handle, player->last_segment.pids.video, player->cur_segment.pids, 0);
hualing chencc91e1c2020-02-28 13:26:17 +0800851 //check sub audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800852 _do_check_pid_info(handle, player->last_segment.pids.ad, player->cur_segment.pids, 2);
hualing chen969fe7b2021-05-26 15:13:17 +0800853 //check audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800854 _do_check_pid_info(handle, player->last_segment.pids.audio, player->cur_segment.pids, 1);
hualing chene3797f02021-01-13 14:53:28 +0800855 DVR_PB_DG(1, ":last apid: %d set apid: %d", player->last_segment.pids.audio.pid,player->cur_segment.pids.audio.pid);
hualing chencc91e1c2020-02-28 13:26:17 +0800856 //check pcr pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +0800857 _do_check_pid_info(handle, player->last_segment.pids.pcr, player->cur_segment.pids, 3);
hualing chencc91e1c2020-02-28 13:26:17 +0800858 }
hualing chena540a7e2020-03-27 16:44:05 +0800859 return DVR_SUCCESS;
hualing chencc91e1c2020-02-28 13:26:17 +0800860}
hualing chen5cbe1a62020-02-10 16:36:36 +0800861
hualing chend241c7a2021-06-22 13:34:27 +0800862static int _dvr_check_speed_con(DVR_PlaybackHandle_t handle)
863{
864 DVR_Playback_t *player = (DVR_Playback_t *) handle;
865 if (player == NULL) {
866 DVR_PB_DG(1, "player is NULL");
867 return DVR_TRUE;
868 }
869 char buf[10];
870 dvr_prop_read("vendor.tv.libdvr.con", buf, sizeof(buf));
871 DVR_PB_DG(1, "player get prop[%d][%s]", atoi(buf), buf);
872
873 if (atoi(buf) != 1) {
874 //return DVR_TRUE;
875 }
876
hualing chen7ea70a72021-09-09 11:25:13 +0800877 DVR_PB_DG(1, ":play speed: %f ply dur: %u sys_dur: %u",
hualing chen03fd4942021-07-15 15:56:41 +0800878 player->speed,
879 player->con_spe.ply_dur,
880 player->con_spe.sys_dur);
hualing chend241c7a2021-06-22 13:34:27 +0800881
882 if (player->speed != 1.0f)
883 return DVR_TRUE;
884
885 if (player->con_spe.ply_dur > 0
hualing chen03fd4942021-07-15 15:56:41 +0800886 && 2 * player->con_spe.ply_dur > 3 * player->con_spe.sys_dur)
hualing chend241c7a2021-06-22 13:34:27 +0800887 return DVR_FALSE;
888
889 return DVR_TRUE;
890}
891
hualing chencc91e1c2020-02-28 13:26:17 +0800892static int _dvr_check_cur_segment_flag(DVR_PlaybackHandle_t handle)
893{
894 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +0800895 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800896 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800897 return DVR_FAILURE;
898 }
hualing chenf43b8ba2020-07-28 13:11:42 +0800899 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
900 DVR_PB_DG(1, "vendor is amlogic. no used segment flag to hide or show av");
901 return DVR_SUCCESS;
902 }
hualing chen03fd4942021-07-15 15:56:41 +0800903 DVR_PB_DG(1, "flag[0x%x]id[%lld]last[0x%x][%llu]",
904 player->cur_segment.flags,
905 player->cur_segment.segment_id,
906 player->last_segment.flags,
907 player->last_segment.segment_id);
hualing chen87072a82020-03-12 16:20:12 +0800908 if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE &&
909 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +0800910 //enable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800911 DVR_PB_DG(1, "unmute");
hualing chen2aba4022020-03-02 13:49:55 +0800912 AmTsPlayer_showVideo(player->handle);
913 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen87072a82020-03-12 16:20:12 +0800914 } else if ((player->cur_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
915 (player->last_segment.flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chen2aba4022020-03-02 13:49:55 +0800916 //disable display
hualing chen4b7c15d2020-04-07 16:13:48 +0800917 DVR_PB_DG(1, "mute");
hualing chen2aba4022020-03-02 13:49:55 +0800918 AmTsPlayer_hideVideo(player->handle);
919 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chencc91e1c2020-02-28 13:26:17 +0800920 }
921 return DVR_SUCCESS;
922}
hualing chene3797f02021-01-13 14:53:28 +0800923/*
924if decodec sucess first time.
925sucess: return true
926fail: return false
927*/
hualing chena540a7e2020-03-27 16:44:05 +0800928static DVR_Bool_t _dvr_pauselive_decode_sucess(DVR_PlaybackHandle_t handle) {
929 DVR_Playback_t *player = (DVR_Playback_t *) handle;
930 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800931 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +0800932 return DVR_TRUE;
933 }
hualing chene3797f02021-01-13 14:53:28 +0800934 if (player->first_frame == 1) {
hualing chena540a7e2020-03-27 16:44:05 +0800935 return DVR_TRUE;
hualing chene3797f02021-01-13 14:53:28 +0800936 } else {
937 return DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +0800938 }
939}
hualing chen86e7d482020-01-16 15:13:33 +0800940static void* _dvr_playback_thread(void *arg)
941{
hualing chen040df222020-01-17 13:35:02 +0800942 DVR_Playback_t *player = (DVR_Playback_t *) arg;
hualing chencc91e1c2020-02-28 13:26:17 +0800943 //int need_open_segment = 1;
hualing chen2aba4022020-03-02 13:49:55 +0800944 am_tsplayer_input_buffer wbufs;
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800945 am_tsplayer_input_buffer dec_bufs;
hualing chen5cbe1a62020-02-10 16:36:36 +0800946 int ret = DVR_SUCCESS;
hualing chen86e7d482020-01-16 15:13:33 +0800947
hualing chen39628212020-05-14 10:35:13 +0800948 #define MAX_REACHEND_TIMEOUT (3000)
949 int reach_end_timeout = 0;//ms
950 int cache_time = 0;
hualing chen6d24aa92020-03-23 18:43:47 +0800951 int timeout = 300;//ms
hualing chen2aba4022020-03-02 13:49:55 +0800952 uint64_t write_timeout_ms = 50;
hualing chen86e7d482020-01-16 15:13:33 +0800953 uint8_t *buf = NULL;
hualing chen040df222020-01-17 13:35:02 +0800954 int buf_len = player->openParams.block_size > 0 ? player->openParams.block_size : (256 * 1024);
hualing chen266b9502020-04-04 17:39:39 +0800955 DVR_Bool_t b_writed_whole_block = player->openParams.block_size > 0 ? DVR_TRUE:DVR_FALSE;
956
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800957 int dec_buf_size = buf_len + 188;
hualing chen86e7d482020-01-16 15:13:33 +0800958 int real_read = 0;
hualing chen2aba4022020-03-02 13:49:55 +0800959 DVR_Bool_t goto_rewrite = DVR_FALSE;
yinming ding0ce94922021-09-08 15:09:15 +0800960 char prop_buf[10];
961
962 memset(prop_buf, 0 ,sizeof(prop_buf));
963 dvr_prop_read("vendor.tv.libdvr.writetm", prop_buf, sizeof(prop_buf));
964 DVR_PB_DG(1, "vendor.tv.libdvr.writetm get prop[%d][%s]", atoi(prop_buf), prop_buf);
965 if (atoi(prop_buf) > 0)
966 write_timeout_ms = atoi(prop_buf);
hualing chen03fd4942021-07-15 15:56:41 +0800967
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800968 if (player->is_secure_mode) {
969 if (dec_buf_size > player->secure_buffer_size) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800970 DVR_PB_DG(1, "playback blocksize too large");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800971 return NULL;
972 }
973 }
hualing chen86e7d482020-01-16 15:13:33 +0800974 buf = malloc(buf_len);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800975 if (!buf) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800976 DVR_PB_DG(1, "Malloc buffer failed");
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800977 return NULL;
978 }
hualing chen2aba4022020-03-02 13:49:55 +0800979 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
980 wbufs.buf_size = 0;
hualing chencc91e1c2020-02-28 13:26:17 +0800981
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800982 dec_bufs.buf_data = malloc(dec_buf_size);
983 if (!dec_bufs.buf_data) {
hualing chen4b7c15d2020-04-07 16:13:48 +0800984 DVR_PB_DG(1, "Malloc dec buffer failed");
Pengfei Liufaf38e42020-05-22 00:28:02 +0800985 free(buf);
pengfei.liu07ddc8a2020-03-24 23:36:53 +0800986 return NULL;
987 }
988 dec_bufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
989 dec_bufs.buf_size = dec_buf_size;
990
hualing chencc91e1c2020-02-28 13:26:17 +0800991 if (player->segment_is_open == DVR_FALSE) {
hualing chen5cbe1a62020-02-10 16:36:36 +0800992 ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
993 }
hualing chen86e7d482020-01-16 15:13:33 +0800994
hualing chen86e7d482020-01-16 15:13:33 +0800995 if (ret != DVR_SUCCESS) {
996 if (buf != NULL) {
997 free(buf);
998 buf = NULL;
999 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001000 free(dec_bufs.buf_data);
hualing chen4b7c15d2020-04-07 16:13:48 +08001001 DVR_PB_DG(1, "get segment error");
hualing chenb31a6c62020-01-13 17:27:00 +08001002 return NULL;
hualing chen86e7d482020-01-16 15:13:33 +08001003 }
hualing chen4fe3bee2020-10-23 13:58:52 +08001004 DVR_PB_DG(1, "player->vendor %d,player->has_video[%d] bufsize[0x%x]whole block[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08001005 player->vendor, player->has_video, buf_len, b_writed_whole_block);
hualing chenfbf8e022020-06-15 13:43:11 +08001006 //get play statue not here,send ok event when vendor is aml or only audio channel if not send ok event
1007 if (((player->first_trans_ok == DVR_FALSE) && (player->vendor == DVR_PLAYBACK_VENDOR_AML) ) ||
1008 (player->first_trans_ok == DVR_FALSE && player->has_video == DVR_FALSE)) {
1009 player->first_trans_ok = DVR_TRUE;
1010 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_TRUE);
1011 }
hualing chencc91e1c2020-02-28 13:26:17 +08001012 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen6d24aa92020-03-23 18:43:47 +08001013 //set video show
1014 AmTsPlayer_showVideo(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08001015
hualing chen86e7d482020-01-16 15:13:33 +08001016 int trick_stat = 0;
1017 while (player->is_running/* || player->cmd.last_cmd != player->cmd.cur_cmd*/) {
hualing chenb31a6c62020-01-13 17:27:00 +08001018
hualing chen86e7d482020-01-16 15:13:33 +08001019 //check trick stat
hualing chencc91e1c2020-02-28 13:26:17 +08001020 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001021
hualing chen2aba4022020-03-02 13:49:55 +08001022 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_SEEK ||
1023 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08001024 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB ||
hualing chena540a7e2020-03-27 16:44:05 +08001025 player->speed > FF_SPEED ||player->speed <= FB_SPEED ||
hualing chen39628212020-05-14 10:35:13 +08001026 (player->state == DVR_PLAYBACK_STATE_PAUSE) ||
hualing chen31140872020-03-25 12:29:26 +08001027 (player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
hualing chen86e7d482020-01-16 15:13:33 +08001028 {
hualing chen2aba4022020-03-02 13:49:55 +08001029 trick_stat = _dvr_playback_get_trick_stat((DVR_PlaybackHandle_t)player);
1030 if (trick_stat > 0) {
hualing chen03fd4942021-07-15 15:56:41 +08001031 DVR_PB_DG(1, "trick stat[%d] is > 0 cur cmd[%d]last cmd[%d]flag[0x%x]",
1032 trick_stat, player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen87072a82020-03-12 16:20:12 +08001033 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 +08001034 //check last cmd
hualing chenbcada022020-04-22 14:27:01 +08001035 if (player->cmd.last_cmd == DVR_PLAYBACK_CMD_PAUSE
hualing chen31140872020-03-25 12:29:26 +08001036 || ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE
hualing chen87072a82020-03-12 16:20:12 +08001037 && ( player->cmd.cur_cmd == DVR_PLAYBACK_CMD_START
1038 ||player->cmd.last_cmd == DVR_PLAYBACK_CMD_VSTART
hualing chen2aba4022020-03-02 13:49:55 +08001039 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_ASTART
1040 || player->cmd.last_cmd == DVR_PLAYBACK_CMD_START))) {
hualing chen03fd4942021-07-15 15:56:41 +08001041 DVR_PB_DG(1, "pause play-------cur cmd[%d]last cmd[%d]flag[0x%x]",
1042 player->cmd.cur_cmd, player->cmd.last_cmd, player->play_flag);
hualing chen2aba4022020-03-02 13:49:55 +08001043 //need change to pause state
1044 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
1045 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen31140872020-03-25 12:29:26 +08001046 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08001047 //clear flag
hualing chen31140872020-03-25 12:29:26 +08001048 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
hualing chena540a7e2020-03-27 16:44:05 +08001049 player->first_frame = 0;
hualing chen10cdb162021-02-05 10:44:41 +08001050 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001051 AmTsPlayer_pauseVideoDecoding(player->handle);
1052 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2bd8a7a2020-04-02 11:31:03 +08001053 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001054 DVR_PB_DG(1, "clear first frame value-------");
hualing chen2bd8a7a2020-04-02 11:31:03 +08001055 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001056 }
1057 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF
1058 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chena540a7e2020-03-27 16:44:05 +08001059 ||player->speed > FF_SPEED ||player->speed < FB_SPEED) {
hualing chen2aba4022020-03-02 13:49:55 +08001060 //restart play stream if speed > 2
hualing chenb5cd42e2020-04-15 17:03:34 +08001061 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen7ea70a72021-09-09 11:25:13 +08001062 DVR_PB_DG(1, "fffb pause state----speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001063 player->speed,
1064 player->fffb_current,
1065 _dvr_time_getClock(),
1066 _dvr_playback_state_toString(player->state),
1067 player->next_fffb_time);
hualing chen2aba4022020-03-02 13:49:55 +08001068 //used timeout wait need lock first,so we unlock and lock
1069 //pthread_mutex_unlock(&player->lock);
1070 //pthread_mutex_lock(&player->lock);
1071 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1072 pthread_mutex_unlock(&player->lock);
1073 continue;
hualing chenb5cd42e2020-04-15 17:03:34 +08001074 } else if (_dvr_time_getClock() < player->next_fffb_time) {
hualing chen7ea70a72021-09-09 11:25:13 +08001075 DVR_PB_DG(1, "fffb timeout-to pause video---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001076 player->speed,
1077 player->fffb_current,
1078 _dvr_time_getClock(),
1079 _dvr_playback_state_toString(player->state),
1080 player->next_fffb_time);
hualing chenb5cd42e2020-04-15 17:03:34 +08001081 //used timeout wait need lock first,so we unlock and lock
1082 //pthread_mutex_unlock(&player->lock);
1083 //pthread_mutex_lock(&player->lock);
1084 AmTsPlayer_pauseVideoDecoding(player->handle);
1085 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1086 pthread_mutex_unlock(&player->lock);
1087 continue;
1088
hualing chen2aba4022020-03-02 13:49:55 +08001089 }
hualing chen03fd4942021-07-15 15:56:41 +08001090 DVR_PB_DG(1, "fffb play-------speed[%f][%d][%d][%s][%d]",
1091 player->speed,
1092 goto_rewrite,
1093 real_read,
1094 _dvr_playback_state_toString(player->state),
1095 player->cmd.cur_cmd);
1096
hualing chen2aba4022020-03-02 13:49:55 +08001097 pthread_mutex_unlock(&player->lock);
1098 goto_rewrite = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001099 real_read = 0;
hualing chena540a7e2020-03-27 16:44:05 +08001100 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1101 player->first_frame = 0;
hualing chen2aba4022020-03-02 13:49:55 +08001102 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chenbcada022020-04-22 14:27:01 +08001103 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001104 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08001105 } else if(player->state == DVR_PLAYBACK_STATE_PAUSE) {
1106 //on pause state,user seek to new pos,we need pause and wait
1107 //user to resume
1108 DVR_PB_DG(1, "pause, when got first frame event when user seek end");
1109 player->first_frame = 0;
1110 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1111 AmTsPlayer_pauseVideoDecoding(player->handle);
1112 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001113 }
hualing chen1ffd85b2021-08-16 15:18:43 +08001114 } else if (player->fffb_play == DVR_TRUE){
hualing chen4b7c15d2020-04-07 16:13:48 +08001115 //for first into fffb when reset speed
1116 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||
1117 _dvr_time_getClock() < player->next_fffb_time) {
hualing chen7ea70a72021-09-09 11:25:13 +08001118 DVR_PB_DG(1, "fffb timeout-fffb play---speed[%f] fffb cur[%u] cur sys[%u] [%s] [%u]",
hualing chen03fd4942021-07-15 15:56:41 +08001119 player->speed,
1120 player->fffb_current,
1121 _dvr_time_getClock(),
1122 _dvr_playback_state_toString(player->state),
1123 player->next_fffb_time);
hualing chen4b7c15d2020-04-07 16:13:48 +08001124 //used timeout wait need lock first,so we unlock and lock
1125 //pthread_mutex_unlock(&player->lock);
1126 //pthread_mutex_lock(&player->lock);
1127 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1128 pthread_mutex_unlock(&player->lock);
1129 continue;
1130 }
hualing chen03fd4942021-07-15 15:56:41 +08001131 DVR_PB_DG(1, "fffb replay-------speed[%f][%d][%d][%s][%d]player->fffb_play[%d]",
1132 player->speed,
1133 goto_rewrite,
1134 real_read,
1135 _dvr_playback_state_toString(player->state),
1136 player->cmd.cur_cmd,
1137 player->fffb_play);
hualing chen4b7c15d2020-04-07 16:13:48 +08001138 pthread_mutex_unlock(&player->lock);
1139 goto_rewrite = DVR_FALSE;
1140 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001141 player->ts_cache_len = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08001142 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1143 player->first_frame = 0;
1144 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
1145 pthread_mutex_lock(&player->lock);
1146 player->fffb_play = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001147 }
hualing chenb31a6c62020-01-13 17:27:00 +08001148 }
hualing chen86e7d482020-01-16 15:13:33 +08001149
hualing chen30423862021-04-16 14:39:12 +08001150 if (player->state == DVR_PLAYBACK_STATE_PAUSE
1151 && player->seek_pause == DVR_FALSE) {
hualing chen6e4bfa52020-03-13 14:37:11 +08001152 //check is need send time send end
hualing chenc70a8df2020-05-12 19:23:11 +08001153 DVR_PB_DG(1, "pause, continue");
hualing chen2932d372020-04-29 13:44:00 +08001154 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen87072a82020-03-12 16:20:12 +08001155 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1156 pthread_mutex_unlock(&player->lock);
1157 continue;
1158 }
hualing chen266b9502020-04-04 17:39:39 +08001159 //when seek action is done. we need drop write timeout data.
1160 if (player->drop_ts == DVR_TRUE) {
1161 goto_rewrite = DVR_FALSE;
1162 real_read = 0;
1163 player->drop_ts = DVR_FALSE;
1164 }
hualing chen2aba4022020-03-02 13:49:55 +08001165 if (goto_rewrite == DVR_TRUE) {
1166 goto_rewrite = DVR_FALSE;
1167 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001168 //DVR_PB_DG(1, "rewrite-player->speed[%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08001169 goto rewrite;
1170 }
hualing chen6e4bfa52020-03-13 14:37:11 +08001171 //.check is need send time send end
hualing chen2932d372020-04-29 13:44:00 +08001172 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001173 pthread_mutex_lock(&player->segment_lock);
hualing chene41f4372020-06-06 16:29:17 +08001174 //DVR_PB_DG(1, "start read");
hualing chen87072a82020-03-12 16:20:12 +08001175 int read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001176 real_read = real_read + read;
1177 player->ts_cache_len = real_read;
hualing chenfbf8e022020-06-15 13:43:11 +08001178 //DVR_PB_DG(1, "start read end [%d]", read);
hualing chen4b7c15d2020-04-07 16:13:48 +08001179 pthread_mutex_unlock(&player->segment_lock);
hualing chen87072a82020-03-12 16:20:12 +08001180 pthread_mutex_unlock(&player->lock);
hualing chenb5cd42e2020-04-15 17:03:34 +08001181 if (read < 0 && errno == EIO) {
1182 //EIO ERROR, EXIT THRAD
1183 DVR_PB_DG(1, "read error.EIO error, exit thread");
1184 DVR_Play_Notify_t notify;
1185 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1186 notify.event = DVR_PLAYBACK_EVENT_ERROR;
hualing chen9b434f02020-06-10 15:06:54 +08001187 notify.info.error_reason = DVR_ERROR_REASON_READ;
hualing chen2932d372020-04-29 13:44:00 +08001188 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player,DVR_PLAYBACK_EVENT_ERROR, &notify, DVR_TRUE);
hualing chenb5cd42e2020-04-15 17:03:34 +08001189 goto end;
1190 } else if (read < 0) {
1191 DVR_PB_DG(1, "read error.:%d EIO:%d", errno, EIO);
1192 }
hualing chen87072a82020-03-12 16:20:12 +08001193 //if on fb mode and read file end , we need calculate pos to retry read.
1194 if (read == 0 && IS_FB(player->speed) && real_read == 0) {
hualing chen03fd4942021-07-15 15:56:41 +08001195 DVR_PB_DG(1, "recalculate read [%d] readed [%d]buf_len[%d]speed[%f]id=[%llu]",
1196 read,
1197 real_read,
1198 buf_len,
1199 player->speed,
1200 player->cur_segment_id);
hualing chen87072a82020-03-12 16:20:12 +08001201 _dvr_playback_calculate_seekpos((DVR_PlaybackHandle_t)player);
1202 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08001203 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1204 pthread_mutex_unlock(&player->lock);
1205 continue;
1206 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001207 //DVR_PB_DG(1, "read ts [%d]buf_len[%d]speed[%f]real_read:%d", read, buf_len, player->speed, real_read);
hualing chen86e7d482020-01-16 15:13:33 +08001208 if (read == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08001209 //file end.need to play next segment
hualing chene41f4372020-06-06 16:29:17 +08001210 #define MIN_CACHE_TIME (3000)
1211 int _cache_time = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player) ;
hualing chene3797f02021-01-13 14:53:28 +08001212 /*if cache time is > min cache time ,not read next segment,wait cache data to play*/
hualing chene41f4372020-06-06 16:29:17 +08001213 if (_cache_time > MIN_CACHE_TIME) {
hualing chene41f4372020-06-06 16:29:17 +08001214 pthread_mutex_lock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001215 /*if cache time > 20s , we think get time is error,*/
1216 if (_cache_time - MIN_CACHE_TIME > 20 * 1000) {
1217 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1218 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1219 DVR_PB_DG(1, "read end but cache time is %d > 20s, this is an error at media_hal", _cache_time);
1220 }
1221 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, ((_cache_time - MIN_CACHE_TIME) > MIN_CACHE_TIME ? MIN_CACHE_TIME : (_cache_time - MIN_CACHE_TIME)));
hualing chene41f4372020-06-06 16:29:17 +08001222 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001223 DVR_PB_DG(1, "read end but cache time is %d > %d, to sleep end and continue", _cache_time, MIN_CACHE_TIME);
hualing chene41f4372020-06-06 16:29:17 +08001224 //continue;
1225 }
hualing chen969fe7b2021-05-26 15:13:17 +08001226
hualing chen040df222020-01-17 13:35:02 +08001227 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen2aba4022020-03-02 13:49:55 +08001228 //init fffb time if change segment
hualing chen041c4092020-04-05 15:11:50 +08001229 _dvr_init_fffb_time((DVR_PlaybackHandle_t)player);
hualing chen31140872020-03-25 12:29:26 +08001230
1231 int delay = _dvr_playback_get_delaytime((DVR_PlaybackHandle_t)player);
hualing chene3797f02021-01-13 14:53:28 +08001232 if (ret != DVR_SUCCESS) {
hualing chene8735082021-10-13 16:44:20 +08001233 if (player->vendor == DVR_PLAYBACK_VENDOR_AMAZON) {
1234 if (delay > 700) {
1235 DVR_PB_DG(1, "delay time [%d] > 700, not send nodata event", delay);
1236 } else {
1237 player->noData++;
1238 }
1239 } else {
1240 player->noData++;
1241 }
hualing chene3797f02021-01-13 14:53:28 +08001242 if (player->noData == 4) {
1243 DVR_PB_DG(1, "playback send nodata event nodata[%d]", player->noData);
1244 //send event here and pause
1245 DVR_Play_Notify_t notify;
1246 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1247 notify.event = DVR_PLAYBACK_EVENT_NODATA;
1248 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_NODATA");
1249 //get play statue not here
1250 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_NODATA, &notify, DVR_FALSE);
1251 }
1252 }
1253 //send reached event
hualing chen39628212020-05-14 10:35:13 +08001254 if ((ret != DVR_SUCCESS &&
hualing chen03fd4942021-07-15 15:56:41 +08001255 (player->vendor != DVR_PLAYBACK_VENDOR_AMAZON) &&
hualing chen041c4092020-04-05 15:11:50 +08001256 (delay <= MIN_TSPLAYER_DELAY_TIME ||
hualing chen4b7c15d2020-04-07 16:13:48 +08001257 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) &&
hualing chen39628212020-05-14 10:35:13 +08001258 _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player)) ||
1259 (reach_end_timeout >= MAX_REACHEND_TIMEOUT )) {
hualing chena540a7e2020-03-27 16:44:05 +08001260 //send end event to hal
hualing chen31140872020-03-25 12:29:26 +08001261 DVR_Play_Notify_t notify;
1262 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1263 notify.event = DVR_PLAYBACK_EVENT_REACHED_END;
1264 //get play statue not here
1265 dvr_playback_pause((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen2932d372020-04-29 13:44:00 +08001266 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_REACHED_END, &notify, DVR_TRUE);
hualing chen31140872020-03-25 12:29:26 +08001267 //continue,timeshift mode, when read end,need wait cur recording segment
hualing chen39628212020-05-14 10:35:13 +08001268 DVR_PB_DG(1, "playback is send end delay:[%d]reach_end_timeout[%d]ms", delay, reach_end_timeout);
hualing chen31140872020-03-25 12:29:26 +08001269 pthread_mutex_lock(&player->lock);
1270 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1271 pthread_mutex_unlock(&player->lock);
1272 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001273 } else if (ret != DVR_SUCCESS) {
1274 //not send event and pause,sleep and go to next time to recheck
hualing chen39628212020-05-14 10:35:13 +08001275 if (delay < cache_time) {
1276 //delay time is changed and then has data to play, so not start timeout
1277 } else {
1278 reach_end_timeout = reach_end_timeout + timeout;
1279 }
1280 cache_time = delay;
hualing chen4b7c15d2020-04-07 16:13:48 +08001281 DVR_PB_DG(1, "delay:%d pauselive:%d", delay, _dvr_pauselive_decode_sucess((DVR_PlaybackHandle_t)player));
hualing chen31140872020-03-25 12:29:26 +08001282 pthread_mutex_lock(&player->lock);
1283 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1284 pthread_mutex_unlock(&player->lock);
1285 continue;
hualing chen86e7d482020-01-16 15:13:33 +08001286 }
hualing chen39628212020-05-14 10:35:13 +08001287 reach_end_timeout = 0;
1288 cache_time = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001289 pthread_mutex_lock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08001290 //change next segment success case
1291 _dvr_playback_sent_transition_ok((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen4b7c15d2020-04-07 16:13:48 +08001292 DVR_PB_DG(1, "_dvr_replay_changed_pid:start");
hualing chencc91e1c2020-02-28 13:26:17 +08001293 _dvr_replay_changed_pid((DVR_PlaybackHandle_t)player);
1294 _dvr_check_cur_segment_flag((DVR_PlaybackHandle_t)player);
hualing chen21a40372021-10-29 11:07:26 +08001295 pthread_mutex_lock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08001296 read = segment_read(player->r_handle, buf + real_read, buf_len - real_read);
hualing chen21a40372021-10-29 11:07:26 +08001297 real_read = real_read + read;
1298 player->ts_cache_len = real_read;
1299 pthread_mutex_unlock(&player->segment_lock);
1300
hualing chen87072a82020-03-12 16:20:12 +08001301 pthread_mutex_unlock(&player->lock);
hualing chene3797f02021-01-13 14:53:28 +08001302 }//read len 0 check end
1303 if (player->noData > 0) {
1304 player->noData = 0;
1305 DVR_PB_DG(1, "playback send data event resume[%d]", player->noData);
1306 //send event here and pause
1307 DVR_Play_Notify_t notify;
1308 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1309 notify.event = DVR_PLAYBACK_EVENT_DATARESUME;
1310 DVR_PB_DG(1, "send event DVR_PLAYBACK_EVENT_DATARESUME");
1311 //get play statue not here
1312 _dvr_playback_sent_event((DVR_PlaybackHandle_t)player, DVR_PLAYBACK_EVENT_DATARESUME, &notify, DVR_FALSE);
hualing chen86e7d482020-01-16 15:13:33 +08001313 }
hualing chen39628212020-05-14 10:35:13 +08001314 reach_end_timeout = 0;
hualing chen21a40372021-10-29 11:07:26 +08001315 //real_read = real_read + read;
hualing chen2aba4022020-03-02 13:49:55 +08001316 wbufs.buf_size = real_read;
hualing chen2aba4022020-03-02 13:49:55 +08001317 wbufs.buf_data = buf;
hualing chen5605eed2020-05-26 18:18:06 +08001318
hualing chena540a7e2020-03-27 16:44:05 +08001319 //check read data len,iflen < 0, we need continue
hualing chen7a56cba2020-04-14 14:09:27 +08001320 if (wbufs.buf_size <= 0 || wbufs.buf_data == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001321 DVR_PB_DG(1, "error occur read_read [%d],buf=[%p]",wbufs.buf_size, wbufs.buf_data);
hualing chen5cbe1a62020-02-10 16:36:36 +08001322 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001323 player->ts_cache_len = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001324 continue;
hualing chena540a7e2020-03-27 16:44:05 +08001325 }
hualing chen266b9502020-04-04 17:39:39 +08001326 //if need write whole block size, we need check read buf len is eq block size.
1327 if (b_writed_whole_block == DVR_TRUE) {
1328 //buf_len is block size value.
1329 if (real_read < buf_len) {
1330 //coontinue to read data from file
hualing chen4b7c15d2020-04-07 16:13:48 +08001331 DVR_PB_DG(1, "read buf len[%d] is < block size [%d]", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001332 pthread_mutex_lock(&player->lock);
1333 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
1334 pthread_mutex_unlock(&player->lock);
hualing chenc70a8df2020-05-12 19:23:11 +08001335 DVR_PB_DG(1, "read buf len[%d] is < block size [%d] continue", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001336 continue;
1337 } else if (real_read > buf_len) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001338 DVR_PB_DG(1, "read buf len[%d] is > block size [%d],this error occur", real_read, buf_len);
hualing chen266b9502020-04-04 17:39:39 +08001339 }
1340 }
1341
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001342 if (player->dec_func) {
1343 DVR_CryptoParams_t crypto_params;
1344
1345 memset(&crypto_params, 0, sizeof(crypto_params));
1346 crypto_params.type = DVR_CRYPTO_TYPE_DECRYPT;
1347 memcpy(crypto_params.location, player->cur_segment.location, strlen(player->cur_segment.location));
1348 crypto_params.segment_id = player->cur_segment.segment_id;
hualing chen1f26ffa2020-11-03 10:39:20 +08001349 crypto_params.offset = segment_tell_position(player->r_handle) - wbufs.buf_size;
hualing chenbafc62d2020-11-02 15:44:05 +08001350 if ((crypto_params.offset % (player->openParams.block_size)) != 0)
1351 DVR_PB_DG(1, "offset is not block_size %d", player->openParams.block_size);
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001352 crypto_params.input_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1353 crypto_params.input_buffer.addr = (size_t)buf;
1354 crypto_params.input_buffer.size = real_read;
1355
1356 if (player->is_secure_mode) {
1357 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_SECURE;
1358 crypto_params.output_buffer.addr = (size_t)player->secure_buffer;
1359 crypto_params.output_buffer.size = dec_buf_size;
1360 ret = player->dec_func(&crypto_params, player->dec_userdata);
1361 wbufs.buf_data = player->secure_buffer;
pengfei.liufda2a972020-04-09 14:47:15 +08001362 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_SECURE;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001363 } else {
1364 crypto_params.output_buffer.type = DVR_BUFFER_TYPE_NORMAL;
1365 crypto_params.output_buffer.addr = (size_t)dec_bufs.buf_data;
1366 crypto_params.output_buffer.size = dec_buf_size;
1367 ret = player->dec_func(&crypto_params, player->dec_userdata);
1368 wbufs.buf_data = dec_bufs.buf_data;
pengfei.liufda2a972020-04-09 14:47:15 +08001369 wbufs.buf_type = TS_INPUT_BUFFER_TYPE_NORMAL;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001370 }
1371 if (ret != DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001372 DVR_PB_DG(1, "decrypt failed");
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001373 }
pengfei.liufda2a972020-04-09 14:47:15 +08001374 wbufs.buf_size = crypto_params.output_size;
pengfei.liu27cc4ec2020-04-03 16:28:16 +08001375 }
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001376rewrite:
hualing chenbcada022020-04-22 14:27:01 +08001377 if (player->drop_ts == DVR_TRUE) {
1378 //need drop ts data when seek occur.we need read next loop,drop this ts data
1379 goto_rewrite = DVR_FALSE;
1380 real_read = 0;
hualing chen5605eed2020-05-26 18:18:06 +08001381 player->ts_cache_len = 0;
hualing chenbcada022020-04-22 14:27:01 +08001382 player->drop_ts = DVR_FALSE;
1383 continue;
1384 }
hualing chen21a40372021-10-29 11:07:26 +08001385
1386 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08001387 player->ts_cache_len = real_read;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001388 ret = AmTsPlayer_writeData(player->handle, &wbufs, write_timeout_ms);
1389 if (ret == AM_TSPLAYER_OK) {
hualing chen5605eed2020-05-26 18:18:06 +08001390 player->ts_cache_len = 0;
hualing chen21a40372021-10-29 11:07:26 +08001391 pthread_mutex_unlock(&player->segment_lock);
hualing chena540a7e2020-03-27 16:44:05 +08001392 real_read = 0;
1393 write_success++;
hualing chend241c7a2021-06-22 13:34:27 +08001394 if (CONTROL_SPEED_ENABLE == 1) {
1395check0:
1396 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1397 pthread_mutex_lock(&player->lock);
1398 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1399 pthread_mutex_unlock(&player->lock);
1400 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1401 goto check0;
1402 }
1403 }
hualing chen5605eed2020-05-26 18:18:06 +08001404 //DVR_PB_DG(1, "write write_success:%d wbufs.buf_size:%d", write_success, wbufs.buf_size);
hualing chena540a7e2020-03-27 16:44:05 +08001405 continue;
hualing chen87072a82020-03-12 16:20:12 +08001406 } else {
hualing chen21a40372021-10-29 11:07:26 +08001407 pthread_mutex_unlock(&player->segment_lock);
hualing chen7ea70a72021-09-09 11:25:13 +08001408 DVR_PB_DG(1, "write time out write_success:%d wbufs.buf_size:%d systime:%u",
hualing chen03fd4942021-07-15 15:56:41 +08001409 write_success,
1410 wbufs.buf_size,
1411 _dvr_time_getClock());
1412
hualing chena540a7e2020-03-27 16:44:05 +08001413 write_success = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001414 if (CONTROL_SPEED_ENABLE == 1) {
1415check1:
1416 if (_dvr_check_speed_con((DVR_PlaybackHandle_t)player) == DVR_FALSE){
1417 pthread_mutex_lock(&player->lock);
1418 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, 50);
1419 pthread_mutex_unlock(&player->lock);
1420 _dvr_playback_sent_playtime((DVR_PlaybackHandle_t)player, DVR_FALSE);
1421 goto check1;
1422 }
1423 }
hualing chencc91e1c2020-02-28 13:26:17 +08001424 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001425 _dvr_playback_timeoutwait((DVR_PlaybackHandle_t)player, timeout);
hualing chencc91e1c2020-02-28 13:26:17 +08001426 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08001427 if (!player->is_running) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001428 DVR_PB_DG(1, "playback thread exit");
hualing chen86e7d482020-01-16 15:13:33 +08001429 break;
1430 }
hualing chen2aba4022020-03-02 13:49:55 +08001431 goto_rewrite = DVR_TRUE;
1432 //goto rewrite;
hualing chen86e7d482020-01-16 15:13:33 +08001433 }
1434 }
hualing chenb5cd42e2020-04-15 17:03:34 +08001435end:
hualing chen4b7c15d2020-04-07 16:13:48 +08001436 DVR_PB_DG(1, "playback thread is end");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001437 free(buf);
1438 free(dec_bufs.buf_data);
hualing chen86e7d482020-01-16 15:13:33 +08001439 return NULL;
hualing chenb31a6c62020-01-13 17:27:00 +08001440}
1441
1442
hualing chen040df222020-01-17 13:35:02 +08001443static int _start_playback_thread(DVR_PlaybackHandle_t handle)
hualing chenb31a6c62020-01-13 17:27:00 +08001444{
hualing chen040df222020-01-17 13:35:02 +08001445 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001446
1447 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001448 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001449 return DVR_FAILURE;
1450 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001451 DVR_PB_DG(1, "start thread is_running:[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001452 if (player->is_running == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001453 return 0;
hualing chen86e7d482020-01-16 15:13:33 +08001454 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001455 player->is_running = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001456 int rc = pthread_create(&player->playback_thread, NULL, _dvr_playback_thread, (void*)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08001457 if (rc < 0)
1458 player->is_running = DVR_FALSE;
hualing chen86e7d482020-01-16 15:13:33 +08001459 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001460}
1461
1462
hualing chen040df222020-01-17 13:35:02 +08001463static int _stop_playback_thread(DVR_PlaybackHandle_t handle)
hualing chen86e7d482020-01-16 15:13:33 +08001464{
hualing chen040df222020-01-17 13:35:02 +08001465 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001466
1467 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001468 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001469 return DVR_FAILURE;
1470 }
1471
hualing chen4b7c15d2020-04-07 16:13:48 +08001472 DVR_PB_DG(1, "stopthread------[%d]", player->is_running);
hualing chencc91e1c2020-02-28 13:26:17 +08001473 if (player->is_running == DVR_TRUE)
hualing chen86e7d482020-01-16 15:13:33 +08001474 {
1475 player->is_running = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001476 _dvr_playback_sendSignal(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001477 pthread_join(player->playback_thread, NULL);
1478 }
1479 if (player->r_handle) {
1480 segment_close(player->r_handle);
1481 player->r_handle = NULL;
1482 }
hualing chen7a56cba2020-04-14 14:09:27 +08001483 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001484 return 0;
1485}
1486
hualing chenb31a6c62020-01-13 17:27:00 +08001487/**\brief Open an dvr palyback
1488 * \param[out] p_handle dvr playback addr
1489 * \param[in] params dvr playback open parameters
1490 * \retval DVR_SUCCESS On success
1491 * \return Error code
1492 */
hualing chen040df222020-01-17 13:35:02 +08001493int dvr_playback_open(DVR_PlaybackHandle_t *p_handle, DVR_PlaybackOpenParams_t *params) {
hualing chenb31a6c62020-01-13 17:27:00 +08001494
hualing chen040df222020-01-17 13:35:02 +08001495 DVR_Playback_t *player;
hualing chen86e7d482020-01-16 15:13:33 +08001496 pthread_condattr_t cattr;
hualing chenb31a6c62020-01-13 17:27:00 +08001497
Zhiqiang Han2d8cd822020-03-16 13:58:10 +08001498 player = (DVR_Playback_t*)calloc(1, sizeof(DVR_Playback_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001499
hualing chen86e7d482020-01-16 15:13:33 +08001500 pthread_mutex_init(&player->lock, NULL);
hualing chen2aba4022020-03-02 13:49:55 +08001501 pthread_mutex_init(&player->segment_lock, NULL);
hualing chen86e7d482020-01-16 15:13:33 +08001502 pthread_condattr_init(&cattr);
1503 pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
1504 pthread_cond_init(&player->cond, &cattr);
1505 pthread_condattr_destroy(&cattr);
hualing chenb31a6c62020-01-13 17:27:00 +08001506
hualing chen5cbe1a62020-02-10 16:36:36 +08001507 //init segment list head
hualing chen040df222020-01-17 13:35:02 +08001508 INIT_LIST_HEAD(&player->segment_list);
1509 player->cmd.last_cmd = DVR_PLAYBACK_CMD_STOP;
1510 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
hualing chen5cbe1a62020-02-10 16:36:36 +08001511 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
hualing chen040df222020-01-17 13:35:02 +08001512 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
hualing chen2aba4022020-03-02 13:49:55 +08001513 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08001514 player->cmd.pos = 0;
hualing chen31140872020-03-25 12:29:26 +08001515 player->speed = 1.0f;
hualing chene41f4372020-06-06 16:29:17 +08001516 player->first_trans_ok = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08001517
hualing chen86e7d482020-01-16 15:13:33 +08001518 //store open params
hualing chen040df222020-01-17 13:35:02 +08001519 player->openParams.dmx_dev_id = params->dmx_dev_id;
1520 player->openParams.block_size = params->block_size;
hualing chen86e7d482020-01-16 15:13:33 +08001521 player->openParams.is_timeshift = params->is_timeshift;
hualing chencc91e1c2020-02-28 13:26:17 +08001522 player->openParams.event_fn = params->event_fn;
1523 player->openParams.event_userdata = params->event_userdata;
hualing chene3797f02021-01-13 14:53:28 +08001524 player->openParams.is_notify_time = params->is_notify_time;
hualing chenfbf8e022020-06-15 13:43:11 +08001525 player->vendor = params->vendor;
hualing chencc91e1c2020-02-28 13:26:17 +08001526
hualing chen5cbe1a62020-02-10 16:36:36 +08001527 player->has_pids = params->has_pids;
1528
hualing chen2aba4022020-03-02 13:49:55 +08001529 player->handle = params->player_handle ;
hualing chen6e4bfa52020-03-13 14:37:11 +08001530
1531 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
1532 //for test get callback
1533 if (0 && player->player_callback_func == NULL) {
1534 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback_test, player);
1535 AmTsPlayer_getCb(player->handle, &player->player_callback_func, &player->player_callback_userdata);
hualing chen03fd4942021-07-15 15:56:41 +08001536 DVR_PB_DG(1, "playback open get callback[%p][%p][%p][%p]",
1537 player->player_callback_func,
1538 player->player_callback_userdata,
1539 _dvr_tsplayer_callback_test,
1540 player);
hualing chen6e4bfa52020-03-13 14:37:11 +08001541 }
1542 AmTsPlayer_registerCb(player->handle, _dvr_tsplayer_callback, player);
hualing chen040df222020-01-17 13:35:02 +08001543
hualing chen86e7d482020-01-16 15:13:33 +08001544 //init has audio and video
1545 player->has_video = DVR_FALSE;
1546 player->has_audio = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08001547 player->cur_segment_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001548 player->last_segment_id = 0LL;
1549 player->segment_is_open = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08001550
hualing chen5cbe1a62020-02-10 16:36:36 +08001551 //init ff fb time
hualing chen7ea70a72021-09-09 11:25:13 +08001552 player->fffb_current = 0;
1553 player->fffb_start = 0;
hualing chen03fd4942021-07-15 15:56:41 +08001554 player->fffb_start_pcr = 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001555 //seek time
1556 player->seek_time = 0;
hualing chen6e4bfa52020-03-13 14:37:11 +08001557 player->send_time = 0;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001558
1559 //init secure stuff
1560 player->dec_func = NULL;
1561 player->dec_userdata = NULL;
1562 player->is_secure_mode = 0;
1563 player->secure_buffer = NULL;
1564 player->secure_buffer_size = 0;
hualing chen266b9502020-04-04 17:39:39 +08001565 player->drop_ts = DVR_FALSE;
pengfei.liu07ddc8a2020-03-24 23:36:53 +08001566
hualing chen4b7c15d2020-04-07 16:13:48 +08001567 player->fffb_play = DVR_FALSE;
1568
1569 player->last_send_time_id = UINT64_MAX;
1570 player->last_cur_time = 0;
hualing chen30423862021-04-16 14:39:12 +08001571 player->seek_pause = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001572
hualing chend241c7a2021-06-22 13:34:27 +08001573 //speed con init
1574 if (CONTROL_SPEED_ENABLE == 1) {
1575 player->con_spe.ply_dur = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001576 player->con_spe.ply_sta = 0;
hualing chend241c7a2021-06-22 13:34:27 +08001577 player->con_spe.sys_dur = 0;
1578 player->con_spe.sys_sta = 0;
1579 }
1580
hualing chen03fd4942021-07-15 15:56:41 +08001581 //limit info
1582 player->rec_start = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08001583 player->limit = 0;
hualing chen8a657f32021-08-30 13:12:49 +08001584 //need seek to start pos
1585 player->first_start_time = 0;
1586 player->need_seek_start = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001587 *p_handle = player;
1588 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001589}
1590
1591/**\brief Close an dvr palyback
1592 * \param[in] handle playback handle
1593 * \retval DVR_SUCCESS On success
1594 * \return Error code
1595 */
hualing chen040df222020-01-17 13:35:02 +08001596int dvr_playback_close(DVR_PlaybackHandle_t handle) {
hualing chenb31a6c62020-01-13 17:27:00 +08001597
hualing chen86e7d482020-01-16 15:13:33 +08001598 DVR_ASSERT(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08001599 DVR_PB_DG(1, ":into");
hualing chen040df222020-01-17 13:35:02 +08001600 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08001601 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001602 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001603 return DVR_FAILURE;
1604 }
1605
hualing chencc91e1c2020-02-28 13:26:17 +08001606 if (player->state != DVR_PLAYBACK_STATE_STOP)
1607 {
hualing chenb96aa2c2020-04-15 14:13:53 +08001608 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chencc91e1c2020-02-28 13:26:17 +08001609 dvr_playback_stop(handle, DVR_TRUE);
hualing chenb96aa2c2020-04-15 14:13:53 +08001610 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
1611 } else {
1612 DVR_PB_DG(1, ":is stoped state");
hualing chencc91e1c2020-02-28 13:26:17 +08001613 }
hualing chen7a56cba2020-04-14 14:09:27 +08001614 DVR_PB_DG(1, ":into");
hualing chen86e7d482020-01-16 15:13:33 +08001615 pthread_mutex_destroy(&player->lock);
1616 pthread_cond_destroy(&player->cond);
hualing chen040df222020-01-17 13:35:02 +08001617
1618 if (player) {
1619 free(player);
1620 player = NULL;
1621 }
hualing chen7a56cba2020-04-14 14:09:27 +08001622 DVR_PB_DG(1, ":end");
hualing chen86e7d482020-01-16 15:13:33 +08001623 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001624}
1625
hualing chenb31a6c62020-01-13 17:27:00 +08001626/**\brief Start play audio and video, used start auido api and start video api
1627 * \param[in] handle playback handle
1628 * \param[in] params audio playback params,contains fmt and pid...
1629 * \retval DVR_SUCCESS On success
1630 * \return Error code
1631 */
hualing chen040df222020-01-17 13:35:02 +08001632int dvr_playback_start(DVR_PlaybackHandle_t handle, DVR_PlaybackFlag_t flag) {
1633 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen2aba4022020-03-02 13:49:55 +08001634 am_tsplayer_video_params vparams;
1635 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08001636 am_tsplayer_audio_params adparams;
hualing chena540a7e2020-03-27 16:44:05 +08001637
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001638 memset(&vparams, 0, sizeof(vparams));
1639 memset(&aparams, 0, sizeof(aparams));
1640
hualing chena540a7e2020-03-27 16:44:05 +08001641 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001642 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001643 return DVR_FAILURE;
1644 }
hualing chencc91e1c2020-02-28 13:26:17 +08001645 uint64_t segment_id = player->cur_segment_id;
hualing chen4b7c15d2020-04-07 16:13:48 +08001646 DVR_PB_DG(1, "[%p]segment_id:[%lld]", handle, segment_id);
hualing chenb31a6c62020-01-13 17:27:00 +08001647
hualing chena540a7e2020-03-27 16:44:05 +08001648 player->first_frame = 0;
hualing chencc91e1c2020-02-28 13:26:17 +08001649 //can used start api to resume playback
1650 if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
1651 return dvr_playback_resume(handle);
1652 }
hualing chen87072a82020-03-12 16:20:12 +08001653 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen9b434f02020-06-10 15:06:54 +08001654 //if flag is puased and not decodec first frame. if user resume, we need
1655 //clear flag and set trickmode none
1656 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
1657 DVR_PB_DG(1, "[%p]clear pause live flag and clear trick mode", handle);
1658 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
1659 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
1660 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001661 DVR_PB_DG(1, "stat is start, not need into start play");
hualing chen87072a82020-03-12 16:20:12 +08001662 return DVR_SUCCESS;
1663 }
hualing chen86e7d482020-01-16 15:13:33 +08001664 player->play_flag = flag;
hualing chene41f4372020-06-06 16:29:17 +08001665 player->first_trans_ok = DVR_FALSE;
hualing chen5cbe1a62020-02-10 16:36:36 +08001666 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08001667 DVR_PB_DG(1, "lock flag:0x%x", flag);
hualing chen86e7d482020-01-16 15:13:33 +08001668 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08001669 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08001670 //start audio and video
Zhiqiang Hana9d261b2020-11-11 18:38:10 +08001671 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08001672 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08001673 DVR_PB_DG(0, "unlock dvr play back start error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08001674 pthread_mutex_unlock(&player->lock);
1675 DVR_Play_Notify_t notify;
1676 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
1677 notify.event = DVR_PLAYBACK_EVENT_TRANSITION_FAILED;
1678 notify.info.error_reason = DVR_PLAYBACK_PID_ERROR;
1679 notify.info.transition_failed_data.segment_id = segment_id;
1680 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08001681 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_TRANSITION_FAILED, &notify, DVR_TRUE);
hualing chen86e7d482020-01-16 15:13:33 +08001682 return -1;
1683 }
hualing chen31140872020-03-25 12:29:26 +08001684
hualing chencc91e1c2020-02-28 13:26:17 +08001685 {
hualing chen86e7d482020-01-16 15:13:33 +08001686 if (VALID_PID(vparams.pid)) {
1687 player->has_video = DVR_TRUE;
hualing chen86e7d482020-01-16 15:13:33 +08001688 //if set flag is pause live, we need set trick mode
hualing chen31140872020-03-25 12:29:26 +08001689 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001690 DVR_PB_DG(1, "set trick mode -pauselive flag--");
hualing chen31140872020-03-25 12:29:26 +08001691 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
1692 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
hualing chen2aba4022020-03-02 13:49:55 +08001693 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001694 DVR_PB_DG(1, "set trick mode -fffb--at pause live");
hualing chen2aba4022020-03-02 13:49:55 +08001695 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08001696 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08001697 DVR_PB_DG(1, "set trick mode ---none");
hualing chen87072a82020-03-12 16:20:12 +08001698 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08001699 }
hualing chena93bbbc2020-12-22 17:23:42 +08001700 AmTsPlayer_showVideo(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08001701 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08001702 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08001703 AmTsPlayer_startVideoDecoding(player->handle);
hualing chenb31a6c62020-01-13 17:27:00 +08001704 }
hualing chena540a7e2020-03-27 16:44:05 +08001705
hualing chen4b7c15d2020-04-07 16:13:48 +08001706 DVR_PB_DG(1, "player->cmd.cur_cmd:%d vpid[0x%x]apis[0x%x]", player->cmd.cur_cmd, vparams.pid, aparams.pid);
1707 player->last_send_time_id = UINT64_MAX;
hualing chencc91e1c2020-02-28 13:26:17 +08001708 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB
1709 || player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF) {
1710 player->cmd.state = DVR_PLAYBACK_STATE_START;
1711 player->state = DVR_PLAYBACK_STATE_START;
hualing chencc91e1c2020-02-28 13:26:17 +08001712 } else {
1713 player->cmd.last_cmd = player->cmd.cur_cmd;
1714 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chena540a7e2020-03-27 16:44:05 +08001715 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08001716 //set fast play
hualing chenb96aa2c2020-04-15 14:13:53 +08001717 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08001718 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/100.0f);
hualing chena540a7e2020-03-27 16:44:05 +08001719 } else {
hualing chendf118dd2020-05-21 15:49:11 +08001720 if (VALID_PID(adparams.pid)) {
1721 player->has_ad_audio = DVR_TRUE;
1722 DVR_PB_DG(1, "start ad audio");
1723 AmTsPlayer_setADParams(player->handle, &adparams);
1724 AmTsPlayer_enableADMix(player->handle);
1725 }
hualing chen969fe7b2021-05-26 15:13:17 +08001726 if (VALID_PID(aparams.pid)) {
1727 DVR_PB_DG(1, "start audio");
1728 player->has_audio = DVR_TRUE;
1729 AmTsPlayer_setAudioParams(player->handle, &aparams);
1730 AmTsPlayer_startAudioDecoding(player->handle);
1731 }
hualing chen31140872020-03-25 12:29:26 +08001732 }
hualing chencc91e1c2020-02-28 13:26:17 +08001733 player->cmd.state = DVR_PLAYBACK_STATE_START;
1734 player->state = DVR_PLAYBACK_STATE_START;
1735 }
hualing chen86e7d482020-01-16 15:13:33 +08001736 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001737 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001738 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08001739 _start_playback_thread(handle);
hualing chen86e7d482020-01-16 15:13:33 +08001740 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001741}
hualing chen040df222020-01-17 13:35:02 +08001742/**\brief dvr play back add segment info to segment list
hualing chenb31a6c62020-01-13 17:27:00 +08001743 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001744 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001745 * \retval DVR_SUCCESS On success
1746 * \return Error code
1747 */
hualing chen040df222020-01-17 13:35:02 +08001748int dvr_playback_add_segment(DVR_PlaybackHandle_t handle, DVR_PlaybackSegmentInfo_t *info) {
1749 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08001750
hualing chena540a7e2020-03-27 16:44:05 +08001751 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001752 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001753 return DVR_FAILURE;
1754 }
1755
hualing chen4b7c15d2020-04-07 16:13:48 +08001756 DVR_PB_DG(1, "add segment id: %lld %p", info->segment_id, handle);
hualing chen040df222020-01-17 13:35:02 +08001757 DVR_PlaybackSegmentInfo_t *segment;
hualing chenb31a6c62020-01-13 17:27:00 +08001758
hualing chen040df222020-01-17 13:35:02 +08001759 segment = malloc(sizeof(DVR_PlaybackSegmentInfo_t));
1760 memset(segment, 0, sizeof(DVR_PlaybackSegmentInfo_t));
hualing chenb31a6c62020-01-13 17:27:00 +08001761
hualing chen86e7d482020-01-16 15:13:33 +08001762 //not memcpy chun info.
hualing chen040df222020-01-17 13:35:02 +08001763 segment->segment_id = info->segment_id;
hualing chen86e7d482020-01-16 15:13:33 +08001764 //cp location
hualing chen040df222020-01-17 13:35:02 +08001765 memcpy(segment->location, info->location, DVR_MAX_LOCATION_SIZE);
hualing chencc91e1c2020-02-28 13:26:17 +08001766
hualing chen4b7c15d2020-04-07 16:13:48 +08001767 DVR_PB_DG(1, "add location [%s]id[%lld]flag[%x]", segment->location, segment->segment_id, info->flags);
hualing chen040df222020-01-17 13:35:02 +08001768 segment->flags = info->flags;
hualing chen5cbe1a62020-02-10 16:36:36 +08001769
1770 //pids
hualing chencc91e1c2020-02-28 13:26:17 +08001771 segment->pids.video.pid = info->pids.video.pid;
1772 segment->pids.video.format = info->pids.video.format;
1773 segment->pids.video.type = info->pids.video.type;
1774
hualing chen2aba4022020-03-02 13:49:55 +08001775 segment->pids.audio.pid = info->pids.audio.pid;
1776 segment->pids.audio.format = info->pids.audio.format;
1777 segment->pids.audio.type = info->pids.audio.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001778
hualing chen2aba4022020-03-02 13:49:55 +08001779 segment->pids.ad.pid = info->pids.ad.pid;
1780 segment->pids.ad.format = info->pids.ad.format;
1781 segment->pids.ad.type = info->pids.ad.type;
hualing chencc91e1c2020-02-28 13:26:17 +08001782
1783 segment->pids.pcr.pid = info->pids.pcr.pid;
1784
hualing chen4b7c15d2020-04-07 16:13:48 +08001785 DVR_PB_DG(1, "lock pid [0x%x][0x%x][0x%x][0x%x]", segment->pids.video.pid,segment->pids.audio.pid, info->pids.video.pid,info->pids.audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001786 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001787 list_add_tail(&segment->head, &player->segment_list);
hualing chen86e7d482020-01-16 15:13:33 +08001788 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08001789 DVR_PB_DG(1, "unlock");
hualing chenb31a6c62020-01-13 17:27:00 +08001790
hualing chen5cbe1a62020-02-10 16:36:36 +08001791 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001792}
hualing chen040df222020-01-17 13:35:02 +08001793/**\brief dvr play back remove segment info by segment_id
hualing chenb31a6c62020-01-13 17:27:00 +08001794 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001795 * \param[in] segment_id need removed segment id
hualing chenb31a6c62020-01-13 17:27:00 +08001796 * \retval DVR_SUCCESS On success
1797 * \return Error code
1798 */
hualing chen5cbe1a62020-02-10 16:36:36 +08001799int dvr_playback_remove_segment(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08001800 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001801 DVR_PB_DG(1, "remove segment id: %lld", segment_id);
hualing chena540a7e2020-03-27 16:44:05 +08001802 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001803 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001804 return DVR_FAILURE;
1805 }
1806
hualing chencc91e1c2020-02-28 13:26:17 +08001807 if (segment_id == player->cur_segment_id) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001808 DVR_PB_DG(1, "not suport remove curren segment id: %lld", segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08001809 return DVR_FAILURE;
1810 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001811 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001812 pthread_mutex_lock(&player->lock);
hualing chena540a7e2020-03-27 16:44:05 +08001813 DVR_PlaybackSegmentInfo_t *segment = NULL;
1814 DVR_PlaybackSegmentInfo_t *segment_tmp = NULL;
1815 list_for_each_entry_safe(segment, segment_tmp, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001816 {
hualing chen040df222020-01-17 13:35:02 +08001817 if (segment->segment_id == segment_id) {
1818 list_del(&segment->head);
1819 free(segment);
hualing chen86e7d482020-01-16 15:13:33 +08001820 break;
hualing chenb31a6c62020-01-13 17:27:00 +08001821 }
hualing chen86e7d482020-01-16 15:13:33 +08001822 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001823 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001824 pthread_mutex_unlock(&player->lock);
1825
1826 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001827}
hualing chen040df222020-01-17 13:35:02 +08001828/**\brief dvr play back add segment info
hualing chenb31a6c62020-01-13 17:27:00 +08001829 * \param[in] handle playback handle
hualing chen040df222020-01-17 13:35:02 +08001830 * \param[in] info added segment info,con vpid fmt apid fmt.....
hualing chenb31a6c62020-01-13 17:27:00 +08001831 * \retval DVR_SUCCESS On success
1832 * \return Error code
1833 */
hualing chen040df222020-01-17 13:35:02 +08001834int dvr_playback_update_segment_flags(DVR_PlaybackHandle_t handle,
hualing chen5cbe1a62020-02-10 16:36:36 +08001835 uint64_t segment_id, DVR_PlaybackSegmentFlag_t flags) {
hualing chen040df222020-01-17 13:35:02 +08001836 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen4b7c15d2020-04-07 16:13:48 +08001837 DVR_PB_DG(1, "update segment id: %lld flag:%d", segment_id, flags);
hualing chena540a7e2020-03-27 16:44:05 +08001838 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001839 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001840 return DVR_FAILURE;
1841 }
hualing chenf43b8ba2020-07-28 13:11:42 +08001842 if (player->vendor == DVR_PLAYBACK_VENDOR_AML) {
1843 DVR_PB_DG(1, "vendor is amlogic. not hide or show av and update segment");
1844 return DVR_SUCCESS;
1845 }
hualing chena540a7e2020-03-27 16:44:05 +08001846
hualing chen040df222020-01-17 13:35:02 +08001847 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08001848 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08001849 pthread_mutex_lock(&player->lock);
hualing chen040df222020-01-17 13:35:02 +08001850 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08001851 {
hualing chen040df222020-01-17 13:35:02 +08001852 if (segment->segment_id != segment_id) {
hualing chen86e7d482020-01-16 15:13:33 +08001853 continue;
hualing chenb31a6c62020-01-13 17:27:00 +08001854 }
hualing chen86e7d482020-01-16 15:13:33 +08001855 // if encramble to free, only set flag and return;
1856
1857 //if displayable to none, we need mute audio and video
hualing chen040df222020-01-17 13:35:02 +08001858 if (segment_id == player->cur_segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08001859 if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE
1860 && (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0) {
hualing chencc91e1c2020-02-28 13:26:17 +08001861 //disable display, mute
hualing chen703f3572021-01-06 12:51:34 +08001862 DVR_PB_DG(1, "mute av");
hualing chen2aba4022020-03-02 13:49:55 +08001863 AmTsPlayer_hideVideo(player->handle);
1864 AmTsPlayer_setAudioMute(player->handle, 1, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08001865 } else if ((segment->flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == 0 &&
1866 (flags & DVR_PLAYBACK_SEGMENT_DISPLAYABLE) == DVR_PLAYBACK_SEGMENT_DISPLAYABLE) {
hualing chencc91e1c2020-02-28 13:26:17 +08001867 //enable display, unmute
hualing chen703f3572021-01-06 12:51:34 +08001868 DVR_PB_DG(1, "unmute av");
hualing chen2aba4022020-03-02 13:49:55 +08001869 AmTsPlayer_showVideo(player->handle);
1870 AmTsPlayer_setAudioMute(player->handle, 0, 0);
hualing chen86e7d482020-01-16 15:13:33 +08001871 } else {
1872 //do nothing
1873 }
1874 } else {
1875 //do nothing
1876 }
1877 //continue , only set flag
hualing chen040df222020-01-17 13:35:02 +08001878 segment->flags = flags;
hualing chen86e7d482020-01-16 15:13:33 +08001879 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001880 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08001881 pthread_mutex_unlock(&player->lock);
1882 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08001883}
1884
1885
hualing chen275379e2021-06-15 17:57:21 +08001886static int _do_check_pid_info(DVR_PlaybackHandle_t handle, DVR_StreamInfo_t now_pid, DVR_PlaybackPids_t set_pids, int type) {
hualing chen040df222020-01-17 13:35:02 +08001887 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen275379e2021-06-15 17:57:21 +08001888 DVR_StreamInfo_t set_pid;
1889
1890 if (type == 0) {
1891 set_pid = set_pids.video;
1892 } else if (type == 1) {
1893 set_pid = set_pids.audio;
1894 } else if (type == 2) {
1895 set_pid = set_pids.ad;
1896 } else {
1897 set_pid = set_pids.pcr;
1898 }
1899
hualing chena540a7e2020-03-27 16:44:05 +08001900 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08001901 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08001902 return DVR_FAILURE;
1903 }
hualing chen4b7c15d2020-04-07 16:13:48 +08001904 DVR_PB_DG(1, " do check");
hualing chen86e7d482020-01-16 15:13:33 +08001905 if (now_pid.pid == set_pid.pid) {
1906 //do nothing
hualing chenb31a6c62020-01-13 17:27:00 +08001907 return 0;
hualing chen5cbe1a62020-02-10 16:36:36 +08001908 } else if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chen86e7d482020-01-16 15:13:33 +08001909 if (VALID_PID(now_pid.pid)) {
1910 //stop now stream
1911 if (type == 0) {
1912 //stop vieo
hualing chenc70a8df2020-05-12 19:23:11 +08001913 if (player->has_video == DVR_TRUE) {
1914 DVR_PB_DG(1, "stop video");
1915 AmTsPlayer_stopVideoDecoding(player->handle);
1916 player->has_video = DVR_FALSE;
1917 }
hualing chen86e7d482020-01-16 15:13:33 +08001918 } else if (type == 1) {
1919 //stop audio
hualing chenc70a8df2020-05-12 19:23:11 +08001920 if (player->has_audio == DVR_TRUE) {
1921 DVR_PB_DG(1, "stop audio");
1922 AmTsPlayer_stopAudioDecoding(player->handle);
1923 player->has_audio = DVR_FALSE;
1924 }
hualing chen86e7d482020-01-16 15:13:33 +08001925 } else if (type == 2) {
1926 //stop sub audio
hualing chen4b7c15d2020-04-07 16:13:48 +08001927 DVR_PB_DG(1, "stop ad");
hualing chena540a7e2020-03-27 16:44:05 +08001928 AmTsPlayer_disableADMix(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08001929 } else if (type == 3) {
1930 //pcr
1931 }
1932 }
1933 if (VALID_PID(set_pid.pid)) {
1934 //start
1935 if (type == 0) {
1936 //start vieo
hualing chen2aba4022020-03-02 13:49:55 +08001937 am_tsplayer_video_params vparams;
hualing chen86e7d482020-01-16 15:13:33 +08001938 vparams.pid = set_pid.pid;
hualing chen2aba4022020-03-02 13:49:55 +08001939 vparams.codectype = _dvr_convert_stream_fmt(set_pid.format, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08001940 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08001941 DVR_PB_DG(1, "start video pid[%d]fmt[%d]",vparams.pid, vparams.codectype);
hualing chen2aba4022020-03-02 13:49:55 +08001942 AmTsPlayer_setVideoParams(player->handle, &vparams);
1943 AmTsPlayer_startVideoDecoding(player->handle);
1944 //playback_device_video_start(player->handle,&vparams);
hualing chen86e7d482020-01-16 15:13:33 +08001945 } else if (type == 1) {
1946 //start audio
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001947 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chen275379e2021-06-15 17:57:21 +08001948 if (VALID_PID(set_pids.ad.pid)) {
1949 am_tsplayer_audio_params adparams;
1950 adparams.pid = set_pids.ad.pid;
1951 adparams.codectype= _dvr_convert_stream_fmt(set_pids.ad.format, DVR_TRUE);
1952 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",adparams.pid, adparams.codectype);
1953 AmTsPlayer_setADParams(player->handle, &adparams);
1954 AmTsPlayer_enableADMix(player->handle);
1955 }
1956
hualing chenc70a8df2020-05-12 19:23:11 +08001957 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001958
1959 memset(&aparams, 0, sizeof(aparams));
1960
hualing chenc70a8df2020-05-12 19:23:11 +08001961 aparams.pid = set_pid.pid;
1962 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1963 player->has_audio = DVR_TRUE;
1964 DVR_PB_DG(1, "start audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1965 AmTsPlayer_setAudioParams(player->handle, &aparams);
1966 AmTsPlayer_startAudioDecoding(player->handle);
1967 //playback_device_audio_start(player->handle,&aparams);
1968 }
hualing chen86e7d482020-01-16 15:13:33 +08001969 } else if (type == 2) {
Gong Ke2a0ebbe2021-05-25 15:22:50 +08001970 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
hualing chenc70a8df2020-05-12 19:23:11 +08001971 am_tsplayer_audio_params aparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08001972
1973 memset(&aparams, 0, sizeof(aparams));
hualing chenc70a8df2020-05-12 19:23:11 +08001974 aparams.pid = set_pid.pid;
1975 aparams.codectype= _dvr_convert_stream_fmt(set_pid.format, DVR_TRUE);
1976 player->has_audio = DVR_TRUE;
1977 DVR_PB_DG(1, "start ad audio pid[%d]fmt[%d]",aparams.pid, aparams.codectype);
1978 AmTsPlayer_setADParams(player->handle, &aparams);
1979 AmTsPlayer_enableADMix(player->handle);
1980 //playback_device_audio_start(player->handle,&aparams);
1981 }
hualing chen86e7d482020-01-16 15:13:33 +08001982 } else if (type == 3) {
1983 //pcr
hualing chen4b7c15d2020-04-07 16:13:48 +08001984 DVR_PB_DG(1, "start set pcr [%d]", set_pid.pid);
hualing chen2aba4022020-03-02 13:49:55 +08001985 AmTsPlayer_setPcrPid(player->handle, set_pid.pid);
hualing chen86e7d482020-01-16 15:13:33 +08001986 }
hualing chen5cbe1a62020-02-10 16:36:36 +08001987 //audio and video all close
1988 if (!player->has_audio && !player->has_video) {
1989 player->state = DVR_PLAYBACK_STATE_STOP;
1990 }
hualing chen86e7d482020-01-16 15:13:33 +08001991 }
1992 }
1993 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08001994}
hualing chen5cbe1a62020-02-10 16:36:36 +08001995/**\brief dvr play back update segment pids
1996 * if updated segment is ongoing segment, we need start new
hualing chenb31a6c62020-01-13 17:27:00 +08001997 * add pid stream and stop remove pid stream.
1998 * \param[in] handle playback handle
hualing chen5cbe1a62020-02-10 16:36:36 +08001999 * \param[in] segment_id need updated pids segment id
hualing chenb31a6c62020-01-13 17:27:00 +08002000 * \retval DVR_SUCCESS On success
2001 * \return Error code
2002 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002003int 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 +08002004 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002005 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002006 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002007 return DVR_FAILURE;
2008 }
2009
hualing chen040df222020-01-17 13:35:02 +08002010 DVR_PlaybackSegmentInfo_t *segment;
hualing chen4b7c15d2020-04-07 16:13:48 +08002011 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002012 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002013 DVR_PB_DG(1, "get lock update segment id: %lld cur id %lld", segment_id, player->cur_segment_id);
hualing chencc91e1c2020-02-28 13:26:17 +08002014
hualing chen040df222020-01-17 13:35:02 +08002015 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08002016 {
hualing chen040df222020-01-17 13:35:02 +08002017 if (segment->segment_id == segment_id) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002018
2019 if (player->cur_segment_id == segment_id) {
2020 if (player->cmd.state == DVR_PLAYBACK_STATE_FF
2021 || player->cmd.state == DVR_PLAYBACK_STATE_FF) {
2022 //do nothing when ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08002023 DVR_PB_DG(1, "unlock now is ff fb, not to update cur segment info\r\n");
hualing chencc91e1c2020-02-28 13:26:17 +08002024 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002025 return 0;
2026 }
2027
2028 //if segment is on going segment,we need stop start stream
2029 if (player->cmd.state == DVR_PLAYBACK_STATE_START) {
hualing chencc91e1c2020-02-28 13:26:17 +08002030 pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002031 //check video pids, stop or restart
hualing chen275379e2021-06-15 17:57:21 +08002032 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.video, *p_pids, 0);
hualing chen5cbe1a62020-02-10 16:36:36 +08002033 //check sub audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08002034 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.ad, *p_pids, 2);
jianchuan.pinge5f8c5a2021-02-03 19:11:05 +08002035 //check audio pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08002036 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.audio, *p_pids, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08002037 //check pcr pids stop or restart
hualing chen275379e2021-06-15 17:57:21 +08002038 _do_check_pid_info((DVR_PlaybackHandle_t)player, segment->pids.pcr, *p_pids, 3);
hualing chen8a657f32021-08-30 13:12:49 +08002039 if (segment->pids.audio.pid != p_pids->audio.pid &&
2040 segment->pids.audio.pid == 0x1fff) {
2041 if (player->need_seek_start == DVR_TRUE) {
2042 player->need_seek_start = DVR_FALSE;
2043 pthread_mutex_lock(&player->segment_lock);
2044 player->drop_ts = DVR_TRUE;
2045 player->ts_cache_len = 0;
2046 if (player->first_start_time > 0)
2047 player->first_start_time = player->first_start_time - 1;
2048 segment_seek(player->r_handle, (uint64_t)(player->first_start_time), player->openParams.block_size);
2049 DVR_PB_DG(0, "update need seek time_offset %llu", player->first_start_time);
2050 pthread_mutex_unlock(&player->segment_lock);
2051 }
2052 }
hualing chencc91e1c2020-02-28 13:26:17 +08002053 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08002054 } else if (player->cmd.state == DVR_PLAYBACK_STATE_PAUSE) {
2055 //if state is pause, we need process at resume api. we only record change info
2056 int v_cmd = DVR_PLAYBACK_CMD_NONE;
2057 int a_cmd = DVR_PLAYBACK_CMD_NONE;
2058 if (VALID_PID(segment->pids.video.pid)
2059 && VALID_PID(p_pids->video.pid)
2060 && segment->pids.video.pid != p_pids->video.pid) {
2061 //restart video
2062 v_cmd = DVR_PLAYBACK_CMD_VRESTART;
2063 }
2064 if (!VALID_PID(segment->pids.video.pid)
2065 && VALID_PID(p_pids->video.pid)
2066 && segment->pids.video.pid != p_pids->video.pid) {
2067 //start video
2068 v_cmd = DVR_PLAYBACK_CMD_VSTART;
2069 }
2070 if (VALID_PID(segment->pids.video.pid)
2071 && !VALID_PID(p_pids->video.pid)
2072 && segment->pids.video.pid != p_pids->video.pid) {
2073 //stop video
2074 v_cmd = DVR_PLAYBACK_CMD_VSTOP;
2075 }
2076 if (VALID_PID(segment->pids.audio.pid)
2077 && VALID_PID(p_pids->audio.pid)
2078 && segment->pids.audio.pid != p_pids->audio.pid) {
2079 //restart audio
2080 a_cmd = DVR_PLAYBACK_CMD_ARESTART;
2081 }
2082 if (!VALID_PID(segment->pids.audio.pid)
2083 && VALID_PID(p_pids->audio.pid)
2084 && segment->pids.audio.pid != p_pids->audio.pid) {
2085 //start audio
2086 a_cmd = DVR_PLAYBACK_CMD_ASTART;
2087 }
2088 if (VALID_PID(segment->pids.audio.pid)
2089 && !VALID_PID(p_pids->audio.pid)
2090 && segment->pids.audio.pid != p_pids->audio.pid) {
2091 //stop audio
2092 a_cmd = DVR_PLAYBACK_CMD_ASTOP;
2093 }
2094 if (a_cmd == DVR_PLAYBACK_CMD_NONE
2095 && v_cmd == DVR_PLAYBACK_CMD_NONE) {
2096 //do nothing
2097 } else if (a_cmd == DVR_PLAYBACK_CMD_NONE
2098 || v_cmd == DVR_PLAYBACK_CMD_NONE) {
2099 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2100 player->cmd.cur_cmd = a_cmd != DVR_PLAYBACK_CMD_NONE ? a_cmd : v_cmd;
2101 } else if (a_cmd != DVR_PLAYBACK_CMD_NONE
2102 && v_cmd != DVR_PLAYBACK_CMD_NONE) {
2103 if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2104 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2105 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2106 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
2107 }else if (v_cmd == DVR_PLAYBACK_CMD_VRESTART
2108 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2109 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2110 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTARTVRESTART;
2111 } else {
2112 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2113 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVRESTART;
2114 }
2115
2116 if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2117 && (a_cmd == DVR_PLAYBACK_CMD_ARESTART)) {
2118 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2119 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTARTARESTART;
2120 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTART
2121 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2122 //not occur this case
2123 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2124 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
2125 } else {
2126 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2127 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOPVSTART;
2128 }
2129
2130 if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2131 && a_cmd == DVR_PLAYBACK_CMD_ASTART) {
2132 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2133 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPASTART;
2134 } else if (v_cmd == DVR_PLAYBACK_CMD_VSTOP
2135 && a_cmd == DVR_PLAYBACK_CMD_ARESTART) {
2136 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2137 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOPARESTART;
2138 } else {
2139 //not occur this case
2140 player->cmd.last_cmd =DVR_PLAYBACK_CMD_PAUSE;
2141 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2142 }
2143 }
2144 }
hualing chene10666f2020-04-14 13:58:37 +08002145 memcpy(&player->cur_segment.pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chen5cbe1a62020-02-10 16:36:36 +08002146 }
hualing chen86e7d482020-01-16 15:13:33 +08002147 //save pids info
hualing chenb5cd42e2020-04-15 17:03:34 +08002148 DVR_PB_DG(1, ":apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen040df222020-01-17 13:35:02 +08002149 memcpy(&segment->pids, p_pids, sizeof(DVR_PlaybackPids_t));
hualing chenb5cd42e2020-04-15 17:03:34 +08002150 DVR_PB_DG(1, ":cp apid :%d %d", segment->pids.audio.pid, p_pids->audio.pid);
hualing chen86e7d482020-01-16 15:13:33 +08002151 break;
hualing chenb31a6c62020-01-13 17:27:00 +08002152 }
hualing chen86e7d482020-01-16 15:13:33 +08002153 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002154 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002155 pthread_mutex_unlock(&player->lock);
2156 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002157}
2158/**\brief Stop play, will stop video and audio
2159 * \param[in] handle playback handle
2160 * \param[in] clear is clear last frame
2161 * \retval DVR_SUCCESS On success
2162 * \return Error code
2163 */
hualing chen040df222020-01-17 13:35:02 +08002164int dvr_playback_stop(DVR_PlaybackHandle_t handle, DVR_Bool_t clear) {
2165 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002166 UNDVRUSED(clear);
hualing chena540a7e2020-03-27 16:44:05 +08002167 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002168 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002169 return DVR_FAILURE;
2170 }
hualing chenb96aa2c2020-04-15 14:13:53 +08002171 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2172 DVR_PB_DG(1, ":playback is stoped");
2173 return DVR_SUCCESS;
2174 }
Ke Gong3c0caba2020-04-21 22:58:18 -07002175 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2176 DVR_PB_DG(1, ":playback is stoped");
2177 return DVR_SUCCESS;
2178 }
hualing chen87072a82020-03-12 16:20:12 +08002179 _stop_playback_thread(handle);
hualing chen7a56cba2020-04-14 14:09:27 +08002180 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002181 pthread_mutex_lock(&player->lock);
hualing chen7a56cba2020-04-14 14:09:27 +08002182 DVR_PB_DG(1, ":get lock into stop fast");
hualing chen31140872020-03-25 12:29:26 +08002183 AmTsPlayer_stopFast(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002184 if (player->has_video) {
2185 AmTsPlayer_resumeVideoDecoding(player->handle);
2186 }
2187 if (player->has_audio) {
2188 AmTsPlayer_resumeAudioDecoding(player->handle);
2189 }
2190 if (player->has_video) {
2191 player->has_video = DVR_FALSE;
hualing chen10cdb162021-02-05 10:44:41 +08002192 AmTsPlayer_hideVideo(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002193 AmTsPlayer_stopVideoDecoding(player->handle);
2194 }
2195 if (player->has_audio) {
2196 player->has_audio = DVR_FALSE;
2197 AmTsPlayer_stopAudioDecoding(player->handle);
2198 }
hualing chendf118dd2020-05-21 15:49:11 +08002199 if (player->has_ad_audio) {
2200 player->has_ad_audio =DVR_FALSE;
2201 AmTsPlayer_disableADMix(player->handle);
2202 }
hualing chen266b9502020-04-04 17:39:39 +08002203
hualing chen86e7d482020-01-16 15:13:33 +08002204 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002205 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_STOP;
2206 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2207 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen87072a82020-03-12 16:20:12 +08002208 player->cur_segment_id = UINT64_MAX;
2209 player->segment_is_open = DVR_FALSE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002210 DVR_PB_DG(1, "unlock");
hualing chenb96aa2c2020-04-15 14:13:53 +08002211 DVR_PB_DG(1, "player->state %s", _dvr_playback_state_toString(player->state));
hualing chen86e7d482020-01-16 15:13:33 +08002212 pthread_mutex_unlock(&player->lock);
hualing chen86e7d482020-01-16 15:13:33 +08002213 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002214}
2215/**\brief Start play audio
2216 * \param[in] handle playback handle
2217 * \param[in] params audio playback params,contains fmt and pid...
2218 * \retval DVR_SUCCESS On success
2219 * \return Error code
2220 */
hualing chen2aba4022020-03-02 13:49:55 +08002221
hualing chendf118dd2020-05-21 15:49:11 +08002222int 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 +08002223 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002224
2225 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002226 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002227 return DVR_FAILURE;
2228 }
hualing chen86e7d482020-01-16 15:13:33 +08002229 _start_playback_thread(handle);
2230 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002231 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002232 pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08002233
hualing chendf118dd2020-05-21 15:49:11 +08002234 if (VALID_PID(adparam->pid)) {
2235 player->has_ad_audio = DVR_TRUE;
2236 DVR_PB_DG(1, "start ad audio");
2237 AmTsPlayer_setADParams(player->handle, adparam);
2238 AmTsPlayer_enableADMix(player->handle);
2239 }
hualing chen969fe7b2021-05-26 15:13:17 +08002240 if (VALID_PID(param->pid)) {
2241 DVR_PB_DG(1, "start audio");
2242 player->has_audio = DVR_TRUE;
2243 AmTsPlayer_setAudioParams(player->handle, param);
2244 AmTsPlayer_startAudioDecoding(player->handle);
2245 }
hualing chendf118dd2020-05-21 15:49:11 +08002246
hualing chen86e7d482020-01-16 15:13:33 +08002247 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002248 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
2249 player->cmd.state = DVR_PLAYBACK_STATE_START;
2250 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002251 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002252 pthread_mutex_unlock(&player->lock);
2253 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002254}
2255/**\brief Stop play audio
2256 * \param[in] handle playback handle
2257 * \retval DVR_SUCCESS On success
2258 * \return Error code
2259 */
hualing chen040df222020-01-17 13:35:02 +08002260int dvr_playback_audio_stop(DVR_PlaybackHandle_t handle) {
2261 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002262
2263 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002264 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002265 return DVR_FAILURE;
2266 }
2267
hualing chen2aba4022020-03-02 13:49:55 +08002268 //playback_device_audio_stop(player->handle);
hualing chen86e7d482020-01-16 15:13:33 +08002269 if (player->has_video == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002270 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2271 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002272 //destory thread
2273 _stop_playback_thread(handle);
2274 } else {
2275 //do nothing.video is playing
2276 }
hualing chen7a56cba2020-04-14 14:09:27 +08002277 DVR_PB_DG(1, "lock");
2278 pthread_mutex_lock(&player->lock);
2279
hualing chenf00cdc82020-06-10 14:23:35 +08002280 if (player->has_audio) {
hualing chendf118dd2020-05-21 15:49:11 +08002281 player->has_audio = DVR_FALSE;
2282 AmTsPlayer_stopAudioDecoding(player->handle);
2283 }
hualing chen87072a82020-03-12 16:20:12 +08002284
hualing chendf118dd2020-05-21 15:49:11 +08002285 if (player->has_ad_audio) {
2286 player->has_ad_audio =DVR_FALSE;
2287 AmTsPlayer_disableADMix(player->handle);
2288 }
2289
hualing chen87072a82020-03-12 16:20:12 +08002290 player->cmd.last_cmd = player->cmd.cur_cmd;
2291 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTOP;
2292
hualing chen4b7c15d2020-04-07 16:13:48 +08002293 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002294 pthread_mutex_unlock(&player->lock);
2295 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002296}
2297/**\brief Start play video
2298 * \param[in] handle playback handle
2299 * \param[in] params video playback params,contains fmt and pid...
2300 * \retval DVR_SUCCESS On success
2301 * \return Error code
2302 */
hualing chen2aba4022020-03-02 13:49:55 +08002303int dvr_playback_video_start(DVR_PlaybackHandle_t handle, am_tsplayer_video_params *param) {
hualing chen040df222020-01-17 13:35:02 +08002304 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002305
2306 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002307 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002308 return DVR_FAILURE;
2309 }
2310
hualing chen86e7d482020-01-16 15:13:33 +08002311 _start_playback_thread(handle);
2312 //start audio and video
hualing chen4b7c15d2020-04-07 16:13:48 +08002313 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002314 pthread_mutex_lock(&player->lock);
2315 player->has_video = DVR_TRUE;
hualing chena540a7e2020-03-27 16:44:05 +08002316 AmTsPlayer_setVideoParams(player->handle, param);
hualing chen21a40372021-10-29 11:07:26 +08002317 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chena540a7e2020-03-27 16:44:05 +08002318 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002319
2320 //playback_device_video_start(player->handle , param);
hualing chen86e7d482020-01-16 15:13:33 +08002321 //if set flag is pause live, we need set trick mode
hualing chen5cbe1a62020-02-10 16:36:36 +08002322 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002323 DVR_PB_DG(1, "settrick mode at video start");
hualing chen2aba4022020-03-02 13:49:55 +08002324 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
2325 //playback_device_trick_mode(player->handle, 1);
hualing chen86e7d482020-01-16 15:13:33 +08002326 }
2327 player->cmd.last_cmd = player->cmd.cur_cmd;
hualing chen040df222020-01-17 13:35:02 +08002328 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTART;
2329 player->cmd.state = DVR_PLAYBACK_STATE_START;
2330 player->state = DVR_PLAYBACK_STATE_START;
hualing chen4b7c15d2020-04-07 16:13:48 +08002331 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002332 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002333 return DVR_SUCCESS;
2334}
2335/**\brief Stop play video
2336 * \param[in] handle playback handle
2337 * \retval DVR_SUCCESS On success
2338 * \return Error code
2339 */
hualing chen040df222020-01-17 13:35:02 +08002340int dvr_playback_video_stop(DVR_PlaybackHandle_t handle) {
2341 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002342
2343 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002344 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002345 return DVR_FAILURE;
2346 }
2347
hualing chen86e7d482020-01-16 15:13:33 +08002348 if (player->has_audio == DVR_FALSE) {
hualing chen040df222020-01-17 13:35:02 +08002349 player->cmd.state = DVR_PLAYBACK_STATE_STOP;
2350 player->state = DVR_PLAYBACK_STATE_STOP;
hualing chen86e7d482020-01-16 15:13:33 +08002351 //destory thread
2352 _stop_playback_thread(handle);
2353 } else {
2354 //do nothing.audio is playing
2355 }
hualing chen7a56cba2020-04-14 14:09:27 +08002356
2357 DVR_PB_DG(1, "lock");
2358 pthread_mutex_lock(&player->lock);
2359
hualing chen87072a82020-03-12 16:20:12 +08002360 player->has_video = DVR_FALSE;
2361
2362 AmTsPlayer_stopVideoDecoding(player->handle);
2363 //playback_device_video_stop(player->handle);
2364
2365 player->cmd.last_cmd = player->cmd.cur_cmd;
2366 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_VSTOP;
2367
hualing chen4b7c15d2020-04-07 16:13:48 +08002368 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002369 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002370 return DVR_SUCCESS;
2371}
2372/**\brief Pause play
2373 * \param[in] handle playback handle
2374 * \param[in] flush whether its internal buffers should be flushed
2375 * \retval DVR_SUCCESS On success
2376 * \return Error code
2377 */
hualing chen040df222020-01-17 13:35:02 +08002378int dvr_playback_pause(DVR_PlaybackHandle_t handle, DVR_Bool_t flush) {
2379 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002380 UNDVRUSED(flush);
hualing chena540a7e2020-03-27 16:44:05 +08002381 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002382 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002383 return DVR_FAILURE;
2384 }
hualing chenf00cdc82020-06-10 14:23:35 +08002385 if (player->state == DVR_PLAYBACK_STATE_PAUSE ||player->state == DVR_PLAYBACK_STATE_STOP ) {
2386 DVR_PB_DG(1, "player state is [%d] pause or stop", player->state);
hualing chenbd977fd2020-06-29 19:14:18 +08002387 return DVR_SUCCESS;
hualing chenf00cdc82020-06-10 14:23:35 +08002388 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002389 DVR_PB_DG(1, "lock");
hualing chen86e7d482020-01-16 15:13:33 +08002390 pthread_mutex_lock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002391 DVR_PB_DG(1, "get lock");
hualing chen266b9502020-04-04 17:39:39 +08002392 if (player->has_video)
2393 AmTsPlayer_pauseVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002394 if (player->has_audio)
hualing chen266b9502020-04-04 17:39:39 +08002395 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08002396
2397 //playback_device_pause(player->handle);
hualing chen87072a82020-03-12 16:20:12 +08002398 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2399 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2400 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2401 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002402 } else {
2403 player->cmd.last_cmd = player->cmd.cur_cmd;
2404 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_PAUSE;
2405 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2406 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen87072a82020-03-12 16:20:12 +08002407 }
hualing chen86e7d482020-01-16 15:13:33 +08002408 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08002409 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08002410
hualing chen86e7d482020-01-16 15:13:33 +08002411 return DVR_SUCCESS;
hualing chenb31a6c62020-01-13 17:27:00 +08002412}
2413
hualing chen5cbe1a62020-02-10 16:36:36 +08002414//not add lock
2415static int _dvr_cmd(DVR_PlaybackHandle_t handle, int cmd)
2416{
2417 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2418
hualing chena540a7e2020-03-27 16:44:05 +08002419 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002420 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002421 return DVR_FAILURE;
2422 }
2423
hualing chen5cbe1a62020-02-10 16:36:36 +08002424 //get video params and audio params
hualing chen4b7c15d2020-04-07 16:13:48 +08002425 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002426 pthread_mutex_lock(&player->lock);
hualing chen2aba4022020-03-02 13:49:55 +08002427 am_tsplayer_video_params vparams;
2428 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002429 am_tsplayer_audio_params adparams;
hualing chencc91e1c2020-02-28 13:26:17 +08002430 uint64_t segmentid = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08002431
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002432 memset(&vparams, 0, sizeof(vparams));
2433 memset(&aparams, 0, sizeof(aparams));
2434
hualing chendf118dd2020-05-21 15:49:11 +08002435 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen4b7c15d2020-04-07 16:13:48 +08002436 DVR_PB_DG(1, "unlock cmd: %d", cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08002437 pthread_mutex_unlock(&player->lock);
2438
2439 switch (cmd) {
2440 case DVR_PLAYBACK_CMD_AVRESTART:
2441 //av restart
hualing chen4b7c15d2020-04-07 16:13:48 +08002442 DVR_PB_DG(1, "do_cmd avrestart");
hualing chen87072a82020-03-12 16:20:12 +08002443 _dvr_playback_replay((DVR_PlaybackHandle_t)player, DVR_FALSE);
hualing chen5cbe1a62020-02-10 16:36:36 +08002444 break;
2445 case DVR_PLAYBACK_CMD_VRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002446 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2447 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002448 break;
2449 case DVR_PLAYBACK_CMD_VSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002450 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002451 break;
2452 case DVR_PLAYBACK_CMD_VSTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002453 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002454 break;
2455 case DVR_PLAYBACK_CMD_ARESTART:
2456 //a restart
hualing chen2aba4022020-03-02 13:49:55 +08002457 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002458 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002459 break;
2460 case DVR_PLAYBACK_CMD_ASTART:
hualing chendf118dd2020-05-21 15:49:11 +08002461 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002462 break;
2463 case DVR_PLAYBACK_CMD_ASTOP:
hualing chen2aba4022020-03-02 13:49:55 +08002464 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002465 break;
2466 case DVR_PLAYBACK_CMD_ASTOPVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002467 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2468 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2469 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002470 break;
2471 case DVR_PLAYBACK_CMD_ASTOPVSTART:
hualing chen2aba4022020-03-02 13:49:55 +08002472 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2473 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002474 break;
2475 case DVR_PLAYBACK_CMD_VSTOPARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002476 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2477 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
hualing chendf118dd2020-05-21 15:49:11 +08002478 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002479 break;
2480 case DVR_PLAYBACK_CMD_STOP:
2481 break;
2482 case DVR_PLAYBACK_CMD_START:
2483 break;
2484 case DVR_PLAYBACK_CMD_ASTARTVRESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002485 dvr_playback_video_stop((DVR_PlaybackHandle_t)player);
2486 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002487 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002488 break;
2489 case DVR_PLAYBACK_CMD_VSTARTARESTART:
hualing chen2aba4022020-03-02 13:49:55 +08002490 dvr_playback_audio_stop((DVR_PlaybackHandle_t)player);
2491 dvr_playback_video_start((DVR_PlaybackHandle_t)player, &vparams);
hualing chendf118dd2020-05-21 15:49:11 +08002492 dvr_playback_audio_start((DVR_PlaybackHandle_t)player, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08002493 break;
2494 case DVR_PLAYBACK_CMD_FF:
2495 case DVR_PLAYBACK_CMD_FB:
hualing chen2aba4022020-03-02 13:49:55 +08002496 _dvr_playback_fffb((DVR_PlaybackHandle_t)player);
hualing chen5cbe1a62020-02-10 16:36:36 +08002497 break;
2498 default:
2499 break;
2500 }
2501 return DVR_SUCCESS;
2502}
2503
2504/**\brief Resume play
hualing chenb31a6c62020-01-13 17:27:00 +08002505 * \param[in] handle playback handle
hualing chenb31a6c62020-01-13 17:27:00 +08002506 * \retval DVR_SUCCESS On success
2507 * \return Error code
2508 */
hualing chen5cbe1a62020-02-10 16:36:36 +08002509int dvr_playback_resume(DVR_PlaybackHandle_t handle) {
2510 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002511 uint32_t pos = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002512 uint64_t segmentid = 0;
hualing chena540a7e2020-03-27 16:44:05 +08002513 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002514 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002515 return DVR_FAILURE;
2516 }
2517
hualing chena991aa82021-08-16 10:21:15 +08002518 if (dvr_playback_check_limit(handle)) {
2519 //get id and pos to check if we can seek to this pos
hualing chen7ea70a72021-09-09 11:25:13 +08002520 DVR_PB_DG(1, "player start calculate time");
hualing chena991aa82021-08-16 10:21:15 +08002521 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
2522 if (segmentid != player->cur_segment_id ||
2523 (segmentid == player->cur_segment_id &&
2524 pos > _dvr_get_cur_time(handle))) {
2525 //first to seek new pos and to resume
2526 DVR_PB_DG(1, "seek new pos and to resume");
2527 dvr_playback_seek(handle, segmentid, pos);
2528 }
hualing chen7ea70a72021-09-09 11:25:13 +08002529 } else {
2530 DVR_PB_DG(1, "player is not set limit");
hualing chen03fd4942021-07-15 15:56:41 +08002531 }
hualing chena991aa82021-08-16 10:21:15 +08002532
hualing chen5cbe1a62020-02-10 16:36:36 +08002533 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002534 DVR_PB_DG(1, "lock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002535 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002536 player->first_frame = 0;
2537 if (player->has_video)
2538 AmTsPlayer_pauseVideoDecoding(player->handle);
2539 if (player->has_audio)
2540 AmTsPlayer_pauseAudioDecoding(player->handle);
2541
hualing chen266b9502020-04-04 17:39:39 +08002542 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002543 DVR_PB_DG(1, "dvr_playback_resume set trick mode none");
hualing chen266b9502020-04-04 17:39:39 +08002544 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
2545 AmTsPlayer_resumeVideoDecoding(player->handle);
2546 }
2547 if (player->has_audio) {
2548 AmTsPlayer_resumeAudioDecoding(player->handle);
2549 }
2550 //check is has audio param,if has audio .we need start audio,
2551 //we will stop audio when ff fb, if reach end, we will pause.so we need
2552 //start audio when resume play
2553
2554 am_tsplayer_video_params vparams;
2555 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002556 am_tsplayer_audio_params adparams;
hualing chen266b9502020-04-04 17:39:39 +08002557 uint64_t segmentid = player->cur_segment_id;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002558
2559 memset(&vparams, 0, sizeof(vparams));
2560 memset(&aparams, 0, sizeof(aparams));
hualing chendf118dd2020-05-21 15:49:11 +08002561 _dvr_playback_get_playinfo(handle, segmentid, &vparams, &aparams, &adparams);
hualing chen266b9502020-04-04 17:39:39 +08002562 //valid audio pid, start audio
hualing chen969fe7b2021-05-26 15:13:17 +08002563 if (player->has_ad_audio == DVR_FALSE && VALID_PID(adparams.pid) && (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)) {
2564 player->has_ad_audio = DVR_TRUE;
2565 DVR_PB_DG(1, "start ad audio");
2566 AmTsPlayer_setADParams(player->handle, &adparams);
2567 AmTsPlayer_enableADMix(player->handle);
2568 }
2569
hualing chenc70a8df2020-05-12 19:23:11 +08002570 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 +08002571 player->has_audio = DVR_TRUE;
2572 AmTsPlayer_setAudioParams(player->handle, &aparams);
2573 AmTsPlayer_startAudioDecoding(player->handle);
2574 } else {
hualing chenc70a8df2020-05-12 19:23:11 +08002575 DVR_PB_DG(1, "aparams.pid:%d player->has_audio:%d speed:%d", aparams.pid, player->has_audio, player->cmd.speed.speed.speed);
hualing chen266b9502020-04-04 17:39:39 +08002576 }
hualing chendf118dd2020-05-21 15:49:11 +08002577
hualing chen87072a82020-03-12 16:20:12 +08002578 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2579 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2580 player->cmd.state = DVR_PLAYBACK_STATE_START;
2581 player->state = DVR_PLAYBACK_STATE_START;
2582 } else {
2583 player->cmd.last_cmd = player->cmd.cur_cmd;
2584 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_RESUME;
2585 player->cmd.state = DVR_PLAYBACK_STATE_START;
2586 player->state = DVR_PLAYBACK_STATE_START;
2587 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002588 DVR_PB_DG(1, "unlock");
hualing chen5cbe1a62020-02-10 16:36:36 +08002589 pthread_mutex_unlock(&player->lock);
hualing chen041c4092020-04-05 15:11:50 +08002590 } else if (player->state == DVR_PLAYBACK_STATE_PAUSE){
hualing chen1ffd85b2021-08-16 15:18:43 +08002591 player->first_frame = 0;
2592 if (player->has_video)
2593 AmTsPlayer_pauseVideoDecoding(player->handle);
2594 if (player->has_audio)
2595 AmTsPlayer_pauseAudioDecoding(player->handle);
2596
hualing chene41f4372020-06-06 16:29:17 +08002597 if (player->has_video) {
hualing chenf00cdc82020-06-10 14:23:35 +08002598 DVR_PB_DG(1, "dvr_playback_resume set trick mode none 1");
hualing chene41f4372020-06-06 16:29:17 +08002599 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen041c4092020-04-05 15:11:50 +08002600 AmTsPlayer_resumeVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002601 }
hualing chen041c4092020-04-05 15:11:50 +08002602 if (player->has_audio)
2603 AmTsPlayer_resumeAudioDecoding(player->handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002604 DVR_PB_DG(1, "set start state cur cmd[%d]", player->cmd.cur_cmd);
hualing chen2aba4022020-03-02 13:49:55 +08002605 player->cmd.state = DVR_PLAYBACK_STATE_START;
2606 player->state = DVR_PLAYBACK_STATE_START;
hualing chen9811b212020-10-29 11:21:44 +08002607 if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1)
2608 _dvr_cmd(handle, player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002609 } else {
2610 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE)
2611 {
2612 pthread_mutex_lock(&player->lock);
hualing chen1ffd85b2021-08-16 15:18:43 +08002613 player->first_frame = 0;
2614 if (player->has_video)
2615 AmTsPlayer_pauseVideoDecoding(player->handle);
2616 if (player->has_audio)
2617 AmTsPlayer_pauseAudioDecoding(player->handle);
hualing chen041c4092020-04-05 15:11:50 +08002618 //clear flag
hualing chen4b7c15d2020-04-07 16:13:48 +08002619 DVR_PB_DG(1, "clear pause live flag cur cmd[%d]", player->cmd.cur_cmd);
hualing chen041c4092020-04-05 15:11:50 +08002620 player->play_flag = player->play_flag & (~DVR_PLAYBACK_STARTED_PAUSEDLIVE);
2621 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen05d09432021-01-25 15:26:55 +08002622 if (player->has_video) {
2623 AmTsPlayer_resumeVideoDecoding(player->handle);
2624 }
2625 if (player->has_audio)
2626 AmTsPlayer_resumeAudioDecoding(player->handle);
2627
hualing chen041c4092020-04-05 15:11:50 +08002628 pthread_mutex_unlock(&player->lock);
2629 }
hualing chen5cbe1a62020-02-10 16:36:36 +08002630 }
2631 return DVR_SUCCESS;
2632}
2633
hualing chena540a7e2020-03-27 16:44:05 +08002634static DVR_Bool_t _dvr_check_playinfo_changed(DVR_PlaybackHandle_t handle, int segment_id, int set_seg_id){
2635
2636 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2637 DVR_PlaybackSegmentInfo_t *segment = NULL;
2638 DVR_PlaybackSegmentInfo_t *cur_segment = NULL;
2639 DVR_PlaybackSegmentInfo_t *set_segment = NULL;
2640
2641 list_for_each_entry(segment, &player->segment_list, head)
2642 {
2643 if (segment->segment_id == segment_id) {
2644 cur_segment = segment;
2645 }
2646 if (segment->segment_id == set_seg_id) {
2647 set_segment = segment;
2648 }
2649 if (cur_segment != NULL && set_segment != NULL) {
2650 break;
2651 }
2652 }
2653 if (cur_segment == NULL || set_segment == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002654 DVR_PB_DG(1, "set segmen or cur segment is null");
hualing chena540a7e2020-03-27 16:44:05 +08002655 return DVR_TRUE;
2656 }
2657 if (cur_segment->pids.video.format != set_segment->pids.video.format ||
2658 cur_segment->pids.video.pid != set_segment->pids.video.pid ||
2659 cur_segment->pids.audio.format != set_segment->pids.audio.format ||
2660 cur_segment->pids.audio.pid != set_segment->pids.audio.pid) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002661 DVR_PB_DG(1, "cur v[%d]a[%d] set v[%d]a[%d]",cur_segment->pids.video.pid,cur_segment->pids.audio.pid,set_segment->pids.video.pid,set_segment->pids.audio.pid);
hualing chena540a7e2020-03-27 16:44:05 +08002662 return DVR_TRUE;
2663 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002664 DVR_PB_DG(1, "play info not change");
hualing chena540a7e2020-03-27 16:44:05 +08002665 return DVR_FALSE;
2666}
2667
hualing chen03fd4942021-07-15 15:56:41 +08002668/**\brief set limit
2669 * \param[in] handle playback handle
2670 * \param[in] rec start time ms
2671 * \param[in] rec limit time ms
2672 * \retval DVR_SUCCESS On success
2673 * \return Error code
2674 */
hualing chen7ea70a72021-09-09 11:25:13 +08002675int dvr_playback_setlimit(DVR_PlaybackHandle_t handle, uint32_t time, uint32_t limit)
hualing chen03fd4942021-07-15 15:56:41 +08002676{ DVR_Playback_t *player = (DVR_Playback_t *) handle;
2677
2678 if (player == NULL) {
2679 DVR_PB_DG(1, "player is NULL");
2680 return DVR_FAILURE;
2681 }
hualing chen7ea70a72021-09-09 11:25:13 +08002682 _dvr_getClock_sec();
2683 DVR_PB_DG(1, "time %lu limit: %u player->state:%d", time, limit, player->state);
hualing chen03fd4942021-07-15 15:56:41 +08002684 pthread_mutex_lock(&player->lock);
2685 player->rec_start = time;
2686 player->limit = limit;
2687 pthread_mutex_unlock(&player->lock);
2688 return DVR_SUCCESS;
2689}
2690
hualing chen5cbe1a62020-02-10 16:36:36 +08002691/**\brief seek
2692 * \param[in] handle playback handle
2693 * \param[in] time_offset time offset base cur segment
2694 * \retval DVR_SUCCESS On success
2695 * \return Error code
2696 */
hualing chencc91e1c2020-02-28 13:26:17 +08002697int dvr_playback_seek(DVR_PlaybackHandle_t handle, uint64_t segment_id, uint32_t time_offset) {
hualing chen040df222020-01-17 13:35:02 +08002698 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen03fd4942021-07-15 15:56:41 +08002699 int ret = DVR_SUCCESS;
hualing chena540a7e2020-03-27 16:44:05 +08002700 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002701 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002702 return DVR_FAILURE;
2703 }
2704
hualing chen4b7c15d2020-04-07 16:13:48 +08002705 DVR_PB_DG(1, "lock segment_id %llu cur id %llu time_offset %u cur end: %d player->state:%d", segment_id,player->cur_segment_id, (uint32_t)time_offset, _dvr_get_end_time(handle), player->state);
hualing chen86e7d482020-01-16 15:13:33 +08002706 pthread_mutex_lock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002707
hualing chen86e7d482020-01-16 15:13:33 +08002708 int offset = -1;
hualing chena540a7e2020-03-27 16:44:05 +08002709 DVR_Bool_t replay = _dvr_check_playinfo_changed(handle, player->cur_segment_id, segment_id);
hualing chen4b7c15d2020-04-07 16:13:48 +08002710 DVR_PB_DG(1, "player->state[%d]-replay[%d]--get lock-", player->state, replay);
hualing chena540a7e2020-03-27 16:44:05 +08002711
hualing chen5cbe1a62020-02-10 16:36:36 +08002712 //open segment if id is not current segment
hualing chen03fd4942021-07-15 15:56:41 +08002713 ret = _dvr_open_segment(handle, segment_id);
hualing chen87072a82020-03-12 16:20:12 +08002714 if (ret ==DVR_FAILURE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002715 DVR_PB_DG(1, "seek error at open segment");
hualing chen87072a82020-03-12 16:20:12 +08002716 pthread_mutex_unlock(&player->lock);
2717 return DVR_FAILURE;
2718 }
2719 if (time_offset >_dvr_get_end_time(handle) &&_dvr_has_next_segmentId(handle, segment_id) == DVR_FAILURE) {
2720 if (segment_ongoing(player->r_handle) == DVR_SUCCESS) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002721 DVR_PB_DG(1, "is ongoing segment when seek end, need return success");
hualing chen87072a82020-03-12 16:20:12 +08002722 //pthread_mutex_unlock(&player->lock);
2723 //return DVR_SUCCESS;
2724 time_offset = _dvr_get_end_time(handle);
2725 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002726 DVR_PB_DG(1, "is not ongoing segment when seek end, return failure");
hualing chene41f4372020-06-06 16:29:17 +08002727 time_offset = _dvr_get_end_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08002728 //pthread_mutex_unlock(&player->lock);
2729 //return DVR_FAILURE;
2730 ret = DVR_FAILURE;
hualing chen87072a82020-03-12 16:20:12 +08002731 }
2732 }
2733
hualing chen03fd4942021-07-15 15:56:41 +08002734 DVR_PB_DG(1, "seek open id[%lld]flag[0x%x] time_offset %u",
2735 player->cur_segment.segment_id,
2736 player->cur_segment.flags,
2737 time_offset);
hualing chen86e7d482020-01-16 15:13:33 +08002738 //get file offset by time
hualing chen2aba4022020-03-02 13:49:55 +08002739 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
2740 //forward playback.not seek end of file
2741 if (time_offset != 0 && time_offset > FB_DEFAULT_LEFT_TIME) {
2742 //default -2000ms
2743 time_offset = time_offset -FB_DEFAULT_LEFT_TIME;
2744 }
hualing chen86e7d482020-01-16 15:13:33 +08002745 }
hualing chen8a657f32021-08-30 13:12:49 +08002746 if (player->need_seek_start == DVR_TRUE) {
2747 player->first_start_time = (uint64_t)time_offset + 1;//set first start time not eq 0
2748 }
hualing chen2aba4022020-03-02 13:49:55 +08002749 pthread_mutex_lock(&player->segment_lock);
hualing chen266b9502020-04-04 17:39:39 +08002750 player->drop_ts = DVR_TRUE;
hualing chen5605eed2020-05-26 18:18:06 +08002751 player->ts_cache_len = 0;
hualing chen266b9502020-04-04 17:39:39 +08002752 offset = segment_seek(player->r_handle, (uint64_t)time_offset, player->openParams.block_size);
hualing chen4b7c15d2020-04-07 16:13:48 +08002753 DVR_PB_DG(0, "seek get offset by time offset, offset=%d time_offset %u",offset, time_offset);
hualing chen2aba4022020-03-02 13:49:55 +08002754 pthread_mutex_unlock(&player->segment_lock);
hualing chen86e7d482020-01-16 15:13:33 +08002755 player->offset = offset;
hualing chen87072a82020-03-12 16:20:12 +08002756
hualing chen2aba4022020-03-02 13:49:55 +08002757 _dvr_get_end_time(handle);
Zhiqiang Han8e4e6db2020-05-15 10:52:20 +08002758
2759 player->last_send_time_id = UINT64_MAX;
hualing chen03fd4942021-07-15 15:56:41 +08002760 player->last_segment_tatol = 0LL;
2761 player->last_segment_id = 0LL;
hualing chen2aba4022020-03-02 13:49:55 +08002762 //init fffb time
hualing chen87072a82020-03-12 16:20:12 +08002763 player->fffb_current = _dvr_time_getClock();
2764 player->fffb_start = player->fffb_current;
2765 player->fffb_start_pcr = _dvr_get_cur_time(handle);
2766 player->next_fffb_time = player->fffb_current;
hualing chena540a7e2020-03-27 16:44:05 +08002767 //pause state if need to replayer false
hualing chen39628212020-05-14 10:35:13 +08002768 if (player->state == DVR_PLAYBACK_STATE_STOP) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002769 //only seek file,not start
hualing chen4b7c15d2020-04-07 16:13:48 +08002770 DVR_PB_DG(1, "unlock");
hualing chencc91e1c2020-02-28 13:26:17 +08002771 pthread_mutex_unlock(&player->lock);
hualing chen87072a82020-03-12 16:20:12 +08002772 return DVR_SUCCESS;
hualing chen5cbe1a62020-02-10 16:36:36 +08002773 }
hualing chen86e7d482020-01-16 15:13:33 +08002774 //stop play
hualing chen03fd4942021-07-15 15:56:41 +08002775 DVR_PB_DG(0, "seek stop play, not inject data has video[%d]audio[%d]",
2776 player->has_video, player->has_audio);
hualing chen1ffd85b2021-08-16 15:18:43 +08002777
hualing chen266b9502020-04-04 17:39:39 +08002778 if (player->has_video) {
hualing chen7e14e532021-09-23 11:23:28 +08002779 //player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08002780 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08002781 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002782 }
2783
2784 if (player->has_audio) {
2785 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08002786 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen266b9502020-04-04 17:39:39 +08002787 }
hualing chendf118dd2020-05-21 15:49:11 +08002788 if (player->has_ad_audio) {
2789 player->has_ad_audio =DVR_FALSE;
2790 AmTsPlayer_disableADMix(player->handle);
2791 }
2792
hualing chen86e7d482020-01-16 15:13:33 +08002793 //start play
hualing chen2aba4022020-03-02 13:49:55 +08002794 am_tsplayer_video_params vparams;
2795 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08002796 am_tsplayer_audio_params adparams;
hualing chenb31a6c62020-01-13 17:27:00 +08002797
jiangfei.hanb8fbad42021-07-29 15:04:48 +08002798 memset(&vparams, 0, sizeof(vparams));
2799 memset(&aparams, 0, sizeof(aparams));
2800
hualing chen040df222020-01-17 13:35:02 +08002801 player->cur_segment_id = segment_id;
2802
2803 int sync = DVR_PLAYBACK_SYNC;
hualing chen5cbe1a62020-02-10 16:36:36 +08002804 //get segment info and audio video pid fmt ;
hualing chendf118dd2020-05-21 15:49:11 +08002805 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen86e7d482020-01-16 15:13:33 +08002806 //start audio and video
Zhiqiang Han9adc9722020-11-11 18:38:10 +08002807 if (vparams.pid != 0x2fff && !VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen86e7d482020-01-16 15:13:33 +08002808 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08002809 DVR_PB_DG(0, "unlock seek start dvr play back start error, not found audio and video info");
hualing chen86e7d482020-01-16 15:13:33 +08002810 pthread_mutex_unlock(&player->lock);
2811 return -1;
2812 }
2813 //add
hualing chen040df222020-01-17 13:35:02 +08002814 if (sync == DVR_PLAYBACK_SYNC) {
hualing chen86e7d482020-01-16 15:13:33 +08002815 if (VALID_PID(vparams.pid)) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002816 //player->has_video;
hualing chen2aba4022020-03-02 13:49:55 +08002817 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_PAUSE ||
hualing chene41f4372020-06-06 16:29:17 +08002818 player->state == DVR_PLAYBACK_STATE_PAUSE ||
hualing chendf118dd2020-05-21 15:49:11 +08002819 player->speed > 2.0f||
hualing chen31140872020-03-25 12:29:26 +08002820 player->speed <= -1.0f) {
hualing chen5cbe1a62020-02-10 16:36:36 +08002821 //if is pause state. we need set trick mode.
hualing chen4b7c15d2020-04-07 16:13:48 +08002822 DVR_PB_DG(1, "seek set trick mode player->speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08002823 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen5cbe1a62020-02-10 16:36:36 +08002824 }
hualing chen2aba4022020-03-02 13:49:55 +08002825 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08002826 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08002827 AmTsPlayer_startVideoDecoding(player->handle);
hualing chene41f4372020-06-06 16:29:17 +08002828 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed) &&
2829 player->cmd.speed.speed.speed != PLAYBACK_SPEED_X1) {
2830 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
2831 } else if (player->cmd.speed.speed.speed == PLAYBACK_SPEED_X1) {
2832 AmTsPlayer_stopFast(player->handle);
2833 }
hualing chen266b9502020-04-04 17:39:39 +08002834 player->has_video = DVR_TRUE;
hualing chen7e14e532021-09-23 11:23:28 +08002835 } else {
2836 player->has_video = DVR_FALSE;
hualing chenb31a6c62020-01-13 17:27:00 +08002837 }
hualing chene41f4372020-06-06 16:29:17 +08002838 if (VALID_PID(adparams.pid) && player->speed == 1.0) {
hualing chendf118dd2020-05-21 15:49:11 +08002839 player->has_ad_audio = DVR_TRUE;
2840 DVR_PB_DG(1, "start ad audio");
2841 AmTsPlayer_setADParams(player->handle, &adparams);
2842 AmTsPlayer_enableADMix(player->handle);
2843 }
hualing chen969fe7b2021-05-26 15:13:17 +08002844 if (VALID_PID(aparams.pid) && player->speed == 1.0) {
2845 DVR_PB_DG(1, "start audio seek");
2846 AmTsPlayer_setAudioParams(player->handle, &aparams);
2847 AmTsPlayer_startAudioDecoding(player->handle);
2848 player->has_audio = DVR_TRUE;
2849 }
hualing chen86e7d482020-01-16 15:13:33 +08002850 }
hualing chen1ffd85b2021-08-16 15:18:43 +08002851 if (player->state == DVR_PLAYBACK_STATE_PAUSE) {
hualing chen2aba4022020-03-02 13:49:55 +08002852 player->cmd.state = DVR_PLAYBACK_STATE_PAUSE;
2853 player->state = DVR_PLAYBACK_STATE_PAUSE;
hualing chen30423862021-04-16 14:39:12 +08002854 player->seek_pause = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08002855 DVR_PB_DG(1, "set state pause in seek");
hualing chen87072a82020-03-12 16:20:12 +08002856 } else if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
2857 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
hualing chen31140872020-03-25 12:29:26 +08002858 player->speed > 1.0f||
2859 player->speed <= -1.0f) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002860 DVR_PB_DG(1, "not set cmd to seek");
hualing chen87072a82020-03-12 16:20:12 +08002861 //not pause state, we need not set cur cmd
hualing chen2aba4022020-03-02 13:49:55 +08002862 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08002863 DVR_PB_DG(1, "set cmd to seek");
hualing chen2aba4022020-03-02 13:49:55 +08002864 player->cmd.last_cmd = player->cmd.cur_cmd;
2865 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_SEEK;
2866 player->cmd.state = DVR_PLAYBACK_STATE_START;
2867 player->state = DVR_PLAYBACK_STATE_START;
2868 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002869 player->last_send_time_id = UINT64_MAX;
2870 DVR_PB_DG(1, "unlock");
hualing chen86e7d482020-01-16 15:13:33 +08002871 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08002872
2873 return DVR_SUCCESS;
2874}
hualing chen5cbe1a62020-02-10 16:36:36 +08002875
hualing chen5cbe1a62020-02-10 16:36:36 +08002876static int _dvr_get_cur_time(DVR_PlaybackHandle_t handle) {
2877 //get cur time of segment
2878 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002879
Gong Ke2a0ebbe2021-05-25 15:22:50 +08002880 if (player == NULL || player->handle == (am_tsplayer_handle)NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002881 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002882 return DVR_FAILURE;
2883 }
2884
hualing chen31140872020-03-25 12:29:26 +08002885 int64_t cache = 0;//defalut es buf cache 500ms
hualing chen2aba4022020-03-02 13:49:55 +08002886 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08002887 loff_t pos = segment_tell_position(player->r_handle) -player->ts_cache_len;
2888 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen21a40372021-10-29 11:07:26 +08002889 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen2aba4022020-03-02 13:49:55 +08002890 pthread_mutex_unlock(&player->segment_lock);
hualing chenfbf8e022020-06-15 13:43:11 +08002891 DVR_PB_DG(1, "get cur time [%lld] cache:%lld cur id [%lld]last id [%lld] pb cache len [%d] [%lld]", cur, cache, player->cur_segment_id,player->last_send_time_id, player->ts_cache_len, pos);
hualing chen87072a82020-03-12 16:20:12 +08002892 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2893 cache = 0;
2894 }
hualing chen4b7c15d2020-04-07 16:13:48 +08002895 int cur_time = (int)(cur > cache ? cur - cache : 0);
2896 return cur_time;
hualing chencc91e1c2020-02-28 13:26:17 +08002897}
2898
hualing chen969fe7b2021-05-26 15:13:17 +08002899static int _dvr_get_play_cur_time(DVR_PlaybackHandle_t handle, uint64_t *id) {
2900 //get cur time of segment
2901 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2902
hualing chen03fd4942021-07-15 15:56:41 +08002903 if (player == NULL || player->handle == 0) {
hualing chen969fe7b2021-05-26 15:13:17 +08002904 DVR_PB_DG(1, "player is NULL");
2905 return DVR_FAILURE;
2906 }
2907
2908 int64_t cache = 0;//defalut es buf cache 500ms
2909 int cur_time = 0;
hualing chen969fe7b2021-05-26 15:13:17 +08002910 pthread_mutex_lock(&player->segment_lock);
hualing chen21a40372021-10-29 11:07:26 +08002911 loff_t pos = segment_tell_position(player->r_handle) - player->ts_cache_len;
hualing chen969fe7b2021-05-26 15:13:17 +08002912 uint64_t cur = segment_tell_position_time(player->r_handle, pos);
hualing chen21a40372021-10-29 11:07:26 +08002913 AmTsPlayer_getDelayTime(player->handle, &cache);
hualing chen969fe7b2021-05-26 15:13:17 +08002914 pthread_mutex_unlock(&player->segment_lock);
hualing chen21a40372021-10-29 11:07:26 +08002915 DVR_PB_DG(1, "***get play cur time [%lld] cache:%lld cur id [%lld]last id [%lld] pb cache len [%d] [%lld]", cur, cache, player->cur_segment_id,player->last_send_time_id, player->ts_cache_len, pos);
hualing chen969fe7b2021-05-26 15:13:17 +08002916 if (player->state == DVR_PLAYBACK_STATE_STOP) {
2917 cache = 0;
2918 }
2919 if (cur > cache) {
2920 cur_time = (int)(cur - cache);
2921 *id = player->cur_segment_id;
2922 } else if (player->last_segment_tatol > 0) {
hualing chen8a657f32021-08-30 13:12:49 +08002923
2924 if (player->last_segment_tatol > (cache - cur))
2925 cur_time = (int)(player->last_segment_tatol - (cache - cur));
2926 else
2927 cur_time = (int)(player->last_segment_tatol - cur);
2928
hualing chen969fe7b2021-05-26 15:13:17 +08002929 *id = player->last_segment_id;
2930 DVR_PB_DG(1, "get play cur time[%lld][%lld][%d]", player->last_segment_id, player->cur_segment_id, player->last_segment_tatol);
2931 } else {
2932 cur_time = 0;
2933 *id = player->cur_segment_id;
2934 }
2935
2936 return cur_time;
2937}
2938
hualing chencc91e1c2020-02-28 13:26:17 +08002939//get current segment current pcr time of read pos
2940static int _dvr_get_end_time(DVR_PlaybackHandle_t handle) {
2941 //get cur time of segment
2942 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08002943
2944 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08002945 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08002946 return DVR_FAILURE;
2947 }
2948
hualing chen2aba4022020-03-02 13:49:55 +08002949 pthread_mutex_lock(&player->segment_lock);
2950 uint64_t end = segment_tell_total_time(player->r_handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08002951 DVR_PB_DG(1, "get tatal time [%lld]", end);
hualing chen2aba4022020-03-02 13:49:55 +08002952 pthread_mutex_unlock(&player->segment_lock);
2953 return (int)end;
hualing chen5cbe1a62020-02-10 16:36:36 +08002954}
2955
hualing chen03fd4942021-07-15 15:56:41 +08002956DVR_Bool_t dvr_playback_check_limit(DVR_PlaybackHandle_t handle)
2957{
2958 //check is set limit info
2959 DVR_Playback_t *player = (DVR_Playback_t *) handle;
2960
2961 if (player == NULL) {
2962 DVR_PB_DG(1, "player is NULL");
2963 return DVR_FALSE;
2964 }
2965 if (player->rec_start > 0 || player->limit > 0) {
2966 return DVR_TRUE;
2967 }
2968 return DVR_FALSE;
2969}
2970
2971/**\brief set DVR playback calculate expired time len
2972 * \param[in] handle, DVR playback session handle
2973 * \return DVR_SUCCESS on success
2974 * \return error code on failure
2975 */
hualing chen7ea70a72021-09-09 11:25:13 +08002976uint32_t dvr_playback_calculate_expiredlen(DVR_PlaybackHandle_t handle)
hualing chen03fd4942021-07-15 15:56:41 +08002977{
2978 //calculate expired time to play
2979 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen7ea70a72021-09-09 11:25:13 +08002980 uint32_t cur_time;
2981 uint32_t tmp_time;
2982 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08002983 if (player == NULL) {
2984 DVR_PB_DG(1, "player is NULL");
2985 return expired;
2986 }
hualing chen7ea70a72021-09-09 11:25:13 +08002987 if (player->rec_start == 0 || player->limit == 0) {
2988 DVR_PB_DG(1, "rec limit 0");
hualing chen03fd4942021-07-15 15:56:41 +08002989 return expired;
2990 }
2991 //get system time
hualing chen7ea70a72021-09-09 11:25:13 +08002992 cur_time = _dvr_getClock_sec();
2993 if ((cur_time - player->rec_start) > player->limit) {
2994 tmp_time = (uint32_t)((cur_time - player->rec_start) - player->limit) * 1000U;
2995 expired = *(int*)&tmp_time;
2996 DVR_PB_DG(1, "cur_time:%u, rec start:%u limit:%d c_r_diff:%u expired:%u tmp_time:%u",
hualing chen03fd4942021-07-15 15:56:41 +08002997 cur_time,
2998 player->rec_start,
2999 player->limit,
hualing chen7ea70a72021-09-09 11:25:13 +08003000 (uint32_t)(cur_time - player->rec_start - player->limit), expired, tmp_time);
3001 }
hualing chen03fd4942021-07-15 15:56:41 +08003002 return expired;
3003}
3004
3005/**\brief set DVR playback obsolete time
3006 * \param[in] handle, DVR playback session handle
3007 * \param[in] obsolete, obsolete len
3008 * \return DVR_SUCCESS on success
3009 * \return error code on failure
3010 */
3011int dvr_playback_set_obsolete(DVR_PlaybackHandle_t handle, int obsolete)
3012{
3013 int expired = 0;
3014 //calculate expired time to play
3015 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3016
3017 if (player == NULL) {
3018 DVR_PB_DG(1, "player is NULL");
3019 return DVR_FALSE;
3020 }
3021 //get system time
3022 pthread_mutex_lock(&player->lock);
3023 player->obsolete = obsolete;
3024 pthread_mutex_unlock(&player->lock);
3025 return expired;
3026}
3027
3028/**\brief update DVR playback newest segment duration
3029 * \param[in] handle, DVR playback session handle
3030 * \param[in] segmentid, newest segment id
3031 * \param[in] dur dur time ms
3032 * \return DVR_SUCCESS on success
3033 * \return error code on failure
3034 */
3035int dvr_playback_update_duration(DVR_PlaybackHandle_t handle,
3036uint64_t segmentid, int dur)
3037{
3038 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3039 DVR_PlaybackSegmentInfo_t *segment;
3040 DVR_PlaybackSegmentInfo_t *pre_segment = NULL;
3041
3042 if (player == NULL) {
3043 DVR_PB_DG(1, " player is NULL");
3044 return DVR_FAILURE;
3045 }
3046 //update the newest segment duration on timeshift mode
3047 list_for_each_entry(segment, &player->segment_list, head)
3048 {
3049 if (segment->segment_id == segmentid) {
3050 segment->duration = dur;
3051 break;
3052 }
3053 pre_segment = segment;
3054 }
3055
3056 return DVR_SUCCESS;
3057}
3058
hualing chen7ea70a72021-09-09 11:25:13 +08003059static uint32_t dvr_playback_calculate_last_valid_segment(
3060 DVR_PlaybackHandle_t handle, uint64_t *segmentid, uint32_t *pos)
hualing chen03fd4942021-07-15 15:56:41 +08003061{
hualing chen7ea70a72021-09-09 11:25:13 +08003062 uint32_t off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003063 uint64_t segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003064 uint32_t pre_off = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003065 uint64_t last_segment_id = 0;
hualing chen7ea70a72021-09-09 11:25:13 +08003066 uint32_t expired = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003067 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3068
3069 if (player == NULL) {
3070 DVR_PB_DG(1, "player is NULL");
3071 return DVR_FAILURE;
3072 }
3073 expired = dvr_playback_calculate_expiredlen(handle);
hualing chen7e14e532021-09-23 11:23:28 +08003074 if (expired == 0) {
3075 *segmentid = player->cur_segment_id;
3076 *pos = 0;
3077 return DVR_SUCCESS;
3078 }
hualing chen03fd4942021-07-15 15:56:41 +08003079 DVR_PlaybackSegmentInfo_t *pseg;
3080 list_for_each_entry_reverse(pseg, &player->segment_list, head) {
3081 segment_id = pseg->segment_id;
3082
3083 if ((player->obsolete + pre_off + pseg->duration) > expired)
3084 break;
3085
3086 last_segment_id = pseg->segment_id;
3087 pre_off += pseg->duration;
3088 }
3089
3090 if (last_segment_id == segment_id) {
3091 /*1.only one seg with id:0, 2.offset exceeds the total duration*/
3092 off = expired;
3093 } else if (player->obsolete >= expired) {
3094 off = 0;
3095 } else {
3096 off = expired - pre_off - player->obsolete;
3097 }
3098 *segmentid = segment_id;
3099 *pos = off;
3100 return DVR_SUCCESS;
3101}
3102
hualing chen4b7c15d2020-04-07 16:13:48 +08003103#define FB_MIX_SEEK_TIME 2000
hualing chen5cbe1a62020-02-10 16:36:36 +08003104//start replay
3105static int _dvr_playback_calculate_seekpos(DVR_PlaybackHandle_t handle) {
3106
3107 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3108 //calculate pcr seek time
3109 int t_diff = 0;
3110 int seek_time = 0;
hualing chen03fd4942021-07-15 15:56:41 +08003111 uint64_t segmentid = 0;
3112 int pos = 0;
hualing chena540a7e2020-03-27 16:44:05 +08003113 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003114 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003115 return DVR_FAILURE;
3116 }
3117
hualing chen5cbe1a62020-02-10 16:36:36 +08003118 if (player->fffb_start == -1) {
3119 //set fffb start time ms
3120 player->fffb_start = _dvr_time_getClock();
3121 player->fffb_current = player->fffb_start;
3122 //get segment current time pos
3123 player->fffb_start_pcr = _dvr_get_cur_time(handle);
hualing chen03fd4942021-07-15 15:56:41 +08003124 DVR_PB_DG(1, "calculate seek pos player->fffb_start_pcr[%d]ms, speed[%f]",
3125 player->fffb_start_pcr, player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003126 t_diff = 0;
hualing chene41f4372020-06-06 16:29:17 +08003127 //default first time 2s seek
hualing chen87072a82020-03-12 16:20:12 +08003128 seek_time = FB_MIX_SEEK_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003129 } else {
3130 player->fffb_current = _dvr_time_getClock();
3131 t_diff = player->fffb_current - player->fffb_start;
hualing chen2aba4022020-03-02 13:49:55 +08003132 //if speed is < 0, cmd is fb.
hualing chen5cbe1a62020-02-10 16:36:36 +08003133 seek_time = player->fffb_start_pcr + t_diff *player->speed;
hualing chen2aba4022020-03-02 13:49:55 +08003134 if (seek_time <= 0) {
3135 //need seek to pre one segment
3136 seek_time = 0;
3137 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003138 //seek segment pos
3139 if (player->r_handle) {
hualing chen2aba4022020-03-02 13:49:55 +08003140 pthread_mutex_lock(&player->segment_lock);
hualing chen5605eed2020-05-26 18:18:06 +08003141 player->ts_cache_len = 0;
hualing chene41f4372020-06-06 16:29:17 +08003142 if (seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3143 //set seek time to 0;
hualing chen03fd4942021-07-15 15:56:41 +08003144 DVR_PB_DG(1, "segment seek to 0 at fb mode [%d]id[%lld]",
3145 seek_time,
3146 player->cur_segment_id);
hualing chene41f4372020-06-06 16:29:17 +08003147 seek_time = 0;
3148 }
hualing chen03fd4942021-07-15 15:56:41 +08003149 if (IS_FB(player->speed)
3150 && dvr_playback_check_limit(handle)) {
3151 //fb case.check expired time
3152 //get id and pos to check if we can seek to this pos
3153 dvr_playback_calculate_last_valid_segment(handle, &segmentid, &pos);
3154 //case cur id < segment id
3155 if (player->cur_segment_id < segmentid) {
3156 //expired ts data is player,return error
3157 //
3158 pthread_mutex_unlock(&player->segment_lock);
3159 return 0;
3160 } else if (player->cur_segment_id == segmentid) {
3161 //id is same,compare seek pos
3162 if (seek_time < pos) {
3163 //expired ts data is player,return error
3164 //
3165 pthread_mutex_unlock(&player->segment_lock);
3166 return 0;
3167 }
3168 }
3169 //case can play
3170 }
hualing chen041c4092020-04-05 15:11:50 +08003171 if (segment_seek(player->r_handle, seek_time, player->openParams.block_size) == DVR_FAILURE) {
3172 seek_time = 0;
3173 }
hualing chen2aba4022020-03-02 13:49:55 +08003174 pthread_mutex_unlock(&player->segment_lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003175 } else {
3176 //
hualing chen4b7c15d2020-04-07 16:13:48 +08003177 DVR_PB_DG(1, "segment not open,can not seek");
hualing chen5cbe1a62020-02-10 16:36:36 +08003178 }
hualing chen03fd4942021-07-15 15:56:41 +08003179 DVR_PB_DG(1, "calculate seek pos seek_time[%d]ms, speed[%f]id[%lld]cur [%d]",
3180 seek_time,
3181 player->speed,
3182 player->cur_segment_id,
3183 _dvr_get_cur_time(handle));
hualing chen5cbe1a62020-02-10 16:36:36 +08003184 }
hualing chen2aba4022020-03-02 13:49:55 +08003185 return seek_time;
hualing chen5cbe1a62020-02-10 16:36:36 +08003186}
3187
3188
3189//start replay
3190static int _dvr_playback_fffb_replay(DVR_PlaybackHandle_t handle) {
3191 //
3192 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003193
3194 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003195 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003196 return DVR_FAILURE;
3197 }
3198
hualing chen5cbe1a62020-02-10 16:36:36 +08003199 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003200 if (player->has_video) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003201 DVR_PB_DG(1, "fffb stop video");
hualing chen21a40372021-10-29 11:07:26 +08003202 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003203 AmTsPlayer_stopVideoDecoding(player->handle);
3204 }
3205 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003206 DVR_PB_DG(1, "fffb stop audio");
hualing chen266b9502020-04-04 17:39:39 +08003207 player->has_audio =DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003208 AmTsPlayer_stopAudioDecoding(player->handle);
3209 }
hualing chendf118dd2020-05-21 15:49:11 +08003210 if (player->has_ad_audio) {
3211 DVR_PB_DG(1, "fffb stop audio");
3212 player->has_ad_audio =DVR_FALSE;
3213 AmTsPlayer_disableADMix(player->handle);
3214 }
hualing chen2aba4022020-03-02 13:49:55 +08003215
hualing chen5cbe1a62020-02-10 16:36:36 +08003216 //start video and audio
3217
hualing chen2aba4022020-03-02 13:49:55 +08003218 am_tsplayer_video_params vparams;
3219 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003220 am_tsplayer_audio_params adparams;
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003221
3222 memset(&vparams, 0, sizeof(vparams));
3223 memset(&aparams, 0, sizeof(aparams));
3224
hualing chen87072a82020-03-12 16:20:12 +08003225 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003226
3227 //get segment info and audio video pid fmt ;
hualing chencc91e1c2020-02-28 13:26:17 +08003228 //pthread_mutex_lock(&player->lock);
hualing chendf118dd2020-05-21 15:49:11 +08003229 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003230 //start audio and video
3231 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
3232 //audio abnd video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08003233 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chencc91e1c2020-02-28 13:26:17 +08003234 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003235 return -1;
3236 }
3237
3238 if (VALID_PID(vparams.pid)) {
3239 player->has_video = DVR_TRUE;
hualing chen4b7c15d2020-04-07 16:13:48 +08003240 DVR_PB_DG(1, "fffb start video");
hualing chen0888c032020-12-18 17:54:57 +08003241 //DVR_PB_DG(1, "fffb start video and save last frame");
3242 //AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen31140872020-03-25 12:29:26 +08003243 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen2aba4022020-03-02 13:49:55 +08003244 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
3245 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003246 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003247 AmTsPlayer_startVideoDecoding(player->handle);
3248 //playback_device_video_start(player->handle , &vparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003249 //if set flag is pause live, we need set trick mode
hualing chen2aba4022020-03-02 13:49:55 +08003250 //playback_device_trick_mode(player->handle, 1);
hualing chen5cbe1a62020-02-10 16:36:36 +08003251 }
hualing chen31140872020-03-25 12:29:26 +08003252 //fffb mode need stop fast;
hualing chen7a56cba2020-04-14 14:09:27 +08003253 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08003254 AmTsPlayer_stopFast(player->handle);
hualing chencc91e1c2020-02-28 13:26:17 +08003255 //pthread_mutex_unlock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003256 return 0;
3257}
3258
3259static int _dvr_playback_fffb(DVR_PlaybackHandle_t handle) {
3260 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003261 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003262 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003263 return DVR_FAILURE;
3264 }
3265
3266 player->first_frame = 0;
hualing chen4b7c15d2020-04-07 16:13:48 +08003267 DVR_PB_DG(1, "lock speed [%f]", player->speed);
hualing chen5cbe1a62020-02-10 16:36:36 +08003268 pthread_mutex_lock(&player->lock);
3269
hualing chen2aba4022020-03-02 13:49:55 +08003270 int seek_time = _dvr_playback_calculate_seekpos(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003271 DVR_PB_DG(1, "get lock speed [%f]id [%lld]seek_time[%d]", player->speed, player->cur_segment_id, seek_time);
hualing chen041c4092020-04-05 15:11:50 +08003272
hualing chen87072a82020-03-12 16:20:12 +08003273 if (_dvr_has_next_segmentId(handle, player->cur_segment_id) == DVR_FAILURE && seek_time < FB_MIX_SEEK_TIME && IS_FB(player->speed)) {
3274 //seek time set 0
3275 seek_time = 0;
3276 }
hualing chen041c4092020-04-05 15:11:50 +08003277 if (seek_time == 0) {
hualing chen2aba4022020-03-02 13:49:55 +08003278 //for fb cmd, we need open pre segment.if reach first one segment, send begin event
3279 int ret = _change_to_next_segment((DVR_PlaybackHandle_t)player);
hualing chen041c4092020-04-05 15:11:50 +08003280 if (ret != DVR_SUCCESS && IS_FB(player->speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003281 pthread_mutex_unlock(&player->lock);
3282 dvr_playback_pause(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003283 //send event here and pause
3284 DVR_Play_Notify_t notify;
3285 memset(&notify, 0 , sizeof(DVR_Play_Notify_t));
hualing chen87072a82020-03-12 16:20:12 +08003286 notify.event = DVR_PLAYBACK_EVENT_REACHED_BEGIN;
hualing chen2aba4022020-03-02 13:49:55 +08003287 //get play statue not here
hualing chen2932d372020-04-29 13:44:00 +08003288 _dvr_playback_sent_event(handle, DVR_PLAYBACK_EVENT_REACHED_BEGIN, &notify, DVR_TRUE);
hualing chen4b7c15d2020-04-07 16:13:48 +08003289 DVR_PB_DG(1, "*******************send begin event speed [%f] cur [%d]", player->speed, _dvr_get_cur_time(handle));
hualing chen2aba4022020-03-02 13:49:55 +08003290 //change to pause
hualing chen2aba4022020-03-02 13:49:55 +08003291 return DVR_SUCCESS;
3292 }
hualing chen2932d372020-04-29 13:44:00 +08003293 _dvr_playback_sent_transition_ok(handle, DVR_FALSE);
hualing chen2aba4022020-03-02 13:49:55 +08003294 _dvr_init_fffb_time(handle);
hualing chen4b7c15d2020-04-07 16:13:48 +08003295 DVR_PB_DG(1, "*******************send trans ok event speed [%f]", player->speed);
hualing chen2aba4022020-03-02 13:49:55 +08003296 }
3297 player->next_fffb_time =_dvr_time_getClock() + FFFB_SLEEP_TIME;
hualing chen5cbe1a62020-02-10 16:36:36 +08003298 _dvr_playback_fffb_replay(handle);
3299
3300 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003301 DVR_PB_DG(1, "unlock");
hualing chen2aba4022020-03-02 13:49:55 +08003302
hualing chen5cbe1a62020-02-10 16:36:36 +08003303 return DVR_SUCCESS;
3304}
3305
hualing chen87072a82020-03-12 16:20:12 +08003306//start replay, need get lock at extern
hualing chen2aba4022020-03-02 13:49:55 +08003307static int _dvr_playback_replay(DVR_PlaybackHandle_t handle, DVR_Bool_t trick) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003308 //
3309 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003310
3311 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003312 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003313 return DVR_FAILURE;
3314 }
3315
hualing chen5cbe1a62020-02-10 16:36:36 +08003316 //stop
hualing chen2aba4022020-03-02 13:49:55 +08003317 if (player->has_video) {
hualing chen266b9502020-04-04 17:39:39 +08003318 player->has_video = DVR_FALSE;
hualing chen21a40372021-10-29 11:07:26 +08003319 AmTsPlayer_setVideoBlackOut(player->handle, 0);
hualing chen2aba4022020-03-02 13:49:55 +08003320 AmTsPlayer_stopVideoDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003321 }
3322
3323 if (player->has_audio) {
hualing chen266b9502020-04-04 17:39:39 +08003324 player->has_audio = DVR_FALSE;
hualing chen2aba4022020-03-02 13:49:55 +08003325 AmTsPlayer_stopAudioDecoding(player->handle);
hualing chen2aba4022020-03-02 13:49:55 +08003326 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003327 //start video and audio
3328
hualing chen2aba4022020-03-02 13:49:55 +08003329 am_tsplayer_video_params vparams;
3330 am_tsplayer_audio_params aparams;
hualing chendf118dd2020-05-21 15:49:11 +08003331 am_tsplayer_audio_params adparams;
hualing chen87072a82020-03-12 16:20:12 +08003332 uint64_t segment_id = player->cur_segment_id;
hualing chen5cbe1a62020-02-10 16:36:36 +08003333
jiangfei.hanb8fbad42021-07-29 15:04:48 +08003334 memset(&vparams, 0, sizeof(vparams));
3335 memset(&aparams, 0, sizeof(aparams));
3336
hualing chen5cbe1a62020-02-10 16:36:36 +08003337 //get segment info and audio video pid fmt ;
hualing chen4b7c15d2020-04-07 16:13:48 +08003338 DVR_PB_DG(1, "into");
hualing chendf118dd2020-05-21 15:49:11 +08003339 _dvr_playback_get_playinfo(handle, segment_id, &vparams, &aparams, &adparams);
hualing chen5cbe1a62020-02-10 16:36:36 +08003340 //start audio and video
3341 if (!VALID_PID(vparams.pid) && !VALID_PID(aparams.pid)) {
hualing chen2aba4022020-03-02 13:49:55 +08003342 //audio and video pis is all invalid, return error.
hualing chen4b7c15d2020-04-07 16:13:48 +08003343 DVR_PB_DG(0, "dvr play back restart error, not found audio and video info");
hualing chen5cbe1a62020-02-10 16:36:36 +08003344 return -1;
3345 }
3346
3347 if (VALID_PID(vparams.pid)) {
3348 player->has_video = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003349 if (trick == DVR_TRUE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003350 DVR_PB_DG(1, "settrick mode at replay");
hualing chen2aba4022020-03-02 13:49:55 +08003351 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_PAUSE_NEXT);
hualing chen87072a82020-03-12 16:20:12 +08003352 }
hualing chen266b9502020-04-04 17:39:39 +08003353 else {
hualing chen2aba4022020-03-02 13:49:55 +08003354 AmTsPlayer_setTrickMode(player->handle, AV_VIDEO_TRICK_MODE_NONE);
hualing chen266b9502020-04-04 17:39:39 +08003355 }
hualing chen2aba4022020-03-02 13:49:55 +08003356 AmTsPlayer_setVideoParams(player->handle, &vparams);
hualing chen21a40372021-10-29 11:07:26 +08003357 AmTsPlayer_setVideoBlackOut(player->handle, 1);
hualing chen2aba4022020-03-02 13:49:55 +08003358 AmTsPlayer_startVideoDecoding(player->handle);
hualing chen5cbe1a62020-02-10 16:36:36 +08003359 }
hualing chena540a7e2020-03-27 16:44:05 +08003360
3361 if (IS_FAST_SPEED(player->cmd.speed.speed.speed)) {
hualing chen7a56cba2020-04-14 14:09:27 +08003362 DVR_PB_DG(1, "start fast");
hualing chen31140872020-03-25 12:29:26 +08003363 AmTsPlayer_startFast(player->handle, (float)player->cmd.speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003364 player->speed = (float)player->cmd.speed.speed.speed/100.0f;
hualing chen31140872020-03-25 12:29:26 +08003365 } else {
hualing chendf118dd2020-05-21 15:49:11 +08003366 if (VALID_PID(adparams.pid)) {
3367 player->has_ad_audio = DVR_TRUE;
3368 DVR_PB_DG(1, "start ad audio");
3369 AmTsPlayer_setADParams(player->handle, &adparams);
3370 AmTsPlayer_enableADMix(player->handle);
3371 }
hualing chen969fe7b2021-05-26 15:13:17 +08003372 if (VALID_PID(aparams.pid)) {
3373 player->has_audio = DVR_TRUE;
3374 DVR_PB_DG(1, "start audio");
3375 AmTsPlayer_setAudioParams(player->handle, &aparams);
3376 AmTsPlayer_startAudioDecoding(player->handle);
3377 }
hualing chendf118dd2020-05-21 15:49:11 +08003378
hualing chen7a56cba2020-04-14 14:09:27 +08003379 DVR_PB_DG(1, "stop fast");
hualing chen31140872020-03-25 12:29:26 +08003380 AmTsPlayer_stopFast(player->handle);
3381 player->cmd.speed.speed.speed = PLAYBACK_SPEED_X1;
3382 player->speed = (float)PLAYBACK_SPEED_X1/100.0f;
3383 }
hualing chen2aba4022020-03-02 13:49:55 +08003384 player->cmd.last_cmd = player->cmd.cur_cmd;
3385 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_START;
hualing chen2aba4022020-03-02 13:49:55 +08003386 player->cmd.state = DVR_PLAYBACK_STATE_START;
3387 player->state = DVR_PLAYBACK_STATE_START;
hualing chen5cbe1a62020-02-10 16:36:36 +08003388 return 0;
3389}
3390
3391
hualing chenb31a6c62020-01-13 17:27:00 +08003392/**\brief Set play speed
3393 * \param[in] handle playback handle
3394 * \param[in] speed playback speed
3395 * \retval DVR_SUCCESS On success
3396 * \return Error code
3397 */
hualing chen5cbe1a62020-02-10 16:36:36 +08003398int dvr_playback_set_speed(DVR_PlaybackHandle_t handle, DVR_PlaybackSpeed_t speed) {
3399
3400 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chena540a7e2020-03-27 16:44:05 +08003401
3402 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003403 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003404 return DVR_FAILURE;
3405 }
3406
hualing chen4b7c15d2020-04-07 16:13:48 +08003407 DVR_PB_DG(1, "lock func: speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003408 if (_dvr_support_speed(speed.speed.speed) == DVR_FALSE) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003409 DVR_PB_DG(1, " func: not support speed [%d]", speed.speed.speed);
hualing chena540a7e2020-03-27 16:44:05 +08003410 return DVR_FAILURE;
3411 }
hualing chenf00cdc82020-06-10 14:23:35 +08003412 if (speed.speed.speed == player->cmd.speed.speed.speed) {
3413 DVR_PB_DG(1, " func: eq speed [%d]", speed.speed.speed);
3414 return DVR_SUCCESS;
3415 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003416 pthread_mutex_lock(&player->lock);
3417 if (player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FF
3418 && player->cmd.cur_cmd != DVR_PLAYBACK_CMD_FB) {
3419 player->cmd.last_cmd = player->cmd.cur_cmd;
3420 }
hualing chene41f4372020-06-06 16:29:17 +08003421
hualing chen31140872020-03-25 12:29:26 +08003422 if (player->state != DVR_PLAYBACK_STATE_PAUSE &&
hualing chenf00cdc82020-06-10 14:23:35 +08003423 IS_KERNEL_SPEED(speed.speed.speed) ) {
3424 //case 1. not start play.only set speed
3425 if (player->state == DVR_PLAYBACK_STATE_STOP) {
3426 //only set speed.and return;
3427 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
3428 player->cmd.speed.speed = speed.speed;
3429 player->speed = (float)speed.speed.speed/(float)100;
3430 player->fffb_play = DVR_FALSE;
3431 pthread_mutex_unlock(&player->lock);
3432 return DVR_SUCCESS;
3433 }
3434 //case 2. cur speed is 100,set 200 50 25 12 .
hualing chena540a7e2020-03-27 16:44:05 +08003435 //we think x1 and x2 s1/2 s 1/4 s 1/8 is normal speed. is not ff fb.
3436 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen87072a82020-03-12 16:20:12 +08003437 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003438 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3439 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003440 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003441 AmTsPlayer_stopFast(player->handle);
3442 pthread_mutex_unlock(&player->lock);
3443 _dvr_cmd(handle, DVR_PLAYBACK_CMD_ASTART);
3444 pthread_mutex_lock(&player->lock);
3445 } else {
3446 //set play speed and if audio is start, stop audio.
3447 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003448 DVR_PB_DG(1, "fast play stop audio");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003449 AmTsPlayer_stopAudioDecoding(player->handle);
3450 player->has_audio = DVR_FALSE;
3451 }
hualing chenb96aa2c2020-04-15 14:13:53 +08003452 DVR_PB_DG(1, "start fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003453 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chena540a7e2020-03-27 16:44:05 +08003454 }
hualing chenbcada022020-04-22 14:27:01 +08003455 player->fffb_play = DVR_FALSE;
hualing chena540a7e2020-03-27 16:44:05 +08003456 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003457 player->cmd.speed.speed = speed.speed;
3458 player->speed = (float)speed.speed.speed/(float)100;
3459 pthread_mutex_unlock(&player->lock);
3460 return DVR_SUCCESS;
3461 }
hualing chen31140872020-03-25 12:29:26 +08003462 //case 3 fffb mode
3463 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3464 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3465 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003466 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003467 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003468 player->cmd.speed.speed = speed.speed;
3469 player->speed = (float)speed.speed.speed/(float)100;
3470 _dvr_playback_replay(handle, DVR_FALSE);
hualing chenbcada022020-04-22 14:27:01 +08003471 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003472 pthread_mutex_unlock(&player->lock);
3473 return DVR_SUCCESS;
3474 }
3475 }
3476 else if (player->state == DVR_PLAYBACK_STATE_PAUSE &&
hualing chena540a7e2020-03-27 16:44:05 +08003477 IS_KERNEL_SPEED(speed.speed.speed)) {
3478 //case 1. cur speed is kernel support speed,set kernel speed.
3479 if (IS_KERNEL_SPEED(player->cmd.speed.speed.speed)) {
hualing chen31140872020-03-25 12:29:26 +08003480 //if last speed is x2 or s2, we need stop fast
hualing chen2bd8a7a2020-04-02 11:31:03 +08003481 if (speed.speed.speed == PLAYBACK_SPEED_X1) {
3482 // resume audio and stop fast play
hualing chen7a56cba2020-04-14 14:09:27 +08003483 DVR_PB_DG(1, "stop fast");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003484 AmTsPlayer_stopFast(player->handle);
hualing chenf00cdc82020-06-10 14:23:35 +08003485 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_ASTART;
hualing chen2bd8a7a2020-04-02 11:31:03 +08003486 } else {
3487 //set play speed and if audio is start, stop audio.
3488 if (player->has_audio) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003489 DVR_PB_DG(1, "fast play stop audio at pause");
hualing chen2bd8a7a2020-04-02 11:31:03 +08003490 AmTsPlayer_stopAudioDecoding(player->handle);
3491 player->has_audio = DVR_FALSE;
3492 }
hualing chenf00cdc82020-06-10 14:23:35 +08003493 DVR_PB_DG(1, "start fast");
3494 AmTsPlayer_startFast(player->handle, (float)speed.speed.speed/(float)100);
hualing chen2bd8a7a2020-04-02 11:31:03 +08003495 }
hualing chena540a7e2020-03-27 16:44:05 +08003496 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003497 player->cmd.speed.speed = speed.speed;
3498 player->speed = (float)speed.speed.speed/(float)100;
hualing chenbcada022020-04-22 14:27:01 +08003499 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003500 pthread_mutex_unlock(&player->lock);
3501 return DVR_SUCCESS;
3502 }
3503 //case 2 fffb mode
3504 if (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3505 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB) {
3506 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003507 DVR_PB_DG(1, "set speed x1 s2 and replay playback");
hualing chena540a7e2020-03-27 16:44:05 +08003508 player->cmd.speed.mode = DVR_PLAYBACK_KERNEL_SUPPORT;
hualing chen31140872020-03-25 12:29:26 +08003509 player->cmd.speed.speed = speed.speed;
3510 player->speed = (float)speed.speed.speed/(float)100;
3511 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chenbcada022020-04-22 14:27:01 +08003512 player->fffb_play = DVR_FALSE;
hualing chen31140872020-03-25 12:29:26 +08003513 pthread_mutex_unlock(&player->lock);
3514 return DVR_SUCCESS;
3515 }
hualing chen31140872020-03-25 12:29:26 +08003516 }
hualing chena540a7e2020-03-27 16:44:05 +08003517 if (IS_KERNEL_SPEED(speed.speed.speed)) {
3518 //we think x1 and s2 s4 s8 x2is normal speed. is not ff fb.
hualing chenbcada022020-04-22 14:27:01 +08003519 player->fffb_play = DVR_FALSE;
hualing chen87072a82020-03-12 16:20:12 +08003520 } else {
hualing chen31140872020-03-25 12:29:26 +08003521 if ((float)speed.speed.speed > 1.0f)
hualing chen87072a82020-03-12 16:20:12 +08003522 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FF;
3523 else
3524 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_FB;
hualing chen4b7c15d2020-04-07 16:13:48 +08003525 player->fffb_play = DVR_TRUE;
3526 }
3527 DVR_Bool_t init_last_time = DVR_FALSE;
3528 if (player->speed > 0.0f && speed.speed.speed < 0) {
3529 init_last_time = DVR_TRUE;
3530 } else if (player->speed < 0.0f && speed.speed.speed > 0) {
3531 init_last_time = DVR_TRUE;
hualing chen87072a82020-03-12 16:20:12 +08003532 }
hualing chen5cbe1a62020-02-10 16:36:36 +08003533 player->cmd.speed.mode = speed.mode;
3534 player->cmd.speed.speed = speed.speed;
hualing chen31140872020-03-25 12:29:26 +08003535 player->speed = (float)speed.speed.speed/(float)100;
3536 //reset fffb time, if change speed value
hualing chen4b7c15d2020-04-07 16:13:48 +08003537 _dvr_init_fffb_t(handle);
3538 if (init_last_time == DVR_TRUE)
3539 player->last_send_time_id = UINT64_MAX;
3540
hualing chen87072a82020-03-12 16:20:12 +08003541 if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
hualing chen6d24aa92020-03-23 18:43:47 +08003542 (player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FF ||
3543 player->cmd.cur_cmd == DVR_PLAYBACK_CMD_FB)) {
hualing chen87072a82020-03-12 16:20:12 +08003544 //restart play at normal speed exit ff fb
hualing chen4b7c15d2020-04-07 16:13:48 +08003545 DVR_PB_DG(1, "set speed normal and replay playback");
hualing chen87072a82020-03-12 16:20:12 +08003546 _dvr_playback_replay(handle, DVR_FALSE);
3547 } else if (speed.speed.speed == PLAYBACK_SPEED_X1 &&
3548 (player->state == DVR_PLAYBACK_STATE_PAUSE)) {
3549 player->cmd.cur_cmd = DVR_PLAYBACK_CMD_AVRESTART;
hualing chen4b7c15d2020-04-07 16:13:48 +08003550 DVR_PB_DG(1, "set speed normal at pause state ,set cur cmd");
hualing chen87072a82020-03-12 16:20:12 +08003551 }
hualing chen4b7c15d2020-04-07 16:13:48 +08003552 DVR_PB_DG(1, "unlock speed[%f]cmd[%d]", player->speed, player->cmd.cur_cmd);
hualing chen5cbe1a62020-02-10 16:36:36 +08003553 pthread_mutex_unlock(&player->lock);
hualing chenb31a6c62020-01-13 17:27:00 +08003554 return DVR_SUCCESS;
3555}
hualing chen2932d372020-04-29 13:44:00 +08003556
hualing chenb31a6c62020-01-13 17:27:00 +08003557/**\brief Get playback status
3558 * \param[in] handle playback handle
3559 * \param[out] p_status playback status
3560 * \retval DVR_SUCCESS On success
3561 * \return Error code
3562 */
hualing chen2932d372020-04-29 13:44:00 +08003563static int _dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3564 DVR_PlaybackStatus_t *p_status, DVR_Bool_t is_lock) {
hualing chen5cbe1a62020-02-10 16:36:36 +08003565//
3566 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chen969fe7b2021-05-26 15:13:17 +08003567 uint64_t segment_id = 0LL;
hualing chena540a7e2020-03-27 16:44:05 +08003568 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003569 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003570 return DVR_FAILURE;
3571 }
hualing chen2932d372020-04-29 13:44:00 +08003572 if (is_lock ==DVR_TRUE)
3573 pthread_mutex_lock(&player->lock);
hualing chen5cbe1a62020-02-10 16:36:36 +08003574 p_status->state = player->state;
hualing chen31140872020-03-25 12:29:26 +08003575 //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 +08003576 if ((player->play_flag&DVR_PLAYBACK_STARTED_PAUSEDLIVE) == DVR_PLAYBACK_STARTED_PAUSEDLIVE &&
3577 player->state == DVR_PLAYBACK_STATE_START) {
3578 p_status->state = DVR_PLAYBACK_STATE_PAUSE;
3579 }
hualing chen041c4092020-04-05 15:11:50 +08003580
hualing chencc91e1c2020-02-28 13:26:17 +08003581 p_status->time_end = _dvr_get_end_time(handle);
hualing chen969fe7b2021-05-26 15:13:17 +08003582 p_status->time_cur = _dvr_get_play_cur_time(handle, &segment_id);
hualing chend241c7a2021-06-22 13:34:27 +08003583
3584 if (CONTROL_SPEED_ENABLE == 1) {
hualing chen7ea70a72021-09-09 11:25:13 +08003585 if (player->con_spe.ply_sta == 0) {
3586 DVR_PB_DG(1, "player dur[%u] sta[%u] cur[%d] -----reinit",
hualing chen03fd4942021-07-15 15:56:41 +08003587 player->con_spe.ply_dur,
3588 player->con_spe.ply_sta,
3589 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003590 player->con_spe.ply_sta = p_status->time_cur;
3591 } else if (player->speed == 1.0f && player->con_spe.ply_sta < p_status->time_cur) {
3592 player->con_spe.ply_dur += (p_status->time_cur - player->con_spe.ply_sta);
hualing chen7ea70a72021-09-09 11:25:13 +08003593 DVR_PB_DG(1, "player dur[%u] sta[%u] cur[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003594 player->con_spe.ply_dur,
3595 player->con_spe.ply_sta,
3596 p_status->time_cur);
hualing chend241c7a2021-06-22 13:34:27 +08003597 player->con_spe.ply_sta = p_status->time_cur;
3598 }
3599
3600 if (player->con_spe.sys_sta == 0) {
3601 player->con_spe.sys_sta = _dvr_time_getClock();
3602 } else if (player->speed == 1.0f && player->con_spe.sys_sta > 0) {
3603 player->con_spe.sys_dur += (_dvr_time_getClock() - player->con_spe.sys_sta);
3604 player->con_spe.sys_sta = _dvr_time_getClock();
3605 }
3606 }
3607
hualing chen4b7c15d2020-04-07 16:13:48 +08003608 if (player->last_send_time_id == UINT64_MAX) {
3609 player->last_send_time_id = player->cur_segment_id;
3610 player->last_cur_time = p_status->time_cur;
3611 }
3612 if (player->last_send_time_id == player->cur_segment_id) {
3613 if (player->speed > 0.0f ) {
3614 //ff
3615 if (p_status->time_cur < player->last_cur_time ) {
hualing chen03fd4942021-07-15 15:56:41 +08003616 DVR_PB_DG(1, "get ff time error last[%d]cur[%d]diff[%d]",
3617 player->last_cur_time,
3618 p_status->time_cur,
3619 player->last_cur_time - p_status->time_cur);
hualing chen4b7c15d2020-04-07 16:13:48 +08003620 p_status->time_cur = player->last_cur_time;
3621 } else {
3622 player->last_cur_time = p_status->time_cur;
3623 }
hualing chene41f4372020-06-06 16:29:17 +08003624 } else if (player->speed <= -1.0f){
hualing chen4b7c15d2020-04-07 16:13:48 +08003625 //fb
3626 if (p_status->time_cur > player->last_cur_time ) {
hualing chen03fd4942021-07-15 15:56:41 +08003627 DVR_PB_DG(1, "get fb time error last[%d]cur[%d]diff[%d]",
3628 player->last_cur_time,
3629 p_status->time_cur,
3630 p_status->time_cur - player->last_cur_time );
hualing chen4b7c15d2020-04-07 16:13:48 +08003631 p_status->time_cur = player->last_cur_time;
3632 } else {
3633 player->last_cur_time = p_status->time_cur;
3634 }
3635 }
hualing chend241c7a2021-06-22 13:34:27 +08003636 } else {
hualing chen4b7c15d2020-04-07 16:13:48 +08003637 player->last_cur_time = p_status->time_cur;
3638 }
hualing chen969fe7b2021-05-26 15:13:17 +08003639 player->last_send_time_id = segment_id;
3640 p_status->segment_id = segment_id;
hualing chen2aba4022020-03-02 13:49:55 +08003641
hualing chen5cbe1a62020-02-10 16:36:36 +08003642 memcpy(&p_status->pids, &player->cur_segment.pids, sizeof(DVR_PlaybackPids_t));
hualing chencc91e1c2020-02-28 13:26:17 +08003643 p_status->speed = player->cmd.speed.speed.speed;
hualing chen5cbe1a62020-02-10 16:36:36 +08003644 p_status->flags = player->cur_segment.flags;
hualing chen2932d372020-04-29 13:44:00 +08003645 DVR_PB_DG(1, "player real state[%s]state[%s]cur[%d]end[%d] id[%lld]playflag[%d]speed[%f]is_lock[%d]",
hualing chen03fd4942021-07-15 15:56:41 +08003646 _dvr_playback_state_toString(player->state),
3647 _dvr_playback_state_toString(p_status->state),
3648 p_status->time_cur, p_status->time_end,
3649 p_status->segment_id,player->play_flag,
3650 player->speed,
3651 is_lock);
hualing chen2932d372020-04-29 13:44:00 +08003652 if (is_lock ==DVR_TRUE)
3653 pthread_mutex_unlock(&player->lock);
3654 return DVR_SUCCESS;
3655}
3656
3657
3658/**\brief Get playback status
3659 * \param[in] handle playback handle
3660 * \param[out] p_status playback status
3661 * \retval DVR_SUCCESS On success
3662 * \return Error code
3663 */
3664int dvr_playback_get_status(DVR_PlaybackHandle_t handle,
3665 DVR_PlaybackStatus_t *p_status) {
3666//
3667 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3668
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003669 _dvr_playback_get_status(handle, p_status, DVR_TRUE);
3670
hualing chen2932d372020-04-29 13:44:00 +08003671 if (player == NULL) {
3672 DVR_PB_DG(1, "player is NULL");
3673 return DVR_FAILURE;
3674 }
Zhiqiang Han9adc9722020-11-11 18:38:10 +08003675 pthread_mutex_lock(&player->lock);
3676 if (!player->has_video && !player->has_audio)
3677 p_status->time_cur = 0;
3678 pthread_mutex_unlock(&player->lock);
hualing chen2932d372020-04-29 13:44:00 +08003679
hualing chenb31a6c62020-01-13 17:27:00 +08003680 return DVR_SUCCESS;
3681}
3682
hualing chen040df222020-01-17 13:35:02 +08003683void _dvr_dump_segment(DVR_PlaybackSegmentInfo_t *segment) {
3684 if (segment != NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003685 DVR_PB_DG(1, "segment id: %lld", segment->segment_id);
3686 DVR_PB_DG(1, "segment flag: %d", segment->flags);
3687 DVR_PB_DG(1, "segment location: [%s]", segment->location);
3688 DVR_PB_DG(1, "segment vpid: 0x%x vfmt:0x%x", segment->pids.video.pid,segment->pids.video.format);
3689 DVR_PB_DG(1, "segment apid: 0x%x afmt:0x%x", segment->pids.audio.pid,segment->pids.audio.format);
3690 DVR_PB_DG(1, "segment pcr pid: 0x%x pcr fmt:0x%x", segment->pids.pcr.pid,segment->pids.pcr.format);
3691 DVR_PB_DG(1, "segment sub apid: 0x%x sub afmt:0x%x", segment->pids.ad.pid,segment->pids.ad.format);
hualing chen86e7d482020-01-16 15:13:33 +08003692 }
hualing chenb31a6c62020-01-13 17:27:00 +08003693}
3694
hualing chen5cbe1a62020-02-10 16:36:36 +08003695int dvr_dump_segmentinfo(DVR_PlaybackHandle_t handle, uint64_t segment_id) {
hualing chen040df222020-01-17 13:35:02 +08003696 DVR_Playback_t *player = (DVR_Playback_t *) handle;
hualing chenb31a6c62020-01-13 17:27:00 +08003697
hualing chena540a7e2020-03-27 16:44:05 +08003698 if (player == NULL) {
hualing chen4b7c15d2020-04-07 16:13:48 +08003699 DVR_PB_DG(1, "player is NULL");
hualing chena540a7e2020-03-27 16:44:05 +08003700 return DVR_FAILURE;
3701 }
3702
hualing chen040df222020-01-17 13:35:02 +08003703 DVR_PlaybackSegmentInfo_t *segment;
3704 list_for_each_entry(segment, &player->segment_list, head)
hualing chen86e7d482020-01-16 15:13:33 +08003705 {
hualing chen040df222020-01-17 13:35:02 +08003706 if (segment_id >= 0) {
3707 if (segment->segment_id == segment_id) {
3708 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003709 break;
3710 }
3711 } else {
hualing chen5cbe1a62020-02-10 16:36:36 +08003712 //printf segment info
hualing chen040df222020-01-17 13:35:02 +08003713 _dvr_dump_segment(segment);
hualing chen86e7d482020-01-16 15:13:33 +08003714 }
3715 }
3716 return 0;
hualing chenb31a6c62020-01-13 17:27:00 +08003717}
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003718
pengfei.liu27cc4ec2020-04-03 16:28:16 +08003719int dvr_playback_set_decrypt_callback(DVR_PlaybackHandle_t handle, DVR_CryptoFunction_t func, void *userdata)
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003720{
3721 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3722 DVR_RETURN_IF_FALSE(player);
3723 DVR_RETURN_IF_FALSE(func);
3724
hualing chen4b7c15d2020-04-07 16:13:48 +08003725 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003726 pthread_mutex_lock(&player->lock);
3727
3728 player->dec_func = func;
3729 player->dec_userdata = userdata;
3730
3731 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003732 DVR_PB_DG(1, "out ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003733 return DVR_SUCCESS;
3734}
3735
3736int dvr_playback_set_secure_buffer(DVR_PlaybackHandle_t handle, uint8_t *p_secure_buf, uint32_t len)
3737{
3738 DVR_Playback_t *player = (DVR_Playback_t *) handle;
3739 DVR_RETURN_IF_FALSE(player);
3740 DVR_RETURN_IF_FALSE(p_secure_buf);
3741 DVR_RETURN_IF_FALSE(len);
3742
hualing chen4b7c15d2020-04-07 16:13:48 +08003743 DVR_PB_DG(1, "in ");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003744 pthread_mutex_lock(&player->lock);
3745
3746 player->is_secure_mode = 1;
3747 player->secure_buffer = p_secure_buf;
3748 player->secure_buffer_size = len;
3749
3750 pthread_mutex_unlock(&player->lock);
hualing chen4b7c15d2020-04-07 16:13:48 +08003751 DVR_PB_DG(1, "out");
pengfei.liu07ddc8a2020-03-24 23:36:53 +08003752 return DVR_SUCCESS;
3753}