xref: /aosp_15_r20/frameworks/av/media/libaaudio/src/legacy/AudioStreamTrack.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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