1 /*
2 * Copyright (c) 2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "HpaeRendererStreamImpl"
17 #endif
18
19 #ifdef FEATURE_POWER_MANAGER
20 #include "power_mgr_client.h"
21 #endif
22
23 #include "hpae_renderer_stream_impl.h"
24 #include "sink/i_audio_render_sink.h"
25 #include "manager/hdi_adapter_manager.h"
26 #include <chrono>
27 #include <thread>
28 #include "safe_map.h"
29 #include "audio_errors.h"
30 #include "audio_utils.h"
31 #include "i_hpae_manager.h"
32 #include "audio_stream_info.h"
33 #include "audio_effect_map.h"
34 #include "down_mixer.h"
35 #include "policy_handler.h"
36 #include "audio_engine_log.h"
37
38 using namespace OHOS::AudioStandard::HPAE;
39 namespace OHOS {
40 namespace AudioStandard {
41
42 static constexpr int32_t MIN_BUFFER_SIZE = 2;
43 static constexpr uint64_t FRAME_LEN_10MS = 10;
44 static constexpr uint64_t FRAME_LEN_20MS = 20;
45 static constexpr uint64_t FRAME_LEN_40MS = 40;
46 static const std::string DEVICE_CLASS_OFFLOAD = "offload";
47 static const std::string DEVICE_CLASS_REMOTE_OFFLOAD = "remote_offload";
48 static std::shared_ptr<IAudioRenderSink> GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId);
49 static inline FadeType GetFadeType(uint64_t expectedPlaybackDurationMs);
HpaeRendererStreamImpl(AudioProcessConfig processConfig,bool isMoveAble,bool isCallbackMode)50 HpaeRendererStreamImpl::HpaeRendererStreamImpl(AudioProcessConfig processConfig, bool isMoveAble, bool isCallbackMode)
51 {
52 processConfig_ = processConfig;
53 spanSizeInFrame_ = processConfig.streamInfo.samplingRate == SAMPLE_RATE_11025 ?
54 FRAME_LEN_40MS * static_cast<uint32_t>(processConfig.streamInfo.samplingRate) / AUDIO_MS_PER_S :
55 FRAME_LEN_20MS * static_cast<uint32_t>(processConfig.streamInfo.samplingRate) / AUDIO_MS_PER_S;
56 byteSizePerFrame_ = (processConfig.streamInfo.channels *
57 static_cast<size_t>(GetSizeFromFormat(processConfig.streamInfo.format)));
58 minBufferSize_ = MIN_BUFFER_SIZE * byteSizePerFrame_ * spanSizeInFrame_;
59 if (byteSizePerFrame_ == 0 || processConfig.streamInfo.samplingRate == 0) {
60 expectedPlaybackDurationMs_ = 0;
61 } else {
62 expectedPlaybackDurationMs_ =
63 (processConfig.rendererInfo.expectedPlaybackDurationBytes * AUDIO_MS_PER_S / byteSizePerFrame_) /
64 processConfig.streamInfo.samplingRate;
65 }
66 isCallbackMode_ = isCallbackMode;
67 isMoveAble_ = isMoveAble;
68 if (!isCallbackMode_) {
69 InitRingBuffer();
70 }
71 }
~HpaeRendererStreamImpl()72 HpaeRendererStreamImpl::~HpaeRendererStreamImpl()
73 {
74 AUDIO_INFO_LOG("~HpaeRendererStreamImpl [%{public}u]", streamIndex_);
75 if (dumpEnqueueIn_ != nullptr) {
76 DumpFileUtil::CloseDumpFile(&dumpEnqueueIn_);
77 }
78 }
79
InitParams(const std::string & deviceName)80 int32_t HpaeRendererStreamImpl::InitParams(const std::string &deviceName)
81 {
82 HpaeStreamInfo streamInfo;
83 streamInfo.channels = processConfig_.streamInfo.channels;
84 streamInfo.samplingRate = processConfig_.streamInfo.samplingRate;
85 streamInfo.format = processConfig_.streamInfo.format;
86 streamInfo.channelLayout = processConfig_.streamInfo.channelLayout;
87 if (streamInfo.channelLayout == CH_LAYOUT_UNKNOWN) {
88 streamInfo.channelLayout = DownMixer::SetDefaultChannelLayout((AudioChannel)streamInfo.channels);
89 }
90 streamInfo.frameLen = spanSizeInFrame_;
91 streamInfo.sessionId = processConfig_.originalSessionId;
92 streamInfo.streamType = processConfig_.streamType;
93 streamInfo.fadeType = GetFadeType(expectedPlaybackDurationMs_);
94 streamInfo.streamClassType = HPAE_STREAM_CLASS_TYPE_PLAY;
95 streamInfo.uid = processConfig_.appInfo.appUid;
96 streamInfo.pid = processConfig_.appInfo.appPid;
97 streamInfo.tokenId = processConfig_.appInfo.appTokenId;
98 effectMode_ = processConfig_.rendererInfo.effectMode;
99 streamInfo.effectInfo.effectMode = (effectMode_ != EFFECT_DEFAULT && effectMode_ != EFFECT_NONE) ? EFFECT_DEFAULT :
100 static_cast<AudioEffectMode>(effectMode_);
101 const std::unordered_map<AudioEffectScene, std::string> &audioSupportedSceneTypes = GetSupportedSceneType();
102 streamInfo.effectInfo.effectScene = static_cast<AudioEffectScene>(GetKeyFromValue(
103 audioSupportedSceneTypes, processConfig_.rendererInfo.sceneType));
104 streamInfo.effectInfo.systemVolumeType = VolumeUtils::GetVolumeTypeFromStreamType(processConfig_.streamType);
105 streamInfo.effectInfo.streamUsage = processConfig_.rendererInfo.streamUsage;
106 streamInfo.sourceType = processConfig_.isInnerCapturer == true ? SOURCE_TYPE_PLAYBACK_CAPTURE : SOURCE_TYPE_INVALID;
107 streamInfo.deviceName = deviceName;
108 streamInfo.isMoveAble = isMoveAble_;
109 streamInfo.privacyType = processConfig_.privacyType;
110 AUDIO_INFO_LOG("InitParams channels %{public}u end", streamInfo.channels);
111 AUDIO_INFO_LOG("InitParams channelLayout %{public}" PRIu64 " end", streamInfo.channelLayout);
112 AUDIO_INFO_LOG("InitParams samplingRate %{public}u end", streamInfo.samplingRate);
113 AUDIO_INFO_LOG("InitParams format %{public}u end", streamInfo.format);
114 AUDIO_INFO_LOG("InitParams frameLen %{public}zu end", streamInfo.frameLen);
115 AUDIO_INFO_LOG("InitParams streamType %{public}u end", streamInfo.streamType);
116 AUDIO_INFO_LOG("InitParams sessionId %{public}u end", streamInfo.sessionId);
117 AUDIO_INFO_LOG("InitParams streamClassType %{public}u end", streamInfo.streamClassType);
118 AUDIO_INFO_LOG("InitParams sourceType %{public}d end", streamInfo.sourceType);
119 AUDIO_INFO_LOG("InitParams fadeType %{public}d end", streamInfo.fadeType);
120 auto &hpaeManager = IHpaeManager::GetHpaeManager();
121 int32_t ret = hpaeManager.CreateStream(streamInfo);
122 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "CreateStream is error");
123
124 // Register Callback
125 ret = hpaeManager.RegisterStatusCallback(HPAE_STREAM_CLASS_TYPE_PLAY, streamInfo.sessionId, shared_from_this());
126 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "RegisterStatusCallback is error");
127 ret = hpaeManager.RegisterWriteCallback(streamInfo.sessionId, shared_from_this());
128 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "RegisterWriteCallback is error");
129 return SUCCESS;
130 }
131
Start()132 int32_t HpaeRendererStreamImpl::Start()
133 {
134 AUDIO_INFO_LOG("[%{public}u] Enter", streamIndex_);
135 ClockTime::GetAllTimeStamp(timestamp_);
136 int32_t ret = IHpaeManager::GetHpaeManager().Start(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId);
137 std::string tempStringSessionId = std::to_string(streamIndex_);
138 IHpaeManager::GetHpaeManager().AddStreamVolumeToEffect(tempStringSessionId, clientVolume_);
139 if (ret != 0) {
140 AUDIO_ERR_LOG("Start is error!");
141 return ERR_INVALID_PARAM;
142 }
143 return SUCCESS;
144 }
145
StartWithSyncId(const int32_t & syncId)146 int32_t HpaeRendererStreamImpl::StartWithSyncId(const int32_t &syncId)
147 {
148 AUDIO_INFO_LOG("[%{public}u] Enter syncId: %{public}d", streamIndex_, syncId);
149 ClockTime::GetAllTimeStamp(timestamp_);
150 int32_t ret = IHpaeManager::GetHpaeManager().StartWithSyncId(HPAE_STREAM_CLASS_TYPE_PLAY,
151 processConfig_.originalSessionId, syncId);
152 if (ret != 0) {
153 AUDIO_ERR_LOG("StartWithSyncId is error!");
154 return ERR_INVALID_PARAM;
155 }
156 return SUCCESS;
157 }
158
Pause(bool isStandby)159 int32_t HpaeRendererStreamImpl::Pause(bool isStandby)
160 {
161 AUDIO_INFO_LOG("[%{public}u] Enter", streamIndex_);
162 int32_t ret = IHpaeManager::GetHpaeManager().Pause(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId);
163 if (ret != 0) {
164 AUDIO_ERR_LOG("Pause is error!");
165 return ERR_INVALID_PARAM;
166 }
167 return SUCCESS;
168 }
169
Flush()170 int32_t HpaeRendererStreamImpl::Flush()
171 {
172 AUDIO_INFO_LOG("[%{public}u] Enter", streamIndex_);
173 int32_t ret = IHpaeManager::GetHpaeManager().Flush(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId);
174 if (ret != 0) {
175 AUDIO_ERR_LOG("Flush is error");
176 return ERR_INVALID_PARAM;
177 }
178 return SUCCESS;
179 }
180
Drain(bool stopFlag)181 int32_t HpaeRendererStreamImpl::Drain(bool stopFlag)
182 {
183 AUDIO_INFO_LOG("[%{public}u] Enter %{public}d", streamIndex_, stopFlag);
184 int32_t ret = IHpaeManager::GetHpaeManager().Drain(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId);
185 if (ret != 0) {
186 AUDIO_ERR_LOG("Drain is error");
187 return ERR_INVALID_PARAM;
188 }
189 return SUCCESS;
190 }
191
Stop()192 int32_t HpaeRendererStreamImpl::Stop()
193 {
194 AUDIO_INFO_LOG("[%{public}u] Enter", streamIndex_);
195 int32_t ret = IHpaeManager::GetHpaeManager().Stop(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId);
196 if (ret != 0) {
197 AUDIO_ERR_LOG("Stop is error!");
198 return ERR_INVALID_PARAM;
199 }
200 state_ = STOPPING;
201 return SUCCESS;
202 }
203
Release()204 int32_t HpaeRendererStreamImpl::Release()
205 {
206 if (state_ == RUNNING) {
207 AUDIO_ERR_LOG("%{public}u Release state_ is RUNNING", processConfig_.originalSessionId);
208 IHpaeManager::GetHpaeManager().Stop(HPAE_STREAM_CLASS_TYPE_PLAY, processConfig_.originalSessionId);
209 }
210 AUDIO_INFO_LOG("[%{public}u] Enter", streamIndex_);
211 int32_t ret = IHpaeManager::GetHpaeManager().DestroyStream(HPAE_STREAM_CLASS_TYPE_PLAY,
212 processConfig_.originalSessionId);
213 std::string tempStringSessionId = std::to_string(streamIndex_);
214 IHpaeManager::GetHpaeManager().DeleteStreamVolumeToEffect(tempStringSessionId);
215 if (ret != 0) {
216 AUDIO_ERR_LOG("Release is error");
217 return ERR_INVALID_PARAM;
218 }
219 state_ = RELEASED;
220 return SUCCESS;
221 }
222
GetStreamFramesWritten(uint64_t & framesWritten)223 int32_t HpaeRendererStreamImpl::GetStreamFramesWritten(uint64_t &framesWritten)
224 {
225 framesWritten = framesWritten_;
226 return SUCCESS;
227 }
228
GetCurrentTimeStamp(uint64_t & timestamp)229 int32_t HpaeRendererStreamImpl::GetCurrentTimeStamp(uint64_t ×tamp)
230 {
231 std::shared_lock<std::shared_mutex> lock(latencyMutex_);
232 timestamp = timestamp_[Timestamp::Timestampbase::MONOTONIC];
233 return SUCCESS;
234 }
235
GetA2dpOffloadLatency()236 uint32_t HpaeRendererStreamImpl::GetA2dpOffloadLatency()
237 {
238 Trace trace("PaRendererStreamImpl::GetA2dpOffloadLatency");
239 uint32_t a2dpOffloadLatency = 0;
240 uint64_t a2dpOffloadSendDataSize = 0;
241 uint32_t a2dpOffloadTimestamp = 0;
242 auto& handle = PolicyHandler::GetInstance();
243 int32_t ret = handle.OffloadGetRenderPosition(a2dpOffloadLatency, a2dpOffloadSendDataSize, a2dpOffloadTimestamp);
244 if (ret != SUCCESS) {
245 AUDIO_ERR_LOG("OffloadGetRenderPosition failed!");
246 }
247 return a2dpOffloadLatency;
248 }
249
GetNearlinkLatency()250 uint32_t HpaeRendererStreamImpl::GetNearlinkLatency()
251 {
252 Trace trace("PaRendererStreamImpl::GetNearlinkLatency");
253 uint32_t nearlinkLatency = 0;
254 auto &handler = PolicyHandler::GetInstance();
255 int32_t ret = handler.NearlinkGetRenderPosition(nearlinkLatency);
256 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, 0, "NearlinkGetRenderPosition failed");
257
258 return nearlinkLatency;
259 }
260
GetRemoteOffloadSpeedPosition(uint64_t & framePosition,uint64_t & timestamp,uint64_t & latency)261 int32_t HpaeRendererStreamImpl::GetRemoteOffloadSpeedPosition(uint64_t &framePosition, uint64_t ×tamp,
262 uint64_t &latency)
263 {
264 CHECK_AND_RETURN_RET(deviceClass_ == DEVICE_CLASS_REMOTE_OFFLOAD, ERR_NOT_SUPPORTED);
265
266 std::shared_ptr<IAudioRenderSink> sink = GetRenderSinkInstance(deviceClass_, deviceNetId_);
267 CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERR_INVALID_OPERATION, "audioRendererSink is null");
268 uint64_t framesUS;
269 int64_t timeSec;
270 int64_t timeNSec;
271 int32_t ret = sink->GetHdiPresentationPosition(framesUS, timeSec, timeNSec);
272 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get position fail");
273
274 uint32_t curLatencyUS = 0;
275 ret = sink->GetHdiLatency(curLatencyUS);
276 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get latency fail");
277
278 // Here, latency and sampling count are calculated, and latency is exposed to the client as 0.
279 latency = static_cast<uint64_t>(curLatencyUS) * processConfig_.streamInfo.samplingRate / AUDIO_US_PER_S;
280
281 uint64_t frames = framesUS * processConfig_.streamInfo.samplingRate / AUDIO_US_PER_S;
282 framePosition = lastHdiFramePosition_ + frames;
283 timestamp = static_cast<uint64_t>(timeNSec + timeSec * AUDIO_NS_PER_SECOND);
284 AUDIO_DEBUG_LOG("HpaeRendererStreamImpl::GetSpeedPosition frame: %{public}" PRIu64, framePosition);
285 return SUCCESS;
286 }
287
GetSpeedPosition(uint64_t & framePosition,uint64_t & timestamp,uint64_t & latency,int32_t base)288 int32_t HpaeRendererStreamImpl::GetSpeedPosition(uint64_t &framePosition, uint64_t ×tamp,
289 uint64_t &latency, int32_t base)
290 {
291 std::shared_lock<std::shared_mutex> lock(latencyMutex_);
292
293 int32_t ret = GetRemoteOffloadSpeedPosition(framePosition, timestamp, latency);
294 CHECK_AND_RETURN_RET(ret == ERR_NOT_SUPPORTED, ret);
295
296 framePosition = lastHdiFramePosition_ + framePosition_ - lastFramePosition_;
297
298 uint64_t latencyUs = 0;
299 GetLatencyInner(timestamp, latencyUs, base);
300 latency = latencyUs * static_cast<uint64_t>(processConfig_.streamInfo.samplingRate) / AUDIO_US_PER_S;
301 return SUCCESS;
302 }
303
GetCurrentPosition(uint64_t & framePosition,uint64_t & timestamp,uint64_t & latency,int32_t base)304 int32_t HpaeRendererStreamImpl::GetCurrentPosition(uint64_t &framePosition, uint64_t ×tamp,
305 uint64_t &latency, int32_t base)
306 {
307 std::shared_lock<std::shared_mutex> lock(latencyMutex_);
308 uint64_t latencyUs = 0;
309 GetLatencyInner(timestamp, latencyUs, base);
310 latency = latencyUs * static_cast<uint64_t>(processConfig_.streamInfo.samplingRate) / AUDIO_US_PER_S;
311 framePosition = framePosition_;
312 AUDIO_DEBUG_LOG("HpaeRendererStreamImpl::GetCurrentPosition Latency info: framePosition: %{public}" PRIu64
313 ", latency %{public}" PRIu64, framePosition, latency);
314 return SUCCESS;
315 }
316
GetLatency(uint64_t & latency)317 int32_t HpaeRendererStreamImpl::GetLatency(uint64_t &latency)
318 {
319 std::shared_lock<std::shared_mutex> lock(latencyMutex_);
320 uint64_t timestamp = 0;
321 int32_t base = Timestamp::Timestampbase::MONOTONIC;
322 GetLatencyInner(timestamp, latency, base);
323 return SUCCESS;
324 }
GetLatencyInner(uint64_t & timestamp,uint64_t & latencyUs,int32_t base)325 void HpaeRendererStreamImpl::GetLatencyInner(uint64_t ×tamp, uint64_t &latencyUs, int32_t base)
326 {
327 int32_t baseUsed = base >= 0 && base < Timestamp::Timestampbase::BASESIZE ?
328 base : Timestamp::Timestampbase::MONOTONIC;
329 uint32_t sinkLatency = 0;
330 uint32_t a2dpOffloadLatency = GetA2dpOffloadLatency();
331 uint32_t nearlinkLatency = GetNearlinkLatency();
332 std::shared_ptr<IAudioRenderSink> audioRendererSink = GetRenderSinkInstance(deviceClass_, deviceNetId_);
333 if (audioRendererSink) {
334 audioRendererSink->GetLatency(sinkLatency);
335 }
336 latencyUs = latency_;
337 latencyUs += sinkLatency * AUDIO_US_PER_MS;
338 latencyUs += a2dpOffloadLatency * AUDIO_US_PER_MS;
339 latencyUs += nearlinkLatency * AUDIO_US_PER_MS;
340 std::vector<uint64_t> timestampCurrent = {0};
341 ClockTime::GetAllTimeStamp(timestampCurrent);
342 timestamp = timestampCurrent[baseUsed];
343
344 AUDIO_DEBUG_LOG("Latency info: framePosition: %{public}" PRIu64 ", latencyUs %{public}" PRIu64
345 ", base %{public}d, timestamp %{public}" PRIu64 ", pipe latency: %{public}" PRIu64
346 ", sink latency: %{public}u ms, a2dp offload latency: %{public}u ms, nearlink latency: %{public}u ms",
347 framePosition_, latencyUs, base, timestamp, latency_, sinkLatency, a2dpOffloadLatency, nearlinkLatency);
348 }
349
SetRate(int32_t rate)350 int32_t HpaeRendererStreamImpl::SetRate(int32_t rate)
351 {
352 AUDIO_INFO_LOG("SetRate in");
353 renderRate_ = rate;
354 return SUCCESS;
355 }
356
SetAudioEffectMode(int32_t effectMode)357 int32_t HpaeRendererStreamImpl::SetAudioEffectMode(int32_t effectMode)
358 {
359 AUDIO_INFO_LOG("SetAudioEffectMode: %{public}d", effectMode);
360 int32_t ret = IHpaeManager::GetHpaeManager().SetAudioEffectMode(processConfig_.originalSessionId, effectMode);
361 if (ret != 0) {
362 AUDIO_ERR_LOG("SetAudioEffectMode is error");
363 return ERR_INVALID_PARAM;
364 }
365 effectMode_ = effectMode;
366 return SUCCESS;
367 }
368
GetAudioEffectMode(int32_t & effectMode)369 int32_t HpaeRendererStreamImpl::GetAudioEffectMode(int32_t &effectMode)
370 {
371 effectMode = effectMode_;
372 return SUCCESS;
373 }
374
SetPrivacyType(int32_t privacyType)375 int32_t HpaeRendererStreamImpl::SetPrivacyType(int32_t privacyType)
376 {
377 AUDIO_DEBUG_LOG("SetInnerCapturerState: %{public}d", privacyType);
378 privacyType_ = privacyType;
379 return SUCCESS;
380 }
381
GetPrivacyType(int32_t & privacyType)382 int32_t HpaeRendererStreamImpl::GetPrivacyType(int32_t &privacyType)
383 {
384 privacyType_ = privacyType;
385 return SUCCESS;
386 }
387
SetSpeed(float speed)388 int32_t HpaeRendererStreamImpl::SetSpeed(float speed)
389 {
390 AUDIO_INFO_LOG("[%{public}u] Enter", streamIndex_);
391 IHpaeManager::GetHpaeManager().SetSpeed(processConfig_.originalSessionId, speed);
392 return SUCCESS;
393 }
394
RegisterStatusCallback(const std::weak_ptr<IStatusCallback> & callback)395 void HpaeRendererStreamImpl::RegisterStatusCallback(const std::weak_ptr<IStatusCallback> &callback)
396 {
397 AUDIO_DEBUG_LOG("RegisterStatusCallback in");
398 statusCallback_ = callback;
399 }
400
RegisterWriteCallback(const std::weak_ptr<IWriteCallback> & callback)401 void HpaeRendererStreamImpl::RegisterWriteCallback(const std::weak_ptr<IWriteCallback> &callback)
402 {
403 AUDIO_DEBUG_LOG("RegisterWriteCallback in");
404 writeCallback_ = callback;
405 }
406
OnDeviceClassChange(const AudioCallBackStreamInfo & callBackStreamInfo)407 void HpaeRendererStreamImpl::OnDeviceClassChange(const AudioCallBackStreamInfo &callBackStreamInfo)
408 {
409 if (deviceClass_ != callBackStreamInfo.deviceClass) {
410 uint64_t newFramePosition = callBackStreamInfo.framePosition;
411
412 // from normal to remote offload
413 if (callBackStreamInfo.deviceClass == DEVICE_CLASS_REMOTE_OFFLOAD) {
414 uint64_t duration = newFramePosition > lastFramePosition_ ? newFramePosition - lastFramePosition_ :
415 lastFramePosition_ - newFramePosition;
416 lastHdiFramePosition_ = newFramePosition > lastFramePosition_ ? lastHdiFramePosition_ + duration :
417 (lastHdiFramePosition_ > duration ? lastHdiFramePosition_ - duration : 0);
418 }
419 // Device type switch, replace lastFramePosition_
420 lastFramePosition_ = callBackStreamInfo.framePosition;
421 }
422
423 // If hdiFramePosition has a value, it indicates that the remote offload device has performed a flush.
424 // The value of hdiFramePosition needs to be accumulated into lastHdiFramePosition_
425 if (callBackStreamInfo.hdiFramePosition > 0) {
426 lastHdiFramePosition_ +=
427 // from time (us) to sample
428 callBackStreamInfo.hdiFramePosition * processConfig_.streamInfo.samplingRate / AUDIO_US_PER_S;
429 }
430 }
431
OnStreamData(AudioCallBackStreamInfo & callBackStreamInfo)432 int32_t HpaeRendererStreamImpl::OnStreamData(AudioCallBackStreamInfo &callBackStreamInfo)
433 {
434 {
435 std::unique_lock<std::shared_mutex> lock(latencyMutex_);
436 OnDeviceClassChange(callBackStreamInfo);
437 framePosition_ = callBackStreamInfo.framePosition;
438 timestamp_ = callBackStreamInfo.timestamp;
439 latency_ = callBackStreamInfo.latency;
440 framesWritten_ = callBackStreamInfo.framesWritten;
441 deviceClass_ = callBackStreamInfo.deviceClass;
442 deviceNetId_ = callBackStreamInfo.deviceNetId;
443 }
444 if (isCallbackMode_) { // callback buffer
445 auto requestDataLen = callBackStreamInfo.requestDataLen;
446 auto writeCallback = writeCallback_.lock();
447 if (callBackStreamInfo.needData && writeCallback) {
448 writeCallback->GetAvailableSize(requestDataLen);
449 requestDataLen = std::min(requestDataLen, callBackStreamInfo.requestDataLen);
450 if (callBackStreamInfo.requestDataLen > requestDataLen) {
451 int chToFill = (processConfig_.streamInfo.format == SAMPLE_U8) ? 0x7f : 0;
452 memset_s(callBackStreamInfo.inputData + requestDataLen,
453 callBackStreamInfo.requestDataLen - requestDataLen, chToFill,
454 callBackStreamInfo.requestDataLen - requestDataLen);
455 requestDataLen = callBackStreamInfo.forceData ? requestDataLen : 0;
456 }
457 callBackStreamInfo.requestDataLen = requestDataLen;
458 return writeCallback->OnWriteData(callBackStreamInfo.inputData,
459 requestDataLen);
460 }
461 } else { // write buffer
462 return WriteDataFromRingBuffer(callBackStreamInfo.forceData,
463 callBackStreamInfo.inputData, callBackStreamInfo.requestDataLen);
464 }
465 return SUCCESS;
466 }
467
DequeueBuffer(size_t length)468 BufferDesc HpaeRendererStreamImpl::DequeueBuffer(size_t length)
469 {
470 BufferDesc bufferDesc;
471 return bufferDesc;
472 }
473
EnqueueBuffer(const BufferDesc & bufferDesc)474 int32_t HpaeRendererStreamImpl::EnqueueBuffer(const BufferDesc &bufferDesc)
475 {
476 CHECK_AND_RETURN_RET_LOG(!isCallbackMode_, ERROR, "Not write buffer mode");
477 CHECK_AND_RETURN_RET_LOG(ringBuffer_ != nullptr, ERROR, "RingBuffer is nullptr");
478
479 size_t targetSize = bufferDesc.bufLength;
480 OptResult result = ringBuffer_->GetWritableSize();
481 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
482 "Get writable size failed, ret:%{public}d size:%{public}zu", result.ret, result.size);
483
484 size_t writableSize = result.size;
485 if (targetSize > writableSize) {
486 AUDIO_ERR_LOG("Enqueue buffer overflow, targetSize: %{public}zu, writableSize: %{public}zu",
487 targetSize, writableSize);
488 }
489
490 size_t writeSize = std::min(writableSize, targetSize);
491 BufferWrap bufferWrap = {bufferDesc.buffer, writeSize};
492 result = ringBuffer_->Enqueue(bufferWrap);
493 if (result.ret != OPERATION_SUCCESS) {
494 AUDIO_ERR_LOG("Enqueue buffer failed, ret:%{public}d size:%{public}zu", result.ret, result.size);
495 return ERROR;
496 }
497 DumpFileUtil::WriteDumpFile(dumpEnqueueIn_, bufferDesc.buffer, writeSize);
498 return writeSize; // success return written in length
499 }
500
GetMinimumBufferSize(size_t & minBufferSize) const501 int32_t HpaeRendererStreamImpl::GetMinimumBufferSize(size_t &minBufferSize) const
502 {
503 minBufferSize = minBufferSize_;
504 return SUCCESS;
505 }
506
GetByteSizePerFrame(size_t & byteSizePerFrame) const507 void HpaeRendererStreamImpl::GetByteSizePerFrame(size_t &byteSizePerFrame) const
508 {
509 byteSizePerFrame = byteSizePerFrame_;
510 }
511
GetSpanSizePerFrame(size_t & spanSizeInFrame) const512 void HpaeRendererStreamImpl::GetSpanSizePerFrame(size_t &spanSizeInFrame) const
513 {
514 spanSizeInFrame = spanSizeInFrame_;
515 }
516
SetStreamIndex(uint32_t index)517 void HpaeRendererStreamImpl::SetStreamIndex(uint32_t index)
518 {
519 AUDIO_INFO_LOG("Using index/sessionId %{public}u", index);
520 streamIndex_ = index;
521 }
522
GetStreamIndex()523 uint32_t HpaeRendererStreamImpl::GetStreamIndex()
524 {
525 return streamIndex_;
526 }
527
AbortCallback(int32_t abortTimes)528 void HpaeRendererStreamImpl::AbortCallback(int32_t abortTimes)
529 {
530 abortFlag_ += abortTimes;
531 }
532
533 // offload
534
GetWritableSize()535 size_t HpaeRendererStreamImpl::GetWritableSize()
536 {
537 return 0;
538 }
539
OffloadSetVolume(float volume)540 int32_t HpaeRendererStreamImpl::OffloadSetVolume(float volume)
541 {
542 if (!offloadEnable_) {
543 return ERR_OPERATION_FAILED;
544 }
545 std::shared_ptr<IAudioRenderSink> audioRendererSinkInstance = GetRenderSinkInstance(deviceClass_, "");
546 if (audioRendererSinkInstance == nullptr) {
547 AUDIO_ERR_LOG("Renderer is null.");
548 return ERROR;
549 }
550 return audioRendererSinkInstance->SetVolume(volume, volume);
551 }
552
SetOffloadDataCallbackState(int32_t state)553 int32_t HpaeRendererStreamImpl::SetOffloadDataCallbackState(int32_t state)
554 {
555 AUDIO_INFO_LOG("SetOffloadDataCallbackState state: %{public}d", state);
556 if (!offloadEnable_) {
557 return ERR_OPERATION_FAILED;
558 }
559 return IHpaeManager::GetHpaeManager().SetOffloadRenderCallbackType(processConfig_.originalSessionId, state);
560 }
561
UpdateSpatializationState(bool spatializationEnabled,bool headTrackingEnabled)562 int32_t HpaeRendererStreamImpl::UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled)
563 {
564 return SUCCESS;
565 }
566
GetOffloadApproximatelyCacheTime(uint64_t & timestamp,uint64_t & paWriteIndex,uint64_t & cacheTimeDsp,uint64_t & cacheTimePa)567 int32_t HpaeRendererStreamImpl::GetOffloadApproximatelyCacheTime(uint64_t ×tamp, uint64_t &paWriteIndex,
568 uint64_t &cacheTimeDsp, uint64_t &cacheTimePa)
569 {
570 if (!offloadEnable_) {
571 return ERR_OPERATION_FAILED;
572 }
573 return SUCCESS;
574 }
575
SyncOffloadMode()576 void HpaeRendererStreamImpl::SyncOffloadMode()
577 {
578 std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
579 if (statusCallback != nullptr) {
580 if (offloadEnable_) {
581 statusCallback->OnStatusUpdate(OPERATION_SET_OFFLOAD_ENABLE);
582 } else {
583 statusCallback->OnStatusUpdate(OPERATION_UNSET_OFFLOAD_ENABLE);
584 }
585 }
586 }
587
SetOffloadMode(int32_t state,bool isAppBack)588 int32_t HpaeRendererStreamImpl::SetOffloadMode(int32_t state, bool isAppBack)
589 {
590 #ifdef FEATURE_POWER_MANAGER
591 static const std::set<PowerMgr::PowerState> screenOffTable = {
592 PowerMgr::PowerState::INACTIVE, PowerMgr::PowerState::STAND_BY,
593 PowerMgr::PowerState::DOZE, PowerMgr::PowerState::SLEEP,
594 PowerMgr::PowerState::HIBERNATE,
595 };
596 AudioOffloadType statePolicy = OFFLOAD_DEFAULT;
597 statePolicy = screenOffTable.count(static_cast<PowerMgr::PowerState>(state)) ?
598 OFFLOAD_INACTIVE_BACKGROUND : OFFLOAD_ACTIVE_FOREGROUND;
599
600 AUDIO_INFO_LOG("calling set stream offloadMode PowerState: %{public}d, isAppBack: %{public}d", state, isAppBack);
601
602 if (offloadStatePolicy_.load() == statePolicy && offloadEnable_) {
603 return SUCCESS;
604 }
605
606 offloadEnable_ = true;
607 SyncOffloadMode();
608 auto ret = IHpaeManager::GetHpaeManager().SetOffloadPolicy(processConfig_.originalSessionId, statePolicy);
609 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED,
610 "SetOffloadPolicy failed, errcode is %{public}d", ret);
611 offloadStatePolicy_.store(statePolicy);
612 #else
613 AUDIO_INFO_LOG("SetStreamOffloadMode not available, FEATURE_POWER_MANAGER no define");
614 #endif
615 return SUCCESS;
616 }
617
UnsetOffloadMode()618 int32_t HpaeRendererStreamImpl::UnsetOffloadMode()
619 {
620 offloadEnable_ = false;
621 SyncOffloadMode();
622 IHpaeManager::GetHpaeManager().SetOffloadPolicy(processConfig_.originalSessionId, OFFLOAD_DEFAULT);
623 return SUCCESS;
624 }
625
UpdateMaxLength(uint32_t maxLength)626 int32_t HpaeRendererStreamImpl::UpdateMaxLength(uint32_t maxLength)
627 {
628 size_t bufferSize = maxLength * spanSizeInFrame_ * byteSizePerFrame_;
629 AUDIO_INFO_LOG("bufferSize: %{public}zu, spanSizeInFrame: %{public}zu, byteSizePerFrame: %{public}zu,"
630 "maxLength:%{public}u", bufferSize, spanSizeInFrame_, byteSizePerFrame_, maxLength);
631 if (ringBuffer_ != nullptr) {
632 ringBuffer_->ReConfig(bufferSize, false);
633 } else {
634 AUDIO_ERR_LOG("ring buffer is nullptr!");
635 }
636 return SUCCESS;
637 }
638
GetAudioProcessConfig() const639 AudioProcessConfig HpaeRendererStreamImpl::GetAudioProcessConfig() const noexcept
640 {
641 return processConfig_;
642 }
643
Peek(std::vector<char> * audioBuffer,int32_t & index)644 int32_t HpaeRendererStreamImpl::Peek(std::vector<char> *audioBuffer, int32_t &index)
645 {
646 return SUCCESS;
647 }
648
ReturnIndex(int32_t index)649 int32_t HpaeRendererStreamImpl::ReturnIndex(int32_t index)
650 {
651 return SUCCESS;
652 }
653
BlockStream()654 void HpaeRendererStreamImpl::BlockStream() noexcept
655 {
656 return;
657 }
658 // offload end
659
SetClientVolume(float clientVolume)660 int32_t HpaeRendererStreamImpl::SetClientVolume(float clientVolume)
661 {
662 AUDIO_PRERELEASE_LOGI("set client volume success");
663 if (clientVolume < MIN_FLOAT_VOLUME || clientVolume > MAX_FLOAT_VOLUME) {
664 AUDIO_ERR_LOG("SetClientVolume with invalid clientVolume %{public}f", clientVolume);
665 return ERR_INVALID_PARAM;
666 }
667 int32_t ret = IHpaeManager::GetHpaeManager().SetClientVolume(processConfig_.originalSessionId, clientVolume);
668 std::string tempStringSessionId = std::to_string(processConfig_.originalSessionId);
669 IHpaeManager::GetHpaeManager().AddStreamVolumeToEffect(tempStringSessionId, clientVolume);
670 if (ret != 0) {
671 AUDIO_ERR_LOG("SetClientVolume is error");
672 return ERR_INVALID_PARAM;
673 }
674 clientVolume_ = clientVolume;
675 return SUCCESS;
676 }
677
SetLoudnessGain(float loudnessGain)678 int32_t HpaeRendererStreamImpl::SetLoudnessGain(float loudnessGain)
679 {
680 AUDIO_INFO_LOG("set loudnessGain: %{public}f", loudnessGain);
681 int32_t ret = IHpaeManager::GetHpaeManager().SetLoudnessGain(processConfig_.originalSessionId, loudnessGain);
682 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_INVALID_PARAM, "SetLoudnessGain is error");
683 return SUCCESS;
684 }
685
InitRingBuffer()686 void HpaeRendererStreamImpl::InitRingBuffer()
687 {
688 uint32_t maxLength = 20; // 20 for dup and dual play, only for enqueue buffer
689 size_t bufferSize = maxLength * spanSizeInFrame_ * byteSizePerFrame_;
690 AUDIO_INFO_LOG("bufferSize: %{public}zu, spanSizeInFrame: %{public}zu, byteSizePerFrame: %{public}zu,"
691 "maxLength:%{public}u", bufferSize, spanSizeInFrame_, byteSizePerFrame_, maxLength);
692 // create ring buffer
693 ringBuffer_ = AudioRingCache::Create(bufferSize);
694 if (ringBuffer_ == nullptr) {
695 AUDIO_ERR_LOG("Create ring buffer failed!");
696 }
697
698 std::string dumpEnqueueInFileName = std::to_string(processConfig_.originalSessionId) + "_dual_in_" +
699 std::to_string(processConfig_.streamInfo.samplingRate) + "_" +
700 std::to_string(processConfig_.streamInfo.channels) + "_" +
701 std::to_string(processConfig_.streamInfo.format) + ".pcm";
702 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpEnqueueInFileName, &dumpEnqueueIn_);
703 }
704
WriteDataFromRingBuffer(bool forceData,int8_t * inputData,size_t & requestDataLen)705 int32_t HpaeRendererStreamImpl::WriteDataFromRingBuffer(bool forceData, int8_t *inputData, size_t &requestDataLen)
706 {
707 CHECK_AND_RETURN_RET_LOG(inputData != nullptr, ERROR, "inputData is nullptr");
708 CHECK_AND_RETURN_RET_LOG(ringBuffer_ != nullptr, ERROR, "RingBuffer is nullptr");
709 OptResult result = ringBuffer_->GetReadableSize();
710 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
711 "RingBuffer get readable size failed, size is:%{public}zu", result.size);
712 CHECK_AND_RETURN_RET_LOG(result.size != 0, ERROR,
713 "Readable size is invalid, result.size:%{public}zu, requestDataLen:%{public}zu, buffer underflow.",
714 result.size, requestDataLen);
715 if (requestDataLen > result.size) {
716 CHECK_AND_RETURN_RET_LOG(forceData, ERROR, "not enough data");
717 int chToFill = (processConfig_.streamInfo.format == SAMPLE_U8) ? 0x7f : 0;
718 memset_s(inputData + result.size,
719 requestDataLen - result.size, chToFill,
720 requestDataLen - result.size);
721 }
722 AUDIO_DEBUG_LOG("requestDataLen is:%{public}zu readSize is:%{public}zu", requestDataLen, result.size);
723 requestDataLen = std::min(requestDataLen, result.size);
724 result = ringBuffer_->Dequeue({reinterpret_cast<uint8_t *>(inputData), requestDataLen});
725 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "RingBuffer dequeue failed");
726 return SUCCESS;
727 }
728
OnStatusUpdate(IOperation operation,uint32_t streamIndex)729 void HpaeRendererStreamImpl::OnStatusUpdate(IOperation operation, uint32_t streamIndex)
730 {
731 auto statusCallback = statusCallback_.lock();
732 if (statusCallback) {
733 statusCallback->OnStatusUpdate(operation);
734 }
735 }
736
GetRenderSinkInstance(std::string deviceClass,std::string deviceNetId)737 static std::shared_ptr<IAudioRenderSink> GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId)
738 {
739 uint32_t renderId = HDI_INVALID_ID;
740 renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass,
741 deviceNetId.empty() ? HDI_ID_INFO_DEFAULT : deviceNetId, false);
742 return HdiAdapterManager::GetInstance().GetRenderSink(renderId, true);
743 }
744
GetFadeType(uint64_t expectedPlaybackDurationMs)745 static inline FadeType GetFadeType(uint64_t expectedPlaybackDurationMs)
746 {
747 // duration <= 10 ms no fade
748 if (expectedPlaybackDurationMs <= FRAME_LEN_10MS && expectedPlaybackDurationMs > 0) {
749 return NONE_FADE;
750 }
751
752 // duration > 10ms && duration <= 40ms do 5ms fade
753 if (expectedPlaybackDurationMs <= FRAME_LEN_40MS && expectedPlaybackDurationMs > FRAME_LEN_10MS) {
754 return SHORT_FADE;
755 }
756
757 // 0 is default; duration > 40ms do default fade
758 return DEFAULT_FADE;
759 }
760 } // namespace AudioStandard
761 } // namespace OHOS
762