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 {
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