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