1 /*
2 * Copyright (c) 2021-2022 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
16 #include <chrono>
17 #include <thread>
18 #include <vector>
19
20 #include "audio_errors.h"
21 #include "audio_log.h"
22 #include "audio_utils.h"
23
24 #include "audio_stream.h"
25
26 using namespace std;
27
28 namespace OHOS {
29 namespace AudioStandard {
30 const unsigned long long TIME_CONVERSION_US_S = 1000000ULL; /* us to s */
31 const unsigned long long TIME_CONVERSION_NS_US = 1000ULL; /* ns to us */
32 const unsigned long long TIME_CONVERSION_NS_S = 1000000000ULL; /* ns to s */
33 constexpr int32_t WRITE_RETRY_DELAY_IN_US = 500;
34 constexpr int32_t CB_WRITE_BUFFERS_WAIT_IN_MS = 80;
35 constexpr int32_t CB_READ_BUFFERS_WAIT_IN_MS = 80;
36
AudioStream(AudioStreamType eStreamType,AudioMode eMode,int32_t appUid)37 AudioStream::AudioStream(AudioStreamType eStreamType, AudioMode eMode, int32_t appUid)
38 : eStreamType_(eStreamType),
39 eMode_(eMode),
40 state_(NEW),
41 resetTime_(false),
42 resetTimestamp_(0),
43 renderMode_(RENDER_MODE_NORMAL),
44 captureMode_(CAPTURE_MODE_NORMAL),
45 isReadyToWrite_(false),
46 isReadyToRead_(false),
47 isFirstRead_(false),
48 isFirstWrite_(false)
49 {
50 AUDIO_DEBUG_LOG("AudioStream ctor, appUID = %{public}d", appUid);
51 audioStreamTracker_ = std::make_unique<AudioStreamTracker>(eMode, appUid);
52 AUDIO_DEBUG_LOG("AudioStreamTracker created");
53 }
54
~AudioStream()55 AudioStream::~AudioStream()
56 {
57 isReadyToWrite_ = false;
58 isReadyToRead_ = false;
59
60 if (writeThread_ && writeThread_->joinable()) {
61 writeThread_->join();
62 }
63
64 if (readThread_ && readThread_->joinable()) {
65 readThread_->join();
66 }
67
68 if (state_ != RELEASED && state_ != NEW) {
69 ReleaseAudioStream(false);
70 }
71
72 if (audioStreamTracker_ && audioStreamTracker_.get()) {
73 AUDIO_DEBUG_LOG("AudioStream:~AudioStream:Calling update tracker");
74 AudioRendererInfo rendererInfo = {};
75 AudioCapturerInfo capturerInfo = {};
76 state_ = RELEASED;
77 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo, capturerInfo);
78 }
79 }
80
SetRendererInfo(const AudioRendererInfo & rendererInfo)81 void AudioStream::SetRendererInfo(const AudioRendererInfo &rendererInfo)
82 {
83 rendererInfo_ = rendererInfo;
84 SetStreamUsage(rendererInfo.streamUsage);
85 }
86
SetCapturerInfo(const AudioCapturerInfo & capturerInfo)87 void AudioStream::SetCapturerInfo(const AudioCapturerInfo &capturerInfo)
88 {
89 capturerInfo_ = capturerInfo;
90 }
91
GetState()92 State AudioStream::GetState()
93 {
94 return state_;
95 }
96
GetAudioSessionID(uint32_t & sessionID)97 int32_t AudioStream::GetAudioSessionID(uint32_t &sessionID)
98 {
99 if ((state_ == RELEASED) || (state_ == NEW)) {
100 return ERR_ILLEGAL_STATE;
101 }
102
103 if (GetSessionID(sessionID) != 0) {
104 return ERR_INVALID_INDEX;
105 }
106
107 sessionId_ = sessionID;
108
109 return SUCCESS;
110 }
111
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)112 bool AudioStream::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base)
113 {
114 if (state_ == STOPPED) {
115 return false;
116 }
117 uint64_t paTimeStamp = 0;
118 if (GetCurrentTimeStamp(paTimeStamp) == SUCCESS) {
119 if (resetTime_) {
120 AUDIO_INFO_LOG("AudioStream::GetAudioTime resetTime_ %{public}d", resetTime_);
121 resetTime_ = false;
122 resetTimestamp_ = paTimeStamp;
123 }
124 if (eMode_ == AUDIO_MODE_PLAYBACK) {
125 timestamp.framePosition = GetStreamFramesWritten();
126 } else {
127 timestamp.framePosition = GetStreamFramesRead();
128 }
129
130 timestamp.time.tv_sec = static_cast<time_t>((paTimeStamp - resetTimestamp_) / TIME_CONVERSION_US_S);
131 timestamp.time.tv_nsec
132 = static_cast<time_t>(((paTimeStamp - resetTimestamp_) - (timestamp.time.tv_sec * TIME_CONVERSION_US_S))
133 * TIME_CONVERSION_NS_US);
134 timestamp.time.tv_sec += baseTimestamp_.tv_sec;
135 timestamp.time.tv_nsec += baseTimestamp_.tv_nsec;
136 timestamp.time.tv_sec += (timestamp.time.tv_nsec / TIME_CONVERSION_NS_S);
137 timestamp.time.tv_nsec = (timestamp.time.tv_nsec % TIME_CONVERSION_NS_S);
138
139 return true;
140 }
141 return false;
142 }
143
GetBufferSize(size_t & bufferSize)144 int32_t AudioStream::GetBufferSize(size_t &bufferSize)
145 {
146 AUDIO_INFO_LOG("AudioStream: Get Buffer size");
147 if (GetMinimumBufferSize(bufferSize) != 0) {
148 return ERR_OPERATION_FAILED;
149 }
150
151 return SUCCESS;
152 }
153
GetFrameCount(uint32_t & frameCount)154 int32_t AudioStream::GetFrameCount(uint32_t &frameCount)
155 {
156 AUDIO_INFO_LOG("AudioStream: Get frame count");
157 if (GetMinimumFrameCount(frameCount) != 0) {
158 return ERR_OPERATION_FAILED;
159 }
160
161 return SUCCESS;
162 }
163
GetLatency(uint64_t & latency)164 int32_t AudioStream::GetLatency(uint64_t &latency)
165 {
166 if (GetAudioLatency(latency) != SUCCESS) {
167 return ERR_OPERATION_FAILED;
168 } else {
169 return SUCCESS;
170 }
171 }
172
GetSupportedFormats() const173 vector<AudioSampleFormat> AudioStream::GetSupportedFormats() const
174 {
175 return AUDIO_SUPPORTED_FORMATS;
176 }
177
GetSupportedEncodingTypes() const178 vector<AudioEncodingType> AudioStream::GetSupportedEncodingTypes() const
179 {
180 return AUDIO_SUPPORTED_ENCODING_TYPES;
181 }
182
GetSupportedSamplingRates() const183 vector<AudioSamplingRate> AudioStream::GetSupportedSamplingRates() const
184 {
185 return AUDIO_SUPPORTED_SAMPLING_RATES;
186 }
187
IsFormatValid(uint8_t format)188 bool IsFormatValid(uint8_t format)
189 {
190 bool isValidFormat = (find(AUDIO_SUPPORTED_FORMATS.begin(), AUDIO_SUPPORTED_FORMATS.end(), format)
191 != AUDIO_SUPPORTED_FORMATS.end());
192 AUDIO_DEBUG_LOG("AudioStream: IsFormatValid: %{public}s", isValidFormat ? "true" : "false");
193 return isValidFormat;
194 }
195
IsRendererChannelValid(uint8_t channel)196 bool IsRendererChannelValid(uint8_t channel)
197 {
198 bool isValidChannel = (find(RENDERER_SUPPORTED_CHANNELS.begin(), RENDERER_SUPPORTED_CHANNELS.end(), channel)
199 != RENDERER_SUPPORTED_CHANNELS.end());
200 AUDIO_DEBUG_LOG("AudioStream: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
201 return isValidChannel;
202 }
203
IsCapturerChannelValid(uint8_t channel)204 bool IsCapturerChannelValid(uint8_t channel)
205 {
206 bool isValidChannel = (find(CAPTURER_SUPPORTED_CHANNELS.begin(), CAPTURER_SUPPORTED_CHANNELS.end(), channel)
207 != CAPTURER_SUPPORTED_CHANNELS.end());
208 AUDIO_DEBUG_LOG("AudioStream: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
209 return isValidChannel;
210 }
211
IsEncodingTypeValid(uint8_t encodingType)212 bool IsEncodingTypeValid(uint8_t encodingType)
213 {
214 bool isValidEncodingType
215 = (find(AUDIO_SUPPORTED_ENCODING_TYPES.begin(), AUDIO_SUPPORTED_ENCODING_TYPES.end(), encodingType)
216 != AUDIO_SUPPORTED_ENCODING_TYPES.end());
217 AUDIO_DEBUG_LOG("AudioStream: IsEncodingTypeValid: %{public}s", isValidEncodingType ? "true" : "false");
218 return isValidEncodingType;
219 }
220
IsSamplingRateValid(uint32_t samplingRate)221 bool IsSamplingRateValid(uint32_t samplingRate)
222 {
223 bool isValidSamplingRate
224 = (find(AUDIO_SUPPORTED_SAMPLING_RATES.begin(), AUDIO_SUPPORTED_SAMPLING_RATES.end(), samplingRate)
225 != AUDIO_SUPPORTED_SAMPLING_RATES.end());
226 AUDIO_DEBUG_LOG("AudioStream: IsSamplingRateValid: %{public}s", isValidSamplingRate ? "true" : "false");
227 return isValidSamplingRate;
228 }
229
GetAudioStreamInfo(AudioStreamParams & audioStreamInfo)230 int32_t AudioStream::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo)
231 {
232 AUDIO_INFO_LOG("AudioStream: GetAudioStreamInfo");
233 if (GetAudioStreamParams(audioStreamInfo) != 0) {
234 return ERR_OPERATION_FAILED;
235 }
236
237 return SUCCESS;
238 }
239
RegisterTracker(const std::shared_ptr<AudioClientTracker> & proxyObj)240 void AudioStream::RegisterTracker(const std::shared_ptr<AudioClientTracker> &proxyObj)
241 {
242 if (audioStreamTracker_ && audioStreamTracker_.get() && !streamTrackerRegistered_) {
243 (void)GetSessionID(sessionId_);
244 AUDIO_DEBUG_LOG("AudioStream:Calling register tracker, sessionid = %{public}d", sessionId_);
245 audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, proxyObj);
246 streamTrackerRegistered_ = true;
247 }
248 }
249
SetAudioStreamInfo(const AudioStreamParams info,const std::shared_ptr<AudioClientTracker> & proxyObj)250 int32_t AudioStream::SetAudioStreamInfo(const AudioStreamParams info,
251 const std::shared_ptr<AudioClientTracker> &proxyObj)
252 {
253 AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d,"
254 " stream type: %{public}d, encoding type: %{public}d", info.samplingRate, info.channels, info.format,
255 eStreamType_, info.encoding);
256
257 if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) {
258 AUDIO_ERR_LOG("AudioStream: Unsupported audio parameter");
259 return ERR_NOT_SUPPORTED;
260 }
261 if (state_ != NEW) {
262 AUDIO_INFO_LOG("AudioStream: State is not new, release existing stream");
263 StopAudioStream();
264 ReleaseAudioStream(false);
265 }
266 {
267 int32_t ret = 0;
268 static std::mutex connectServerMutex;
269 std::lock_guard<std::mutex> lockConnect(connectServerMutex);
270 Trace trace("AudioStream::Initialize");
271 if (eMode_ == AUDIO_MODE_PLAYBACK) {
272 AUDIO_DEBUG_LOG("AudioStream: Initialize playback");
273 if (!IsRendererChannelValid(info.channels)) {
274 AUDIO_ERR_LOG("AudioStream: Invalid sink channel %{public}d", info.channels);
275 return ERR_NOT_SUPPORTED;
276 }
277 ret = Initialize(AUDIO_SERVICE_CLIENT_PLAYBACK);
278 } else if (eMode_ == AUDIO_MODE_RECORD) {
279 AUDIO_DEBUG_LOG("AudioStream: Initialize recording");
280 if (!IsCapturerChannelValid(info.channels)) {
281 AUDIO_ERR_LOG("AudioStream: Invalid source channel %{public}d", info.channels);
282 return ERR_NOT_SUPPORTED;
283 }
284 ret = Initialize(AUDIO_SERVICE_CLIENT_RECORD);
285 } else {
286 AUDIO_ERR_LOG("AudioStream: error eMode.");
287 return ERR_INVALID_OPERATION;
288 }
289 CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "AudioStream: Error initializing!");
290 }
291
292 if (CreateStream(info, eStreamType_) != SUCCESS) {
293 AUDIO_ERR_LOG("AudioStream:Create stream failed");
294 return ERROR;
295 }
296 state_ = PREPARED;
297 AUDIO_DEBUG_LOG("AudioStream:Set stream Info SUCCESS");
298 RegisterTracker(proxyObj);
299 return SUCCESS;
300 }
301
StartAudioStream(StateChangeCmdType cmdType)302 bool AudioStream::StartAudioStream(StateChangeCmdType cmdType)
303 {
304 if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) {
305 AUDIO_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_);
306 return false;
307 }
308
309 int32_t ret = StartStream(cmdType);
310 if (ret != SUCCESS) {
311 AUDIO_ERR_LOG("StartStream Start failed:%{public}d", ret);
312 return false;
313 }
314
315 resetTime_ = true;
316 int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_);
317 if (retCode != 0) {
318 AUDIO_ERR_LOG("AudioStream::StartAudioStream get system elapsed time failed: %d", retCode);
319 }
320
321 isFirstRead_ = true;
322 isFirstWrite_ = true;
323 state_ = RUNNING;
324
325 if (renderMode_ == RENDER_MODE_CALLBACK) {
326 isReadyToWrite_ = true;
327 writeThread_ = std::make_unique<std::thread>(&AudioStream::WriteCbTheadLoop, this);
328 } else if (captureMode_ == CAPTURE_MODE_CALLBACK) {
329 isReadyToRead_ = true;
330 readThread_ = std::make_unique<std::thread>(&AudioStream::ReadCbThreadLoop, this);
331 }
332
333 AUDIO_INFO_LOG("StartAudioStream SUCCESS, sessionId: %{public}d", sessionId_);
334
335 if (audioStreamTracker_ && audioStreamTracker_.get()) {
336 AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for Running");
337 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
338 }
339 return true;
340 }
341
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)342 int32_t AudioStream::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
343 {
344 if (userSize <= 0) {
345 AUDIO_ERR_LOG("Invalid userSize:%{public}zu", userSize);
346 return ERR_INVALID_PARAM;
347 }
348
349 if (state_ != RUNNING) {
350 AUDIO_ERR_LOG("Read: State is not RUNNNIG. Illegal state:%{public}u", state_);
351 return ERR_ILLEGAL_STATE;
352 }
353
354 if (isFirstRead_) {
355 FlushAudioStream();
356 isFirstRead_ = false;
357 }
358
359 StreamBuffer stream;
360 stream.buffer = &buffer;
361 stream.bufferLen = userSize;
362 int32_t readLen = ReadStream(stream, isBlockingRead);
363 if (readLen < 0) {
364 AUDIO_ERR_LOG("ReadStream fail,ret:%{public}d", readLen);
365 return ERR_INVALID_READ;
366 }
367
368 return readLen;
369 }
370
Write(uint8_t * buffer,size_t buffer_size)371 size_t AudioStream::Write(uint8_t *buffer, size_t buffer_size)
372 {
373 Trace trace("AudioStream::Write");
374 if (renderMode_ == RENDER_MODE_CALLBACK) {
375 AUDIO_ERR_LOG("AudioStream::Write not supported. RenderMode is callback");
376 return ERR_INCORRECT_MODE;
377 }
378
379 if ((buffer == nullptr) || (buffer_size <= 0)) {
380 AUDIO_ERR_LOG("Invalid buffer size:%{public}zu", buffer_size);
381 return ERR_INVALID_PARAM;
382 }
383
384 if (state_ != RUNNING) {
385 AUDIO_ERR_LOG("Write: Illegal state:%{public}u", state_);
386 // To allow context switch for APIs running in different thread contexts
387 std::this_thread::sleep_for(std::chrono::microseconds(WRITE_RETRY_DELAY_IN_US));
388 return ERR_ILLEGAL_STATE;
389 }
390
391 int32_t writeError;
392 StreamBuffer stream;
393 stream.buffer = buffer;
394 stream.bufferLen = buffer_size;
395
396 if (isFirstWrite_) {
397 if (RenderPrebuf(stream.bufferLen)) {
398 AUDIO_ERR_LOG("ERR_WRITE_FAILED");
399 return ERR_WRITE_FAILED;
400 }
401 isFirstWrite_ = false;
402 }
403
404 size_t bytesWritten = WriteStream(stream, writeError);
405 if (writeError != 0) {
406 AUDIO_ERR_LOG("WriteStream fail,writeError:%{public}d", writeError);
407 return ERR_WRITE_FAILED;
408 }
409 return bytesWritten;
410 }
411
PauseAudioStream(StateChangeCmdType cmdType)412 bool AudioStream::PauseAudioStream(StateChangeCmdType cmdType)
413 {
414 if (state_ != RUNNING) {
415 AUDIO_ERR_LOG("PauseAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
416 return false;
417 }
418 State oldState = state_;
419 // Update state to stop write thread
420 state_ = PAUSED;
421
422 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
423 isReadyToRead_ = false;
424 if (readThread_ && readThread_->joinable()) {
425 readThread_->join();
426 }
427 }
428
429 // Ends the WriteCb thread
430 if (renderMode_ == RENDER_MODE_CALLBACK) {
431 isReadyToWrite_ = false;
432 // wake write thread to make pause faster
433 bufferQueueCV_.notify_all();
434 if (writeThread_ && writeThread_->joinable()) {
435 writeThread_->join();
436 }
437 }
438
439 AUDIO_DEBUG_LOG("AudioStream::PauseAudioStream:renderMode_ : %{public}d state_: %{public}d", renderMode_, state_);
440 int32_t ret = PauseStream(cmdType);
441 if (ret != SUCCESS) {
442 AUDIO_DEBUG_LOG("StreamPause fail,ret:%{public}d", ret);
443 state_ = oldState;
444 return false;
445 }
446
447 AUDIO_INFO_LOG("PauseAudioStream SUCCESS, sessionId: %{public}d", sessionId_);
448
449 // flush stream after stream paused
450 FlushAudioStream();
451
452 if (audioStreamTracker_ && audioStreamTracker_.get()) {
453 AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for Pause");
454 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
455 }
456 return true;
457 }
458
StopAudioStream()459 bool AudioStream::StopAudioStream()
460 {
461 AUDIO_INFO_LOG("AudioStream: begin StopAudioStream for sessionId %{public}d", sessionId_);
462 if ((state_ != RUNNING) && (state_ != PAUSED)) {
463 AUDIO_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
464 return false;
465 }
466 State oldState = state_;
467 state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads
468
469 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
470 isReadyToRead_ = false;
471 if (readThread_ && readThread_->joinable()) {
472 readThread_->join();
473 }
474 }
475
476 if (renderMode_ == RENDER_MODE_CALLBACK) {
477 isReadyToWrite_ = false;
478 if (writeThread_ && writeThread_->joinable()) {
479 writeThread_->join();
480 }
481 }
482
483 int32_t ret = StopStream();
484 if (ret != SUCCESS) {
485 AUDIO_DEBUG_LOG("StreamStop fail,ret:%{public}d", ret);
486 state_ = oldState;
487 return false;
488 }
489
490 if (audioStreamTracker_ && audioStreamTracker_.get()) {
491 AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for stop");
492 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
493 }
494 return true;
495 }
496
FlushAudioStream()497 bool AudioStream::FlushAudioStream()
498 {
499 Trace trace("AudioStream::FlushAudioStream");
500 if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
501 AUDIO_ERR_LOG("FlushAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
502 return false;
503 }
504
505 int32_t ret = FlushStream();
506 if (ret != SUCCESS) {
507 AUDIO_DEBUG_LOG("Flush stream fail,ret:%{public}d", ret);
508 return false;
509 }
510
511 AUDIO_INFO_LOG("Flush stream SUCCESS, sessionId: %{public}d", sessionId_);
512 return true;
513 }
514
DrainAudioStream()515 bool AudioStream::DrainAudioStream()
516 {
517 if (state_ != RUNNING) {
518 AUDIO_ERR_LOG("DrainAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
519 return false;
520 }
521
522 int32_t ret = DrainStream();
523 if (ret != SUCCESS) {
524 AUDIO_DEBUG_LOG("Drain stream fail,ret:%{public}d", ret);
525 return false;
526 }
527
528 AUDIO_INFO_LOG("Drain stream SUCCESS");
529 return true;
530 }
531
ReleaseAudioStream(bool releaseRunner)532 bool AudioStream::ReleaseAudioStream(bool releaseRunner)
533 {
534 if (state_ == RELEASED || state_ == NEW) {
535 AUDIO_ERR_LOG("Illegal state: state = %{public}u", state_);
536 return false;
537 }
538 // If state_ is RUNNING try to Stop it first and Release
539 if (state_ == RUNNING) {
540 StopAudioStream();
541 }
542
543 ReleaseStream(releaseRunner);
544 state_ = RELEASED;
545 AUDIO_INFO_LOG("ReleaseAudiostream SUCCESS, sessionId: %{public}d", sessionId_);
546
547 if (audioStreamTracker_ && audioStreamTracker_.get()) {
548 AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for release");
549 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
550 }
551 return true;
552 }
553
SetAudioStreamType(AudioStreamType audioStreamType)554 int32_t AudioStream::SetAudioStreamType(AudioStreamType audioStreamType)
555 {
556 return SetStreamType(audioStreamType);
557 }
558
SetVolume(float volume)559 int32_t AudioStream::SetVolume(float volume)
560 {
561 return SetStreamVolume(volume);
562 }
563
GetVolume()564 float AudioStream::GetVolume()
565 {
566 return GetStreamVolume();
567 }
568
SetRenderRate(AudioRendererRate renderRate)569 int32_t AudioStream::SetRenderRate(AudioRendererRate renderRate)
570 {
571 return SetStreamRenderRate(renderRate);
572 }
573
GetRenderRate()574 AudioRendererRate AudioStream::GetRenderRate()
575 {
576 return GetStreamRenderRate();
577 }
578
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)579 int32_t AudioStream::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
580 {
581 if (callback == nullptr) {
582 AUDIO_ERR_LOG("AudioStream::SetStreamCallback failed. callback == nullptr");
583 return ERR_INVALID_PARAM;
584 }
585
586 SaveStreamCallback(callback);
587
588 return SUCCESS;
589 }
590
SetRenderMode(AudioRenderMode renderMode)591 int32_t AudioStream::SetRenderMode(AudioRenderMode renderMode)
592 {
593 int32_t ret = SetAudioRenderMode(renderMode);
594 if (ret) {
595 AUDIO_ERR_LOG("AudioStream::SetRenderMode: renderMode: %{public}d failed", renderMode);
596 return ERR_OPERATION_FAILED;
597 }
598 renderMode_ = renderMode;
599
600 lock_guard<mutex> lock(bufferQueueLock_);
601
602 for (int32_t i = 0; i < MAX_WRITECB_NUM_BUFFERS; ++i) {
603 size_t length;
604 GetMinimumBufferSize(length);
605 AUDIO_INFO_LOG("AudioServiceClient:: GetMinimumBufferSize: %{public}zu", length);
606
607 writeBufferPool_[i] = std::make_unique<uint8_t[]>(length);
608 if (writeBufferPool_[i] == nullptr) {
609 AUDIO_ERR_LOG(
610 "AudioServiceClient::GetBufferDescriptor writeBufferPool_[i]==nullptr. Allocate memory failed.");
611 return ERR_OPERATION_FAILED;
612 }
613
614 BufferDesc bufDesc {};
615 bufDesc.buffer = writeBufferPool_[i].get();
616 bufDesc.bufLength = length;
617 freeBufferQ_.emplace(bufDesc);
618 }
619
620 return SUCCESS;
621 }
622
GetRenderMode()623 AudioRenderMode AudioStream::GetRenderMode()
624 {
625 return GetAudioRenderMode();
626 }
627
SetCaptureMode(AudioCaptureMode captureMode)628 int32_t AudioStream::SetCaptureMode(AudioCaptureMode captureMode)
629 {
630 int32_t ret = SetAudioCaptureMode(captureMode);
631 if (ret) {
632 AUDIO_ERR_LOG("AudioStream::SetCaptureMode: captureMode: %{public}d failed", captureMode);
633 return ERR_OPERATION_FAILED;
634 }
635 captureMode_ = captureMode;
636
637 lock_guard<mutex> lock(bufferQueueLock_);
638
639 for (int32_t i = 0; i < MAX_READCB_NUM_BUFFERS; ++i) {
640 size_t length;
641 GetMinimumBufferSize(length);
642 AUDIO_INFO_LOG("AudioStream::SetCaptureMode: length %{public}zu", length);
643
644 readBufferPool_[i] = std::make_unique<uint8_t[]>(length);
645 if (readBufferPool_[i] == nullptr) {
646 AUDIO_ERR_LOG("AudioStream::SetCaptureMode readBufferPool_[i]==nullptr. Allocate memory failed.");
647 return ERR_OPERATION_FAILED;
648 }
649
650 BufferDesc bufDesc {};
651 bufDesc.buffer = readBufferPool_[i].get();
652 bufDesc.bufLength = length;
653 freeBufferQ_.emplace(bufDesc);
654 }
655
656 return SUCCESS;
657 }
658
GetCaptureMode()659 AudioCaptureMode AudioStream::GetCaptureMode()
660 {
661 return GetAudioCaptureMode();
662 }
663
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)664 int32_t AudioStream::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
665 {
666 if (renderMode_ != RENDER_MODE_CALLBACK) {
667 AUDIO_ERR_LOG("SetRendererWriteCallback not supported. Render mode is not callback.");
668 return ERR_INCORRECT_MODE;
669 }
670
671 if (!callback) {
672 AUDIO_ERR_LOG("SetRendererWriteCallback callback is nullptr");
673 return ERR_INVALID_PARAM;
674 }
675 return AudioServiceClient::SetRendererWriteCallback(callback);
676 }
677
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)678 int32_t AudioStream::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
679 {
680 if (captureMode_ != CAPTURE_MODE_CALLBACK) {
681 AUDIO_ERR_LOG("SetCapturerReadCallback not supported. Capture mode is not callback.");
682 return ERR_INCORRECT_MODE;
683 }
684
685 if (!callback) {
686 AUDIO_ERR_LOG("SetCapturerReadCallback callback is nullptr");
687 return ERR_INVALID_PARAM;
688 }
689 return AudioServiceClient::SetCapturerReadCallback(callback);
690 }
691
GetBufferDesc(BufferDesc & bufDesc)692 int32_t AudioStream::GetBufferDesc(BufferDesc &bufDesc)
693 {
694 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
695 AUDIO_ERR_LOG("AudioStream::GetBufferDesc not supported. Render or Capture mode is not callback.");
696 return ERR_INCORRECT_MODE;
697 }
698
699 lock_guard<mutex> lock(bufferQueueLock_);
700
701 if (renderMode_ == RENDER_MODE_CALLBACK) {
702 if (!freeBufferQ_.empty()) {
703 bufDesc.buffer = freeBufferQ_.front().buffer;
704 bufDesc.bufLength = freeBufferQ_.front().bufLength;
705 bufDesc.dataLength = freeBufferQ_.front().dataLength;
706 freeBufferQ_.pop();
707 } else {
708 bufDesc.buffer = nullptr;
709 AUDIO_ERR_LOG("AudioStream::GetBufferDesc freeBufferQ_.empty()");
710 return ERR_OPERATION_FAILED;
711 }
712 }
713
714 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
715 if (!filledBufferQ_.empty()) {
716 bufDesc.buffer = filledBufferQ_.front().buffer;
717 bufDesc.bufLength = filledBufferQ_.front().bufLength;
718 bufDesc.dataLength = filledBufferQ_.front().dataLength;
719 filledBufferQ_.pop();
720 } else {
721 bufDesc.buffer = nullptr;
722 AUDIO_ERR_LOG("AudioStream::GetBufferDesc filledBufferQ_.empty()");
723 return ERR_OPERATION_FAILED;
724 }
725 }
726 return SUCCESS;
727 }
728
GetBufQueueState(BufferQueueState & bufState)729 int32_t AudioStream::GetBufQueueState(BufferQueueState &bufState)
730 {
731 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
732 AUDIO_ERR_LOG("AudioStream::GetBufQueueState not supported. Render or Capture mode is not callback.");
733 return ERR_INCORRECT_MODE;
734 }
735
736 lock_guard<mutex> lock(bufferQueueLock_);
737
738 if (renderMode_ == RENDER_MODE_CALLBACK) {
739 bufState.numBuffers = filledBufferQ_.size();
740 }
741
742 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
743 bufState.numBuffers = freeBufferQ_.size();
744 }
745
746 return SUCCESS;
747 }
748
Enqueue(const BufferDesc & bufDesc)749 int32_t AudioStream::Enqueue(const BufferDesc &bufDesc)
750 {
751 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
752 AUDIO_ERR_LOG("AudioStream::Enqueue not supported. Render or capture mode is not callback.");
753 return ERR_INCORRECT_MODE;
754 }
755
756 if (bufDesc.buffer == nullptr) {
757 AUDIO_ERR_LOG("AudioStream::Enqueue: failed. bufDesc.buffer == nullptr.");
758 return ERR_INVALID_PARAM;
759 }
760
761 unique_lock<mutex> lock(bufferQueueLock_);
762
763 if (renderMode_ == RENDER_MODE_CALLBACK) {
764 AUDIO_DEBUG_LOG("AudioStream::Enqueue: filledBuffer length: %{public}zu.", bufDesc.bufLength);
765 filledBufferQ_.emplace(bufDesc);
766 }
767
768 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
769 AUDIO_DEBUG_LOG("AudioStream::Enqueue: freeBuffer length: %{public}zu.", bufDesc.bufLength);
770 freeBufferQ_.emplace(bufDesc);
771 }
772
773 bufferQueueCV_.notify_all();
774
775 return SUCCESS;
776 }
777
Clear()778 int32_t AudioStream::Clear()
779 {
780 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
781 AUDIO_ERR_LOG("AudioStream::Clear not supported. Render or capture mode is not callback.");
782 return ERR_INCORRECT_MODE;
783 }
784
785 lock_guard<mutex> lock(bufferQueueLock_);
786
787 while (!filledBufferQ_.empty()) {
788 freeBufferQ_.emplace(filledBufferQ_.front());
789 filledBufferQ_.pop();
790 }
791
792 return SUCCESS;
793 }
794
WriteCbTheadLoop()795 void AudioStream::WriteCbTheadLoop()
796 {
797 AUDIO_INFO_LOG("WriteCb thread start");
798 StreamBuffer stream;
799 size_t bytesWritten;
800 int32_t writeError;
801
802 if (isReadyToWrite_) {
803 // send write events for application to fill all free buffers at the beginning
804 SubmitAllFreeBuffers();
805
806 while (true) {
807 if (state_ != RUNNING) {
808 AUDIO_INFO_LOG("Write: not running state: %{public}u", state_);
809 isReadyToWrite_ = false;
810 break;
811 }
812
813 unique_lock<mutex> lock(bufferQueueLock_);
814
815 if (filledBufferQ_.empty()) {
816 // wait signal with timeout
817 bufferQueueCV_.wait_for(lock, chrono::milliseconds(CB_WRITE_BUFFERS_WAIT_IN_MS));
818 continue;
819 }
820 stream.buffer = filledBufferQ_.front().buffer;
821 stream.bufferLen = filledBufferQ_.front().bufLength;
822
823 if (stream.buffer == nullptr) {
824 AUDIO_ERR_LOG("WriteCb stream.buffer is nullptr return");
825 break;
826 }
827 bytesWritten = WriteStreamInCb(stream, writeError);
828 if (writeError != 0) {
829 AUDIO_ERR_LOG("WriteStreamInCb fail, writeError:%{public}d", writeError);
830 } else {
831 AUDIO_DEBUG_LOG("WriteCb WriteStream, bytesWritten:%{public}zu", bytesWritten);
832 freeBufferQ_.emplace(filledBufferQ_.front());
833 filledBufferQ_.pop();
834 SendWriteBufferRequestEvent();
835 }
836 }
837 }
838 }
839
ReadCbThreadLoop()840 void AudioStream::ReadCbThreadLoop()
841 {
842 AUDIO_INFO_LOG("ReadCb thread start");
843 StreamBuffer stream;
844 if (isReadyToRead_) {
845 int32_t readLen;
846 bool isBlockingRead = true;
847 while (true) {
848 if (state_ != RUNNING) {
849 AUDIO_INFO_LOG("Read: not running state: %{public}u", state_);
850 isReadyToRead_ = false;
851 break;
852 }
853
854 unique_lock<mutex> lock(bufferQueueLock_);
855
856 if (freeBufferQ_.empty()) {
857 // wait signal with timeout
858 bufferQueueCV_.wait_for(lock, chrono::milliseconds(CB_READ_BUFFERS_WAIT_IN_MS));
859 continue;
860 }
861 stream.buffer = freeBufferQ_.front().buffer;
862 stream.bufferLen = freeBufferQ_.front().bufLength;
863
864 if (stream.buffer == nullptr) {
865 AUDIO_ERR_LOG("ReadCb stream.buffer == nullptr return");
866 break;
867 }
868 readLen = ReadStream(stream, isBlockingRead);
869 if (readLen < 0) {
870 AUDIO_ERR_LOG("ReadCb ReadStream fail, ret: %{public}d", readLen);
871 } else {
872 AUDIO_DEBUG_LOG("ReadCb ReadStream, bytesRead:%{public}d", readLen);
873 freeBufferQ_.front().dataLength = readLen;
874 filledBufferQ_.emplace(freeBufferQ_.front());
875 freeBufferQ_.pop();
876 SendReadBufferRequestEvent();
877 }
878 }
879 }
880 }
881
SetLowPowerVolume(float volume)882 int32_t AudioStream::SetLowPowerVolume(float volume)
883 {
884 return SetStreamLowPowerVolume(volume);
885 }
886
GetLowPowerVolume()887 float AudioStream::GetLowPowerVolume()
888 {
889 return GetStreamLowPowerVolume();
890 }
891
GetSingleStreamVolume()892 float AudioStream::GetSingleStreamVolume()
893 {
894 return GetSingleStreamVol();
895 }
896
SubmitAllFreeBuffers()897 void AudioStream::SubmitAllFreeBuffers()
898 {
899 lock_guard<mutex> lock(bufferQueueLock_);
900 for (size_t i = 0; i < freeBufferQ_.size(); ++i) {
901 SendWriteBufferRequestEvent();
902 }
903 }
904
SetAudioEffectMode(AudioEffectMode effectMode)905 int32_t AudioStream::SetAudioEffectMode(AudioEffectMode effectMode)
906 {
907 return SetStreamAudioEffectMode(effectMode);
908 }
909
GetAudioEffectMode()910 AudioEffectMode AudioStream::GetAudioEffectMode()
911 {
912 return GetStreamAudioEffectMode();
913 }
914
SetInnerCapturerState(bool isInnerCapturer)915 void AudioStream::SetInnerCapturerState(bool isInnerCapturer)
916 {
917 SetStreamInnerCapturerState(isInnerCapturer);
918 }
919
SetPrivacyType(AudioPrivacyType privacyType)920 void AudioStream::SetPrivacyType(AudioPrivacyType privacyType)
921 {
922 SetStreamPrivacyType(privacyType);
923 }
924
GetFramesWritten()925 int64_t AudioStream::GetFramesWritten()
926 {
927 return GetStreamFramesWritten();
928 }
929
GetFramesRead()930 int64_t AudioStream::GetFramesRead()
931 {
932 return GetStreamFramesRead();
933 }
934
SetStreamTrackerState(bool trackerRegisteredState)935 void AudioStream::SetStreamTrackerState(bool trackerRegisteredState)
936 {
937 streamTrackerRegistered_ = trackerRegisteredState;
938 }
939
GetSwitchInfo(SwitchInfo & info)940 void AudioStream::GetSwitchInfo(SwitchInfo& info)
941 {
942 GetAudioStreamParams(info.params);
943
944 info.rendererInfo = rendererInfo_;
945 info.capturerInfo = capturerInfo_;
946 info.eStreamType = eStreamType_;
947 info.renderMode = renderMode_;
948 info.state = state_;
949 info.sessionId = sessionId_;
950 info.streamTrackerRegistered = streamTrackerRegistered_;
951 GetStreamSwitchInfo(info);
952 }
953
954 } // namespace AudioStandard
955 } // namespace OHOS
956