1 /*
2  * Copyright (C) 2023 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 #define MEDIA_PIPELINE
16 
17 #define HST_LOG_TAG "AudioSinkFilter"
18 #include "audio_sink_filter.h"
19 #include "common/log.h"
20 #include "osal/utils/util.h"
21 #include "osal/utils/dump_buffer.h"
22 #include "filter/filter_factory.h"
23 #include "media_core.h"
24 #include "parameters.h"
25 
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "AudioSinkFilter" };
28 }
29 
30 namespace OHOS {
31 namespace Media {
32 namespace Pipeline {
33 using namespace Plugins;
34 
35 static AutoRegisterFilter<AudioSinkFilter> g_registerAudioSinkFilter("builtin.player.audiosink",
__anon0ae3585f0202(const std::string& name, const FilterType type) 36     FilterType::FILTERTYPE_ASINK, [](const std::string& name, const FilterType type) {
37         return std::make_shared<AudioSinkFilter>(name, FilterType::FILTERTYPE_ASINK);
38     });
39 
40 static const bool IS_FILTER_ASYNC = system::GetParameter("persist.media_service.async_filter", "1") == "1";
41 
AVBufferAvailableListener(std::shared_ptr<AudioSinkFilter> audioSinkFilter)42 AudioSinkFilter::AVBufferAvailableListener::AVBufferAvailableListener(std::shared_ptr<AudioSinkFilter> audioSinkFilter)
43 {
44     audioSinkFilter_ = audioSinkFilter;
45 }
46 
OnBufferAvailable()47 void AudioSinkFilter::AVBufferAvailableListener::OnBufferAvailable()
48 {
49     if (auto sink = audioSinkFilter_.lock()) {
50         sink->ProcessInputBuffer();
51     } else {
52         MEDIA_LOG_I("invalid audioSink");
53     }
54 }
55 
AudioSinkFilter(const std::string & name,FilterType filterType)56 AudioSinkFilter::AudioSinkFilter(const std::string& name, FilterType filterType)
57     : Filter(name, FilterType::FILTERTYPE_ASINK, IS_FILTER_ASYNC)
58 {
59     filterType_ = filterType;
60     audioSink_ = std::make_shared<AudioSink>();
61     MEDIA_LOG_I("audio sink ctor called");
62 }
63 
~AudioSinkFilter()64 AudioSinkFilter::~AudioSinkFilter()
65 {
66     MEDIA_LOG_I("dtor called");
67 }
68 
Init(const std::shared_ptr<EventReceiver> & receiver,const std::shared_ptr<FilterCallback> & callback)69 void AudioSinkFilter::Init(const std::shared_ptr<EventReceiver> &receiver,
70                            const std::shared_ptr<FilterCallback> &callback)
71 {
72     Filter::Init(receiver, callback);
73     eventReceiver_ = receiver;
74     filterCallback_ = callback;
75     MEDIA_LOG_I("audio sink Init called");
76 }
77 
DoInitAfterLink()78 Status AudioSinkFilter::DoInitAfterLink()
79 {
80     audioSink_->SetParameter(globalMeta_);
81     Status ret = audioSink_->Init(trackMeta_, eventReceiver_);
82     audioSink_->SetEventReceiver(eventReceiver_);
83     audioSink_->SetThreadGroupId(groupId_);
84     return ret;
85 }
86 
DoPrepare()87 Status AudioSinkFilter::DoPrepare()
88 {
89     audioSink_->Prepare();
90     inputBufferQueueConsumer_ = audioSink_->GetBufferQueueConsumer();
91     sptr<IConsumerListener> listener = new AVBufferAvailableListener(shared_from_this());
92     inputBufferQueueConsumer_->SetBufferAvailableListener(listener);
93     if (onLinkedResultCallback_ != nullptr) {
94         onLinkedResultCallback_->OnLinkedResult(audioSink_->GetBufferQueueProducer(), trackMeta_);
95     }
96     state_ = FilterState::READY;
97     return Status::OK;
98 }
99 
DoStart()100 Status AudioSinkFilter::DoStart()
101 {
102     MEDIA_LOG_I("start called");
103     if (state_ == FilterState::RUNNING || isCancelStart_) {
104         return Status::OK;
105     }
106     if (state_ != FilterState::READY && state_ != FilterState::PAUSED) {
107         MEDIA_LOG_W("sink is not ready when start, state: " PUBLIC_LOG_D32, state_);
108         return Status::ERROR_INVALID_OPERATION;
109     }
110     forceUpdateTimeAnchorNextTime_ = true;
111     auto err = audioSink_->Start();
112     if (err != Status::OK) {
113         eventReceiver_->OnEvent({"audio_sink_filter", EventType::EVENT_ERROR, MSERR_AUD_RENDER_FAILED});
114         return err;
115     }
116     state_ = FilterState::RUNNING;
117     frameCnt_ = 0;
118     return err;
119 }
120 
DoPause()121 Status AudioSinkFilter::DoPause()
122 {
123     MEDIA_LOG_I("audio sink filter pause start");
124     if (state_ == FilterState::PAUSED || state_ == FilterState::STOPPED) {
125         return Status::OK;
126     }
127     // only worked when state is working
128     if (state_ != FilterState::READY && state_ != FilterState::RUNNING) {
129         MEDIA_LOG_W("audio sink cannot pause when not working");
130         return Status::ERROR_INVALID_OPERATION;
131     }
132     state_ = FilterState::PAUSED;
133     auto err = audioSink_->Pause();
134     MEDIA_LOG_D("audio sink filter pause end");
135     return err;
136 }
137 
DoResume()138 Status AudioSinkFilter::DoResume()
139 {
140     MEDIA_LOG_I("audio sink filter resume");
141     // only worked when state is paused
142     if (state_ == FilterState::PAUSED) {
143         forceUpdateTimeAnchorNextTime_ = true;
144         state_ = FilterState::RUNNING;
145         if (frameCnt_ > 0) {
146             frameCnt_ = 0;
147         }
148         return audioSink_->Resume();
149     }
150     return Status::OK;
151 }
152 
DoFlush()153 Status AudioSinkFilter::DoFlush()
154 {
155     MEDIA_LOG_I("audio sink flush start");
156     if (audioSink_ != nullptr) {
157         audioSink_->Flush();
158     }
159     MEDIA_LOG_I("audio sink flush end");
160     return Status::OK;
161 }
162 
DoStop()163 Status AudioSinkFilter::DoStop()
164 {
165     MEDIA_LOG_I("audio sink stop start");
166     if (audioSink_ != nullptr) {
167         audioSink_->Stop();
168     }
169     state_ = FilterState::STOPPED;
170     MEDIA_LOG_I("audio sink stop finish");
171     return Status::OK;
172 }
173 
DoRelease()174 Status AudioSinkFilter::DoRelease()
175 {
176     return audioSink_->Release();
177 }
178 
DoSetPlayRange(int64_t start,int64_t end)179 Status AudioSinkFilter::DoSetPlayRange(int64_t start, int64_t end)
180 {
181     MEDIA_LOG_I("DoSetPlayRange enter.");
182     audioSink_->SetPlayRange(start, end);
183     return Status::OK;
184 }
185 
DoProcessInputBuffer(int recvArg,bool dropFrame)186 Status AudioSinkFilter::DoProcessInputBuffer(int recvArg, bool dropFrame)
187 {
188     audioSink_->DrainOutputBuffer(dropFrame);
189     return Status::OK;
190 }
191 
SetVolumeWithRamp(float targetVolume,int32_t duration)192 int32_t AudioSinkFilter::SetVolumeWithRamp(float targetVolume, int32_t duration)
193 {
194     MEDIA_LOG_I("start Flush");
195     return audioSink_->SetVolumeWithRamp(targetVolume, duration);
196 }
197 
SetParameter(const std::shared_ptr<Meta> & meta)198 void AudioSinkFilter::SetParameter(const std::shared_ptr<Meta>& meta)
199 {
200     globalMeta_ = meta;
201     audioSink_->SetParameter(meta);
202 }
203 
GetParameter(std::shared_ptr<Meta> & meta)204 void AudioSinkFilter::GetParameter(std::shared_ptr<Meta>& meta)
205 {
206     audioSink_->GetParameter(meta);
207 }
208 
OnLinked(StreamType inType,const std::shared_ptr<Meta> & meta,const std::shared_ptr<FilterLinkCallback> & callback)209 Status AudioSinkFilter::OnLinked(StreamType inType, const std::shared_ptr<Meta>& meta,
210     const std::shared_ptr<FilterLinkCallback>& callback)
211 {
212     Plugins::AudioRenderInfo audioRenderInfo;
213     int32_t interruptMode;
214     if (globalMeta_ != nullptr && meta != nullptr) {
215         if (globalMeta_->GetData(OHOS::Media::Tag::AUDIO_RENDER_INFO, audioRenderInfo)) {
216             meta->SetData(Tag::AUDIO_RENDER_INFO, audioRenderInfo);
217         }
218         if (globalMeta_->GetData(OHOS::Media::Tag::AUDIO_INTERRUPT_MODE, interruptMode)) {
219             meta->SetData(Tag::AUDIO_INTERRUPT_MODE, interruptMode);
220         }
221     }
222     trackMeta_ = meta;
223     onLinkedResultCallback_ = callback;
224     return Filter::OnLinked(inType, meta, callback);
225 }
226 
SetVolume(float volume)227 Status AudioSinkFilter::SetVolume(float volume)
228 {
229     FALSE_RETURN_V(audioSink_ != nullptr, Status::ERROR_INVALID_STATE);
230     volume_ = volume;
231     if (volume_ < 0) {
232         MEDIA_LOG_D("No need to set volume because upper layer hasn't set it.");
233         return Status::ERROR_INVALID_PARAMETER;
234     }
235     auto err = audioSink_->SetVolume(volume);
236     MEDIA_LOG_I("set volume " PUBLIC_LOG ".3f", volume);
237     return err;
238 }
239 
SetSyncCenter(std::shared_ptr<MediaSyncManager> syncCenter)240 void AudioSinkFilter::SetSyncCenter(std::shared_ptr<MediaSyncManager> syncCenter)
241 {
242     FALSE_RETURN(audioSink_ != nullptr);
243     audioSink_->SetSyncCenter(syncCenter);
244 }
245 
SetSpeed(float speed)246 Status AudioSinkFilter::SetSpeed(float speed)
247 {
248     MEDIA_LOG_I("AudioSinkFilter::SetSpeed in, speed is " PUBLIC_LOG ".3f", speed);
249     FALSE_RETURN_V(audioSink_ != nullptr, Status::ERROR_INVALID_STATE);
250     if (speed < 0) {
251         MEDIA_LOG_E("AudioSinkFilter::SetSpeed speed is less than 0.");
252         return Status::ERROR_INVALID_PARAMETER;
253     }
254     Status res = audioSink_->SetSpeed(speed);
255     MEDIA_LOG_I("AudioSinkFilter::SetSpeed out");
256     return res;
257 }
258 
SetAudioEffectMode(int32_t effectMode)259 Status AudioSinkFilter::SetAudioEffectMode(int32_t effectMode)
260 {
261     MEDIA_LOG_I("AudioSinkFilter::SetAudioEffectMode in");
262     FALSE_RETURN_V(audioSink_ != nullptr, Status::ERROR_INVALID_STATE);
263 
264     Status res = audioSink_->SetAudioEffectMode(effectMode);
265     return res;
266 }
267 
GetAudioEffectMode(int32_t & effectMode)268 Status AudioSinkFilter::GetAudioEffectMode(int32_t &effectMode)
269 {
270     MEDIA_LOG_I("AudioSinkFilter::GetAudioEffectMode in");
271     FALSE_RETURN_V(audioSink_ != nullptr, Status::ERROR_INVALID_STATE);
272     Status res = audioSink_->GetAudioEffectMode(effectMode);
273     return res;
274 }
275 
SetIsTransitent(bool isTransitent)276 Status AudioSinkFilter::SetIsTransitent(bool isTransitent)
277 {
278     MEDIA_LOG_I("AudioSinkFilter::SetIsTransitent in");
279     FALSE_RETURN_V(audioSink_ != nullptr, Status::ERROR_INVALID_STATE);
280     return audioSink_->SetIsTransitent(isTransitent);
281 }
282 
ChangeTrack(std::shared_ptr<Meta> & meta)283 Status AudioSinkFilter::ChangeTrack(std::shared_ptr<Meta>& meta)
284 {
285     MEDIA_LOG_I("AudioSinkFilter::ChangeTrack in");
286     FALSE_RETURN_V(audioSink_ != nullptr, Status::ERROR_INVALID_STATE);
287     return audioSink_->ChangeTrack(meta, eventReceiver_);
288 }
289 
OnUpdated(StreamType inType,const std::shared_ptr<Meta> & meta,const std::shared_ptr<FilterLinkCallback> & callback)290 Status AudioSinkFilter::OnUpdated(StreamType inType, const std::shared_ptr<Meta>& meta,
291     const std::shared_ptr<FilterLinkCallback>& callback)
292 {
293     return Filter::OnUpdated(inType, meta, callback);
294 }
295 
OnUnLinked(StreamType inType,const std::shared_ptr<FilterLinkCallback> & callback)296 Status AudioSinkFilter::OnUnLinked(StreamType inType, const std::shared_ptr<FilterLinkCallback>& callback)
297 {
298     return Filter::OnUnLinked(inType, callback);
299 }
300 
SetMuted(bool isMuted)301 Status AudioSinkFilter::SetMuted(bool isMuted)
302 {
303     MEDIA_LOG_D("SetMuted");
304     FALSE_RETURN_V(audioSink_ != nullptr, Status::ERROR_INVALID_STATE);
305     return audioSink_->SetMuted(isMuted);
306 }
307 
SetSeekTime(int64_t seekTime)308 Status AudioSinkFilter::SetSeekTime(int64_t seekTime)
309 {
310     MEDIA_LOG_D("SetSeekTime");
311     FALSE_RETURN_V(audioSink_ != nullptr, Status::ERROR_INVALID_STATE);
312     return audioSink_->SetSeekTime(seekTime);
313 }
GetMaxAmplitude()314 float AudioSinkFilter::GetMaxAmplitude()
315 {
316     FALSE_RETURN_V(audioSink_ != nullptr, 0.0f);
317     return audioSink_->GetMaxAmplitude();
318 }
319 
SetMaxAmplitudeCbStatus(bool status)320 int32_t AudioSinkFilter::SetMaxAmplitudeCbStatus(bool status)
321 {
322     FALSE_RETURN_V(audioSink_ != nullptr, MSERR_INVALID_VAL);
323     return audioSink_->SetMaxAmplitudeCbStatus(status);
324 }
325 
SetIsCancelStart(bool isCancelStart)326 void AudioSinkFilter::SetIsCancelStart(bool isCancelStart)
327 {
328     isCancelStart_ = isCancelStart;
329 }
330 } // namespace Pipeline
331 } // namespace Media
332 } // namespace OHOS
333