1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "player_sink_manager.h"
17 #include <sys/time.h>
18 #include "media_log.h"
19
20 namespace OHOS {
21 namespace Media {
22
23 #define CHECK_FAILED_RETURN(value, target, ret, printfString) \
24 do { \
25 if ((value) != (target)) { \
26 MEDIA_ERR_LOG(" %s ", (printfString != nullptr) ? (printfString) : " "); \
27 return (ret); \
28 } \
29 } while (0)
30
SinkManager()31 SinkManager::SinkManager()
32 : speed_(1.0f), direction_(TPLAY_DIRECT_BUTT),
33 leftVolume_(0.0f), rightVolume_(0.0f), paused_(false), started_(false),
34 pauseAfterPlay_(false), audioSinkNum_(0),
35 videoSinkNum_(0), sync_(nullptr), recieveAudioEos_(false), recieveVideoEos_(false)
36 {
37 callBack_.onEventCallback = nullptr;
38 callBack_.priv = nullptr;
39 for (int32_t i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
40 audioSinkInfo_[i].trackId = -1;
41 audioSinkInfo_[i].sink = nullptr;
42 videoSinkInfo_[i].trackId = -1;
43 videoSinkInfo_[i].sink = nullptr;
44 }
45 }
46
~SinkManager()47 SinkManager::~SinkManager()
48 {
49 }
50
AddNewSink(SinkAttr & attr)51 int32_t SinkManager::AddNewSink(SinkAttr &attr)
52 {
53 int32_t ret;
54 if (sync_ == nullptr) {
55 sync_ = std::make_shared<PlayerSync>();
56 }
57 if (sync_ != nullptr) {
58 sync_->Init();
59 }
60
61 if (attr.sinkType == SINK_TYPE_AUDIO) {
62 if (audioSinkNum_ >= MAX_PIPELINE_SINK_NUM) {
63 return -1;
64 }
65 audioSinkInfo_[audioSinkNum_].trackId = attr.trackId;
66 audioSinkInfo_[audioSinkNum_].sink = std::make_shared<AudioSink>();
67 ret = audioSinkInfo_[audioSinkNum_].sink->Init(attr);
68 if (ret != 0) {
69 audioSinkInfo_[audioSinkNum_].sink.reset();
70 audioSinkInfo_[audioSinkNum_].sink = nullptr;
71 MEDIA_ERR_LOG("audio sink Init failed:%d", ret);
72 return -1;
73 }
74 audioSinkInfo_[audioSinkNum_].sink->SetSync(sync_.get());
75 audioSinkNum_++;
76 } else if (attr.sinkType == SINK_TYPE_VIDEO) {
77 if (videoSinkNum_ >= MAX_PIPELINE_SINK_NUM) {
78 return -1;
79 }
80 videoSinkInfo_[videoSinkNum_].trackId = attr.trackId;
81 videoSinkInfo_[videoSinkNum_].sink = std::make_shared<VideoSink>();
82 ret = videoSinkInfo_[videoSinkNum_].sink->Init(attr);
83 if (ret != 0) {
84 videoSinkInfo_[videoSinkNum_].sink.reset();
85 videoSinkInfo_[videoSinkNum_].sink = nullptr;
86 MEDIA_ERR_LOG("video sink Init failed:%d", ret);
87 return -1;
88 }
89 videoSinkInfo_[videoSinkNum_].sink->SetSync(sync_.get());
90 videoSinkNum_++;
91 }
92 return 0;
93 }
94
95
Start(void)96 int32_t SinkManager::Start(void)
97 {
98 if (videoSinkInfo_[0].sink != nullptr) {
99 int32_t ret = videoSinkInfo_[0].sink->Start();
100 CHECK_FAILED_RETURN(ret, SINK_SUCCESS, ret, "videoSinkInfo_ start failed");
101 if (sync_ != nullptr) {
102 sync_->Start(SYNC_CHN_VID);
103 }
104 }
105
106 if (audioSinkInfo_[0].sink != nullptr) {
107 int32_t ret = audioSinkInfo_[0].sink->Start();
108 CHECK_FAILED_RETURN(ret, SINK_SUCCESS, ret, "audioSinkInfo_ start failed");
109 if (sync_ != nullptr) {
110 sync_->Start(SYNC_CHN_AUD);
111 }
112 }
113
114 started_ = true;
115 return HI_SUCCESS;
116 }
117
Flush(void)118 int32_t SinkManager::Flush(void)
119 {
120 int32_t i;
121 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
122 if (videoSinkInfo_[i].sink != nullptr) {
123 videoSinkInfo_[i].sink->Flush();
124 }
125 }
126
127 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
128 if (audioSinkInfo_[i].sink != nullptr) {
129 audioSinkInfo_[i].sink->Flush();
130 }
131 }
132 return 0;
133 }
134
Reset(void)135 int32_t SinkManager::Reset(void)
136 {
137 int32_t i;
138 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
139 if (videoSinkInfo_[i].sink != nullptr) {
140 videoSinkInfo_[i].sink->Reset();
141 }
142 }
143
144 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
145 if (audioSinkInfo_[i].sink != nullptr) {
146 audioSinkInfo_[i].sink->Reset();
147 }
148 }
149
150 recieveAudioEos_ = false;
151 recieveVideoEos_ = false;
152 if (sync_ != nullptr) {
153 sync_->Reset(SYNC_CHN_VID);
154 sync_->Reset(SYNC_CHN_AUD);
155 }
156
157 return 0;
158 }
159
Pause()160 int32_t SinkManager::Pause()
161 {
162 if (paused_) {
163 MEDIA_WARNING_LOG("sink already paused");
164 return HI_SUCCESS;
165 }
166 if (!started_) {
167 MEDIA_ERR_LOG("not in running");
168 return -1;
169 }
170
171 if (audioSinkInfo_[0].sink != nullptr) {
172 audioSinkInfo_[0].sink->Pause();
173 }
174 if (videoSinkInfo_[0].sink != nullptr) {
175 videoSinkInfo_[0].sink->Pause();
176 }
177
178 if ((audioSinkInfo_[0].sink == nullptr || recieveAudioEos_ || speed_ != 1.0) &&
179 (sync_ != nullptr)) {
180 sync_->Reset(SYNC_CHN_VID);
181 }
182 if ((audioSinkInfo_[0].sink != nullptr) && (sync_ != nullptr)) {
183 sync_->Reset(SYNC_CHN_AUD);
184 }
185 paused_ = true;
186 return 0;
187 }
188
Resume()189 int32_t SinkManager::Resume()
190 {
191 if (!paused_) {
192 MEDIA_WARNING_LOG("sink not in pause");
193 return HI_FAILURE;
194 }
195
196 if (audioSinkInfo_[0].sink != nullptr) {
197 audioSinkInfo_[0].sink->Resume();
198 }
199 if (videoSinkInfo_[0].sink != nullptr) {
200 videoSinkInfo_[0].sink->Resume();
201 }
202
203 pauseAfterPlay_ = false;
204 paused_ = false;
205
206 return 0;
207 }
208
TplayToNormal(void)209 int32_t SinkManager::TplayToNormal(void)
210 {
211 int32_t ret;
212
213 ret = Pause();
214 if (ret != 0) {
215 MEDIA_ERR_LOG("m_render pause failed Ret: %d", ret);
216 return ret;
217 }
218 ret = sync_->Resume();
219 if (ret != HI_SUCCESS) {
220 MEDIA_ERR_LOG("m_syncHdl Resume failed Ret: %d", ret);
221 return ret;
222 }
223
224 ret = sync_->Reset(SYNC_CHN_VID);
225 if (ret != HI_SUCCESS) {
226 MEDIA_ERR_LOG("m_syncHdl Reset vid Ret: %d", ret);
227 return ret;
228 }
229 ret = sync_->Reset(SYNC_CHN_AUD);
230 if (ret != HI_SUCCESS) {
231 MEDIA_ERR_LOG("m_syncHdl Reset aud Ret: %d", ret);
232 return ret;
233 }
234 ret = Resume();
235 if (ret != HI_SUCCESS) {
236 MEDIA_ERR_LOG("m_render resume failed Ret: %d", ret);
237 return ret;
238 }
239 speed_ = 1.0;
240 direction_ = TPLAY_DIRECT_BUTT;
241 return 0;
242 }
243
Tplay(float speed,TplayDirect tplayDirect)244 int32_t SinkManager::Tplay(float speed, TplayDirect tplayDirect)
245 {
246 int32_t ret;
247
248 ret = Pause();
249 if (ret != 0) {
250 MEDIA_ERR_LOG("m_render pause failed Ret: %d", ret);
251 return ret;
252 }
253 ret = sync_->SetSpeed(speed, tplayDirect);
254 if (ret != 0) {
255 MEDIA_ERR_LOG("m_syncHdl TPlay Ret: %d", ret);
256 return ret;
257 }
258
259 ret = sync_->Reset(SYNC_CHN_VID);
260 if (ret != HI_SUCCESS) {
261 MEDIA_ERR_LOG("m_syncHdl Reset vid Ret: %d", ret);
262 return ret;
263 }
264
265 ret = Resume();
266 if (ret != 0) {
267 MEDIA_ERR_LOG("m_render resume failed Ret: %d", ret);
268 return ret;
269 }
270 speed_ = speed;
271 direction_ = tplayDirect;
272 return 0;
273 }
274
SetSpeed(float speed,TplayDirect tplayDirect)275 int32_t SinkManager::SetSpeed(float speed, TplayDirect tplayDirect)
276 {
277 if (speed_ == speed && tplayDirect == direction_) {
278 return 0;
279 }
280 if (speed == 1.0) { /* tplay ---> normal */
281 TplayToNormal();
282 } else { /* tplay / ormal ---> tplay */
283 Tplay(speed, tplayDirect);
284 }
285 return 0;
286 }
287
GetSpeed(float & speed,TplayDirect & tplayDirect)288 int32_t SinkManager::GetSpeed(float &speed, TplayDirect &tplayDirect)
289 {
290 speed = speed_;
291 tplayDirect = direction_;
292 return 0;
293 }
294
RenderFrame(PlayerBufferInfo & frame,CodecType type)295 int32_t SinkManager::RenderFrame(PlayerBufferInfo &frame, CodecType type)
296 {
297 int ret;
298 if (type == AUDIO_DECODER) {
299 ret = audioSinkInfo_[0].sink->RenderFrame(frame);
300 } else if (type == VIDEO_DECODER) {
301 ret = videoSinkInfo_[0].sink->RenderFrame(frame);
302 } else {
303 MEDIA_ERR_LOG("RenderFrame not support frame type: %d", type);
304 ret = -1;
305 }
306 return ret;
307 }
308
SetRenderMode(RenderMode mode)309 void SinkManager::SetRenderMode(RenderMode mode)
310 {
311 if (videoSinkInfo_[0].sink != nullptr) {
312 videoSinkInfo_[0].sink->SetRenderMode(mode);
313 }
314 if (audioSinkInfo_[0].sink != nullptr) {
315 audioSinkInfo_[0].sink->SetRenderMode(mode);
316 }
317 pauseAfterPlay_ = (mode == RENDER_MODE_PAUSE_AFTER_PLAY) ? true : false;
318 }
319
SetVolume(float left,float right)320 int32_t SinkManager::SetVolume(float left, float right)
321 {
322 int i;
323
324 leftVolume_ = left;
325 rightVolume_ = right;
326 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
327 if (audioSinkInfo_[i].sink != nullptr) {
328 audioSinkInfo_[i].sink->SetVolume(left, right);
329 }
330 }
331 return HI_SUCCESS;
332 }
333
GetVolume(float & left,float & right)334 int32_t SinkManager::GetVolume(float &left, float &right)
335 {
336 left = leftVolume_;
337 right = rightVolume_;
338 return 0;
339 }
340
341
Stop(void)342 int32_t SinkManager::Stop(void)
343 {
344 int32_t i;
345
346 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
347 if (audioSinkInfo_[i].sink != nullptr) {
348 audioSinkInfo_[i].sink->Stop();
349 }
350 }
351 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
352 if (videoSinkInfo_[i].sink != nullptr) {
353 videoSinkInfo_[i].sink->Stop();
354 }
355 }
356 if (sync_ != nullptr) {
357 sync_->Stop(SYNC_CHN_VID);
358 sync_->Stop(SYNC_CHN_AUD);
359 }
360 started_ = false;
361 return 0;
362 }
363
RegisterCallBack(PlayEventCallback & callback)364 int32_t SinkManager::RegisterCallBack(PlayEventCallback &callback)
365 {
366 int32_t i;
367 callBack_ = callback;
368 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
369 if (audioSinkInfo_[i].sink != nullptr) {
370 audioSinkInfo_[i].sink->RegisterCallBack(callback);
371 }
372 }
373 for (i = 0; i < MAX_PIPELINE_SINK_NUM; i++) {
374 if (videoSinkInfo_[i].sink != nullptr) {
375 videoSinkInfo_[i].sink->RegisterCallBack(callback);
376 }
377 }
378 return 0;
379 }
380
GetStatus(PlayerStreamInfo & streamInfo)381 int32_t SinkManager::GetStatus(PlayerStreamInfo &streamInfo)
382 {
383 if (audioSinkInfo_[0].sink != nullptr) {
384 AudioSinkStatus audioStatus;
385 audioSinkInfo_[0].sink->GetStatus(audioStatus);
386 streamInfo.avStatus.audFrameCount = audioStatus.audFrameCount;
387 }
388 if (videoSinkInfo_[0].sink != nullptr) {
389 VideoSinkStatus videoStatus;
390 videoSinkInfo_[0].sink->GetStatus(videoStatus);
391 streamInfo.avStatus.vidFrameCount = videoStatus.vidFrameCount;
392 streamInfo.videoInfo.decHeight = videoStatus.decHeight;
393 streamInfo.videoInfo.decWidth = videoStatus.decWidth;
394 streamInfo.videoInfo.fpsDecimal = videoStatus.fpsDecimal;
395 streamInfo.videoInfo.fpsInteger = videoStatus.fpsInteger;
396 }
397
398 streamInfo.avStatus.syncStatus.lastAudPts = AV_INVALID_PTS;
399 streamInfo.avStatus.syncStatus.lastVidPts = AV_INVALID_PTS;
400 if (sync_ != nullptr) {
401 sync_->GetStatus(streamInfo.avStatus.syncStatus);
402 }
403 return 0;
404 }
405
SetParam(const char * key,dataType type,void * value)406 int32_t SinkManager::SetParam(const char *key, dataType type, void* value)
407 {
408 return 0;
409 }
410
GetParam(const char * key,dataType * type,void ** value,int32_t * size)411 int32_t SinkManager::GetParam(const char *key, dataType *type, void** value, int32_t *size)
412 {
413 return 0;
414 }
415
RenderEos(bool isAudio)416 void SinkManager::RenderEos(bool isAudio)
417 {
418 if (audioSinkInfo_[0].sink != nullptr && isAudio == true) {
419 audioSinkInfo_[0].sink->RenderEos();
420 recieveAudioEos_ = true;
421 }
422 if (videoSinkInfo_[0].sink != nullptr && isAudio == false) {
423 videoSinkInfo_[0].sink->RenderEos();
424 recieveVideoEos_ = true;
425 }
426 }
427
DequeReleaseFrame(bool audioSink,PlayerBufferInfo & frame)428 int32_t SinkManager::DequeReleaseFrame(bool audioSink, PlayerBufferInfo &frame)
429 {
430 if (audioSinkInfo_[0].sink != nullptr && audioSink == true) {
431 return audioSinkInfo_[0].sink->DequeReleaseFrame(frame);
432 }
433 if (videoSinkInfo_[0].sink != nullptr && audioSink == false) {
434 return videoSinkInfo_[0].sink->DequeReleaseFrame(frame);
435 }
436 return -1;
437 }
438
GetRenderPosition(int64_t & position)439 void SinkManager::GetRenderPosition(int64_t &position)
440 {
441 if (audioSinkInfo_[0].sink == nullptr && videoSinkInfo_[0].sink == nullptr) {
442 return;
443 }
444
445 /* use video position, if tplay or no audio */
446 if ((speed_ != 1.0 && videoSinkInfo_[0].sink != nullptr) || audioSinkInfo_[0].sink == nullptr) {
447 videoSinkInfo_[0].sink->GetRenderPosition(position);
448 return;
449 }
450 /* audio not recieve eos, use audio position */
451 if (!recieveAudioEos_ || videoSinkInfo_[0].sink == nullptr) {
452 audioSinkInfo_[0].sink->GetRenderPosition(position);
453 return;
454 }
455
456 /* use the max position of audio and video sink, if have received audio eos */
457 int64_t audioPos;
458 int64_t videoPos;
459 audioSinkInfo_[0].sink->GetRenderPosition(audioPos);
460 videoSinkInfo_[0].sink->GetRenderPosition(videoPos);
461 position = (audioPos >= videoPos) ? audioPos : videoPos;
462 }
463
SetAudioStreamType(int32_t & type)464 void SinkManager::SetAudioStreamType(int32_t &type)
465 {
466 if (audioSinkInfo_[0].sink == nullptr) {
467 MEDIA_ERR_LOG("audioSinkInfo_[0].sink is null");
468 return;
469 }
470 audioSinkInfo_[0].sink->SetAudioStreamType(type);
471 }
472 }
473 }
474