1 /*
2 * Copyright (c) 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_info.h"
22 #include "audio_log.h"
23 #include "audio_container_stream_base.h"
24 #include "audio_policy_manager.h"
25 #include "audio_container_client_base.h"
26
27 using namespace std;
28
29 namespace OHOS {
30 namespace AudioStandard {
31 const unsigned long long TIME_CONVERSION_US_S = 1000000ULL; /* us to s */
32 const unsigned long long TIME_CONVERSION_NS_US = 1000ULL; /* ns to us */
33 const unsigned long long TIME_CONVERSION_NS_S = 1000000000ULL; /* ns to s */
34 constexpr int32_t WRITE_RETRY_DELAY_IN_US = 500;
35 constexpr int32_t READ_WRITE_WAIT_TIME_IN_US = 500;
36 constexpr int32_t CB_WRITE_BUFFERS_WAIT_IN_US = 500;
37 constexpr int32_t CB_READ_BUFFERS_WAIT_IN_US = 500;
38 constexpr int32_t AUDIO_RENDERER_SERVICE_GATEWAY_ID = 13011;
39 constexpr int32_t AUDIO_CAPTURER_SERVICE_GATEWAY_ID = 13013;
40
41
42 const map<pair<ContentType, StreamUsage>, AudioStreamType> AudioContainerStreamBase::streamTypeMap_ =
43 AudioContainerStreamBase::CreateStreamMap();
44
CreateStreamMap()45 map<pair<ContentType, StreamUsage>, AudioStreamType> AudioContainerStreamBase::CreateStreamMap()
46 {
47 map<pair<ContentType, StreamUsage>, AudioStreamType> streamMap;
48
49 streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
50 streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_MEDIA)] = STREAM_MUSIC;
51 streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
52 streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
53 streamMap[make_pair(CONTENT_TYPE_UNKNOWN, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
54
55 streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
56 streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_MEDIA)] = STREAM_VOICE_ASSISTANT;
57 streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_VOICE_CALL;
58 streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
59 streamMap[make_pair(CONTENT_TYPE_SPEECH, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
60
61 streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_UNKNOWN)] = STREAM_MUSIC;
62 streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_MEDIA)] = STREAM_MUSIC;
63 streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
64 streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_VOICE_ASSISTANT;
65 streamMap[make_pair(CONTENT_TYPE_MUSIC, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
66
67 streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_UNKNOWN)] = STREAM_MEDIA;
68 streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_MEDIA)] = STREAM_MEDIA;
69 streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
70 streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
71 streamMap[make_pair(CONTENT_TYPE_MOVIE, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
72
73 streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_UNKNOWN)] = STREAM_NOTIFICATION;
74 streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_MEDIA)] = STREAM_NOTIFICATION;
75 streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
76 streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
77 streamMap[make_pair(CONTENT_TYPE_SONIFICATION, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_MUSIC;
78
79 streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_UNKNOWN)] = STREAM_RING;
80 streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_MEDIA)] = STREAM_RING;
81 streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_VOICE_COMMUNICATION)] = STREAM_MUSIC;
82 streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_VOICE_ASSISTANT)] = STREAM_MUSIC;
83 streamMap[make_pair(CONTENT_TYPE_RINGTONE, STREAM_USAGE_NOTIFICATION_RINGTONE)] = STREAM_RING;
84
85 return streamMap;
86 }
87
AudioContainerStreamBase(AudioStreamType eStreamType,AudioMode eMode,int32_t appUid)88 AudioContainerStreamBase::AudioContainerStreamBase(AudioStreamType eStreamType, AudioMode eMode, int32_t appUid)
89 : eStreamType_(eStreamType),
90 eMode_(eMode),
91 state_(NEW),
92 isReadInProgress_(false),
93 isWriteInProgress_(false),
94 resetTime_(false),
95 resetTimestamp_(0),
96 renderMode_(RENDER_MODE_NORMAL),
97 captureMode_(CAPTURE_MODE_NORMAL),
98 isReadyToWrite_(false),
99 isReadyToRead_(false),
100 isFirstRead_(false)
101 {
102 audioStreamTracker_ = std::make_unique<AudioStreamTracker>(eMode, appUid);
103 AUDIO_DEBUG_LOG("AudioContainerStreamBase::AudioContainerStreamBase");
104 }
105
~AudioContainerStreamBase()106 AudioContainerStreamBase::~AudioContainerStreamBase()
107 {
108 isReadyToWrite_ = false;
109 isReadyToRead_ = false;
110
111 if (writeThread_ && writeThread_->joinable()) {
112 writeThread_->join();
113 }
114
115 if (readThread_ && readThread_->joinable()) {
116 readThread_->join();
117 }
118
119 if (state_ != RELEASED && state_ != NEW) {
120 ReleaseAudioStream();
121 }
122 if (audioStreamTracker_) {
123 AUDIO_DEBUG_LOG("AudioContainerStreamBase:~AudioContainerStreamBase:Calling update tracker");
124 AudioRendererInfo rendererInfo = {};
125 AudioCapturerInfo capturerInfo = {};
126 state_ = RELEASED;
127 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo, capturerInfo);
128 }
129 }
SetRendererInfo(const AudioRendererInfo & rendererInfo)130 void AudioContainerStreamBase::SetRendererInfo(const AudioRendererInfo &rendererInfo)
131 {
132 rendererInfo_ = rendererInfo;
133 }
134
SetCapturerInfo(const AudioCapturerInfo & capturerInfo)135 void AudioContainerStreamBase::SetCapturerInfo(const AudioCapturerInfo &capturerInfo)
136 {
137 capturerInfo_ = capturerInfo;
138 }
139
GetState()140 State AudioContainerStreamBase::GetState()
141 {
142 return state_;
143 }
144
GetAudioSessionID(uint32_t & sessionID) const145 int32_t AudioContainerStreamBase::GetAudioSessionID(uint32_t &sessionID) const
146 {
147 if ((state_ == RELEASED) || (state_ == NEW)) {
148 return ERR_ILLEGAL_STATE;
149 }
150
151 if (GetSessionID(sessionID, trackId_) != 0) {
152 return ERR_INVALID_INDEX;
153 }
154
155 return SUCCESS;
156 }
157
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)158 bool AudioContainerStreamBase::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base)
159 {
160 uint64_t paTimeStamp = 0;
161 if (GetCurrentTimeStamp(paTimeStamp, trackId_) == SUCCESS) {
162 if (resetTime_) {
163 AUDIO_INFO_LOG("AudioContainerStreamBase::GetAudioTime resetTime_ %{public}d", resetTime_);
164 resetTime_ = false;
165 resetTimestamp_ = paTimeStamp;
166 }
167
168 timestamp.time.tv_sec = static_cast<time_t>((paTimeStamp - resetTimestamp_) / TIME_CONVERSION_US_S);
169 timestamp.time.tv_nsec = static_cast<time_t>(((paTimeStamp - resetTimestamp_) -
170 (timestamp.time.tv_sec * TIME_CONVERSION_US_S)) * TIME_CONVERSION_NS_US);
171 timestamp.time.tv_sec += baseTimestamp_.tv_sec;
172 timestamp.time.tv_nsec += baseTimestamp_.tv_nsec;
173 timestamp.time.tv_sec += (timestamp.time.tv_nsec / TIME_CONVERSION_NS_S);
174 timestamp.time.tv_nsec = (timestamp.time.tv_nsec % TIME_CONVERSION_NS_S);
175
176 return true;
177 }
178 return false;
179 }
180
GetBufferSize(size_t & bufferSize) const181 int32_t AudioContainerStreamBase::GetBufferSize(size_t &bufferSize) const
182 {
183 if (GetMinimumBufferSize(bufferSize, trackId_) != 0) {
184 return ERR_OPERATION_FAILED;
185 }
186 return SUCCESS;
187 }
188
GetFrameCount(uint32_t & frameCount) const189 int32_t AudioContainerStreamBase::GetFrameCount(uint32_t &frameCount) const
190 {
191 AUDIO_INFO_LOG("AudioContainerStreamBase: Get frame count");
192 if (GetMinimumFrameCount(frameCount, trackId_) != 0) {
193 return ERR_OPERATION_FAILED;
194 }
195
196 return SUCCESS;
197 }
198
GetLatency(uint64_t & latency) const199 int32_t AudioContainerStreamBase::GetLatency(uint64_t &latency) const
200 {
201 if (GetAudioLatency(latency, trackId_) != SUCCESS) {
202 return ERR_OPERATION_FAILED;
203 } else {
204 return SUCCESS;
205 }
206 }
207
GetSupportedFormats() const208 vector<AudioSampleFormat> AudioContainerStreamBase::GetSupportedFormats() const
209 {
210 return AUDIO_SUPPORTED_FORMATS;
211 }
212
GetSupportedEncodingTypes() const213 vector<AudioEncodingType> AudioContainerStreamBase::GetSupportedEncodingTypes() const
214 {
215 return AUDIO_SUPPORTED_ENCODING_TYPES;
216 }
217
GetSupportedSamplingRates() const218 vector<AudioSamplingRate> AudioContainerStreamBase::GetSupportedSamplingRates() const
219 {
220 return AUDIO_SUPPORTED_SAMPLING_RATES;
221 }
222
IsFormatValid(uint8_t format)223 bool IsFormatValid(uint8_t format)
224 {
225 bool isValidFormat = (find(AUDIO_SUPPORTED_FORMATS.begin(), AUDIO_SUPPORTED_FORMATS.end(), format)
226 != AUDIO_SUPPORTED_FORMATS.end());
227 AUDIO_DEBUG_LOG("AudioContainerStreamBase: IsFormatValid: %{public}s", isValidFormat ? "true" : "false");
228 return isValidFormat;
229 }
230
IsRendererChannelValid(uint8_t channel)231 bool IsRendererChannelValid(uint8_t channel)
232 {
233 bool isValidChannel = (find(RENDERER_SUPPORTED_CHANNELS.begin(), RENDERER_SUPPORTED_CHANNELS.end(), channel)
234 != RENDERER_SUPPORTED_CHANNELS.end());
235 AUDIO_DEBUG_LOG("AudioContainerStreamBase: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
236 return isValidChannel;
237 }
238
IsCapturerChannelValid(uint8_t channel)239 bool IsCapturerChannelValid(uint8_t channel)
240 {
241 bool isValidChannel = (find(CAPTURER_SUPPORTED_CHANNELS.begin(), CAPTURER_SUPPORTED_CHANNELS.end(), channel)
242 != CAPTURER_SUPPORTED_CHANNELS.end());
243 AUDIO_DEBUG_LOG("AudioContainerStreamBase: IsChannelValid: %{public}s", isValidChannel ? "true" : "false");
244 return isValidChannel;
245 }
246
IsEncodingTypeValid(uint8_t encodingType)247 bool IsEncodingTypeValid(uint8_t encodingType)
248 {
249 bool isValidEncodingType = (find(AUDIO_SUPPORTED_ENCODING_TYPES.begin(), AUDIO_SUPPORTED_ENCODING_TYPES.end(),
250 encodingType) != AUDIO_SUPPORTED_ENCODING_TYPES.end());
251 AUDIO_DEBUG_LOG("AudioContainerStreamBase: IsEncodingTypeValid: %{public}s",
252 isValidEncodingType ? "true" : "false");
253 return isValidEncodingType;
254 }
255
IsSamplingRateValid(uint32_t samplingRate)256 bool IsSamplingRateValid(uint32_t samplingRate)
257 {
258 bool isValidSamplingRate = (find(AUDIO_SUPPORTED_SAMPLING_RATES.begin(), AUDIO_SUPPORTED_SAMPLING_RATES.end(),
259 samplingRate) != AUDIO_SUPPORTED_SAMPLING_RATES.end());
260 AUDIO_DEBUG_LOG("AudioContainerStreamBase: IsSamplingRateValid: %{public}s",
261 isValidSamplingRate ? "true" : "false");
262 return isValidSamplingRate;
263 }
264
GetAudioStreamInfo(AudioStreamParams & audioStreamInfo)265 int32_t AudioContainerStreamBase::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo)
266 {
267 if (GetAudioStreamParams(audioStreamInfo, trackId_) != 0) {
268 return ERR_OPERATION_FAILED;
269 }
270
271 return SUCCESS;
272 }
273
VerifyClientPermission(const std::string & permissionName,uint32_t appTokenId,int32_t appUid,bool privacyFlag,AudioPermissionState state)274 bool AudioContainerStreamBase::VerifyClientPermission(const std::string &permissionName, uint32_t appTokenId,
275 int32_t appUid, bool privacyFlag, AudioPermissionState state)
276 {
277 if (!AudioPolicyManager::GetInstance().VerifyClientPermission(permissionName, appTokenId, appUid,
278 privacyFlag, state)) {
279 AUDIO_ERR_LOG("AudioContainerStreamBase: Client doesn't have MICROPHONE permission");
280 return false;
281 }
282 return true;
283 }
284
SetAudioStreamInfo(const AudioStreamParams info)285 int32_t AudioContainerStreamBase::SetAudioStreamInfo(const AudioStreamParams info)
286 {
287 if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) {
288 AUDIO_ERR_LOG("AudioContainerStreamBase: Unsupported audio parameter");
289 return ERR_NOT_SUPPORTED;
290 }
291 sample_rate_ = info.samplingRate;
292 format_ = info.format;
293 channelCount_ = info.channels;
294 if (state_ != NEW) {
295 AUDIO_DEBUG_LOG("AudioContainerStreamBase: State is not new, release existing stream");
296 StopAudioStream();
297 ReleaseAudioStream();
298 }
299
300 int32_t ret = 0;
301 switch (eMode_) {
302 case AUDIO_MODE_PLAYBACK:
303 AUDIO_ERR_LOG("AudioContainerStreamBase: Initialize playback");
304 if (!IsRendererChannelValid(info.channels)) {
305 AUDIO_ERR_LOG("AudioContainerStreamBase: Invalid sink channel %{public}d", info.channels);
306 return ERR_NOT_SUPPORTED;
307 }
308 ret = Initialize(AUDIO_SERVICE_CLIENT_PLAYBACK, AUDIO_RENDERER_SERVICE_GATEWAY_ID);
309 break;
310 case AUDIO_MODE_RECORD:
311 AUDIO_ERR_LOG("AudioContainerStreamBase: Initialize recording");
312 if (!IsCapturerChannelValid(info.channels)) {
313 AUDIO_ERR_LOG("AudioContainerStreamBase: Invalid source channel %{public}d", info.channels);
314 return ERR_NOT_SUPPORTED;
315 }
316 ret = Initialize(AUDIO_SERVICE_CLIENT_RECORD, AUDIO_CAPTURER_SERVICE_GATEWAY_ID);
317 break;
318 default:
319 return ERR_INVALID_OPERATION;
320 }
321
322 if (ret != SUCCESS) {
323 AUDIO_ERR_LOG("AudioContainerStreamBase: Error initializing!");
324 return ret;
325 }
326 trackId_ = CreateStream(info, eStreamType_);
327 if (trackId_ < 0) {
328 AUDIO_ERR_LOG("AudioContainerStreamBase: Create stream failed");
329 return ERROR;
330 }
331
332 state_ = PREPARED;
333 if (audioStreamTracker_) {
334 (void)GetAudioSessionID(sessionId_);
335 AUDIO_DEBUG_LOG("AudioContainerStreamBase:Calling register tracker, sessionid = %{public}d", sessionId_);
336 audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, nullptr);
337 }
338 AUDIO_INFO_LOG("AudioContainerStreamBase: CreateStream trackId_ %{public}d", trackId_);
339 return SUCCESS;
340 }
341
StartAudioStream()342 bool AudioContainerStreamBase::StartAudioStream()
343 {
344 if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) {
345 AUDIO_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_);
346 return false;
347 }
348
349 int32_t ret = StartStream(trackId_);
350 if (ret != SUCCESS) {
351 AUDIO_ERR_LOG("StartStream Start failed:%{public}d", ret);
352 return false;
353 }
354
355 resetTime_ = true;
356 int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_);
357 if (retCode != 0) {
358 AUDIO_ERR_LOG("AudioContainerStreamBase::StartAudioStream get system elapsed time failed: %d", retCode);
359 }
360
361 if (renderMode_ == RENDER_MODE_CALLBACK) {
362 isReadyToWrite_ = true;
363 if (writeThread_ == nullptr) {
364 writeThread_ = std::make_unique<std::thread>(&AudioContainerStreamBase::WriteBuffers, this);
365 }
366 } else if (captureMode_ == CAPTURE_MODE_CALLBACK) {
367 isReadyToRead_ = true;
368 readThread_ = std::make_unique<std::thread>(&AudioContainerStreamBase::ReadBuffers, this);
369 }
370
371 isFirstRead_ = true;
372 state_ = RUNNING;
373 pthread_cond_signal(&writeCondition_);
374 AUDIO_INFO_LOG("AudioContainerStreamBase::StartAudioStream SUCCESS trackId_ %{public}d", trackId_);
375 if (audioStreamTracker_) {
376 AUDIO_DEBUG_LOG("AudioContainerStreamBase:Calling Update tracker for Running");
377 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
378 }
379 return true;
380 }
381
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)382 int32_t AudioContainerStreamBase::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
383 {
384 if (userSize <= 0) {
385 AUDIO_ERR_LOG("Invalid userSize:%{public}zu", userSize);
386 return ERR_INVALID_PARAM;
387 }
388
389 if (state_ != RUNNING) {
390 AUDIO_ERR_LOG("Read: State is not RUNNNIG. Illegal state:%{public}u", state_);
391 return ERR_ILLEGAL_STATE;
392 }
393
394 if (isFirstRead_) {
395 FlushAudioStream();
396 isFirstRead_ = false;
397 }
398
399 StreamBuffer stream;
400 stream.buffer = &buffer;
401 stream.bufferLen = userSize;
402 isReadInProgress_ = true;
403 int32_t readLen = ReadStream(stream, isBlockingRead, trackId_);
404 isReadInProgress_ = false;
405 if (readLen < 0) {
406 AUDIO_ERR_LOG("ReadStream fail,ret:%{public}d", readLen);
407 return ERR_INVALID_READ;
408 }
409
410 return readLen;
411 }
412
Write(uint8_t * buffer,size_t buffer_size)413 size_t AudioContainerStreamBase::Write(uint8_t *buffer, size_t buffer_size)
414 {
415 if (renderMode_ == RENDER_MODE_CALLBACK) {
416 AUDIO_ERR_LOG("AudioContainerStreamBase::Write not supported. RenderMode is callback");
417 return ERR_INCORRECT_MODE;
418 }
419
420 if ((buffer == nullptr) || (buffer_size <= 0)) {
421 AUDIO_ERR_LOG("Invalid buffer size:%{public}zu", buffer_size);
422 return ERR_INVALID_PARAM;
423 }
424
425 if (state_ != RUNNING) {
426 // To allow context switch for APIs running in different thread contexts
427 std::this_thread::sleep_for(std::chrono::microseconds(WRITE_RETRY_DELAY_IN_US));
428 return ERR_ILLEGAL_STATE;
429 }
430
431 int32_t writeError;
432 StreamBuffer stream;
433 stream.buffer = buffer;
434 stream.bufferLen = buffer_size;
435 isWriteInProgress_ = true;
436 size_t bytesWritten = WriteStream(stream, writeError, trackId_);
437 isWriteInProgress_ = false;
438 if (writeError != 0) {
439 AUDIO_ERR_LOG("WriteStream fail,writeError:%{public}d", writeError);
440 return ERR_WRITE_FAILED;
441 }
442 return bytesWritten;
443 }
444
PauseAudioStream()445 bool AudioContainerStreamBase::PauseAudioStream()
446 {
447 if (state_ != RUNNING) {
448 AUDIO_ERR_LOG("PauseAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
449 return false;
450 }
451 State oldState = state_;
452 state_ = PAUSED; // Set it before stopping as Read/Write and Stop can be called from different threads
453 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
454 isReadyToRead_ = false;
455 if (readThread_ && readThread_->joinable()) {
456 readThread_->join();
457 }
458 }
459 while (isReadInProgress_ || isWriteInProgress_) {
460 std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
461 }
462
463 int32_t ret = PauseStream(trackId_);
464 if (ret != SUCCESS) {
465 AUDIO_ERR_LOG("StreamPause fail, ret:%{public}d", ret);
466 state_ = oldState;
467 return false;
468 }
469 AUDIO_DEBUG_LOG("PauseAudioStream SUCCESS");
470
471 if (audioStreamTracker_) {
472 AUDIO_DEBUG_LOG("AudioContainerStreamBase:Calling Update tracker for Pause");
473 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
474 }
475 return true;
476 }
477
StopAudioStream()478 bool AudioContainerStreamBase::StopAudioStream()
479 {
480 if (state_ == PAUSED) {
481 state_ = STOPPED;
482 AUDIO_INFO_LOG("StopAudioStream SUCCESS");
483 return true;
484 }
485
486 if (state_ != RUNNING) {
487 AUDIO_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
488 return false;
489 }
490 State oldState = state_;
491 state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads
492 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
493 isReadyToRead_ = false;
494 if (readThread_ && readThread_->joinable()) {
495 readThread_->join();
496 }
497 }
498 while (isReadInProgress_ || isWriteInProgress_) {
499 std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
500 }
501
502 int32_t ret = StopStream(trackId_);
503 if (ret != SUCCESS) {
504 AUDIO_ERR_LOG("StreamStop fail, ret:%{public}d", ret);
505 state_ = oldState;
506 return false;
507 }
508
509 // Ends the WriteBuffers thread
510 if (renderMode_ == RENDER_MODE_CALLBACK) {
511 isReadyToWrite_ = false;
512 pthread_cond_signal(&writeCondition_);
513 }
514
515 AUDIO_DEBUG_LOG("StopAudioStream SUCCESS");
516
517 if (audioStreamTracker_) {
518 AUDIO_DEBUG_LOG("AudioContainerStreamBase:Calling Update tracker for stop");
519 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
520 }
521 return true;
522 }
523
FlushAudioStream()524 bool AudioContainerStreamBase::FlushAudioStream()
525 {
526 if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
527 AUDIO_ERR_LOG("FlushAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
528 return false;
529 }
530
531 int32_t ret = FlushStream(trackId_);
532 if (ret != SUCCESS) {
533 AUDIO_ERR_LOG("Flush stream fail,ret:%{public}d", ret);
534 return false;
535 }
536
537 AUDIO_DEBUG_LOG("Flush stream SUCCESS");
538 return true;
539 }
540
DrainAudioStream()541 bool AudioContainerStreamBase::DrainAudioStream()
542 {
543 if (state_ != RUNNING) {
544 AUDIO_ERR_LOG("DrainAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
545 return false;
546 }
547
548 int32_t ret = DrainStream(trackId_);
549 if (ret != SUCCESS) {
550 AUDIO_ERR_LOG("Drain stream fail,ret:%{public}d", ret);
551 return false;
552 }
553
554 AUDIO_DEBUG_LOG("Drain stream SUCCESS");
555 return true;
556 }
557
ReleaseAudioStream()558 bool AudioContainerStreamBase::ReleaseAudioStream()
559 {
560 if (state_ == RELEASED || state_ == NEW) {
561 AUDIO_ERR_LOG("Illegal state: state = %{public}u", state_);
562 return false;
563 }
564 // If state_ is RUNNING try to Stop it first and Release
565 if (state_ == RUNNING || state_ == PAUSED) {
566 StopAudioStream();
567 }
568
569 ReleaseStream(trackId_);
570 state_ = RELEASED;
571 AUDIO_DEBUG_LOG("ReleaseAudiostream SUCCESS");
572 pthread_cond_signal(&writeCondition_);
573
574 if (audioStreamTracker_) {
575 AUDIO_DEBUG_LOG("AudioContainerStreamBase:Calling Update tracker for release");
576 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
577 }
578 return true;
579 }
580
GetStreamType(ContentType contentType,StreamUsage streamUsage)581 AudioStreamType AudioContainerStreamBase::GetStreamType(ContentType contentType, StreamUsage streamUsage)
582 {
583 AudioStreamType streamType = STREAM_MUSIC;
584 auto pos = streamTypeMap_.find(make_pair(contentType, streamUsage));
585 if (pos != streamTypeMap_.end()) {
586 streamType = pos->second;
587 }
588
589 if (streamType == STREAM_MEDIA) {
590 streamType = STREAM_MUSIC;
591 }
592
593 return streamType;
594 }
595
SetAudioStreamType(AudioStreamType audioStreamType)596 int32_t AudioContainerStreamBase::SetAudioStreamType(AudioStreamType audioStreamType)
597 {
598 return SetStreamType(audioStreamType, trackId_);
599 }
600
SetVolume(float volume)601 int32_t AudioContainerStreamBase::SetVolume(float volume)
602 {
603 return SetStreamVolume(volume, trackId_);
604 }
605
GetVolume()606 float AudioContainerStreamBase::GetVolume()
607 {
608 return GetStreamVolume(trackId_);
609 }
610
SetRenderRate(AudioRendererRate renderRate)611 int32_t AudioContainerStreamBase::SetRenderRate(AudioRendererRate renderRate)
612 {
613 switch (renderRate) {
614 case RENDER_RATE_NORMAL:
615 case RENDER_RATE_DOUBLE:
616 case RENDER_RATE_HALF:
617 break;
618 default:
619 return AUDIO_CLIENT_INVALID_PARAMS_ERR;
620 }
621 renderRate_ = renderRate;
622 return SetStreamRenderRate(renderRate, trackId_);
623 }
624
GetRenderRate()625 AudioRendererRate AudioContainerStreamBase::GetRenderRate()
626 {
627 return GetStreamRenderRate();
628 }
629
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)630 int32_t AudioContainerStreamBase::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
631 {
632 if (callback == nullptr) {
633 AUDIO_ERR_LOG("AudioContainerStreamBase::SetStreamCallback failed. callback == nullptr");
634 return ERR_INVALID_PARAM;
635 }
636
637 SaveStreamCallback(callback);
638
639 return SUCCESS;
640 }
641
SetRenderMode(AudioRenderMode renderMode)642 int32_t AudioContainerStreamBase::SetRenderMode(AudioRenderMode renderMode)
643 {
644 int32_t ret = SetAudioRenderMode(renderMode, trackId_);
645 if (ret != SUCCESS) {
646 AUDIO_ERR_LOG("AudioContainerStreamBase::SetRenderMode: renderMode: %{public}d failed", renderMode);
647 return ERR_OPERATION_FAILED;
648 }
649 renderMode_ = renderMode;
650
651 for (int32_t i = 0; i < MAX_LEN_BUFFERS; ++i) {
652 size_t length;
653 GetMinimumBufferSize(length, trackId_);
654 AUDIO_DEBUG_LOG("AudioContainerStreamBase::GetMinimumBufferSize: %{public}zu", length);
655
656 bufferPool_[i] = std::make_unique<uint8_t[]>(length);
657 if (bufferPool_[i] == nullptr) {
658 AUDIO_ERR_LOG("GetBufferDescriptor bufferPool_[i]==nullptr. Allocate memory failed.");
659 return ERR_OPERATION_FAILED;
660 }
661
662 BufferDesc bufDesc {};
663 bufDesc.buffer = bufferPool_[i].get();
664 bufDesc.bufLength = length;
665 freeBufferQ_.emplace(bufDesc);
666 }
667
668 return SUCCESS;
669 }
670
GetRenderMode()671 AudioRenderMode AudioContainerStreamBase::GetRenderMode()
672 {
673 return GetAudioRenderMode();
674 }
675
SetCaptureMode(AudioCaptureMode captureMode)676 int32_t AudioContainerStreamBase::SetCaptureMode(AudioCaptureMode captureMode)
677 {
678 int32_t ret = SetAudioCaptureMode(captureMode);
679 if (ret != SUCCESS) {
680 AUDIO_ERR_LOG("AudioContainerStreamBase::SetCaptureMode: captureMode: %{public}d failed", captureMode);
681 return ERR_OPERATION_FAILED;
682 }
683 captureMode_ = captureMode;
684
685 for (int32_t i = 0; i < MAX_LEN_BUFFERS; ++i) {
686 size_t length;
687 GetMinimumBufferSize(length, trackId_);
688 AUDIO_DEBUG_LOG("AudioContainerStreamBase::SetCaptureMode: length %{public}zu", length);
689
690 bufferPool_[i] = std::make_unique<uint8_t[]>(length);
691 if (bufferPool_[i] == nullptr) {
692 AUDIO_ERR_LOG("AudioContainerStreamBase::SetCaptureMode bufferPool_[i]==nullptr. Allocate memory failed.");
693 return ERR_OPERATION_FAILED;
694 }
695
696 BufferDesc bufDesc {};
697 bufDesc.buffer = bufferPool_[i].get();
698 bufDesc.bufLength = length;
699 freeBufferQ_.emplace(bufDesc);
700 }
701
702 return SUCCESS;
703 }
704
GetCaptureMode()705 AudioCaptureMode AudioContainerStreamBase::GetCaptureMode()
706 {
707 return GetAudioCaptureMode();
708 }
709
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)710 int32_t AudioContainerStreamBase::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
711 {
712 if (renderMode_ != RENDER_MODE_CALLBACK) {
713 AUDIO_ERR_LOG("AudioContainerStreamBase::SetRendererWriteCallback not supported. Render mode is not callback.");
714 return ERR_INCORRECT_MODE;
715 }
716
717 callback_ = callback;
718 return SUCCESS;
719 }
720
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)721 int32_t AudioContainerStreamBase::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
722 {
723 if (captureMode_ != CAPTURE_MODE_CALLBACK) {
724 AUDIO_ERR_LOG("AudioContainerStreamBase::SetCapturerReadCallback not supported. Capture mode is not callback.");
725 return ERR_INCORRECT_MODE;
726 }
727
728 int32_t ret = SaveReadCallback(callback);
729 if (ret != SUCCESS) {
730 AUDIO_ERR_LOG("AudioContainerStreamBase::SetCapturerReadCallback: failed.");
731 return ERR_INVALID_PARAM;
732 }
733
734 return SUCCESS;
735 }
736
GetBufferDesc(BufferDesc & bufDesc)737 int32_t AudioContainerStreamBase::GetBufferDesc(BufferDesc &bufDesc)
738 {
739 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
740 AUDIO_ERR_LOG("GetBufferDesc not supported. Render or Capture mode is not callback.");
741 return ERR_INCORRECT_MODE;
742 }
743
744 AUDIO_DEBUG_LOG("freeBufferQ_ count %{public}zu", freeBufferQ_.size());
745 AUDIO_DEBUG_LOG("filledBufferQ_ count %{public}zu", filledBufferQ_.size());
746
747 lock_guard<mutex> lock(mBufferQueueLock);
748 if (renderMode_ == RENDER_MODE_CALLBACK) {
749 if (!freeBufferQ_.empty()) {
750 bufDesc.buffer = freeBufferQ_.front().buffer;
751 bufDesc.bufLength = freeBufferQ_.front().bufLength;
752 freeBufferQ_.pop();
753 } else {
754 bufDesc.buffer = nullptr;
755 AUDIO_ERR_LOG("GetBufferDesc freeBufferQ_.empty()");
756 return ERR_OPERATION_FAILED;
757 }
758 }
759
760 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
761 if (!filledBufferQ_.empty()) {
762 bufDesc.buffer = filledBufferQ_.front().buffer;
763 bufDesc.bufLength = filledBufferQ_.front().bufLength;
764 bufDesc.dataLength = filledBufferQ_.front().dataLength;
765 filledBufferQ_.pop();
766 } else {
767 bufDesc.buffer = nullptr;
768 AUDIO_ERR_LOG("GetBufferDesc filledBufferQ_.empty()");
769 return ERR_OPERATION_FAILED;
770 }
771 }
772 return SUCCESS;
773 }
774
GetBufQueueState(BufferQueueState & bufState)775 int32_t AudioContainerStreamBase::GetBufQueueState(BufferQueueState &bufState)
776 {
777 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
778 AUDIO_ERR_LOG("GetBufQueueState not supported. Render or Capture mode is not callback.");
779 return ERR_INCORRECT_MODE;
780 }
781
782 lock_guard<mutex> lock(mBufferQueueLock);
783 if (renderMode_ == RENDER_MODE_CALLBACK) {
784 AUDIO_DEBUG_LOG("GetBufQueueState: bufferlength: %{public}zu.", filledBufferQ_.size());
785 bufState.numBuffers = filledBufferQ_.size();
786 }
787
788 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
789 bufState.numBuffers = freeBufferQ_.size();
790 }
791
792 return SUCCESS;
793 }
794
Enqueue(const BufferDesc & bufDesc)795 int32_t AudioContainerStreamBase::Enqueue(const BufferDesc &bufDesc)
796 {
797 AUDIO_DEBUG_LOG("AudioContainerStreamBase::Enqueue");
798 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
799 AUDIO_ERR_LOG("Enqueue not supported. Render or capture mode is not callback.");
800 return ERR_INCORRECT_MODE;
801 }
802
803 if (bufDesc.buffer == nullptr) {
804 AUDIO_ERR_LOG("Enqueue: failed. bufDesc.buffer == nullptr.");
805 return ERR_INVALID_PARAM;
806 }
807
808 lock_guard<mutex> lock(mBufferQueueLock);
809 if (renderMode_ == RENDER_MODE_CALLBACK) {
810 AUDIO_INFO_LOG("Enqueue: filledBuffer length: %{public}zu.", bufDesc.bufLength);
811 filledBufferQ_.emplace(bufDesc);
812 }
813
814 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
815 AUDIO_INFO_LOG("Enqueue: freeBuffer length: %{public}zu.", bufDesc.bufLength);
816 freeBufferQ_.emplace(bufDesc);
817 }
818
819 return SUCCESS;
820 }
821
Clear()822 int32_t AudioContainerStreamBase::Clear()
823 {
824 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
825 AUDIO_ERR_LOG("Clear not supported. Render or capture mode is not callback.");
826 return ERR_INCORRECT_MODE;
827 }
828
829 lock_guard<mutex> lock(mBufferQueueLock);
830 while (!filledBufferQ_.empty()) {
831 freeBufferQ_.emplace(filledBufferQ_.front());
832 filledBufferQ_.pop();
833 }
834
835 return SUCCESS;
836 }
837
WriteBuffers()838 void AudioContainerStreamBase::WriteBuffers()
839 {
840 StreamBuffer stream;
841 size_t bytesWritten;
842 int32_t writeError;
843 while (isReadyToWrite_) {
844 size_t callback_size;
845 GetMinimumBufferSize(callback_size, trackId_);
846 for (size_t i = 0; i < freeBufferQ_.size(); ++i) {
847 callback_->OnWriteData(callback_size);
848 }
849 while (!filledBufferQ_.empty()) {
850 if (state_ != RUNNING) {
851 AUDIO_ERR_LOG("Write: Illegal state:%{public}u", state_);
852 break;
853 }
854 if ((state_ != STOPPED) && (state_ != PAUSED)) {
855 stream.buffer = filledBufferQ_.front().buffer;
856 stream.bufferLen = filledBufferQ_.front().bufLength;
857 if (stream.buffer == nullptr) {
858 AUDIO_ERR_LOG("WriteBuffers stream.buffer == nullptr return");
859 return;
860 }
861 bytesWritten = WriteStreamInCb(stream, writeError, trackId_);
862 if (writeError != 0) {
863 AUDIO_ERR_LOG("WriteStreamInCb fail, writeError:%{public}d", writeError);
864 } else {
865 AUDIO_INFO_LOG("WriteBuffers WriteStream, bytesWritten:%{public}zu", bytesWritten);
866 freeBufferQ_.emplace(filledBufferQ_.front());
867 filledBufferQ_.pop();
868 }
869 callback_->OnWriteData(callback_size);
870 } else {
871 pthread_cond_wait(&writeCondition_, &writeLock_);
872 }
873 }
874 std::this_thread::sleep_for(std::chrono::microseconds(CB_WRITE_BUFFERS_WAIT_IN_US));
875 }
876 }
877
ReadBuffers()878 void AudioContainerStreamBase::ReadBuffers()
879 {
880 AUDIO_INFO_LOG("ReadBuffers thread start");
881 StreamBuffer stream;
882 int32_t readLen;
883 bool isBlockingRead = true;
884
885 while (isReadyToRead_) {
886 while (!freeBufferQ_.empty()) {
887 if (state_ != RUNNING) {
888 AUDIO_ERR_LOG("ReadBuffers Read: Illegal state:%{public}u", state_);
889 isReadyToRead_ = false;
890 return;
891 }
892 AUDIO_DEBUG_LOG("ReadBuffers !freeBufferQ_.empty()");
893 stream.buffer = freeBufferQ_.front().buffer;
894 stream.bufferLen = freeBufferQ_.front().bufLength;
895 AUDIO_DEBUG_LOG("ReadBuffers requested stream.bufferLen:%{public}d", stream.bufferLen);
896 if (stream.buffer == nullptr) {
897 AUDIO_ERR_LOG("ReadBuffers stream.buffer == nullptr return");
898 return;
899 }
900 readLen = ReadStream(stream, isBlockingRead, trackId_);
901 if (readLen < 0) {
902 AUDIO_ERR_LOG("ReadBuffers ReadStream fail, ret: %{public}d", readLen);
903 } else {
904 AUDIO_DEBUG_LOG("ReadBuffers ReadStream, bytesRead:%{public}d", readLen);
905 freeBufferQ_.front().dataLength = readLen;
906 filledBufferQ_.emplace(freeBufferQ_.front());
907 freeBufferQ_.pop();
908 }
909 }
910 std::this_thread::sleep_for(std::chrono::microseconds(CB_READ_BUFFERS_WAIT_IN_US));
911 }
912
913 AUDIO_INFO_LOG("ReadBuffers thread end");
914 }
915
SetApplicationCachePath(const std::string cachePath)916 void AudioContainerStreamBase::SetApplicationCachePath(const std::string cachePath)
917 {
918 SetAppCachePath(cachePath);
919 }
920
SetClientID(int32_t clientPid,int32_t clientUid)921 void AudioContainerStreamBase::SetClientID(int32_t clientPid, int32_t clientUid)
922 {
923 AUDIO_DEBUG_LOG("Set client PID: %{public}d, UID: %{public}d", clientPid, clientUid);
924 }
925
AudioContainerCaptureStream(AudioStreamType eStreamType,AudioMode eMode,int32_t appUid)926 AudioContainerCaptureStream::AudioContainerCaptureStream(AudioStreamType eStreamType, AudioMode eMode, int32_t appUid)
927 : AudioContainerStreamBase(eStreamType, eMode, appUid)
928 {
929 AUDIO_INFO_LOG("AudioContainerCaptureStream::AudioContainerCaptureStream");
930 }
931
~AudioContainerCaptureStream()932 AudioContainerCaptureStream::~AudioContainerCaptureStream()
933 {
934 if (audioStreamTracker_) {
935 AUDIO_DEBUG_LOG("AudioContainerCaptureStream:~AudioContainerCaptureStream:Calling update tracker");
936 AudioRendererInfo rendererInfo = {};
937 AudioCapturerInfo capturerInfo = {};
938 state_ = RELEASED;
939 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo, capturerInfo);
940 }
941 }
942
StartAudioStream()943 bool AudioContainerCaptureStream::StartAudioStream()
944 {
945 if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) {
946 AUDIO_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_);
947 return false;
948 }
949
950 pthread_cond_signal(&writeCondition_);
951 int32_t ret = StartStream(trackId_);
952 if (ret != SUCCESS) {
953 AUDIO_ERR_LOG("StartStream Start failed:%{public}d", ret);
954 return false;
955 }
956
957 resetTime_ = true;
958 int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_);
959 if (retCode != 0) {
960 AUDIO_ERR_LOG("AudioContainerCaptureStream::StartAudioStream get system elapsed time failed: %d", retCode);
961 }
962
963 if (renderMode_ == RENDER_MODE_CALLBACK) {
964 isReadyToWrite_ = true;
965 if (writeThread_ == nullptr) {
966 writeThread_ = std::make_unique<std::thread>(&AudioContainerStreamBase::WriteBuffers, this);
967 }
968 } else if (captureMode_ == CAPTURE_MODE_CALLBACK) {
969 isReadyToRead_ = true;
970 readThread_ = std::make_unique<std::thread>(&AudioContainerStreamBase::ReadBuffers, this);
971 }
972
973 isFirstRead_ = true;
974 state_ = RUNNING;
975 AUDIO_INFO_LOG("AudioContainerCaptureStream::StartAudioStream SUCCESS trackId_ %{public}d", trackId_);
976 if (audioStreamTracker_) {
977 AUDIO_DEBUG_LOG("AudioContainerCaptureStream:Calling Update tracker for Running");
978 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
979 }
980 return true;
981 }
982
StopAudioStream()983 bool AudioContainerCaptureStream::StopAudioStream()
984 {
985 if (state_ == PAUSED) {
986 state_ = STOPPED;
987 AUDIO_INFO_LOG("StopAudioStream SUCCESS");
988 return true;
989 }
990
991 if (state_ != RUNNING) {
992 AUDIO_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
993 return false;
994 }
995 State oldState = state_;
996 state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads
997 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
998 isReadyToRead_ = false;
999 if (readThread_ && readThread_->joinable()) {
1000 readThread_->join();
1001 }
1002 readThread_ = nullptr;
1003 }
1004 while (isReadInProgress_ || isWriteInProgress_) {
1005 std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
1006 }
1007
1008 int32_t ret = StopStream(trackId_);
1009 if (ret != SUCCESS) {
1010 AUDIO_ERR_LOG("StreamStop fail, ret:%{public}d", ret);
1011 state_ = oldState;
1012 return false;
1013 }
1014
1015 // Ends the WriteBuffers thread
1016 if (renderMode_ == RENDER_MODE_CALLBACK) {
1017 isReadyToWrite_ = false;
1018 }
1019
1020 if (audioStreamTracker_) {
1021 AUDIO_DEBUG_LOG("AudioContainerCaptureStream:Calling Update tracker for stop");
1022 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
1023 }
1024 AUDIO_DEBUG_LOG("StopAudioStream SUCCESS");
1025
1026 return true;
1027 }
1028
GetBufferDesc(BufferDesc & bufDesc)1029 int32_t AudioContainerCaptureStream::GetBufferDesc(BufferDesc & bufDesc)
1030 {
1031 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
1032 AUDIO_ERR_LOG("GetBufferDesc not supported. Render or Capture mode is not callback.");
1033 return ERR_INCORRECT_MODE;
1034 }
1035
1036 AUDIO_DEBUG_LOG("AudioContainerStreamBase::freeBufferQ_ count %{public}zu", freeBufferQ_.size());
1037 AUDIO_DEBUG_LOG("AudioContainerStreamBase::filledBufferQ_ count %{public}zu", filledBufferQ_.size());
1038
1039 if (renderMode_ == RENDER_MODE_CALLBACK) {
1040 if (!freeBufferQ_.empty()) {
1041 bufDesc.buffer = freeBufferQ_.front().buffer;
1042 bufDesc.bufLength = freeBufferQ_.front().bufLength;
1043 bufDesc.dataLength = freeBufferQ_.front().dataLength;
1044 freeBufferQ_.pop();
1045 } else {
1046 bufDesc.buffer = nullptr;
1047 AUDIO_ERR_LOG("AudioContainerCaptureStream::GetBufferDesc freeBufferQ_.empty()");
1048 return ERR_OPERATION_FAILED;
1049 }
1050 }
1051
1052 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
1053 if (!filledBufferQ_.empty()) {
1054 bufDesc.buffer = filledBufferQ_.front().buffer;
1055 bufDesc.bufLength = filledBufferQ_.front().bufLength;
1056 bufDesc.dataLength = filledBufferQ_.front().dataLength;
1057 filledBufferQ_.pop();
1058 } else {
1059 bufDesc.buffer = nullptr;
1060 AUDIO_ERR_LOG("AudioContainerCaptureStream::GetBufferDesc filledBufferQ_.empty()");
1061 return ERR_OPERATION_FAILED;
1062 }
1063 }
1064 return SUCCESS;
1065 }
1066
GetBufQueueState(BufferQueueState & bufState)1067 int32_t AudioContainerCaptureStream::GetBufQueueState(BufferQueueState &bufState)
1068 {
1069 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
1070 AUDIO_ERR_LOG("GetBufQueueState not supported. Render or Capture mode is not callback.");
1071 return ERR_INCORRECT_MODE;
1072 }
1073
1074 if (renderMode_ == RENDER_MODE_CALLBACK) {
1075 bufState.numBuffers = filledBufferQ_.size();
1076 }
1077
1078 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
1079 bufState.numBuffers = freeBufferQ_.size();
1080 }
1081
1082 return SUCCESS;
1083 }
1084
Enqueue(const BufferDesc & bufDesc)1085 int32_t AudioContainerCaptureStream::Enqueue(const BufferDesc &bufDesc)
1086 {
1087 AUDIO_DEBUG_LOG("AudioContainerCaptureStream::Enqueue");
1088 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
1089 AUDIO_ERR_LOG("AudioContainerCaptureStream::Enqueue not supported. Render or capture mode is not callback.");
1090 return ERR_INCORRECT_MODE;
1091 }
1092
1093 if (bufDesc.buffer == nullptr) {
1094 AUDIO_ERR_LOG("AudioContainerCaptureStream::Enqueue: failed. bufDesc.buffer == nullptr.");
1095 return ERR_INVALID_PARAM;
1096 }
1097
1098 if (renderMode_ == RENDER_MODE_CALLBACK) {
1099 AUDIO_INFO_LOG("AudioContainerCaptureStream::Enqueue: filledBuffer length: %{public}zu.", bufDesc.bufLength);
1100 filledBufferQ_.emplace(bufDesc);
1101 }
1102
1103 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
1104 AUDIO_INFO_LOG("AudioContainerCaptureStream::Enqueue: freeBuffer length: %{public}zu.", bufDesc.bufLength);
1105 freeBufferQ_.emplace(bufDesc);
1106 }
1107
1108 return SUCCESS;
1109 }
1110
Clear()1111 int32_t AudioContainerCaptureStream::Clear()
1112 {
1113 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
1114 AUDIO_ERR_LOG("AudioContainerCaptureStream::Clear not supported. Render or capture mode is not callback.");
1115 return ERR_INCORRECT_MODE;
1116 }
1117
1118 while (!filledBufferQ_.empty()) {
1119 freeBufferQ_.emplace(filledBufferQ_.front());
1120 filledBufferQ_.pop();
1121 }
1122
1123 return SUCCESS;
1124 }
1125
AudioContainerRenderStream(AudioStreamType eStreamType,AudioMode eMode,int32_t appUid)1126 AudioContainerRenderStream::AudioContainerRenderStream(AudioStreamType eStreamType, AudioMode eMode, int32_t appUid)
1127 : AudioContainerStreamBase(eStreamType, eMode, appUid)
1128 {
1129 AUDIO_INFO_LOG("AudioContainerRenderStream::AudioContainerRenderStream");
1130 }
1131
~AudioContainerRenderStream()1132 AudioContainerRenderStream::~AudioContainerRenderStream()
1133 {
1134 if (audioStreamTracker_) {
1135 AUDIO_DEBUG_LOG("AudioContainerRenderStream:~AudioContainerRenderStream:Calling update tracker");
1136 AudioRendererInfo rendererInfo = {};
1137 AudioCapturerInfo capturerInfo = {};
1138 state_ = RELEASED;
1139 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo, capturerInfo);
1140 }
1141 }
1142
StartAudioStream()1143 bool AudioContainerRenderStream::StartAudioStream()
1144 {
1145 AUDIO_INFO_LOG("AudioContainerRenderStream::StartAudioStream");
1146 if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) {
1147 AUDIO_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_);
1148 return false;
1149 }
1150
1151 int32_t ret = StartStream(trackId_);
1152 if (ret != SUCCESS) {
1153 AUDIO_ERR_LOG("StartStream Start failed:%{public}d", ret);
1154 return false;
1155 }
1156
1157 resetTime_ = true;
1158 int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_);
1159 if (retCode != 0) {
1160 AUDIO_ERR_LOG("AudioContainerRenderStream::StartAudioStream get system elapsed time failed: %d", retCode);
1161 }
1162
1163 if (renderMode_ == RENDER_MODE_CALLBACK) {
1164 isReadyToWrite_ = true;
1165 if (writeThread_ == nullptr) {
1166 writeThread_ = std::make_unique<std::thread>(&AudioContainerStreamBase::WriteBuffers, this);
1167 }
1168 } else if (captureMode_ == CAPTURE_MODE_CALLBACK) {
1169 isReadyToRead_ = true;
1170 readThread_ = std::make_unique<std::thread>(&AudioContainerStreamBase::ReadBuffers, this);
1171 }
1172
1173 isFirstRead_ = true;
1174 state_ = RUNNING;
1175 pthread_cond_signal(&writeCondition_);
1176 AUDIO_INFO_LOG("AudioContainerRenderStream::StartAudioStream SUCCESS trackId_ %{public}d", trackId_);
1177 if (audioStreamTracker_) {
1178 AUDIO_DEBUG_LOG("AudioContainerRenderStream:Calling Update tracker for Running");
1179 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
1180 }
1181 return true;
1182 }
1183
StopAudioStream()1184 bool AudioContainerRenderStream::StopAudioStream()
1185 {
1186 if (state_ != RUNNING && state_ != PAUSED) {
1187 AUDIO_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_);
1188 return false;
1189 }
1190 State oldState = state_;
1191 state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads
1192 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
1193 isReadyToRead_ = false;
1194 if (readThread_ && readThread_->joinable()) {
1195 readThread_->join();
1196 }
1197 }
1198 while (isReadInProgress_ || isWriteInProgress_) {
1199 std::this_thread::sleep_for(std::chrono::microseconds(READ_WRITE_WAIT_TIME_IN_US));
1200 }
1201
1202 int32_t ret = StopStream(trackId_);
1203 if (ret != SUCCESS) {
1204 AUDIO_ERR_LOG("AudioContainerRenderStream::StreamStop fail, ret:%{public}d", ret);
1205 state_ = oldState;
1206 return false;
1207 }
1208
1209 // Ends the WriteBuffers thread
1210 if (renderMode_ == RENDER_MODE_CALLBACK) {
1211 isReadyToWrite_ = false;
1212 pthread_cond_signal(&writeCondition_);
1213 if (writeThread_ && writeThread_->joinable()) {
1214 writeThread_->join();
1215 }
1216 writeThread_ = nullptr;
1217 }
1218
1219 AUDIO_DEBUG_LOG("AudioContainerRenderStream::StopAudioStream SUCCESS");
1220 if (audioStreamTracker_) {
1221 AUDIO_DEBUG_LOG("AudioContainerRenderStream:Calling Update tracker for stop");
1222 audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_);
1223 }
1224
1225 return true;
1226 }
1227
GetBufferDesc(BufferDesc & bufDesc)1228 int32_t AudioContainerRenderStream::GetBufferDesc(BufferDesc &bufDesc)
1229 {
1230 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
1231 AUDIO_ERR_LOG("GetBufferDesc not supported. Render or Capture mode is not callback.");
1232 return ERR_INCORRECT_MODE;
1233 }
1234
1235 AUDIO_DEBUG_LOG("AudioContainerStreamBase::freeBufferQ_ count %{public}zu", freeBufferQ_.size());
1236 AUDIO_DEBUG_LOG("AudioContainerStreamBase::filledBufferQ_ count %{public}zu", filledBufferQ_.size());
1237
1238 lock_guard<mutex> lock(mBufferQueueLock);
1239 if (renderMode_ == RENDER_MODE_CALLBACK) {
1240 if (!freeBufferQ_.empty()) {
1241 bufDesc.buffer = freeBufferQ_.front().buffer;
1242 bufDesc.bufLength = freeBufferQ_.front().bufLength;
1243 freeBufferQ_.pop();
1244 } else {
1245 bufDesc.buffer = nullptr;
1246 AUDIO_ERR_LOG("AudioContainerRenderStream::GetBufferDesc freeBufferQ_.empty()");
1247 return ERR_OPERATION_FAILED;
1248 }
1249 }
1250
1251 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
1252 if (!filledBufferQ_.empty()) {
1253 bufDesc.buffer = filledBufferQ_.front().buffer;
1254 bufDesc.bufLength = filledBufferQ_.front().bufLength;
1255 bufDesc.dataLength = filledBufferQ_.front().dataLength;
1256 filledBufferQ_.pop();
1257 } else {
1258 bufDesc.buffer = nullptr;
1259 AUDIO_ERR_LOG("AudioContainerRenderStream::GetBufferDesc filledBufferQ_.empty()");
1260 return ERR_OPERATION_FAILED;
1261 }
1262 }
1263 return SUCCESS;
1264 }
1265
GetBufQueueState(BufferQueueState & bufState)1266 int32_t AudioContainerRenderStream::GetBufQueueState(BufferQueueState &bufState)
1267 {
1268 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
1269 AUDIO_ERR_LOG("GetBufQueueState not supported. Render or Capture mode is not callback.");
1270 return ERR_INCORRECT_MODE;
1271 }
1272
1273 lock_guard<mutex> lock(mBufferQueueLock);
1274 if (renderMode_ == RENDER_MODE_CALLBACK) {
1275 AUDIO_DEBUG_LOG("GetBufQueueState: bufferlength: %{public}zu.", filledBufferQ_.size());
1276 bufState.numBuffers = filledBufferQ_.size();
1277 }
1278
1279 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
1280 bufState.numBuffers = freeBufferQ_.size();
1281 }
1282
1283 return SUCCESS;
1284 }
1285
Enqueue(const BufferDesc & bufDesc)1286 int32_t AudioContainerRenderStream::Enqueue(const BufferDesc &bufDesc)
1287 {
1288 AUDIO_DEBUG_LOG("AudioContainerRenderStream::Enqueue");
1289 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
1290 AUDIO_ERR_LOG("AudioContainerRenderStream::Enqueue not supported. Render or capture mode is not callback.");
1291 return ERR_INCORRECT_MODE;
1292 }
1293
1294 if (bufDesc.buffer == nullptr) {
1295 AUDIO_ERR_LOG("AudioContainerRenderStream::Enqueue: failed. bufDesc.buffer == nullptr.");
1296 return ERR_INVALID_PARAM;
1297 }
1298
1299 lock_guard<mutex> lock(mBufferQueueLock);
1300 if (renderMode_ == RENDER_MODE_CALLBACK) {
1301 AUDIO_INFO_LOG("AudioContainerRenderStream::Enqueue: filledBuffer length: %{public}zu.", bufDesc.bufLength);
1302 filledBufferQ_.emplace(bufDesc);
1303 }
1304
1305 if (captureMode_ == CAPTURE_MODE_CALLBACK) {
1306 AUDIO_INFO_LOG("AudioContainerRenderStream::Enqueue: freeBuffer length: %{public}zu.", bufDesc.bufLength);
1307 freeBufferQ_.emplace(bufDesc);
1308 }
1309
1310 return SUCCESS;
1311 }
1312
Clear()1313 int32_t AudioContainerRenderStream::Clear()
1314 {
1315 if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) {
1316 AUDIO_ERR_LOG("AudioContainerRenderStream::Clear not supported. Render or capture mode is not callback.");
1317 return ERR_INCORRECT_MODE;
1318 }
1319
1320 lock_guard<mutex> lock(mBufferQueueLock);
1321 while (!filledBufferQ_.empty()) {
1322 freeBufferQ_.emplace(filledBufferQ_.front());
1323 filledBufferQ_.pop();
1324 }
1325
1326 return SUCCESS;
1327 }
1328 } // namespace AudioStandard
1329 } // namespace OHOS
1330