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