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