Loading media/libaaudio/src/legacy/AudioStreamTrack.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -103,7 +103,7 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder) : getFormat(); : getFormat(); // Setup the callback if there is one. // Setup the callback if there is one. AudioTrack::callback_t callback = nullptr; AudioTrack::legacy_callback_t callback = nullptr; void *callbackData = nullptr; void *callbackData = nullptr; // Note that TRANSFER_SYNC does not allow FAST track // Note that TRANSFER_SYNC does not allow FAST track AudioTrack::transfer_type streamTransferType = AudioTrack::transfer_type::TRANSFER_SYNC; AudioTrack::transfer_type streamTransferType = AudioTrack::transfer_type::TRANSFER_SYNC; Loading media/libaudioclient/AudioTrack.cpp +189 −40 Original line number Original line Diff line number Diff line Loading @@ -254,8 +254,7 @@ AudioTrack::AudioTrack( audio_channel_mask_t channelMask, audio_channel_mask_t channelMask, size_t frameCount, size_t frameCount, audio_output_flags_t flags, audio_output_flags_t flags, callback_t cbf, const wp<IAudioTrackCallback> & callback, void* user, int32_t notificationFrames, int32_t notificationFrames, audio_session_t sessionId, audio_session_t sessionId, transfer_type transferType, transfer_type transferType, Loading @@ -275,19 +274,60 @@ AudioTrack::AudioTrack( mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; (void)set(streamType, sampleRate, format, channelMask, (void)set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, frameCount, flags, callback, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); } } namespace { class LegacyCallbackWrapper : public AudioTrack::IAudioTrackCallback { const AudioTrack::legacy_callback_t mCallback; void * const mData; public: LegacyCallbackWrapper(AudioTrack::legacy_callback_t callback, void* user) : mCallback(callback), mData(user) {} size_t onMoreData(const AudioTrack::Buffer & buffer) override { AudioTrack::Buffer copy = buffer; mCallback(AudioTrack::EVENT_MORE_DATA, mData, static_cast<void*>(©)); return copy.size; } void onUnderrun() override { mCallback(AudioTrack::EVENT_UNDERRUN, mData, nullptr); } void onLoopEnd(int32_t loopsRemaining) override { mCallback(AudioTrack::EVENT_LOOP_END, mData, &loopsRemaining); } void onMarker(uint32_t markerPosition) override { mCallback(AudioTrack::EVENT_MARKER, mData, &markerPosition); } void onNewPos(uint32_t newPos) override { mCallback(AudioTrack::EVENT_NEW_POS, mData, &newPos); } void onBufferEnd() override { mCallback(AudioTrack::EVENT_BUFFER_END, mData, nullptr); } void onNewIAudioTrack() override { mCallback(AudioTrack::EVENT_NEW_IAUDIOTRACK, mData, nullptr); } void onStreamEnd() override { mCallback(AudioTrack::EVENT_STREAM_END, mData, nullptr); } size_t onCanWriteMoreData(const AudioTrack::Buffer & buffer) override { AudioTrack::Buffer copy = buffer; mCallback(AudioTrack::EVENT_CAN_WRITE_MORE_DATA, mData, static_cast<void*>(©)); return copy.size; } }; } AudioTrack::AudioTrack( AudioTrack::AudioTrack( audio_stream_type_t streamType, audio_stream_type_t streamType, uint32_t sampleRate, uint32_t sampleRate, audio_format_t format, audio_format_t format, audio_channel_mask_t channelMask, audio_channel_mask_t channelMask, const sp<IMemory>& sharedBuffer, size_t frameCount, audio_output_flags_t flags, audio_output_flags_t flags, callback_t cbf, legacy_callback_t callback, void* user, void* user, int32_t notificationFrames, int32_t notificationFrames, audio_session_t sessionId, audio_session_t sessionId, Loading @@ -296,6 +336,42 @@ AudioTrack::AudioTrack( const AttributionSourceState& attributionSource, const AttributionSourceState& attributionSource, const audio_attributes_t* pAttributes, const audio_attributes_t* pAttributes, bool doNotReconnect, bool doNotReconnect, float maxRequiredSpeed, audio_port_handle_t selectedDeviceId) : mStatus(NO_INIT), mState(STATE_STOPPED), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0), mAudioTrackCallback(new AudioTrackCallback()) { mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; if (callback != nullptr) { mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user); } else if (user) { LOG_ALWAYS_FATAL("Callback data provided without callback pointer!"); } (void)set(streamType, sampleRate, format, channelMask, frameCount, flags, mLegacyCallbackWrapper, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); } AudioTrack::AudioTrack( audio_stream_type_t streamType, uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, const sp<IMemory>& sharedBuffer, audio_output_flags_t flags, const wp<IAudioTrackCallback>& callback, int32_t notificationFrames, audio_session_t sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, const AttributionSourceState& attributionSource, const audio_attributes_t* pAttributes, bool doNotReconnect, float maxRequiredSpeed) float maxRequiredSpeed) : mStatus(NO_INIT), : mStatus(NO_INIT), mState(STATE_STOPPED), mState(STATE_STOPPED), Loading @@ -308,11 +384,49 @@ AudioTrack::AudioTrack( mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; (void)set(streamType, sampleRate, format, channelMask, (void)set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, 0 /*frameCount*/, flags, callback, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed); attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed); } } AudioTrack::AudioTrack( audio_stream_type_t streamType, uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, const sp<IMemory>& sharedBuffer, audio_output_flags_t flags, legacy_callback_t callback, void* user, int32_t notificationFrames, audio_session_t sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, const AttributionSourceState& attributionSource, const audio_attributes_t* pAttributes, bool doNotReconnect, float maxRequiredSpeed) : mStatus(NO_INIT), mState(STATE_STOPPED), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0), mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mAudioTrackCallback(new AudioTrackCallback()) { mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; if (callback) { mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user); } else if (user) { LOG_ALWAYS_FATAL("Callback data provided without callback pointer!"); } (void)set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, mLegacyCallbackWrapper, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed); } AudioTrack::~AudioTrack() AudioTrack::~AudioTrack() { { // pull together the numbers, before we clean up our structures // pull together the numbers, before we clean up our structures Loading Loading @@ -374,7 +488,7 @@ status_t AudioTrack::set( audio_channel_mask_t channelMask, audio_channel_mask_t channelMask, size_t frameCount, size_t frameCount, audio_output_flags_t flags, audio_output_flags_t flags, callback_t cbf, legacy_callback_t callback, void * user, void * user, int32_t notificationFrames, int32_t notificationFrames, const sp<IMemory>& sharedBuffer, const sp<IMemory>& sharedBuffer, Loading @@ -387,6 +501,36 @@ status_t AudioTrack::set( bool doNotReconnect, bool doNotReconnect, float maxRequiredSpeed, float maxRequiredSpeed, audio_port_handle_t selectedDeviceId) audio_port_handle_t selectedDeviceId) { if (callback) { mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user); } else if (user) { LOG_ALWAYS_FATAL("Callback data provided without callback pointer!"); } return set(streamType, sampleRate,format, channelMask, frameCount, flags, mLegacyCallbackWrapper, notificationFrames, sharedBuffer, threadCanCallJava, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); } status_t AudioTrack::set( audio_stream_type_t streamType, uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, size_t frameCount, audio_output_flags_t flags, const wp<IAudioTrackCallback>& callback, int32_t notificationFrames, const sp<IMemory>& sharedBuffer, bool threadCanCallJava, audio_session_t sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, const AttributionSourceState& attributionSource, const audio_attributes_t* pAttributes, bool doNotReconnect, float maxRequiredSpeed, audio_port_handle_t selectedDeviceId) { { status_t status; status_t status; uint32_t channelCount; uint32_t channelCount; Loading @@ -394,7 +538,7 @@ status_t AudioTrack::set( pid_t myPid; pid_t myPid; uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid)); pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid)); sp<IAudioTrackCallback> _callback = callback.promote(); // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set. // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set. ALOGV("%s(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " ALOGV("%s(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d", "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d", Loading @@ -410,7 +554,7 @@ status_t AudioTrack::set( case TRANSFER_DEFAULT: case TRANSFER_DEFAULT: if (sharedBuffer != 0) { if (sharedBuffer != 0) { transferType = TRANSFER_SHARED; transferType = TRANSFER_SHARED; } else if (cbf == NULL || threadCanCallJava) { } else if (_callback == nullptr|| threadCanCallJava) { transferType = TRANSFER_SYNC; transferType = TRANSFER_SYNC; } else { } else { transferType = TRANSFER_CALLBACK; transferType = TRANSFER_CALLBACK; Loading @@ -418,8 +562,8 @@ status_t AudioTrack::set( break; break; case TRANSFER_CALLBACK: case TRANSFER_CALLBACK: case TRANSFER_SYNC_NOTIF_CALLBACK: case TRANSFER_SYNC_NOTIF_CALLBACK: if (cbf == NULL || sharedBuffer != 0) { if (_callback == nullptr || sharedBuffer != 0) { ALOGE("%s(): Transfer type %s but cbf == NULL || sharedBuffer != 0", ALOGE("%s(): Transfer type %s but callback == nullptr || sharedBuffer != 0", convertTransferToText(transferType), __func__); convertTransferToText(transferType), __func__); status = BAD_VALUE; status = BAD_VALUE; goto exit; goto exit; Loading Loading @@ -609,10 +753,10 @@ status_t AudioTrack::set( } } mAuxEffectId = 0; mAuxEffectId = 0; mOrigFlags = mFlags = flags; mOrigFlags = mFlags = flags; mCbf = cbf; mCallback = callback; if (cbf != NULL) { if (_callback != nullptr) { mAudioTrackThread = new AudioTrackThread(*this); mAudioTrackThread = sp<AudioTrackThread>::make(*this); mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/); mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/); // thread begins in paused state, and will not reference us until start() // thread begins in paused state, and will not reference us until start() } } Loading @@ -631,7 +775,6 @@ status_t AudioTrack::set( goto exit; goto exit; } } mUserData = user; mLoopCount = 0; mLoopCount = 0; mLoopStart = 0; mLoopStart = 0; mLoopEnd = 0; mLoopEnd = 0; Loading Loading @@ -675,7 +818,7 @@ status_t AudioTrack::set( uint32_t channelMask, uint32_t channelMask, size_t frameCount, size_t frameCount, audio_output_flags_t flags, audio_output_flags_t flags, callback_t cbf, legacy_callback_t callback, void* user, void* user, int32_t notificationFrames, int32_t notificationFrames, const sp<IMemory>& sharedBuffer, const sp<IMemory>& sharedBuffer, Loading @@ -694,9 +837,13 @@ status_t AudioTrack::set( attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(uid)); attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(uid)); attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(pid)); attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(pid)); attributionSource.token = sp<BBinder>::make(); attributionSource.token = sp<BBinder>::make(); return set(streamType, sampleRate, format, if (callback) { static_cast<audio_channel_mask_t>(channelMask), mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user); frameCount, flags, cbf, user, notificationFrames, sharedBuffer, } else if (user) { LOG_ALWAYS_FATAL("Callback data provided without callback pointer!"); } return set(streamType, sampleRate, format, static_cast<audio_channel_mask_t>(channelMask), frameCount, flags, mLegacyCallbackWrapper, notificationFrames, sharedBuffer, threadCanCallJava, sessionId, transferType, offloadInfo, attributionSource, threadCanCallJava, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); } } Loading Loading @@ -1407,7 +1554,7 @@ void AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount) status_t AudioTrack::setMarkerPosition(uint32_t marker) status_t AudioTrack::setMarkerPosition(uint32_t marker) { { // The only purpose of setting marker position is to get a callback // The only purpose of setting marker position is to get a callback if (mCbf == NULL || isOffloadedOrDirect()) { if (!mCallback.promote() || isOffloadedOrDirect()) { return INVALID_OPERATION; return INVALID_OPERATION; } } Loading Loading @@ -1440,7 +1587,7 @@ status_t AudioTrack::getMarkerPosition(uint32_t *marker) const status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) { { // The only purpose of setting position update period is to get a callback // The only purpose of setting position update period is to get a callback if (mCbf == NULL || isOffloadedOrDirect()) { if (!mCallback.promote() || isOffloadedOrDirect()) { return INVALID_OPERATION; return INVALID_OPERATION; } } Loading Loading @@ -2209,10 +2356,14 @@ nsecs_t AudioTrack::processAudioBuffer() { { // Currently the AudioTrack thread is not created if there are no callbacks. // Currently the AudioTrack thread is not created if there are no callbacks. // Would it ever make sense to run the thread, even without callbacks? // Would it ever make sense to run the thread, even without callbacks? // If so, then replace this by checks at each use for mCbf != NULL. // If so, then replace this by checks at each use for mCallback != NULL. LOG_ALWAYS_FATAL_IF(mCblk == NULL); LOG_ALWAYS_FATAL_IF(mCblk == NULL); mLock.lock(); mLock.lock(); sp<IAudioTrackCallback> callback = mCallback.promote(); if (!callback) { mCallback = nullptr; return NS_NEVER; } if (mAwaitBoost) { if (mAwaitBoost) { mAwaitBoost = false; mAwaitBoost = false; mLock.unlock(); mLock.unlock(); Loading Loading @@ -2310,7 +2461,7 @@ nsecs_t AudioTrack::processAudioBuffer() sp<AudioTrackClientProxy> proxy = mProxy; sp<AudioTrackClientProxy> proxy = mProxy; // Determine the number of new loop callback(s) that will be needed, while locked. // Determine the number of new loop callback(s) that will be needed, while locked. int loopCountNotifications = 0; uint32_t loopCountNotifications = 0; uint32_t loopPeriod = 0; // time in frames for next EVENT_LOOP_END or EVENT_BUFFER_END uint32_t loopPeriod = 0; // time in frames for next EVENT_LOOP_END or EVENT_BUFFER_END if (mLoopCount > 0) { if (mLoopCount > 0) { Loading @@ -2332,7 +2483,7 @@ nsecs_t AudioTrack::processAudioBuffer() } } // These fields don't need to be cached, because they are assigned only by set(): // These fields don't need to be cached, because they are assigned only by set(): // mTransfer, mCbf, mUserData, mFormat, mFrameSize, mFlags // mTransfer, mCallback, mUserData, mFormat, mFrameSize, mFlags // mFlags is also assigned by createTrack_l(), but not the bit we care about. // mFlags is also assigned by createTrack_l(), but not the bit we care about. mLock.unlock(); mLock.unlock(); Loading @@ -2357,7 +2508,7 @@ nsecs_t AudioTrack::processAudioBuffer() if (status != DEAD_OBJECT) { if (status != DEAD_OBJECT) { // for DEAD_OBJECT, we do not send a EVENT_STREAM_END after stop(); // for DEAD_OBJECT, we do not send a EVENT_STREAM_END after stop(); // instead, the application should handle the EVENT_NEW_IAUDIOTRACK. // instead, the application should handle the EVENT_NEW_IAUDIOTRACK. mCbf(EVENT_STREAM_END, mUserData, NULL); callback->onStreamEnd(); } } { { AutoMutex lock(mLock); AutoMutex lock(mLock); Loading @@ -2380,28 +2531,27 @@ nsecs_t AudioTrack::processAudioBuffer() // perform callbacks while unlocked // perform callbacks while unlocked if (newUnderrun) { if (newUnderrun) { mCbf(EVENT_UNDERRUN, mUserData, NULL); callback->onUnderrun(); } } while (loopCountNotifications > 0) { while (loopCountNotifications > 0) { mCbf(EVENT_LOOP_END, mUserData, NULL); --loopCountNotifications; --loopCountNotifications; callback->onLoopEnd(mLoopCount > 0 ? loopCountNotifications + mLoopCountNotified : -1); } } if (flags & CBLK_BUFFER_END) { if (flags & CBLK_BUFFER_END) { mCbf(EVENT_BUFFER_END, mUserData, NULL); callback->onBufferEnd(); } } if (markerReached) { if (markerReached) { mCbf(EVENT_MARKER, mUserData, &markerPosition); callback->onMarker(markerPosition.value()); } } while (newPosCount > 0) { while (newPosCount > 0) { size_t temp = newPosition.value(); // FIXME size_t != uint32_t callback->onNewPos(newPosition.value()); mCbf(EVENT_NEW_POS, mUserData, &temp); newPosition += updatePeriod; newPosition += updatePeriod; newPosCount--; newPosCount--; } } if (mObservedSequence != sequence) { if (mObservedSequence != sequence) { mObservedSequence = sequence; mObservedSequence = sequence; mCbf(EVENT_NEW_IAUDIOTRACK, mUserData, NULL); callback->onNewIAudioTrack(); // for offloaded tracks, just wait for the upper layers to recreate the track // for offloaded tracks, just wait for the upper layers to recreate the track if (isOffloadedOrDirect()) { if (isOffloadedOrDirect()) { return NS_INACTIVE; return NS_INACTIVE; Loading Loading @@ -2539,10 +2689,9 @@ nsecs_t AudioTrack::processAudioBuffer() // written in the next write() call, since it's not passed through the callback // written in the next write() call, since it's not passed through the callback audioBuffer.size += nonContig; audioBuffer.size += nonContig; } } mCbf(mTransfer == TRANSFER_CALLBACK ? EVENT_MORE_DATA : EVENT_CAN_WRITE_MORE_DATA, size_t writtenSize = (mTransfer == TRANSFER_CALLBACK) mUserData, &audioBuffer); ? callback->onMoreData(audioBuffer) size_t writtenSize = audioBuffer.size; : callback->onCanWriteMoreData(audioBuffer); // Validate on returned size // Validate on returned size if (ssize_t(writtenSize) < 0 || writtenSize > reqSize) { if (ssize_t(writtenSize) < 0 || writtenSize > reqSize) { ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes", ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes", Loading media/libaudioclient/include/media/AudioTrack.h +121 −21 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
media/libaaudio/src/legacy/AudioStreamTrack.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -103,7 +103,7 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder) : getFormat(); : getFormat(); // Setup the callback if there is one. // Setup the callback if there is one. AudioTrack::callback_t callback = nullptr; AudioTrack::legacy_callback_t callback = nullptr; void *callbackData = nullptr; void *callbackData = nullptr; // Note that TRANSFER_SYNC does not allow FAST track // Note that TRANSFER_SYNC does not allow FAST track AudioTrack::transfer_type streamTransferType = AudioTrack::transfer_type::TRANSFER_SYNC; AudioTrack::transfer_type streamTransferType = AudioTrack::transfer_type::TRANSFER_SYNC; Loading
media/libaudioclient/AudioTrack.cpp +189 −40 Original line number Original line Diff line number Diff line Loading @@ -254,8 +254,7 @@ AudioTrack::AudioTrack( audio_channel_mask_t channelMask, audio_channel_mask_t channelMask, size_t frameCount, size_t frameCount, audio_output_flags_t flags, audio_output_flags_t flags, callback_t cbf, const wp<IAudioTrackCallback> & callback, void* user, int32_t notificationFrames, int32_t notificationFrames, audio_session_t sessionId, audio_session_t sessionId, transfer_type transferType, transfer_type transferType, Loading @@ -275,19 +274,60 @@ AudioTrack::AudioTrack( mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; (void)set(streamType, sampleRate, format, channelMask, (void)set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, frameCount, flags, callback, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); } } namespace { class LegacyCallbackWrapper : public AudioTrack::IAudioTrackCallback { const AudioTrack::legacy_callback_t mCallback; void * const mData; public: LegacyCallbackWrapper(AudioTrack::legacy_callback_t callback, void* user) : mCallback(callback), mData(user) {} size_t onMoreData(const AudioTrack::Buffer & buffer) override { AudioTrack::Buffer copy = buffer; mCallback(AudioTrack::EVENT_MORE_DATA, mData, static_cast<void*>(©)); return copy.size; } void onUnderrun() override { mCallback(AudioTrack::EVENT_UNDERRUN, mData, nullptr); } void onLoopEnd(int32_t loopsRemaining) override { mCallback(AudioTrack::EVENT_LOOP_END, mData, &loopsRemaining); } void onMarker(uint32_t markerPosition) override { mCallback(AudioTrack::EVENT_MARKER, mData, &markerPosition); } void onNewPos(uint32_t newPos) override { mCallback(AudioTrack::EVENT_NEW_POS, mData, &newPos); } void onBufferEnd() override { mCallback(AudioTrack::EVENT_BUFFER_END, mData, nullptr); } void onNewIAudioTrack() override { mCallback(AudioTrack::EVENT_NEW_IAUDIOTRACK, mData, nullptr); } void onStreamEnd() override { mCallback(AudioTrack::EVENT_STREAM_END, mData, nullptr); } size_t onCanWriteMoreData(const AudioTrack::Buffer & buffer) override { AudioTrack::Buffer copy = buffer; mCallback(AudioTrack::EVENT_CAN_WRITE_MORE_DATA, mData, static_cast<void*>(©)); return copy.size; } }; } AudioTrack::AudioTrack( AudioTrack::AudioTrack( audio_stream_type_t streamType, audio_stream_type_t streamType, uint32_t sampleRate, uint32_t sampleRate, audio_format_t format, audio_format_t format, audio_channel_mask_t channelMask, audio_channel_mask_t channelMask, const sp<IMemory>& sharedBuffer, size_t frameCount, audio_output_flags_t flags, audio_output_flags_t flags, callback_t cbf, legacy_callback_t callback, void* user, void* user, int32_t notificationFrames, int32_t notificationFrames, audio_session_t sessionId, audio_session_t sessionId, Loading @@ -296,6 +336,42 @@ AudioTrack::AudioTrack( const AttributionSourceState& attributionSource, const AttributionSourceState& attributionSource, const audio_attributes_t* pAttributes, const audio_attributes_t* pAttributes, bool doNotReconnect, bool doNotReconnect, float maxRequiredSpeed, audio_port_handle_t selectedDeviceId) : mStatus(NO_INIT), mState(STATE_STOPPED), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0), mAudioTrackCallback(new AudioTrackCallback()) { mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; if (callback != nullptr) { mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user); } else if (user) { LOG_ALWAYS_FATAL("Callback data provided without callback pointer!"); } (void)set(streamType, sampleRate, format, channelMask, frameCount, flags, mLegacyCallbackWrapper, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); } AudioTrack::AudioTrack( audio_stream_type_t streamType, uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, const sp<IMemory>& sharedBuffer, audio_output_flags_t flags, const wp<IAudioTrackCallback>& callback, int32_t notificationFrames, audio_session_t sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, const AttributionSourceState& attributionSource, const audio_attributes_t* pAttributes, bool doNotReconnect, float maxRequiredSpeed) float maxRequiredSpeed) : mStatus(NO_INIT), : mStatus(NO_INIT), mState(STATE_STOPPED), mState(STATE_STOPPED), Loading @@ -308,11 +384,49 @@ AudioTrack::AudioTrack( mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; (void)set(streamType, sampleRate, format, channelMask, (void)set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, 0 /*frameCount*/, flags, callback, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed); attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed); } } AudioTrack::AudioTrack( audio_stream_type_t streamType, uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, const sp<IMemory>& sharedBuffer, audio_output_flags_t flags, legacy_callback_t callback, void* user, int32_t notificationFrames, audio_session_t sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, const AttributionSourceState& attributionSource, const audio_attributes_t* pAttributes, bool doNotReconnect, float maxRequiredSpeed) : mStatus(NO_INIT), mState(STATE_STOPPED), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0), mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mAudioTrackCallback(new AudioTrackCallback()) { mAttributes = AUDIO_ATTRIBUTES_INITIALIZER; if (callback) { mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user); } else if (user) { LOG_ALWAYS_FATAL("Callback data provided without callback pointer!"); } (void)set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, mLegacyCallbackWrapper, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed); } AudioTrack::~AudioTrack() AudioTrack::~AudioTrack() { { // pull together the numbers, before we clean up our structures // pull together the numbers, before we clean up our structures Loading Loading @@ -374,7 +488,7 @@ status_t AudioTrack::set( audio_channel_mask_t channelMask, audio_channel_mask_t channelMask, size_t frameCount, size_t frameCount, audio_output_flags_t flags, audio_output_flags_t flags, callback_t cbf, legacy_callback_t callback, void * user, void * user, int32_t notificationFrames, int32_t notificationFrames, const sp<IMemory>& sharedBuffer, const sp<IMemory>& sharedBuffer, Loading @@ -387,6 +501,36 @@ status_t AudioTrack::set( bool doNotReconnect, bool doNotReconnect, float maxRequiredSpeed, float maxRequiredSpeed, audio_port_handle_t selectedDeviceId) audio_port_handle_t selectedDeviceId) { if (callback) { mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user); } else if (user) { LOG_ALWAYS_FATAL("Callback data provided without callback pointer!"); } return set(streamType, sampleRate,format, channelMask, frameCount, flags, mLegacyCallbackWrapper, notificationFrames, sharedBuffer, threadCanCallJava, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); } status_t AudioTrack::set( audio_stream_type_t streamType, uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, size_t frameCount, audio_output_flags_t flags, const wp<IAudioTrackCallback>& callback, int32_t notificationFrames, const sp<IMemory>& sharedBuffer, bool threadCanCallJava, audio_session_t sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, const AttributionSourceState& attributionSource, const audio_attributes_t* pAttributes, bool doNotReconnect, float maxRequiredSpeed, audio_port_handle_t selectedDeviceId) { { status_t status; status_t status; uint32_t channelCount; uint32_t channelCount; Loading @@ -394,7 +538,7 @@ status_t AudioTrack::set( pid_t myPid; pid_t myPid; uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid)); pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid)); sp<IAudioTrackCallback> _callback = callback.promote(); // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set. // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set. ALOGV("%s(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " ALOGV("%s(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d", "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d", Loading @@ -410,7 +554,7 @@ status_t AudioTrack::set( case TRANSFER_DEFAULT: case TRANSFER_DEFAULT: if (sharedBuffer != 0) { if (sharedBuffer != 0) { transferType = TRANSFER_SHARED; transferType = TRANSFER_SHARED; } else if (cbf == NULL || threadCanCallJava) { } else if (_callback == nullptr|| threadCanCallJava) { transferType = TRANSFER_SYNC; transferType = TRANSFER_SYNC; } else { } else { transferType = TRANSFER_CALLBACK; transferType = TRANSFER_CALLBACK; Loading @@ -418,8 +562,8 @@ status_t AudioTrack::set( break; break; case TRANSFER_CALLBACK: case TRANSFER_CALLBACK: case TRANSFER_SYNC_NOTIF_CALLBACK: case TRANSFER_SYNC_NOTIF_CALLBACK: if (cbf == NULL || sharedBuffer != 0) { if (_callback == nullptr || sharedBuffer != 0) { ALOGE("%s(): Transfer type %s but cbf == NULL || sharedBuffer != 0", ALOGE("%s(): Transfer type %s but callback == nullptr || sharedBuffer != 0", convertTransferToText(transferType), __func__); convertTransferToText(transferType), __func__); status = BAD_VALUE; status = BAD_VALUE; goto exit; goto exit; Loading Loading @@ -609,10 +753,10 @@ status_t AudioTrack::set( } } mAuxEffectId = 0; mAuxEffectId = 0; mOrigFlags = mFlags = flags; mOrigFlags = mFlags = flags; mCbf = cbf; mCallback = callback; if (cbf != NULL) { if (_callback != nullptr) { mAudioTrackThread = new AudioTrackThread(*this); mAudioTrackThread = sp<AudioTrackThread>::make(*this); mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/); mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/); // thread begins in paused state, and will not reference us until start() // thread begins in paused state, and will not reference us until start() } } Loading @@ -631,7 +775,6 @@ status_t AudioTrack::set( goto exit; goto exit; } } mUserData = user; mLoopCount = 0; mLoopCount = 0; mLoopStart = 0; mLoopStart = 0; mLoopEnd = 0; mLoopEnd = 0; Loading Loading @@ -675,7 +818,7 @@ status_t AudioTrack::set( uint32_t channelMask, uint32_t channelMask, size_t frameCount, size_t frameCount, audio_output_flags_t flags, audio_output_flags_t flags, callback_t cbf, legacy_callback_t callback, void* user, void* user, int32_t notificationFrames, int32_t notificationFrames, const sp<IMemory>& sharedBuffer, const sp<IMemory>& sharedBuffer, Loading @@ -694,9 +837,13 @@ status_t AudioTrack::set( attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(uid)); attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(uid)); attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(pid)); attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(pid)); attributionSource.token = sp<BBinder>::make(); attributionSource.token = sp<BBinder>::make(); return set(streamType, sampleRate, format, if (callback) { static_cast<audio_channel_mask_t>(channelMask), mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user); frameCount, flags, cbf, user, notificationFrames, sharedBuffer, } else if (user) { LOG_ALWAYS_FATAL("Callback data provided without callback pointer!"); } return set(streamType, sampleRate, format, static_cast<audio_channel_mask_t>(channelMask), frameCount, flags, mLegacyCallbackWrapper, notificationFrames, sharedBuffer, threadCanCallJava, sessionId, transferType, offloadInfo, attributionSource, threadCanCallJava, sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId); } } Loading Loading @@ -1407,7 +1554,7 @@ void AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount) status_t AudioTrack::setMarkerPosition(uint32_t marker) status_t AudioTrack::setMarkerPosition(uint32_t marker) { { // The only purpose of setting marker position is to get a callback // The only purpose of setting marker position is to get a callback if (mCbf == NULL || isOffloadedOrDirect()) { if (!mCallback.promote() || isOffloadedOrDirect()) { return INVALID_OPERATION; return INVALID_OPERATION; } } Loading Loading @@ -1440,7 +1587,7 @@ status_t AudioTrack::getMarkerPosition(uint32_t *marker) const status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) { { // The only purpose of setting position update period is to get a callback // The only purpose of setting position update period is to get a callback if (mCbf == NULL || isOffloadedOrDirect()) { if (!mCallback.promote() || isOffloadedOrDirect()) { return INVALID_OPERATION; return INVALID_OPERATION; } } Loading Loading @@ -2209,10 +2356,14 @@ nsecs_t AudioTrack::processAudioBuffer() { { // Currently the AudioTrack thread is not created if there are no callbacks. // Currently the AudioTrack thread is not created if there are no callbacks. // Would it ever make sense to run the thread, even without callbacks? // Would it ever make sense to run the thread, even without callbacks? // If so, then replace this by checks at each use for mCbf != NULL. // If so, then replace this by checks at each use for mCallback != NULL. LOG_ALWAYS_FATAL_IF(mCblk == NULL); LOG_ALWAYS_FATAL_IF(mCblk == NULL); mLock.lock(); mLock.lock(); sp<IAudioTrackCallback> callback = mCallback.promote(); if (!callback) { mCallback = nullptr; return NS_NEVER; } if (mAwaitBoost) { if (mAwaitBoost) { mAwaitBoost = false; mAwaitBoost = false; mLock.unlock(); mLock.unlock(); Loading Loading @@ -2310,7 +2461,7 @@ nsecs_t AudioTrack::processAudioBuffer() sp<AudioTrackClientProxy> proxy = mProxy; sp<AudioTrackClientProxy> proxy = mProxy; // Determine the number of new loop callback(s) that will be needed, while locked. // Determine the number of new loop callback(s) that will be needed, while locked. int loopCountNotifications = 0; uint32_t loopCountNotifications = 0; uint32_t loopPeriod = 0; // time in frames for next EVENT_LOOP_END or EVENT_BUFFER_END uint32_t loopPeriod = 0; // time in frames for next EVENT_LOOP_END or EVENT_BUFFER_END if (mLoopCount > 0) { if (mLoopCount > 0) { Loading @@ -2332,7 +2483,7 @@ nsecs_t AudioTrack::processAudioBuffer() } } // These fields don't need to be cached, because they are assigned only by set(): // These fields don't need to be cached, because they are assigned only by set(): // mTransfer, mCbf, mUserData, mFormat, mFrameSize, mFlags // mTransfer, mCallback, mUserData, mFormat, mFrameSize, mFlags // mFlags is also assigned by createTrack_l(), but not the bit we care about. // mFlags is also assigned by createTrack_l(), but not the bit we care about. mLock.unlock(); mLock.unlock(); Loading @@ -2357,7 +2508,7 @@ nsecs_t AudioTrack::processAudioBuffer() if (status != DEAD_OBJECT) { if (status != DEAD_OBJECT) { // for DEAD_OBJECT, we do not send a EVENT_STREAM_END after stop(); // for DEAD_OBJECT, we do not send a EVENT_STREAM_END after stop(); // instead, the application should handle the EVENT_NEW_IAUDIOTRACK. // instead, the application should handle the EVENT_NEW_IAUDIOTRACK. mCbf(EVENT_STREAM_END, mUserData, NULL); callback->onStreamEnd(); } } { { AutoMutex lock(mLock); AutoMutex lock(mLock); Loading @@ -2380,28 +2531,27 @@ nsecs_t AudioTrack::processAudioBuffer() // perform callbacks while unlocked // perform callbacks while unlocked if (newUnderrun) { if (newUnderrun) { mCbf(EVENT_UNDERRUN, mUserData, NULL); callback->onUnderrun(); } } while (loopCountNotifications > 0) { while (loopCountNotifications > 0) { mCbf(EVENT_LOOP_END, mUserData, NULL); --loopCountNotifications; --loopCountNotifications; callback->onLoopEnd(mLoopCount > 0 ? loopCountNotifications + mLoopCountNotified : -1); } } if (flags & CBLK_BUFFER_END) { if (flags & CBLK_BUFFER_END) { mCbf(EVENT_BUFFER_END, mUserData, NULL); callback->onBufferEnd(); } } if (markerReached) { if (markerReached) { mCbf(EVENT_MARKER, mUserData, &markerPosition); callback->onMarker(markerPosition.value()); } } while (newPosCount > 0) { while (newPosCount > 0) { size_t temp = newPosition.value(); // FIXME size_t != uint32_t callback->onNewPos(newPosition.value()); mCbf(EVENT_NEW_POS, mUserData, &temp); newPosition += updatePeriod; newPosition += updatePeriod; newPosCount--; newPosCount--; } } if (mObservedSequence != sequence) { if (mObservedSequence != sequence) { mObservedSequence = sequence; mObservedSequence = sequence; mCbf(EVENT_NEW_IAUDIOTRACK, mUserData, NULL); callback->onNewIAudioTrack(); // for offloaded tracks, just wait for the upper layers to recreate the track // for offloaded tracks, just wait for the upper layers to recreate the track if (isOffloadedOrDirect()) { if (isOffloadedOrDirect()) { return NS_INACTIVE; return NS_INACTIVE; Loading Loading @@ -2539,10 +2689,9 @@ nsecs_t AudioTrack::processAudioBuffer() // written in the next write() call, since it's not passed through the callback // written in the next write() call, since it's not passed through the callback audioBuffer.size += nonContig; audioBuffer.size += nonContig; } } mCbf(mTransfer == TRANSFER_CALLBACK ? EVENT_MORE_DATA : EVENT_CAN_WRITE_MORE_DATA, size_t writtenSize = (mTransfer == TRANSFER_CALLBACK) mUserData, &audioBuffer); ? callback->onMoreData(audioBuffer) size_t writtenSize = audioBuffer.size; : callback->onCanWriteMoreData(audioBuffer); // Validate on returned size // Validate on returned size if (ssize_t(writtenSize) < 0 || writtenSize > reqSize) { if (ssize_t(writtenSize) < 0 || writtenSize > reqSize) { ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes", ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes", Loading
media/libaudioclient/include/media/AudioTrack.h +121 −21 File changed.Preview size limit exceeded, changes collapsed. Show changes