1 /*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "AudioStreamTrack"
18 //#define LOG_NDEBUG 0
19 #include <utils/Log.h>
20
21 #include <stdint.h>
22 #include <media/AudioTrack.h>
23
24 #include <aaudio/AAudio.h>
25 #include <com_android_media_aaudio.h>
26 #include <system/audio.h>
27 #include <system/aaudio/AAudio.h>
28
29 #include "core/AudioGlobal.h"
30 #include "legacy/AudioStreamLegacy.h"
31 #include "legacy/AudioStreamTrack.h"
32 #include "utility/AudioClock.h"
33 #include "utility/FixedBlockReader.h"
34
35 using namespace android;
36 using namespace aaudio;
37
38 using android::content::AttributionSourceState;
39
40 // Arbitrary and somewhat generous number of bursts.
41 #define DEFAULT_BURSTS_PER_BUFFER_CAPACITY 8
42
43 /*
44 * Create a stream that uses the AudioTrack.
45 */
AudioStreamTrack()46 AudioStreamTrack::AudioStreamTrack()
47 : AudioStreamLegacy()
48 , mFixedBlockReader(*this)
49 {
50 }
51
~AudioStreamTrack()52 AudioStreamTrack::~AudioStreamTrack()
53 {
54 const aaudio_stream_state_t state = getState();
55 bool bad = !(state == AAUDIO_STREAM_STATE_UNINITIALIZED || state == AAUDIO_STREAM_STATE_CLOSED);
56 ALOGE_IF(bad, "stream not closed, in state %d", state);
57 }
58
open(const AudioStreamBuilder & builder)59 aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder)
60 {
61 if (!com::android::media::aaudio::offload_support() &&
62 builder.getPerformanceMode() == AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
63 return AAUDIO_ERROR_UNIMPLEMENTED;
64 }
65 aaudio_result_t result = AAUDIO_OK;
66
67 result = AudioStream::open(builder);
68 if (result != OK) {
69 return result;
70 }
71
72 const aaudio_session_id_t requestedSessionId = builder.getSessionId();
73 const audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
74
75 audio_channel_mask_t channelMask =
76 AAudio_getChannelMaskForOpen(getChannelMask(), getSamplesPerFrame(), false /*isInput*/);
77
78 // Set flags based on selected parameters.
79 audio_output_flags_t flags;
80 aaudio_performance_mode_t perfMode = getPerformanceMode();
81 switch(perfMode) {
82 case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY: {
83 // Bypass the normal mixer and go straight to the FAST mixer.
84 // Some Usages need RAW mode so they can get the lowest possible latency.
85 // Other Usages should avoid RAW because it can interfere with
86 // dual sink routing or other features.
87 bool usageBenefitsFromRaw = getUsage() == AAUDIO_USAGE_GAME ||
88 getUsage() == AAUDIO_USAGE_MEDIA;
89 // If an app does not ask for a sessionId then there will be no effects.
90 // So we can use the use RAW flag.
91 flags = (audio_output_flags_t) (((requestedSessionId == AAUDIO_SESSION_ID_NONE)
92 && usageBenefitsFromRaw)
93 ? (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)
94 : (AUDIO_OUTPUT_FLAG_FAST));
95 }
96 break;
97
98 case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
99 // This uses a mixer that wakes up less often than the FAST mixer.
100 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
101 break;
102
103 case AAUDIO_PERFORMANCE_MODE_NONE:
104 default:
105 // No flags. Use a normal mixer in front of the FAST mixer.
106 flags = AUDIO_OUTPUT_FLAG_NONE;
107 break;
108 }
109
110 size_t frameCount = (size_t)builder.getBufferCapacity();
111
112 // To avoid glitching, let AudioFlinger pick the optimal burst size.
113 int32_t notificationFrames = 0;
114
115 const audio_format_t format = (getFormat() == AUDIO_FORMAT_DEFAULT)
116 ? AUDIO_FORMAT_PCM_FLOAT
117 : getFormat();
118
119 // Setup the callback if there is one.
120 wp<AudioTrack::IAudioTrackCallback> callback;
121 // Note that TRANSFER_SYNC does not allow FAST track
122 AudioTrack::transfer_type streamTransferType = AudioTrack::transfer_type::TRANSFER_SYNC;
123 if (builder.getDataCallbackProc() != nullptr) {
124 streamTransferType = AudioTrack::transfer_type::TRANSFER_CALLBACK;
125 callback = wp<AudioTrack::IAudioTrackCallback>::fromExisting(this);
126
127 // If the total buffer size is unspecified then base the size on the burst size.
128 if (frameCount == 0
129 && ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0)) {
130 // Take advantage of a special trick that allows us to create a buffer
131 // that is some multiple of the burst size.
132 notificationFrames = 0 - DEFAULT_BURSTS_PER_BUFFER_CAPACITY;
133 }
134 }
135 mCallbackBufferSize = builder.getFramesPerDataCallback();
136
137 ALOGD("open(), request notificationFrames = %d, frameCount = %u",
138 notificationFrames, (uint)frameCount);
139
140 // Don't call mAudioTrack->setDeviceId() because it will be overwritten by set()!
141 audio_port_handle_t selectedDeviceId = getFirstDeviceId(getDeviceIds());
142
143 const audio_content_type_t contentType =
144 AAudioConvert_contentTypeToInternal(builder.getContentType());
145 const audio_usage_t usage =
146 AAudioConvert_usageToInternal(builder.getUsage());
147 const audio_flags_mask_t attributesFlags = AAudio_computeAudioFlagsMask(
148 builder.getAllowedCapturePolicy(),
149 builder.getSpatializationBehavior(),
150 builder.isContentSpatialized(),
151 flags);
152
153 const std::string tags = getTagsAsString();
154 audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
155 attributes.content_type = contentType;
156 attributes.usage = usage;
157 attributes.flags = attributesFlags;
158 if (!tags.empty()) {
159 strncpy(attributes.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
160 attributes.tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1] = '\0';
161 }
162
163 audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
164 if (getPerformanceMode() == AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
165 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
166 config.format = format;
167 config.channel_mask = channelMask;
168 config.sample_rate = getSampleRate();
169 audio_direct_mode_t directMode = AUDIO_DIRECT_NOT_SUPPORTED;
170 if (status_t status = AudioSystem::getDirectPlaybackSupport(
171 &attributes, &config, &directMode);
172 status != NO_ERROR) {
173 ALOGE("%s, failed to query direct support, error=%d", __func__, status);
174 return status;
175 }
176 static const audio_direct_mode_t offloadMode = static_cast<audio_direct_mode_t>(
177 AUDIO_DIRECT_OFFLOAD_SUPPORTED | AUDIO_DIRECT_OFFLOAD_GAPLESS_SUPPORTED);
178 if ((directMode & offloadMode) == AUDIO_DIRECT_NOT_SUPPORTED) {
179 return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
180 }
181 flags = AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
182 frameCount = 0;
183 offloadInfo.format = format;
184 offloadInfo.sample_rate = getSampleRate();
185 offloadInfo.channel_mask = channelMask;
186 offloadInfo.has_video = false;
187 offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
188 }
189
190 mAudioTrack = new AudioTrack();
191 // TODO b/182392769: use attribution source util
192 mAudioTrack->set(
193 AUDIO_STREAM_DEFAULT, // ignored because we pass attributes below
194 getSampleRate(),
195 format,
196 channelMask,
197 frameCount,
198 flags,
199 callback,
200 notificationFrames,
201 nullptr, // DEFAULT sharedBuffer*/,
202 false, // DEFAULT threadCanCallJava
203 sessionId,
204 streamTransferType,
205 getPerformanceMode() == AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED
206 ? &offloadInfo : nullptr,
207 AttributionSourceState(), // DEFAULT uid and pid
208 &attributes,
209 // WARNING - If doNotReconnect set true then audio stops after plugging and unplugging
210 // headphones a few times.
211 false, // DEFAULT doNotReconnect,
212 1.0f, // DEFAULT maxRequiredSpeed
213 selectedDeviceId
214 );
215
216 // Set it here so it can be logged by the destructor if the open failed.
217 mAudioTrack->setCallerName(kCallerName);
218
219 // Did we get a valid track?
220 status_t status = mAudioTrack->initCheck();
221 if (status != NO_ERROR) {
222 safeReleaseClose();
223 ALOGE("open(), initCheck() returned %d", status);
224 return AAudioConvert_androidToAAudioResult(status);
225 }
226
227 mMetricsId = std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK)
228 + std::to_string(mAudioTrack->getPortId());
229 android::mediametrics::LogItem(mMetricsId)
230 .set(AMEDIAMETRICS_PROP_PERFORMANCEMODE,
231 AudioGlobal_convertPerformanceModeToText(builder.getPerformanceMode()))
232 .set(AMEDIAMETRICS_PROP_SHARINGMODE,
233 AudioGlobal_convertSharingModeToText(builder.getSharingMode()))
234 .set(AMEDIAMETRICS_PROP_ENCODINGCLIENT,
235 android::toString(getFormat()).c_str()).record();
236
237 doSetVolume();
238
239 // Get the actual values from the AudioTrack.
240 setChannelMask(AAudioConvert_androidToAAudioChannelMask(
241 mAudioTrack->channelMask(), false /*isInput*/,
242 AAudio_isChannelIndexMask(getChannelMask())));
243 setFormat(mAudioTrack->format());
244 setDeviceFormat(mAudioTrack->format());
245 setSampleRate(mAudioTrack->getSampleRate());
246 setBufferCapacity(getBufferCapacityFromDevice());
247 setFramesPerBurst(getFramesPerBurstFromDevice());
248
249 // Use the same values for device values.
250 setDeviceSamplesPerFrame(getSamplesPerFrame());
251 setDeviceSampleRate(mAudioTrack->getSampleRate());
252 setDeviceBufferCapacity(getBufferCapacityFromDevice());
253 setDeviceFramesPerBurst(getFramesPerBurstFromDevice());
254
255 setHardwareSamplesPerFrame(mAudioTrack->getHalChannelCount());
256 setHardwareSampleRate(mAudioTrack->getHalSampleRate());
257 setHardwareFormat(mAudioTrack->getHalFormat());
258
259 // We may need to pass the data through a block size adapter to guarantee constant size.
260 if (mCallbackBufferSize != AAUDIO_UNSPECIFIED) {
261 // This may need to change if we add format conversion before
262 // the block size adaptation.
263 mBlockAdapterBytesPerFrame = getBytesPerFrame();
264 int callbackSizeBytes = mBlockAdapterBytesPerFrame * mCallbackBufferSize;
265 mFixedBlockReader.open(callbackSizeBytes);
266 mBlockAdapter = &mFixedBlockReader;
267 } else {
268 mBlockAdapter = nullptr;
269 }
270
271 setDeviceIds(mAudioTrack->getRoutedDeviceIds());
272
273 aaudio_session_id_t actualSessionId =
274 (requestedSessionId == AAUDIO_SESSION_ID_NONE)
275 ? AAUDIO_SESSION_ID_NONE
276 : (aaudio_session_id_t) mAudioTrack->getSessionId();
277 setSessionId(actualSessionId);
278
279 mAudioTrack->addAudioDeviceCallback(this);
280
281 // Update performance mode based on the actual stream flags.
282 // For example, if the sample rate is not allowed then you won't get a FAST track.
283 audio_output_flags_t actualFlags = mAudioTrack->getFlags();
284 aaudio_performance_mode_t actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
285 // We may not get the RAW flag. But as long as we get the FAST flag we can call it LOW_LATENCY.
286 if ((actualFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != AUDIO_OUTPUT_FLAG_NONE) {
287 actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED;
288 } else if ((actualFlags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
289 actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
290 } else if ((actualFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
291 actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING;
292 }
293 setPerformanceMode(actualPerformanceMode);
294
295 setSharingMode(AAUDIO_SHARING_MODE_SHARED); // EXCLUSIVE mode not supported in legacy
296
297 // Log if we did not get what we asked for.
298 ALOGD_IF(actualFlags != flags,
299 "open() flags changed from 0x%08X to 0x%08X",
300 flags, actualFlags);
301 ALOGD_IF(actualPerformanceMode != perfMode,
302 "open() perfMode changed from %d to %d",
303 perfMode, actualPerformanceMode);
304
305 if (getState() != AAUDIO_STREAM_STATE_UNINITIALIZED) {
306 ALOGE("%s - Open canceled since state = %d", __func__, getState());
307 if (isDisconnected())
308 {
309 ALOGE("%s - Opening while state is disconnected", __func__);
310 safeReleaseClose();
311 return AAUDIO_ERROR_DISCONNECTED;
312 }
313 safeReleaseClose();
314 return AAUDIO_ERROR_INVALID_STATE;
315 }
316
317 setState(AAUDIO_STREAM_STATE_OPEN);
318 return AAUDIO_OK;
319 }
320
release_l()321 aaudio_result_t AudioStreamTrack::release_l() {
322 if (getState() != AAUDIO_STREAM_STATE_CLOSING) {
323 status_t err = mAudioTrack->removeAudioDeviceCallback(this);
324 ALOGE_IF(err, "%s() removeAudioDeviceCallback returned %d", __func__, err);
325 logReleaseBufferState();
326 // Data callbacks may still be running!
327 return AudioStream::release_l();
328 } else {
329 return AAUDIO_OK; // already released
330 }
331 }
332
close_l()333 void AudioStreamTrack::close_l() {
334 // The callbacks are normally joined in the AudioTrack destructor.
335 // But if another object has a reference to the AudioTrack then
336 // it will not get deleted here.
337 // So we should join callbacks explicitly before returning.
338 // Unlock around the join to avoid deadlocks if the callback tries to lock.
339 // This can happen if the callback returns AAUDIO_CALLBACK_RESULT_STOP
340 mStreamLock.unlock();
341 mAudioTrack->stopAndJoinCallbacks();
342 mStreamLock.lock();
343 mAudioTrack.clear();
344 // Do not close mFixedBlockReader. It has a unique_ptr to its buffer
345 // so it will clean up by itself.
346 AudioStream::close_l();
347 }
348
349
onNewIAudioTrack()350 void AudioStreamTrack::onNewIAudioTrack() {
351 // Stream got rerouted so we disconnect.
352 // request stream disconnect if the restored AudioTrack has properties not matching
353 // what was requested initially
354 if (mAudioTrack->channelCount() != getSamplesPerFrame()
355 || mAudioTrack->format() != getFormat()
356 || mAudioTrack->getSampleRate() != getSampleRate()
357 || !areDeviceIdsEqual(mAudioTrack->getRoutedDeviceIds(), getDeviceIds())
358 || getBufferCapacityFromDevice() != getBufferCapacity()
359 || getFramesPerBurstFromDevice() != getFramesPerBurst()) {
360 AudioStreamLegacy::onNewIAudioTrack();
361 }
362 }
363
requestStart_l()364 aaudio_result_t AudioStreamTrack::requestStart_l() {
365 if (mAudioTrack.get() == nullptr) {
366 ALOGE("requestStart() no AudioTrack");
367 return AAUDIO_ERROR_INVALID_STATE;
368 }
369 // Get current position so we can detect when the track is playing.
370 status_t err = mAudioTrack->getPosition(&mPositionWhenStarting);
371 if (err != OK) {
372 return AAudioConvert_androidToAAudioResult(err);
373 }
374
375 // Enable callback before starting AudioTrack to avoid shutting
376 // down because of a race condition.
377 mCallbackEnabled.store(true);
378 aaudio_stream_state_t originalState = getState();
379 // Set before starting the callback so that we are in the correct state
380 // before updateStateMachine() can be called by the callback.
381 setState(AAUDIO_STREAM_STATE_STARTING);
382 err = mAudioTrack->start();
383 if (err != OK) {
384 mCallbackEnabled.store(false);
385 setState(originalState);
386 return AAudioConvert_androidToAAudioResult(err);
387 }
388 mOffloadEosPending = false;
389 return AAUDIO_OK;
390 }
391
requestPause_l()392 aaudio_result_t AudioStreamTrack::requestPause_l() {
393 if (mAudioTrack.get() == nullptr) {
394 ALOGE("%s() no AudioTrack", __func__);
395 return AAUDIO_ERROR_INVALID_STATE;
396 }
397
398 setState(AAUDIO_STREAM_STATE_PAUSING);
399 mAudioTrack->pause();
400 mCallbackEnabled.store(false);
401 status_t err = mAudioTrack->getPosition(&mPositionWhenPausing);
402 if (err != OK) {
403 return AAudioConvert_androidToAAudioResult(err);
404 }
405 return checkForDisconnectRequest(false);
406 }
407
requestFlush_l()408 aaudio_result_t AudioStreamTrack::requestFlush_l() {
409 if (mAudioTrack.get() == nullptr) {
410 ALOGE("%s() no AudioTrack", __func__);
411 return AAUDIO_ERROR_INVALID_STATE;
412 }
413
414 setState(AAUDIO_STREAM_STATE_FLUSHING);
415 incrementFramesRead(getFramesWritten() - getFramesRead());
416 mAudioTrack->flush();
417 mFramesRead.reset32(); // service reads frames, service position reset on flush
418 mTimestampPosition.reset32();
419 return AAUDIO_OK;
420 }
421
requestStop_l()422 aaudio_result_t AudioStreamTrack::requestStop_l() {
423 if (mAudioTrack.get() == nullptr) {
424 ALOGE("%s() no AudioTrack", __func__);
425 return AAUDIO_ERROR_INVALID_STATE;
426 }
427
428 setState(AAUDIO_STREAM_STATE_STOPPING);
429 mFramesRead.catchUpTo(getFramesWritten());
430 mTimestampPosition.catchUpTo(getFramesWritten());
431 mFramesRead.reset32(); // service reads frames, service position reset on stop
432 mTimestampPosition.reset32();
433 mAudioTrack->stop();
434 mCallbackEnabled.store(false);
435 return checkForDisconnectRequest(false);;
436 }
437
processCommands()438 aaudio_result_t AudioStreamTrack::processCommands() {
439 status_t err;
440 aaudio_wrapping_frames_t position;
441 switch (getState()) {
442 // TODO add better state visibility to AudioTrack
443 case AAUDIO_STREAM_STATE_STARTING:
444 if (mAudioTrack->hasStarted()) {
445 setState(AAUDIO_STREAM_STATE_STARTED);
446 }
447 break;
448 case AAUDIO_STREAM_STATE_PAUSING:
449 if (mAudioTrack->stopped()) {
450 err = mAudioTrack->getPosition(&position);
451 if (err != OK) {
452 return AAudioConvert_androidToAAudioResult(err);
453 } else if (position == mPositionWhenPausing) {
454 // Has stream really stopped advancing?
455 setState(AAUDIO_STREAM_STATE_PAUSED);
456 }
457 mPositionWhenPausing = position;
458 }
459 break;
460 case AAUDIO_STREAM_STATE_FLUSHING:
461 {
462 err = mAudioTrack->getPosition(&position);
463 if (err != OK) {
464 return AAudioConvert_androidToAAudioResult(err);
465 } else if (position == 0) {
466 setState(AAUDIO_STREAM_STATE_FLUSHED);
467 }
468 }
469 break;
470 case AAUDIO_STREAM_STATE_STOPPING:
471 if (mAudioTrack->stopped()) {
472 if (getPerformanceMode() == AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
473 std::lock_guard<std::mutex> lock(mStreamLock);
474 if (!mOffloadEosPending) {
475 break;
476 }
477 }
478 setState(AAUDIO_STREAM_STATE_STOPPED);
479 }
480 break;
481 default:
482 break;
483 }
484 return AAUDIO_OK;
485 }
486
write(const void * buffer,int32_t numFrames,int64_t timeoutNanoseconds)487 aaudio_result_t AudioStreamTrack::write(const void *buffer,
488 int32_t numFrames,
489 int64_t timeoutNanoseconds)
490 {
491 int32_t bytesPerFrame = getBytesPerFrame();
492 int32_t numBytes;
493 aaudio_result_t result = AAudioConvert_framesToBytes(numFrames, bytesPerFrame, &numBytes);
494 if (result != AAUDIO_OK) {
495 return result;
496 }
497
498 if (isDisconnected()) {
499 return AAUDIO_ERROR_DISCONNECTED;
500 }
501
502 // TODO add timeout to AudioTrack
503 bool blocking = timeoutNanoseconds > 0;
504 ssize_t bytesWritten = mAudioTrack->write(buffer, numBytes, blocking);
505 if (bytesWritten == WOULD_BLOCK) {
506 return 0;
507 } else if (bytesWritten < 0) {
508 ALOGE("invalid write, returned %d", (int)bytesWritten);
509 // in this context, a DEAD_OBJECT is more likely to be a disconnect notification due to
510 // AudioTrack invalidation
511 if (bytesWritten == DEAD_OBJECT) {
512 setDisconnected();
513 return AAUDIO_ERROR_DISCONNECTED;
514 }
515 return AAudioConvert_androidToAAudioResult(bytesWritten);
516 }
517 int32_t framesWritten = (int32_t)(bytesWritten / bytesPerFrame);
518 incrementFramesWritten(framesWritten);
519
520 result = updateStateMachine();
521 if (result != AAUDIO_OK) {
522 return result;
523 }
524
525 return framesWritten;
526 }
527
setBufferSize(int32_t requestedFrames)528 aaudio_result_t AudioStreamTrack::setBufferSize(int32_t requestedFrames)
529 {
530 // Do not ask for less than one burst.
531 if (requestedFrames < getFramesPerBurst()) {
532 requestedFrames = getFramesPerBurst();
533 }
534 ssize_t result = mAudioTrack->setBufferSizeInFrames(requestedFrames);
535 if (result < 0) {
536 return AAudioConvert_androidToAAudioResult(result);
537 } else {
538 return result;
539 }
540 }
541
getBufferSize() const542 int32_t AudioStreamTrack::getBufferSize() const
543 {
544 return static_cast<int32_t>(mAudioTrack->getBufferSizeInFrames());
545 }
546
getBufferCapacityFromDevice() const547 int32_t AudioStreamTrack::getBufferCapacityFromDevice() const
548 {
549 return static_cast<int32_t>(mAudioTrack->frameCount());
550 }
551
getXRunCount() const552 int32_t AudioStreamTrack::getXRunCount() const
553 {
554 return static_cast<int32_t>(mAudioTrack->getUnderrunCount());
555 }
556
getFramesPerBurstFromDevice() const557 int32_t AudioStreamTrack::getFramesPerBurstFromDevice() const {
558 return static_cast<int32_t>(mAudioTrack->getNotificationPeriodInFrames());
559 }
560
getFramesRead()561 int64_t AudioStreamTrack::getFramesRead() {
562 aaudio_wrapping_frames_t position;
563 status_t result;
564 switch (getState()) {
565 case AAUDIO_STREAM_STATE_STARTING:
566 case AAUDIO_STREAM_STATE_STARTED:
567 case AAUDIO_STREAM_STATE_STOPPING:
568 case AAUDIO_STREAM_STATE_PAUSING:
569 case AAUDIO_STREAM_STATE_PAUSED:
570 result = mAudioTrack->getPosition(&position);
571 if (result == OK) {
572 mFramesRead.update32((int32_t)position);
573 }
574 break;
575 default:
576 break;
577 }
578 return AudioStreamLegacy::getFramesRead();
579 }
580
getTimestamp(clockid_t clockId,int64_t * framePosition,int64_t * timeNanoseconds)581 aaudio_result_t AudioStreamTrack::getTimestamp(clockid_t clockId,
582 int64_t *framePosition,
583 int64_t *timeNanoseconds) {
584 ExtendedTimestamp extendedTimestamp;
585 status_t status = mAudioTrack->getTimestamp(&extendedTimestamp);
586 if (status == WOULD_BLOCK) {
587 return AAUDIO_ERROR_INVALID_STATE;
588 } if (status != NO_ERROR) {
589 return AAudioConvert_androidToAAudioResult(status);
590 }
591 int64_t position = 0;
592 int64_t nanoseconds = 0;
593 aaudio_result_t result = getBestTimestamp(clockId, &position,
594 &nanoseconds, &extendedTimestamp);
595 if (result == AAUDIO_OK) {
596 if (position < getFramesWritten()) {
597 *framePosition = position;
598 *timeNanoseconds = nanoseconds;
599 return result;
600 } else {
601 return AAUDIO_ERROR_INVALID_STATE; // TODO review, documented but not consistent
602 }
603 }
604 return result;
605 }
606
doSetVolume()607 status_t AudioStreamTrack::doSetVolume() {
608 status_t status = NO_INIT;
609 if (mAudioTrack.get() != nullptr) {
610 float volume = getDuckAndMuteVolume();
611 mAudioTrack->setVolume(volume, volume);
612 status = NO_ERROR;
613 }
614 return status;
615 }
616
registerPlayerBase()617 void AudioStreamTrack::registerPlayerBase() {
618 AudioStream::registerPlayerBase();
619
620 if (mAudioTrack == nullptr) {
621 ALOGW("%s: cannot set piid, AudioTrack is null", __func__);
622 return;
623 }
624 mAudioTrack->setPlayerIId(mPlayerBase->getPlayerIId());
625 }
626
systemStopInternal_l()627 aaudio_result_t AudioStreamTrack::systemStopInternal_l() {
628 if (aaudio_result_t result = AudioStream::systemStopInternal_l(); result != AAUDIO_OK) {
629 return result;
630 }
631 mOffloadEosPending = false;
632 return AAUDIO_OK;
633 }
634
setOffloadDelayPadding(int32_t delayInFrames,int32_t paddingInFrames)635 aaudio_result_t AudioStreamTrack::setOffloadDelayPadding(
636 int32_t delayInFrames, int32_t paddingInFrames) {
637 if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED ||
638 audio_is_linear_pcm(getFormat())) {
639 return AAUDIO_ERROR_UNIMPLEMENTED;
640 }
641 if (mAudioTrack == nullptr) {
642 return AAUDIO_ERROR_INVALID_STATE;
643 }
644 AudioParameter param = AudioParameter();
645 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delayInFrames);
646 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingInFrames);
647 mAudioTrack->setParameters(param.toString());
648 mOffloadDelayFrames.store(delayInFrames);
649 mOffloadPaddingFrames.store(paddingInFrames);
650 return AAUDIO_OK;
651 }
652
getOffloadDelay()653 int32_t AudioStreamTrack::getOffloadDelay() {
654 if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED ||
655 audio_is_linear_pcm(getFormat())) {
656 return AAUDIO_ERROR_UNIMPLEMENTED;
657 }
658 if (mAudioTrack == nullptr) {
659 return AAUDIO_ERROR_INVALID_STATE;
660 }
661 return mOffloadDelayFrames.load();
662 }
663
getOffloadPadding()664 int32_t AudioStreamTrack::getOffloadPadding() {
665 if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED ||
666 audio_is_linear_pcm(getFormat())) {
667 return AAUDIO_ERROR_UNIMPLEMENTED;
668 }
669 if (mAudioTrack == nullptr) {
670 return AAUDIO_ERROR_INVALID_STATE;
671 }
672 return mOffloadPaddingFrames.load();
673 }
674
setOffloadEndOfStream()675 aaudio_result_t AudioStreamTrack::setOffloadEndOfStream() {
676 if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
677 return AAUDIO_ERROR_UNIMPLEMENTED;
678 }
679 if (mAudioTrack == nullptr) {
680 return AAUDIO_ERROR_INVALID_STATE;
681 }
682 std::lock_guard<std::mutex> lock(mStreamLock);
683 if (aaudio_result_t result = safeStop_l(); result != AAUDIO_OK) {
684 return result;
685 }
686 mOffloadEosPending = true;
687 return AAUDIO_OK;
688 }
689
collidesWithCallback() const690 bool AudioStreamTrack::collidesWithCallback() const {
691 if (AudioStream::collidesWithCallback()) {
692 return true;
693 }
694 pid_t thisThread = gettid();
695 return mPresentationEndCallbackThread.load() == thisThread;
696 }
697
onStreamEnd()698 void AudioStreamTrack::onStreamEnd() {
699 if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
700 return;
701 }
702 if (getState() == AAUDIO_STREAM_STATE_STOPPING) {
703 std::lock_guard<std::mutex> lock(mStreamLock);
704 if (mOffloadEosPending) {
705 requestStart_l();
706 }
707 mOffloadEosPending = false;
708 }
709 maybeCallPresentationEndCallback();
710 }
711
maybeCallPresentationEndCallback()712 void AudioStreamTrack::maybeCallPresentationEndCallback() {
713 if (mPresentationEndCallbackProc != nullptr) {
714 pid_t expected = CALLBACK_THREAD_NONE;
715 if (mPresentationEndCallbackThread.compare_exchange_strong(expected, gettid())) {
716 (*mPresentationEndCallbackProc)(
717 (AAudioStream *) this, mPresentationEndCallbackUserData);
718 mPresentationEndCallbackThread.store(CALLBACK_THREAD_NONE);
719 } else {
720 ALOGW("%s() error callback already running!", __func__);
721 }
722 }
723 }
724
725 #if AAUDIO_USE_VOLUME_SHAPER
726
727 using namespace android::media::VolumeShaper;
728
applyVolumeShaper(const VolumeShaper::Configuration & configuration,const VolumeShaper::Operation & operation)729 binder::Status AudioStreamTrack::applyVolumeShaper(
730 const VolumeShaper::Configuration& configuration,
731 const VolumeShaper::Operation& operation) {
732
733 sp<VolumeShaper::Configuration> spConfiguration = new VolumeShaper::Configuration(configuration);
734 sp<VolumeShaper::Operation> spOperation = new VolumeShaper::Operation(operation);
735
736 if (mAudioTrack.get() != nullptr) {
737 ALOGD("applyVolumeShaper() from IPlayer");
738 binder::Status status = mAudioTrack->applyVolumeShaper(spConfiguration, spOperation);
739 if (status < 0) { // a non-negative value is the volume shaper id.
740 ALOGE("applyVolumeShaper() failed with status %d", status);
741 }
742 return aidl_utils::binderStatusFromStatusT(status);
743 } else {
744 ALOGD("applyVolumeShaper()"
745 " no AudioTrack for volume control from IPlayer");
746 return binder::Status::ok();
747 }
748 }
749 #endif
750