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 ×tamp, 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 int32_t ret = 0;
309 switch (eMode_) {
310 case AUDIO_MODE_PLAYBACK:
311 AUDIO_DEBUG_LOG("AudioStream: Initialize playback");
312 if (!IsRendererChannelValid(info.channels)) {
313 AUDIO_ERR_LOG("AudioStream: Invalid sink channel %{public}d", info.channels);
314 return ERR_NOT_SUPPORTED;
315 }
316 ret = Initialize(AUDIO_SERVICE_CLIENT_PLAYBACK);
317 break;
318 case AUDIO_MODE_RECORD:
319 AUDIO_DEBUG_LOG("AudioStream: Initialize recording");
320 if (!IsCapturerChannelValid(info.channels)) {
321 AUDIO_ERR_LOG("AudioStream: Invalid source channel %{public}d", info.channels);
322 return ERR_NOT_SUPPORTED;
323 }
324 ret = Initialize(AUDIO_SERVICE_CLIENT_RECORD);
325 break;
326 default:
327 return ERR_INVALID_OPERATION;
328 }
329
330 if (ret) {
331 AUDIO_DEBUG_LOG("AudioStream: Error initializing!");
332 return ret;
333 }
334 if (CreateStream(info, eStreamType_) != SUCCESS) {
335 AUDIO_ERR_LOG("AudioStream:Create stream failed");
336 return ERROR;
337 }
338 state_ = PREPARED;
339 AUDIO_INFO_LOG("AudioStream:Set stream Info SUCCESS");
340
341 if (audioStreamTracker_ && audioStreamTracker_.get()) {
342 (void)GetSessionID(sessionId_);
343 AUDIO_DEBUG_LOG("AudioStream:Calling register tracker, sessionid = %{public}d", sessionId_);
344 audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, proxyObj);
345 }
346 return SUCCESS;
347 }
348
StartAudioStream(StateChangeCmdType cmdType)349 bool AudioStream::StartAudioStream(StateChangeCmdType cmdType)
350 {
351 if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) {
352 AUDIO_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_);
353 return false;
354 }
355
356 int32_t ret = StartStream(cmdType);
357 if (ret != SUCCESS) {
358 AUDIO_ERR_LOG("StartStream Start failed:%{public}d", ret);
359 return false;
360 }
361
362 resetTime_ = true;
363 int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_);
364 if (retCode != 0) {
365 AUDIO_ERR_LOG("AudioStream::StartAudioStream get system elapsed time failed: %d", retCode);
366 }
367
368 isFirstRead_ = true;
369 isFirstWrite_ = true;
370 state_ = RUNNING;
371
372 if (renderMode_ == RENDER_MODE_CALLBACK) {
373 isReadyToWrite_ = true;
374 writeThread_ = std::make_unique<std::thread>(&AudioStream::WriteCbTheadLoop, this);
375 } else if (captureMode_ == CAPTURE_MODE_CALLBACK) {
376 isReadyToRead_ = true;
377 readThread_ = std::make_unique<std::thread>(&AudioStream::ReadCbThreadLoop, this);
378 }
379
380 AUDIO_INFO_LOG("StartAudioStream SUCCESS");
381
382 if (audioStreamTracker_ && audioStreamTracker_.get()) {
383 AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for Running");
384 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
385 }
386 return true;
387 }
388
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)389 int32_t AudioStream::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
390 {
391 if (userSize <= 0) {
392 AUDIO_ERR_LOG("Invalid userSize:%{public}zu", userSize);
393 return ERR_INVALID_PARAM;
394 }
395
396 if (state_ != RUNNING) {
397 AUDIO_ERR_LOG("Read: State is not RUNNNIG. Illegal state:%{public}u", state_);
398 return ERR_ILLEGAL_STATE;
399 }
400
401 if (isFirstRead_) {
402 FlushAudioStream();
403 isFirstRead_ = false;
404 }
405
406 StreamBuffer stream;
407 stream.buffer = &buffer;
408 stream.bufferLen = userSize;
409 isReadInProgress_ = true;
410 int32_t readLen = ReadStream(stream, isBlockingRead);
411 isReadInProgress_ = false;
412 if (readLen < 0) {
413 AUDIO_ERR_LOG("ReadStream fail,ret:%{public}d", readLen);
414 return ERR_INVALID_READ;
415 }
416
417 return readLen;
418 }
419
Write(uint8_t * buffer,size_t buffer_size)420 size_t AudioStream::Write(uint8_t *buffer, size_t buffer_size)
421 {
422 if (renderMode_ == RENDER_MODE_CALLBACK) {
423 AUDIO_ERR_LOG("AudioStream::Write not supported. RenderMode is callback");
424 return ERR_INCORRECT_MODE;
425 }
426
427 if ((buffer == nullptr) || (buffer_size <= 0)) {
428 AUDIO_ERR_LOG("Invalid buffer size:%{public}zu", buffer_size);
429 return ERR_INVALID_PARAM;
430 }
431
432 if (state_ != RUNNING) {
433 AUDIO_ERR_LOG("Write: Illegal state:%{public}u", state_);
434 // To allow context switch for APIs running in different thread contexts
435 std::this_thread::sleep_for(std::chrono::microseconds(WRITE_RETRY_DELAY_IN_US));
436 return ERR_ILLEGAL_STATE;
437 }
438
439 int32_t writeError;
440 StreamBuffer stream;
441 stream.buffer = buffer;
442 stream.bufferLen = buffer_size;
443 isWriteInProgress_ = true;
444
445 if (isFirstWrite_) {
446 if (RenderPrebuf(stream.bufferLen)) {
447 return ERR_WRITE_FAILED;
448 }
449 isFirstWrite_ = false;
450 }
451
452 size_t bytesWritten = WriteStream(stream, writeError);
453 isWriteInProgress_ = false;
454 if (writeError != 0) {
455 AUDIO_ERR_LOG("WriteStream fail,writeError:%{public}d", writeError);
456 return ERR_WRITE_FAILED;
457 }
458 return bytesWritten;
459 }
460
PauseAudioStream(StateChangeCmdType cmdType)461 bool AudioStream::PauseAudioStream(StateChangeCmdType cmdType)
462 {
463 if (state_ != RUNNING) {
464 AUDIO_ERR_LOG("PauseAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
465 return false;
466 }
467 State oldState = state_;
468 // Update state to stop write thread
469 state_ = PAUSED;
470
471 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
472 isReadyToRead_ = false;
473 if (readThread_ && readThread_->joinable()) {
474 readThread_->join();
475 }
476 }
477
478 // Ends the WriteCb thread
479 if (renderMode_ == RENDER_MODE_CALLBACK) {
480 isReadyToWrite_ = false;
481 // wake write thread to make pause faster
482 bufferQueueCV_.notify_all();
483 if (writeThread_ && writeThread_->joinable()) {
484 writeThread_->join();
485 }
486 }
487
488 while (isReadInProgress_ || isWriteInProgress_) {
489 std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
490 }
491
492 AUDIO_DEBUG_LOG("AudioStream::PauseAudioStream:renderMode_ : %{public}d state_: %{public}d", renderMode_, state_);
493
494 int32_t ret = PauseStream(cmdType);
495 if (ret != SUCCESS) {
496 AUDIO_DEBUG_LOG("StreamPause fail,ret:%{public}d", ret);
497 state_ = oldState;
498 return false;
499 }
500
501 AUDIO_INFO_LOG("PauseAudioStream SUCCESS");
502
503 // flush stream after stream paused
504 FlushAudioStream();
505
506 if (audioStreamTracker_ && audioStreamTracker_.get()) {
507 AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for Pause");
508 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
509 }
510 return true;
511 }
512
StopAudioStream()513 bool AudioStream::StopAudioStream()
514 {
515 AUDIO_INFO_LOG("AudioStream: begin StopAudioStream for sessionId %{public}d", sessionId_);
516 if (state_ == PAUSED) {
517 state_ = STOPPED;
518 AUDIO_INFO_LOG("StopAudioStream SUCCESS");
519 return true;
520 }
521
522 if (state_ != RUNNING) {
523 AUDIO_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
524 return false;
525 }
526 State oldState = state_;
527 state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads
528
529 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
530 isReadyToRead_ = false;
531 if (readThread_ && readThread_->joinable()) {
532 readThread_->join();
533 }
534 }
535
536 if (renderMode_ == RENDER_MODE_CALLBACK) {
537 isReadyToWrite_ = false;
538 if (writeThread_ && writeThread_->joinable()) {
539 writeThread_->join();
540 }
541 }
542
543 while (isReadInProgress_ || isWriteInProgress_) {
544 std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
545 }
546
547 int32_t ret = StopStream();
548 if (ret != SUCCESS) {
549 AUDIO_DEBUG_LOG("StreamStop fail,ret:%{public}d", ret);
550 state_ = oldState;
551 return false;
552 }
553
554 AUDIO_INFO_LOG("StopAudioStream SUCCESS");
555
556 if (audioStreamTracker_ && audioStreamTracker_.get()) {
557 AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for stop");
558 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
559 }
560 return true;
561 }
562
FlushAudioStream()563 bool AudioStream::FlushAudioStream()
564 {
565 if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
566 AUDIO_ERR_LOG("FlushAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
567 return false;
568 }
569
570 int32_t ret = FlushStream();
571 if (ret != SUCCESS) {
572 AUDIO_DEBUG_LOG("Flush stream fail,ret:%{public}d", ret);
573 return false;
574 }
575
576 AUDIO_INFO_LOG("Flush stream SUCCESS");
577 return true;
578 }
579
DrainAudioStream()580 bool AudioStream::DrainAudioStream()
581 {
582 if (state_ != RUNNING) {
583 AUDIO_ERR_LOG("DrainAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
584 return false;
585 }
586
587 int32_t ret = DrainStream();
588 if (ret != SUCCESS) {
589 AUDIO_DEBUG_LOG("Drain stream fail,ret:%{public}d", ret);
590 return false;
591 }
592
593 AUDIO_INFO_LOG("Drain stream SUCCESS");
594 return true;
595 }
596
ReleaseAudioStream(bool releaseRunner)597 bool AudioStream::ReleaseAudioStream(bool releaseRunner)
598 {
599 if (state_ == RELEASED || state_ == NEW) {
600 AUDIO_ERR_LOG("Illegal state: state = %{public}u", state_);
601 return false;
602 }
603 // If state_ is RUNNING try to Stop it first and Release
604 if (state_ == RUNNING) {
605 StopAudioStream();
606 }
607
608 ReleaseStream(releaseRunner);
609 state_ = RELEASED;
610 AUDIO_INFO_LOG("ReleaseAudiostream SUCCESS");
611
612 if (audioStreamTracker_ && audioStreamTracker_.get()) {
613 AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for release");
614 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
615 }
616 return true;
617 }
618
GetStreamType(ContentType contentType,StreamUsage streamUsage)619 AudioStreamType AudioStream::GetStreamType(ContentType contentType, StreamUsage streamUsage)
620 {
621 AudioStreamType streamType = STREAM_MUSIC;
622 auto pos = streamTypeMap_.find(make_pair(contentType, streamUsage));
623 if (pos != streamTypeMap_.end()) {
624 streamType = pos->second;
625 }
626
627 if (streamType == STREAM_MEDIA) {
628 streamType = STREAM_MUSIC;
629 }
630
631 return streamType;
632 }
633
SetAudioStreamType(AudioStreamType audioStreamType)634 int32_t AudioStream::SetAudioStreamType(AudioStreamType audioStreamType)
635 {
636 return SetStreamType(audioStreamType);
637 }
638
SetVolume(float volume)639 int32_t AudioStream::SetVolume(float volume)
640 {
641 return SetStreamVolume(volume);
642 }
643
GetVolume()644 float AudioStream::GetVolume()
645 {
646 return GetStreamVolume();
647 }
648
SetRenderRate(AudioRendererRate renderRate)649 int32_t AudioStream::SetRenderRate(AudioRendererRate renderRate)
650 {
651 return SetStreamRenderRate(renderRate);
652 }
653
GetRenderRate()654 AudioRendererRate AudioStream::GetRenderRate()
655 {
656 return GetStreamRenderRate();
657 }
658
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)659 int32_t AudioStream::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
660 {
661 if (callback == nullptr) {
662 AUDIO_ERR_LOG("AudioStream::SetStreamCallback failed. callback == nullptr");
663 return ERR_INVALID_PARAM;
664 }
665
666 SaveStreamCallback(callback);
667
668 return SUCCESS;
669 }
670
SetRenderMode(AudioRenderMode renderMode)671 int32_t AudioStream::SetRenderMode(AudioRenderMode renderMode)
672 {
673 int32_t ret = SetAudioRenderMode(renderMode);
674 if (ret) {
675 AUDIO_ERR_LOG("AudioStream::SetRenderMode: renderMode: %{public}d failed", renderMode);
676 return ERR_OPERATION_FAILED;
677 }
678 renderMode_ = renderMode;
679
680 lock_guard<mutex> lock(bufferQueueLock_);
681
682 for (int32_t i = 0; i < MAX_WRITECB_NUM_BUFFERS; ++i) {
683 size_t length;
684 GetMinimumBufferSize(length);
685 AUDIO_INFO_LOG("AudioServiceClient:: GetMinimumBufferSize: %{public}zu", length);
686
687 writeBufferPool_[i] = std::make_unique<uint8_t[]>(length);
688 if (writeBufferPool_[i] == nullptr) {
689 AUDIO_INFO_LOG(
690 "AudioServiceClient::GetBufferDescriptor writeBufferPool_[i]==nullptr. Allocate memory failed.");
691 return ERR_OPERATION_FAILED;
692 }
693
694 BufferDesc bufDesc {};
695 bufDesc.buffer = writeBufferPool_[i].get();
696 bufDesc.bufLength = length;
697 freeBufferQ_.emplace(bufDesc);
698 }
699
700 return SUCCESS;
701 }
702
GetRenderMode()703 AudioRenderMode AudioStream::GetRenderMode()
704 {
705 return GetAudioRenderMode();
706 }
707
SetCaptureMode(AudioCaptureMode captureMode)708 int32_t AudioStream::SetCaptureMode(AudioCaptureMode captureMode)
709 {
710 int32_t ret = SetAudioCaptureMode(captureMode);
711 if (ret) {
712 AUDIO_ERR_LOG("AudioStream::SetCaptureMode: captureMode: %{public}d failed", captureMode);
713 return ERR_OPERATION_FAILED;
714 }
715 captureMode_ = captureMode;
716
717 lock_guard<mutex> lock(bufferQueueLock_);
718
719 for (int32_t i = 0; i < MAX_READCB_NUM_BUFFERS; ++i) {
720 size_t length;
721 GetMinimumBufferSize(length);
722 AUDIO_INFO_LOG("AudioStream::SetCaptureMode: length %{public}zu", length);
723
724 readBufferPool_[i] = std::make_unique<uint8_t[]>(length);
725 if (readBufferPool_[i] == nullptr) {
726 AUDIO_INFO_LOG("AudioStream::SetCaptureMode readBufferPool_[i]==nullptr. Allocate memory failed.");
727 return ERR_OPERATION_FAILED;
728 }
729
730 BufferDesc bufDesc {};
731 bufDesc.buffer = readBufferPool_[i].get();
732 bufDesc.bufLength = length;
733 freeBufferQ_.emplace(bufDesc);
734 }
735
736 return SUCCESS;
737 }
738
GetCaptureMode()739 AudioCaptureMode AudioStream::GetCaptureMode()
740 {
741 return GetAudioCaptureMode();
742 }
743
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)744 int32_t AudioStream::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
745 {
746 if (renderMode_ != RENDER_MODE_CALLBACK) {
747 AUDIO_ERR_LOG("AudioStream::SetRendererWriteCallback not supported. Render mode is not callback.");
748 return ERR_INCORRECT_MODE;
749 }
750
751 if (!callback) {
752 AUDIO_ERR_LOG("SetRendererWriteCallback callback is nullptr");
753 return ERR_INVALID_PARAM;
754 }
755 return AudioServiceClient::SetRendererWriteCallback(callback);
756 }
757
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)758 int32_t AudioStream::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
759 {
760 if (captureMode_ != CAPTURE_MODE_CALLBACK) {
761 AUDIO_ERR_LOG("AudioStream::SetCapturerReadCallback not supported. Capture mode is not callback.");
762 return ERR_INCORRECT_MODE;
763 }
764
765 int32_t ret = SaveReadCallback(callback);
766 if (ret) {
767 AUDIO_ERR_LOG("AudioStream::SetCapturerReadCallback: failed.");
768 return ERR_INVALID_PARAM;
769 }
770
771 return SUCCESS;
772 }
773
GetBufferDesc(BufferDesc & bufDesc)774 int32_t AudioStream::GetBufferDesc(BufferDesc &bufDesc)
775 {
776 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
777 AUDIO_ERR_LOG("AudioStream::GetBufferDesc not supported. Render or Capture mode is not callback.");
778 return ERR_INCORRECT_MODE;
779 }
780
781 lock_guard<mutex> lock(bufferQueueLock_);
782
783 if (renderMode_ == RENDER_MODE_CALLBACK) {
784 if (!freeBufferQ_.empty()) {
785 bufDesc.buffer = freeBufferQ_.front().buffer;
786 bufDesc.bufLength = freeBufferQ_.front().bufLength;
787 bufDesc.dataLength = freeBufferQ_.front().dataLength;
788 freeBufferQ_.pop();
789 } else {
790 bufDesc.buffer = nullptr;
791 AUDIO_INFO_LOG("AudioStream::GetBufferDesc freeBufferQ_.empty()");
792 return ERR_OPERATION_FAILED;
793 }
794 }
795
796 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
797 if (!filledBufferQ_.empty()) {
798 bufDesc.buffer = filledBufferQ_.front().buffer;
799 bufDesc.bufLength = filledBufferQ_.front().bufLength;
800 bufDesc.dataLength = filledBufferQ_.front().dataLength;
801 filledBufferQ_.pop();
802 } else {
803 bufDesc.buffer = nullptr;
804 AUDIO_INFO_LOG("AudioStream::GetBufferDesc filledBufferQ_.empty()");
805 return ERR_OPERATION_FAILED;
806 }
807 }
808 return SUCCESS;
809 }
810
GetBufQueueState(BufferQueueState & bufState)811 int32_t AudioStream::GetBufQueueState(BufferQueueState &bufState)
812 {
813 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
814 AUDIO_ERR_LOG("AudioStream::GetBufQueueState not supported. Render or Capture mode is not callback.");
815 return ERR_INCORRECT_MODE;
816 }
817
818 lock_guard<mutex> lock(bufferQueueLock_);
819
820 if (renderMode_ == RENDER_MODE_CALLBACK) {
821 bufState.numBuffers = filledBufferQ_.size();
822 }
823
824 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
825 bufState.numBuffers = freeBufferQ_.size();
826 }
827
828 return SUCCESS;
829 }
830
Enqueue(const BufferDesc & bufDesc)831 int32_t AudioStream::Enqueue(const BufferDesc &bufDesc)
832 {
833 AUDIO_INFO_LOG("AudioStream::Enqueue");
834 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
835 AUDIO_ERR_LOG("AudioStream::Enqueue not supported. Render or capture mode is not callback.");
836 return ERR_INCORRECT_MODE;
837 }
838
839 if (bufDesc.buffer == nullptr) {
840 AUDIO_ERR_LOG("AudioStream::Enqueue: failed. bufDesc.buffer == nullptr.");
841 return ERR_INVALID_PARAM;
842 }
843
844 unique_lock<mutex> lock(bufferQueueLock_);
845
846 if (renderMode_ == RENDER_MODE_CALLBACK) {
847 AUDIO_DEBUG_LOG("AudioStream::Enqueue: filledBuffer length: %{public}zu.", bufDesc.bufLength);
848 filledBufferQ_.emplace(bufDesc);
849 }
850
851 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
852 AUDIO_DEBUG_LOG("AudioStream::Enqueue: freeBuffer length: %{public}zu.", bufDesc.bufLength);
853 freeBufferQ_.emplace(bufDesc);
854 }
855
856 bufferQueueCV_.notify_all();
857
858 return SUCCESS;
859 }
860
Clear()861 int32_t AudioStream::Clear()
862 {
863 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
864 AUDIO_ERR_LOG("AudioStream::Clear not supported. Render or capture mode is not callback.");
865 return ERR_INCORRECT_MODE;
866 }
867
868 lock_guard<mutex> lock(bufferQueueLock_);
869
870 while (!filledBufferQ_.empty()) {
871 freeBufferQ_.emplace(filledBufferQ_.front());
872 filledBufferQ_.pop();
873 }
874
875 return SUCCESS;
876 }
877
WriteCbTheadLoop()878 void AudioStream::WriteCbTheadLoop()
879 {
880 AUDIO_INFO_LOG("AudioStream::WriteCb thread start");
881 StreamBuffer stream;
882 size_t bytesWritten;
883 int32_t writeError;
884
885 if (isReadyToWrite_) {
886 // send write events for application to fill all free buffers at the beginning
887 SubmitAllFreeBuffers();
888
889 while (true) {
890 if (state_ != RUNNING) {
891 AUDIO_INFO_LOG("Write: not running state: %{public}u", state_);
892 isReadyToWrite_ = false;
893 break;
894 }
895
896 unique_lock<mutex> lock(bufferQueueLock_);
897
898 if (filledBufferQ_.empty()) {
899 // wait signal with timeout
900 bufferQueueCV_.wait_for(lock, chrono::milliseconds(CB_WRITE_BUFFERS_WAIT_IN_MS));
901 continue;
902 }
903 stream.buffer = filledBufferQ_.front().buffer;
904 stream.bufferLen = filledBufferQ_.front().bufLength;
905
906 if (stream.buffer == nullptr) {
907 AUDIO_ERR_LOG("AudioStream::WriteCb stream.buffer is nullptr return");
908 break;
909 }
910 bytesWritten = WriteStreamInCb(stream, writeError);
911 if (writeError != 0) {
912 AUDIO_ERR_LOG("AudioStream::WriteStreamInCb fail, writeError:%{public}d", writeError);
913 } else {
914 AUDIO_DEBUG_LOG("AudioStream::WriteCb WriteStream, bytesWritten:%{public}zu", bytesWritten);
915 freeBufferQ_.emplace(filledBufferQ_.front());
916 filledBufferQ_.pop();
917 SendWriteBufferRequestEvent();
918 }
919 }
920 }
921 AUDIO_INFO_LOG("AudioStream::WriteCb thread end");
922 }
923
ReadCbThreadLoop()924 void AudioStream::ReadCbThreadLoop()
925 {
926 AUDIO_INFO_LOG("AudioStream::ReadCb thread start");
927 StreamBuffer stream;
928 int32_t readLen;
929 bool isBlockingRead = true;
930
931 while (isReadyToRead_) {
932 while (!freeBufferQ_.empty()) {
933 if (state_ != RUNNING) {
934 AUDIO_ERR_LOG("AudioStream::ReadCb Read: Illegal state:%{public}u", state_);
935 isReadyToRead_ = false;
936 return;
937 }
938
939 stream.buffer = freeBufferQ_.front().buffer;
940 stream.bufferLen = freeBufferQ_.front().bufLength;
941 AUDIO_DEBUG_LOG("AudioStream::ReadCb requested stream.bufferLen:%{public}d", stream.bufferLen);
942
943 if (stream.buffer == nullptr) {
944 AUDIO_ERR_LOG("AudioStream::ReadCb stream.buffer == nullptr return");
945 return;
946 }
947 readLen = ReadStream(stream, isBlockingRead);
948 if (readLen < 0) {
949 AUDIO_ERR_LOG("AudioStream::ReadCb ReadStream fail, ret: %{public}d", readLen);
950 } else {
951 AUDIO_DEBUG_LOG("AudioStream::ReadCb ReadStream, bytesRead:%{public}d", readLen);
952 freeBufferQ_.front().dataLength = readLen;
953 filledBufferQ_.emplace(freeBufferQ_.front());
954 freeBufferQ_.pop();
955 }
956 }
957 std::this_thread::sleep_for(std::chrono::microseconds(CB_READ_BUFFERS_WAIT_IN_US));
958 }
959
960 AUDIO_INFO_LOG("AudioStream::ReadCb thread end");
961 }
962
SetLowPowerVolume(float volume)963 int32_t AudioStream::SetLowPowerVolume(float volume)
964 {
965 return SetStreamLowPowerVolume(volume);
966 }
967
GetLowPowerVolume()968 float AudioStream::GetLowPowerVolume()
969 {
970 return GetStreamLowPowerVolume();
971 }
972
GetSingleStreamVolume()973 float AudioStream::GetSingleStreamVolume()
974 {
975 return GetSingleStreamVol();
976 }
977
SubmitAllFreeBuffers()978 void AudioStream::SubmitAllFreeBuffers()
979 {
980 lock_guard<mutex> lock(bufferQueueLock_);
981 for (size_t i = 0; i < freeBufferQ_.size(); ++i) {
982 SendWriteBufferRequestEvent();
983 }
984 }
985 } // namespace AudioStandard
986 } // namespace OHOS
987