1 /*
2  * Copyright (c) 2024 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 "ProRendererStream"
17 #endif
18 
19 #include "pro_renderer_stream_impl.h"
20 #include "audio_errors.h"
21 #include "audio_renderer_log.h"
22 #include "audio_utils.h"
23 #include "securec.h"
24 #include "policy_handler.h"
25 #include "audio_common_converter.h"
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 constexpr uint64_t AUDIO_US_PER_S = 1000000;
30 constexpr uint64_t AUDIO_NS_PER_S = 1000000000;
31 constexpr int32_t SECOND_TO_MILLISECOND = 1000;
32 constexpr int32_t DEFAULT_BUFFER_MILLISECOND = 20;
33 constexpr int32_t DEFAULT_BUFFER_MICROSECOND = 20000000;
34 constexpr uint32_t DOUBLE_VALUE = 2;
35 constexpr int32_t DEFAULT_RESAMPLE_QUANTITY = 2;
36 constexpr int32_t STEREO_CHANNEL_COUNT = 2;
37 constexpr int32_t DEFAULT_TOTAL_SPAN_COUNT = 4;
38 constexpr int32_t DRAIN_WAIT_TIMEOUT_TIME = 100;
39 constexpr int32_t FIRST_FRAME_TIMEOUT_TIME = 500;
40 const std::string DUMP_DIRECT_STREAM_FILE = "dump_direct_audio_stream.pcm";
41 
ProRendererStreamImpl(AudioProcessConfig processConfig,bool isDirect)42 ProRendererStreamImpl::ProRendererStreamImpl(AudioProcessConfig processConfig, bool isDirect)
43     : isDirect_(isDirect),
44       isNeedResample_(false),
45       isNeedMcr_(false),
46       isBlock_(true),
47       isDrain_(false),
48       isFirstFrame_(true),
49       privacyType_(0),
50       renderRate_(0),
51       streamIndex_(static_cast<uint32_t>(-1)),
52       abortFlag_(0),
53       currentRate_(1),
54       desSamplingRate_(0),
55       desFormat_(AudioSampleFormat::SAMPLE_S32LE),
56       byteSizePerFrame_(0),
57       spanSizeInFrame_(0),
58       totalBytesWritten_(0),
59       sinkBytesWritten_(0),
60       minBufferSize_(0),
61       status_(I_STATUS_INVALID),
62       resample_(nullptr),
63       processConfig_(processConfig),
64       downMixer_(nullptr),
65       dumpFile_(nullptr)
66 {
67     AUDIO_DEBUG_LOG("constructor");
68 }
69 
~ProRendererStreamImpl()70 ProRendererStreamImpl::~ProRendererStreamImpl()
71 {
72     AUDIO_DEBUG_LOG("deconstructor");
73     status_ = I_STATUS_INVALID;
74     DumpFileUtil::CloseDumpFile(&dumpFile_);
75 }
76 
GetDirectSampleRate(AudioSamplingRate sampleRate) const77 AudioSamplingRate ProRendererStreamImpl::GetDirectSampleRate(AudioSamplingRate sampleRate) const noexcept
78 {
79     if (processConfig_.streamType == STREAM_VOICE_CALL) {
80         // VoIP stream type. Return the special sample rate of direct VoIP mode.
81         if (sampleRate <= AudioSamplingRate::SAMPLE_RATE_16000) {
82             return AudioSamplingRate::SAMPLE_RATE_16000;
83         } else {
84             return AudioSamplingRate::SAMPLE_RATE_48000;
85         }
86     }
87     // High resolution for music
88     AudioSamplingRate result = sampleRate;
89     switch (sampleRate) {
90         case AudioSamplingRate::SAMPLE_RATE_44100:
91             result = AudioSamplingRate::SAMPLE_RATE_48000;
92             break;
93         case AudioSamplingRate::SAMPLE_RATE_88200:
94             result = AudioSamplingRate::SAMPLE_RATE_96000;
95             break;
96         case AudioSamplingRate::SAMPLE_RATE_176400:
97             result = AudioSamplingRate::SAMPLE_RATE_192000;
98             break;
99         default:
100             break;
101     }
102     return result;
103 }
104 
GetDirectFormat(AudioSampleFormat format) const105 AudioSampleFormat ProRendererStreamImpl::GetDirectFormat(AudioSampleFormat format) const noexcept
106 {
107     if (isDirect_) {
108         // Only SAMPLE_S32LE is supported for high resolution stream.
109         return AudioSampleFormat::SAMPLE_S32LE;
110     }
111 
112     // Both SAMPLE_S16LE and SAMPLE_S32LE are supported for direct VoIP stream.
113     if (format == SAMPLE_S16LE || format == SAMPLE_S32LE) {
114         return format;
115     } else {
116         AUDIO_WARNING_LOG("The format %{public}u is unsupported for direct VoIP. Use 32Bit.", format);
117         return AudioSampleFormat::SAMPLE_S32LE;
118     }
119 }
120 
InitParams()121 int32_t ProRendererStreamImpl::InitParams()
122 {
123     if (status_ != I_STATUS_INVALID) {
124         return ERR_ILLEGAL_STATE;
125     }
126     AudioStreamInfo streamInfo = processConfig_.streamInfo;
127     AUDIO_INFO_LOG("sampleSpec: channels: %{public}u, formats: %{public}d, rate: %{public}d", streamInfo.channels,
128         streamInfo.format, streamInfo.samplingRate);
129     InitBasicInfo(streamInfo);
130     size_t frameSize = spanSizeInFrame_ * streamInfo.channels;
131     uint32_t desChannels = streamInfo.channels >= STEREO_CHANNEL_COUNT ? STEREO_CHANNEL_COUNT : 1;
132     uint32_t desSpanSize = (desSamplingRate_ * DEFAULT_BUFFER_MILLISECOND) / SECOND_TO_MILLISECOND;
133     if (streamInfo.samplingRate != desSamplingRate_) {
134         AUDIO_INFO_LOG("stream need resample, dest:%{public}d", desSamplingRate_);
135         isNeedResample_ = true;
136         resample_ = std::make_shared<AudioResample>(desChannels, streamInfo.samplingRate, desSamplingRate_,
137             DEFAULT_RESAMPLE_QUANTITY);
138         if (!resample_->IsResampleInit()) {
139             AUDIO_ERR_LOG("resample not supported.");
140             return ERR_INVALID_PARAM;
141         }
142         resampleSrcBuffer.resize(frameSize, 0.f);
143         resampleDesBuffer.resize(desSpanSize * desChannels, 0.f);
144         resample_->ProcessFloatResample(resampleSrcBuffer, resampleDesBuffer);
145     }
146     if (streamInfo.channels > STEREO_CHANNEL_COUNT) {
147         isNeedMcr_ = true;
148         if (!isNeedResample_) {
149             resampleSrcBuffer.resize(frameSize, 0.f);
150             resampleDesBuffer.resize(desSpanSize * desChannels, 0.f);
151         }
152         downMixer_ = std::make_unique<AudioDownMixStereo>();
153         int32_t ret = downMixer_->InitMixer(streamInfo.channelLayout, streamInfo.channels);
154         if (ret != SUCCESS) {
155             AUDIO_ERR_LOG("down mixer not supported.");
156             return ret;
157         }
158     }
159     uint32_t bufferSize = Util::GetSamplePerFrame(desFormat_) * desSpanSize * desChannels;
160     sinkBuffer_.resize(DEFAULT_TOTAL_SPAN_COUNT, std::vector<char>(bufferSize, 0));
161     for (int32_t i = 0; i < DEFAULT_TOTAL_SPAN_COUNT; i++) {
162         writeQueue_.emplace(i);
163     }
164     SetOffloadDisable();
165     DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, DUMP_DIRECT_STREAM_FILE, &dumpFile_);
166     status_ = I_STATUS_IDLE;
167     return SUCCESS;
168 }
169 
Start()170 int32_t ProRendererStreamImpl::Start()
171 {
172     isBlock_ = false;
173     AUDIO_INFO_LOG("Enter");
174     if (status_ == I_STATUS_INVALID) {
175         return ERR_ILLEGAL_STATE;
176     }
177     if (status_ == I_STATUS_STARTED) {
178         return SUCCESS;
179     }
180     status_ = I_STATUS_STARTED;
181     isFirstFrame_ = true;
182     isFirstNoUnderrunFrame_ = false;
183     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
184     if (statusCallback != nullptr) {
185         statusCallback->OnStatusUpdate(OPERATION_STARTED);
186     }
187     return SUCCESS;
188 }
189 
Pause(bool isStandby)190 int32_t ProRendererStreamImpl::Pause(bool isStandby)
191 {
192     AUDIO_INFO_LOG("Enter");
193     if (status_ == I_STATUS_STARTED) {
194         status_ = I_STATUS_PAUSED;
195     }
196     if (isFirstFrame_) {
197         firstFrameSync_.notify_all();
198     }
199     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
200     if (statusCallback != nullptr) {
201         statusCallback->OnStatusUpdate(OPERATION_PAUSED);
202     }
203     return SUCCESS;
204 }
205 
Flush()206 int32_t ProRendererStreamImpl::Flush()
207 {
208     AUDIO_INFO_LOG("Enter");
209     {
210         std::lock_guard lock(enqueueMutex);
211         while (!readQueue_.empty()) {
212             int32_t index = readQueue_.front();
213             readQueue_.pop();
214             writeQueue_.emplace(index);
215         }
216         if (isDrain_) {
217             drainSync_.notify_all();
218         }
219     }
220     for (auto &buffer : sinkBuffer_) {
221         memset_s(buffer.data(), buffer.size(), 0, buffer.size());
222     }
223     sinkBytesWritten_ = 0;
224     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
225     if (statusCallback != nullptr) {
226         statusCallback->OnStatusUpdate(OPERATION_FLUSHED);
227     }
228     return SUCCESS;
229 }
230 
Drain()231 int32_t ProRendererStreamImpl::Drain()
232 {
233     AUDIO_INFO_LOG("Enter");
234     isDrain_ = true;
235     if (!readQueue_.empty()) {
236         std::unique_lock lock(enqueueMutex);
237         drainSync_.wait_for(lock, std::chrono::milliseconds(DRAIN_WAIT_TIMEOUT_TIME),
238             [this] { return readQueue_.empty(); });
239     }
240     isDrain_ = false;
241     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
242     if (statusCallback != nullptr) {
243         statusCallback->OnStatusUpdate(OPERATION_DRAINED);
244     }
245     status_ = I_STATUS_DRAINED;
246     return SUCCESS;
247 }
248 
Stop()249 int32_t ProRendererStreamImpl::Stop()
250 {
251     AUDIO_INFO_LOG("Enter");
252     status_ = I_STATUS_STOPPED;
253     if (isFirstFrame_) {
254         firstFrameSync_.notify_all();
255     }
256     totalBytesWritten_ = 0;
257     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
258     if (statusCallback != nullptr) {
259         statusCallback->OnStatusUpdate(OPERATION_STOPPED);
260     }
261     return SUCCESS;
262 }
263 
Release()264 int32_t ProRendererStreamImpl::Release()
265 {
266     AUDIO_INFO_LOG("Enter");
267     status_ = I_STATUS_INVALID;
268     isBlock_ = true;
269     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
270     if (statusCallback != nullptr) {
271         statusCallback->OnStatusUpdate(OPERATION_RELEASED);
272     }
273     return SUCCESS;
274 }
275 
GetStreamFramesWritten(uint64_t & framesWritten)276 int32_t ProRendererStreamImpl::GetStreamFramesWritten(uint64_t &framesWritten)
277 {
278     CHECK_AND_RETURN_RET_LOG(byteSizePerFrame_ != 0, ERR_ILLEGAL_STATE, "Error frame size");
279     framesWritten = totalBytesWritten_ / byteSizePerFrame_;
280     return SUCCESS;
281 }
282 
GetCurrentTimeStamp(uint64_t & timestamp)283 int32_t ProRendererStreamImpl::GetCurrentTimeStamp(uint64_t &timestamp)
284 {
285     int64_t timeSec = 0;
286     int64_t timeNsec = 0;
287     uint64_t framePosition;
288     bool ret = GetAudioTime(framePosition, timeSec, timeNsec);
289     CHECK_AND_RETURN_RET_LOG(ret, ERROR, "GetAudioTime error");
290     timestamp = static_cast<uint64_t>(timeSec * AUDIO_NS_PER_S + timeNsec);
291     return SUCCESS;
292 }
GetCurrentPosition(uint64_t & framePosition,uint64_t & timestamp,uint64_t & latency)293 int32_t ProRendererStreamImpl::GetCurrentPosition(uint64_t &framePosition, uint64_t &timestamp, uint64_t &latency)
294 {
295     int64_t timeSec = 0;
296     int64_t timeNsec = 0;
297     bool ret = GetAudioTime(framePosition, timeSec, timeNsec);
298     CHECK_AND_RETURN_RET_LOG(ret, ERROR, "GetAudioTime error");
299     timespec tm {};
300     clock_gettime(CLOCK_MONOTONIC, &tm);
301     timestamp = static_cast<uint64_t>(tm.tv_sec) * AUDIO_NS_PER_S + static_cast<uint64_t>(tm.tv_nsec);
302     latency = 0;
303     return SUCCESS;
304 }
305 
GetLatency(uint64_t & latency)306 int32_t ProRendererStreamImpl::GetLatency(uint64_t &latency)
307 {
308     CHECK_AND_RETURN_RET_LOG(byteSizePerFrame_ != 0, ERR_ILLEGAL_STATE, "Error frame size");
309     uint64_t framePos = sinkBytesWritten_ / byteSizePerFrame_;
310     latency = ((framePos / byteSizePerFrame_) * AUDIO_US_PER_S) / processConfig_.streamInfo.samplingRate;
311     return SUCCESS;
312 }
313 
SetRate(int32_t rate)314 int32_t ProRendererStreamImpl::SetRate(int32_t rate)
315 {
316     uint32_t currentRate = processConfig_.streamInfo.samplingRate;
317     switch (rate) {
318         case RENDER_RATE_NORMAL:
319             break;
320         case RENDER_RATE_DOUBLE:
321             currentRate *= DOUBLE_VALUE;
322             break;
323         case RENDER_RATE_HALF:
324             currentRate /= DOUBLE_VALUE;
325             break;
326         default:
327             return ERR_INVALID_PARAM;
328     }
329     (void)currentRate;
330     renderRate_ = rate;
331     return SUCCESS;
332 }
333 
SetAudioEffectMode(int32_t effectMode)334 int32_t ProRendererStreamImpl::SetAudioEffectMode(int32_t effectMode)
335 {
336     return SUCCESS;
337 }
GetAudioEffectMode(int32_t & effectMode)338 int32_t ProRendererStreamImpl::GetAudioEffectMode(int32_t &effectMode)
339 {
340     return SUCCESS;
341 }
342 
SetPrivacyType(int32_t privacyType)343 int32_t ProRendererStreamImpl::SetPrivacyType(int32_t privacyType)
344 {
345     privacyType_ = privacyType;
346     return SUCCESS;
347 }
348 
GetPrivacyType(int32_t & privacyType)349 int32_t ProRendererStreamImpl::GetPrivacyType(int32_t &privacyType)
350 {
351     privacyType = privacyType_;
352     return SUCCESS;
353 }
354 
RegisterStatusCallback(const std::weak_ptr<IStatusCallback> & callback)355 void ProRendererStreamImpl::RegisterStatusCallback(const std::weak_ptr<IStatusCallback> &callback)
356 {
357     AUDIO_DEBUG_LOG("enter in");
358     statusCallback_ = callback;
359 }
RegisterWriteCallback(const std::weak_ptr<IWriteCallback> & callback)360 void ProRendererStreamImpl::RegisterWriteCallback(const std::weak_ptr<IWriteCallback> &callback)
361 {
362     AUDIO_DEBUG_LOG("enter in");
363     writeCallback_ = callback;
364 }
365 
DequeueBuffer(size_t length)366 BufferDesc ProRendererStreamImpl::DequeueBuffer(size_t length)
367 {
368     BufferDesc bufferDesc = {nullptr, 0, 0};
369     if (status_ != I_STATUS_STARTED) {
370         return bufferDesc;
371     }
372     bufferDesc.buffer = reinterpret_cast<uint8_t *>(sinkBuffer_[0].data());
373     bufferDesc.bufLength = sinkBuffer_[0].size();
374     return bufferDesc;
375 }
376 
EnqueueBuffer(const BufferDesc & bufferDesc)377 int32_t ProRendererStreamImpl::EnqueueBuffer(const BufferDesc &bufferDesc)
378 {
379     int32_t writeIndex = PopWriteBufferIndex();
380     if (writeIndex < 0) {
381         AUDIO_ERR_LOG("write index is empty.");
382         return ERR_WRITE_BUFFER;
383     }
384     std::lock_guard lock(peekMutex);
385     float volume = GetStreamVolume();
386     if (isNeedMcr_ && !isNeedResample_) {
387         ConvertSrcToFloat(bufferDesc.buffer, bufferDesc.bufLength, volume);
388         downMixer_->Apply(spanSizeInFrame_, resampleSrcBuffer.data(), resampleDesBuffer.data());
389         DumpFileUtil::WriteDumpFile(dumpFile_, resampleDesBuffer.data(), resampleDesBuffer.size() * sizeof(float));
390         ConvertFloatToDes(writeIndex);
391     } else if (isNeedMcr_ && isNeedResample_) {
392         ConvertSrcToFloat(bufferDesc.buffer, bufferDesc.bufLength, volume);
393         downMixer_->Apply(spanSizeInFrame_, resampleSrcBuffer.data(), resampleSrcBuffer.data());
394     }
395     if (isNeedResample_) {
396         if (!isNeedMcr_) {
397             ConvertSrcToFloat(bufferDesc.buffer, bufferDesc.bufLength, volume);
398         }
399         resample_->ProcessFloatResample(resampleSrcBuffer, resampleDesBuffer);
400         DumpFileUtil::WriteDumpFile(dumpFile_, resampleDesBuffer.data(), resampleDesBuffer.size() * sizeof(float));
401         ConvertFloatToDes(writeIndex);
402     } else if (!isNeedMcr_) {
403         auto streamInfo = processConfig_.streamInfo;
404         uint32_t samplePerFrame = Util::GetSamplePerFrame(streamInfo.format);
405         uint32_t frameLength = bufferDesc.bufLength / samplePerFrame;
406         if (desFormat_ == AudioSampleFormat::SAMPLE_S16LE) {
407             AudioCommonConverter::ConvertBufferTo16Bit(bufferDesc.buffer, streamInfo.format,
408                 reinterpret_cast<int16_t *>(sinkBuffer_[writeIndex].data()), frameLength, volume);
409         } else {
410             AudioCommonConverter::ConvertBufferTo32Bit(bufferDesc.buffer, streamInfo.format,
411                 reinterpret_cast<int32_t *>(sinkBuffer_[writeIndex].data()), frameLength, volume);
412         }
413     }
414     readQueue_.emplace(writeIndex);
415     if (isFirstFrame_) {
416         firstFrameSync_.notify_all();
417     }
418     AUDIO_DEBUG_LOG("buffer length:%{public}zu ,sink buffer length:%{public}zu,volume:%{public}f", bufferDesc.bufLength,
419         sinkBuffer_[0].size(), volume);
420     totalBytesWritten_ += bufferDesc.bufLength;
421     sinkBytesWritten_ += bufferDesc.bufLength;
422     return SUCCESS;
423 }
424 
GetMinimumBufferSize(size_t & minBufferSize) const425 int32_t ProRendererStreamImpl::GetMinimumBufferSize(size_t &minBufferSize) const
426 {
427     minBufferSize = minBufferSize_;
428     return SUCCESS;
429 }
430 
GetByteSizePerFrame(size_t & byteSizePerFrame) const431 void ProRendererStreamImpl::GetByteSizePerFrame(size_t &byteSizePerFrame) const
432 {
433     byteSizePerFrame = byteSizePerFrame_;
434 }
435 
GetSpanSizePerFrame(size_t & spanSizeInFrame) const436 void ProRendererStreamImpl::GetSpanSizePerFrame(size_t &spanSizeInFrame) const
437 {
438     spanSizeInFrame = spanSizeInFrame_;
439 }
440 
SetStreamIndex(uint32_t index)441 void ProRendererStreamImpl::SetStreamIndex(uint32_t index)
442 {
443     AUDIO_INFO_LOG("Using index/sessionId %{public}d", index);
444     streamIndex_ = index;
445 }
446 
AbortCallback(int32_t abortTimes)447 void ProRendererStreamImpl::AbortCallback(int32_t abortTimes)
448 {
449     abortFlag_ += abortTimes;
450 }
451 
GetStreamIndex()452 uint32_t ProRendererStreamImpl::GetStreamIndex()
453 {
454     return streamIndex_;
455 }
456 
457 // offload
SetOffloadMode(int32_t state,bool isAppBack)458 int32_t ProRendererStreamImpl::SetOffloadMode(int32_t state, bool isAppBack)
459 {
460     SetOffloadDisable();
461     return SUCCESS;
462 }
463 
UnsetOffloadMode()464 int32_t ProRendererStreamImpl::UnsetOffloadMode()
465 {
466     SetOffloadDisable();
467     return SUCCESS;
468 }
469 
GetOffloadApproximatelyCacheTime(uint64_t & timestamp,uint64_t & paWriteIndex,uint64_t & cacheTimeDsp,uint64_t & cacheTimePa)470 int32_t ProRendererStreamImpl::GetOffloadApproximatelyCacheTime(uint64_t &timestamp, uint64_t &paWriteIndex,
471     uint64_t &cacheTimeDsp, uint64_t &cacheTimePa)
472 {
473     return SUCCESS;
474 }
OffloadSetVolume(float volume)475 int32_t ProRendererStreamImpl::OffloadSetVolume(float volume)
476 {
477     return SUCCESS;
478 }
479 
GetWritableSize()480 size_t ProRendererStreamImpl::GetWritableSize()
481 {
482     return writeQueue_.size() * minBufferSize_;
483 }
484 // offload end
UpdateSpatializationState(bool spatializationEnabled,bool headTrackingEnabled)485 int32_t ProRendererStreamImpl::UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled)
486 {
487     return SUCCESS;
488 }
489 
GetAudioProcessConfig() const490 AudioProcessConfig ProRendererStreamImpl::GetAudioProcessConfig() const noexcept
491 {
492     return processConfig_;
493 }
494 
GetAudioTime(uint64_t & framePos,int64_t & sec,int64_t & nanoSec)495 bool ProRendererStreamImpl::GetAudioTime(uint64_t &framePos, int64_t &sec, int64_t &nanoSec)
496 {
497     GetStreamFramesWritten(framePos);
498     int64_t time = handleTimeModel_.GetTimeOfPos(framePos);
499     int64_t deltaTime = DEFAULT_BUFFER_MICROSECOND; // note: 20ms
500     time += deltaTime;
501     sec = time / AUDIO_NS_PER_S;
502     nanoSec = time % AUDIO_NS_PER_S;
503     return true;
504 }
505 
Peek(std::vector<char> * audioBuffer,int32_t & index)506 int32_t ProRendererStreamImpl::Peek(std::vector<char> *audioBuffer, int32_t &index)
507 {
508     int32_t result = SUCCESS;
509     if (isBlock_) {
510         return ERR_WRITE_BUFFER;
511     }
512     if (!readQueue_.empty()) {
513         PopSinkBuffer(audioBuffer, index);
514         return result;
515     }
516 
517     std::shared_ptr<IWriteCallback> writeCallback = writeCallback_.lock();
518     if (writeCallback != nullptr) {
519         result = writeCallback->OnWriteData(minBufferSize_);
520         switch (result) {
521             // As a low-risk change, temporarily keep the previous behavior
522             // and avoid enterring the err logic on underrun.
523             case ERR_RENDERER_IN_SERVER_UNDERRUN: {
524                 auto statusCallback = statusCallback_.lock();
525                 if (statusCallback != nullptr && isFirstNoUnderrunFrame_) {
526                     statusCallback->OnStatusUpdate(OPERATION_UNDERFLOW);
527                 }
528                 [[fallthrough]];
529             }
530             case SUCCESS: {
531                 PopSinkBuffer(audioBuffer, index);
532                 if (result != ERR_RENDERER_IN_SERVER_UNDERRUN) {
533                     isFirstNoUnderrunFrame_ = true;
534                     result = SUCCESS;
535                 }
536                 break;
537             }
538             default: {
539                 AUDIO_ERR_LOG("Write callback failed,result:%{public}d", result);
540                 return result;
541             }
542         }
543     } else {
544         AUDIO_ERR_LOG("Write callback is nullptr");
545         result = ERR_WRITE_BUFFER;
546     }
547     return result;
548 }
549 
ReturnIndex(int32_t index)550 int32_t ProRendererStreamImpl::ReturnIndex(int32_t index)
551 {
552     Trace::Count("ProRendererStreamImpl::ReturnIndex", index);
553     if (index < 0) {
554         return SUCCESS;
555     }
556     std::lock_guard lock(enqueueMutex);
557     writeQueue_.emplace(index);
558     return SUCCESS;
559 }
560 
SetClientVolume(float clientVolume)561 int32_t ProRendererStreamImpl::SetClientVolume(float clientVolume)
562 {
563     AUDIO_INFO_LOG("clientVolume: %{public}f", clientVolume);
564     return SUCCESS;
565 }
566 
UpdateMaxLength(uint32_t maxLength)567 int32_t ProRendererStreamImpl::UpdateMaxLength(uint32_t maxLength)
568 {
569     return SUCCESS;
570 }
571 
PopWriteBufferIndex()572 int32_t ProRendererStreamImpl::PopWriteBufferIndex()
573 {
574     std::lock_guard lock(enqueueMutex);
575     int32_t writeIndex = -1;
576     if (!writeQueue_.empty()) {
577         writeIndex = writeQueue_.front();
578         writeQueue_.pop();
579     }
580     return writeIndex;
581 }
582 
PopSinkBuffer(std::vector<char> * audioBuffer,int32_t & index)583 void ProRendererStreamImpl::PopSinkBuffer(std::vector<char> *audioBuffer, int32_t &index)
584 {
585     if (readQueue_.empty() && isFirstFrame_) {
586         std::unique_lock firstFrameLock(firstFrameMutex);
587         firstFrameSync_.wait_for(firstFrameLock, std::chrono::milliseconds(FIRST_FRAME_TIMEOUT_TIME),
588             [this] { return (!readQueue_.empty() || isBlock_); });
589         if (!readQueue_.empty()) {
590             isFirstFrame_ = false;
591         }
592     }
593     std::lock_guard lock(enqueueMutex);
594     if (!readQueue_.empty()) {
595         index = readQueue_.front();
596         readQueue_.pop();
597         *audioBuffer = sinkBuffer_[index];
598         Trace::Count("ProRendererStreamImpl::PopSinkBuffer", index);
599     }
600     if (readQueue_.empty() && isDrain_) {
601         drainSync_.notify_all();
602     }
603 }
604 
SetOffloadDisable()605 void ProRendererStreamImpl::SetOffloadDisable()
606 {
607     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
608     if (statusCallback != nullptr) {
609         statusCallback->OnStatusUpdate(OPERATION_UNSET_OFFLOAD_ENABLE);
610     }
611 }
612 
ConvertSrcToFloat(uint8_t * buffer,size_t bufLength,float volume)613 void ProRendererStreamImpl::ConvertSrcToFloat(uint8_t *buffer, size_t bufLength, float volume)
614 {
615     auto streamInfo = processConfig_.streamInfo;
616     uint32_t samplePerFrame = Util::GetSamplePerFrame(streamInfo.format);
617     if (streamInfo.format == AudioSampleFormat::SAMPLE_F32LE) {
618         if (volume >= 1.0f) {
619             auto error =
620                 memcpy_s(resampleSrcBuffer.data(), resampleSrcBuffer.size() * samplePerFrame, buffer, bufLength);
621             if (error != EOK) {
622                 AUDIO_ERR_LOG("copy failed");
623             }
624         } else {
625             float *tempBuffer = reinterpret_cast<float *>(buffer);
626             for (uint32_t i = 0; i < resampleSrcBuffer.size(); i++) {
627                 resampleSrcBuffer[i] = volume * tempBuffer[i];
628             }
629         }
630         return;
631     }
632 
633     AUDIO_DEBUG_LOG("ConvertSrcToFloat resample buffer,samplePerFrame:%{public}d,size:%{public}zu", samplePerFrame,
634         resampleSrcBuffer.size());
635     AudioCommonConverter::ConvertBufferToFloat(buffer, samplePerFrame, resampleSrcBuffer, volume);
636 }
637 
ConvertFloatToDes(int32_t writeIndex)638 void ProRendererStreamImpl::ConvertFloatToDes(int32_t writeIndex)
639 {
640     uint32_t samplePerFrame = Util::GetSamplePerFrame(desFormat_);
641     if (desFormat_ == AudioSampleFormat::SAMPLE_F32LE) {
642         auto error = memcpy_s(sinkBuffer_[writeIndex].data(), sinkBuffer_[writeIndex].size(), resampleDesBuffer.data(),
643             resampleDesBuffer.size() * samplePerFrame);
644         if (error != EOK) {
645             AUDIO_ERR_LOG("copy failed");
646         }
647         return;
648     }
649     AudioCommonConverter::ConvertFloatToAudioBuffer(resampleDesBuffer,
650         reinterpret_cast<uint8_t *>(sinkBuffer_[writeIndex].data()), samplePerFrame);
651 }
652 
GetStreamVolume()653 float ProRendererStreamImpl::GetStreamVolume()
654 {
655     float volume = 1.0f;
656     AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(processConfig_.streamType);
657     DeviceType currentOutputDevice = PolicyHandler::GetInstance().GetActiveOutPutDevice();
658     Volume vol = {true, 1.0f, 0};
659     if (PolicyHandler::GetInstance().GetSharedVolume(volumeType, currentOutputDevice, vol)) {
660         volume = vol.isMute ? 0 : vol.volumeFloat;
661     }
662     return volume;
663 }
664 
InitBasicInfo(const AudioStreamInfo & streamInfo)665 void ProRendererStreamImpl::InitBasicInfo(const AudioStreamInfo &streamInfo)
666 {
667     currentRate_ = streamInfo.samplingRate;
668     desSamplingRate_ = GetDirectSampleRate(streamInfo.samplingRate);
669     desFormat_ = GetDirectFormat(streamInfo.format);
670     spanSizeInFrame_ = (streamInfo.samplingRate * DEFAULT_BUFFER_MILLISECOND) / SECOND_TO_MILLISECOND;
671     byteSizePerFrame_ = Util::GetSamplePerFrame(streamInfo.format) * streamInfo.channels;
672     minBufferSize_ = spanSizeInFrame_ * byteSizePerFrame_;
673     handleTimeModel_.ConfigSampleRate(currentRate_);
674 }
675 } // namespace AudioStandard
676 } // namespace OHOS
677