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