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