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 ×tamp)
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 ×tamp, 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 ×tamp, 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