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