• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &timestamp)
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 &timestamp,
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 &timestamp,
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 &timestamp,
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 &timestamp, 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 &timestamp, 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