Loading include/media/AudioTrack.h +11 −3 Original line number Diff line number Diff line Loading @@ -201,6 +201,10 @@ public: binder to AudioFlinger. It will return an error instead. The application will recreate the track based on offloading or different channel configuration, etc. * maxRequiredSpeed: For PCM tracks, this creates an appropriate buffer size that will allow * maxRequiredSpeed playback. Values less than 1.0f and greater than * AUDIO_TIMESTRETCH_SPEED_MAX will be clamped. For non-PCM tracks * and direct or offloaded tracks, this parameter is ignored. * threadCanCallJava: Not present in parameter list, and so is fixed at false. */ Loading @@ -219,7 +223,8 @@ public: int uid = -1, pid_t pid = -1, const audio_attributes_t* pAttributes = NULL, bool doNotReconnect = false); bool doNotReconnect = false, float maxRequiredSpeed = 1.0f); /* Creates an audio track and registers it with AudioFlinger. * With this constructor, the track is configured for static buffer mode. Loading Loading @@ -248,7 +253,8 @@ public: int uid = -1, pid_t pid = -1, const audio_attributes_t* pAttributes = NULL, bool doNotReconnect = false); bool doNotReconnect = false, float maxRequiredSpeed = 1.0f); /* Terminates the AudioTrack and unregisters it from AudioFlinger. * Also destroys all resources associated with the AudioTrack. Loading Loading @@ -293,7 +299,8 @@ public: int uid = -1, pid_t pid = -1, const audio_attributes_t* pAttributes = NULL, bool doNotReconnect = false); bool doNotReconnect = false, float maxRequiredSpeed = 1.0f); /* Result of constructing the AudioTrack. This must be checked for successful initialization * before using any AudioTrack API (except for set()), because using Loading Loading @@ -916,6 +923,7 @@ protected: mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it uint32_t mOriginalSampleRate; AudioPlaybackRate mPlaybackRate; float mMaxRequiredSpeed; // use PCM buffer size to allow this speed // Corresponds to current IAudioTrack, value is reported back by AudioFlinger to the client. // This allocated buffer size is maintained by the proxy. Loading media/libmedia/AudioTrack.cpp +23 −7 Original line number Diff line number Diff line Loading @@ -191,7 +191,8 @@ AudioTrack::AudioTrack( int uid, pid_t pid, const audio_attributes_t* pAttributes, bool doNotReconnect) bool doNotReconnect, float maxRequiredSpeed) : mStatus(NO_INIT), mState(STATE_STOPPED), mPreviousPriority(ANDROID_PRIORITY_NORMAL), Loading @@ -202,7 +203,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid, pid, pAttributes, doNotReconnect); offloadInfo, uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed); } AudioTrack::AudioTrack( Loading @@ -221,7 +222,8 @@ AudioTrack::AudioTrack( int uid, pid_t pid, const audio_attributes_t* pAttributes, bool doNotReconnect) bool doNotReconnect, float maxRequiredSpeed) : mStatus(NO_INIT), mState(STATE_STOPPED), mPreviousPriority(ANDROID_PRIORITY_NORMAL), Loading @@ -232,7 +234,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid, pid, pAttributes, doNotReconnect); uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed); } AudioTrack::~AudioTrack() Loading Loading @@ -281,7 +283,8 @@ status_t AudioTrack::set( int uid, pid_t pid, const audio_attributes_t* pAttributes, bool doNotReconnect) bool doNotReconnect, float maxRequiredSpeed) { ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " "flags #%x, notificationFrames %u, sessionId %d, transferType %d, uid %d, pid %d", Loading Loading @@ -422,6 +425,8 @@ status_t AudioTrack::set( mSampleRate = sampleRate; mOriginalSampleRate = sampleRate; mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT; // 1.0 <= mMaxRequiredSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX mMaxRequiredSpeed = min(max(maxRequiredSpeed, 1.0f), AUDIO_TIMESTRETCH_SPEED_MAX); // Make copy of input parameter offloadInfo so that in the future: // (a) createTrack_l doesn't need it as an input parameter Loading Loading @@ -824,6 +829,9 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) if (mFlags & AUDIO_OUTPUT_FLAG_FAST) { return INVALID_OPERATION; } ALOGV("setPlaybackRate (input): mSampleRate:%u mSpeed:%f mPitch:%f", mSampleRate, playbackRate.mSpeed, playbackRate.mPitch); // pitch is emulated by adjusting speed and sampleRate const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch); const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch); Loading @@ -832,12 +840,18 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) playbackRateTemp.mSpeed = effectiveSpeed; playbackRateTemp.mPitch = effectivePitch; ALOGV("setPlaybackRate (effective): mSampleRate:%u mSpeed:%f mPitch:%f", effectiveRate, effectiveSpeed, effectivePitch); if (!isAudioPlaybackRateValid(playbackRateTemp)) { ALOGV("setPlaybackRate(%f, %f) failed (effective rate out of bounds)", playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; } // Check if the buffer size is compatible. if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) { ALOGV("setPlaybackRate(%f, %f) failed", playbackRate.mSpeed, playbackRate.mPitch); ALOGV("setPlaybackRate(%f, %f) failed (buffer size)", playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; } Loading Loading @@ -1275,9 +1289,11 @@ status_t AudioTrack::createTrack_l() if ((mFlags & AUDIO_OUTPUT_FLAG_FAST) == 0) { // for normal tracks precompute the frame count based on speed. const float speed = !isPurePcmData_l() || isOffloadedOrDirect_l() ? 1.0f : max(mMaxRequiredSpeed, mPlaybackRate.mSpeed); const size_t minFrameCount = calculateMinFrameCount( mAfLatency, mAfFrameCount, mAfSampleRate, mSampleRate, mPlaybackRate.mSpeed); speed); if (frameCount < minFrameCount) { frameCount = minFrameCount; } Loading media/libmediaplayerservice/MediaPlayerService.cpp +12 −1 Original line number Diff line number Diff line Loading @@ -94,6 +94,8 @@ using android::Parcel; // Max number of entries in the filter. const int kMaxFilterSize = 64; // I pulled that out of thin air. const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup. // FIXME: Move all the metadata related function in the Metadata.cpp Loading Loading @@ -1749,6 +1751,14 @@ status_t MediaPlayerService::AudioOutput::open( mAttributes, doNotReconnect); } else { // TODO: Due to buffer memory concerns, we use a max target playback speed // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed), // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed. const float targetSpeed = std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed); ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed, "track target speed:%f clamped from playback speed:%f", targetSpeed, mPlaybackRate.mSpeed); t = new AudioTrack( mStreamType, sampleRate, Loading @@ -1765,7 +1775,8 @@ status_t MediaPlayerService::AudioOutput::open( mUid, mPid, mAttributes, doNotReconnect); doNotReconnect, targetSpeed); } if ((t == 0) || (t->initCheck() != NO_ERROR)) { Loading media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -1876,6 +1876,10 @@ status_t NuPlayer::Renderer::onOpenAudioSink( // NuPlayer a chance to switch from non-offload mode to offload mode. // So we only set doNotReconnect when there's no video. const bool doNotReconnect = !hasVideo; // We should always be able to set our playback settings if the sink is closed. LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK, "onOpenAudioSink: can't set playback rate on closed sink"); status_t err = mAudioSink->open( sampleRate, numChannels, Loading @@ -1888,9 +1892,6 @@ status_t NuPlayer::Renderer::onOpenAudioSink( NULL, doNotReconnect, frameCount); if (err == OK) { err = mAudioSink->setPlaybackRate(mPlaybackSettings); } if (err != OK) { ALOGW("openAudioSink: non offloaded open failed status: %d", err); mAudioSink->close(); Loading Loading
include/media/AudioTrack.h +11 −3 Original line number Diff line number Diff line Loading @@ -201,6 +201,10 @@ public: binder to AudioFlinger. It will return an error instead. The application will recreate the track based on offloading or different channel configuration, etc. * maxRequiredSpeed: For PCM tracks, this creates an appropriate buffer size that will allow * maxRequiredSpeed playback. Values less than 1.0f and greater than * AUDIO_TIMESTRETCH_SPEED_MAX will be clamped. For non-PCM tracks * and direct or offloaded tracks, this parameter is ignored. * threadCanCallJava: Not present in parameter list, and so is fixed at false. */ Loading @@ -219,7 +223,8 @@ public: int uid = -1, pid_t pid = -1, const audio_attributes_t* pAttributes = NULL, bool doNotReconnect = false); bool doNotReconnect = false, float maxRequiredSpeed = 1.0f); /* Creates an audio track and registers it with AudioFlinger. * With this constructor, the track is configured for static buffer mode. Loading Loading @@ -248,7 +253,8 @@ public: int uid = -1, pid_t pid = -1, const audio_attributes_t* pAttributes = NULL, bool doNotReconnect = false); bool doNotReconnect = false, float maxRequiredSpeed = 1.0f); /* Terminates the AudioTrack and unregisters it from AudioFlinger. * Also destroys all resources associated with the AudioTrack. Loading Loading @@ -293,7 +299,8 @@ public: int uid = -1, pid_t pid = -1, const audio_attributes_t* pAttributes = NULL, bool doNotReconnect = false); bool doNotReconnect = false, float maxRequiredSpeed = 1.0f); /* Result of constructing the AudioTrack. This must be checked for successful initialization * before using any AudioTrack API (except for set()), because using Loading Loading @@ -916,6 +923,7 @@ protected: mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it uint32_t mOriginalSampleRate; AudioPlaybackRate mPlaybackRate; float mMaxRequiredSpeed; // use PCM buffer size to allow this speed // Corresponds to current IAudioTrack, value is reported back by AudioFlinger to the client. // This allocated buffer size is maintained by the proxy. Loading
media/libmedia/AudioTrack.cpp +23 −7 Original line number Diff line number Diff line Loading @@ -191,7 +191,8 @@ AudioTrack::AudioTrack( int uid, pid_t pid, const audio_attributes_t* pAttributes, bool doNotReconnect) bool doNotReconnect, float maxRequiredSpeed) : mStatus(NO_INIT), mState(STATE_STOPPED), mPreviousPriority(ANDROID_PRIORITY_NORMAL), Loading @@ -202,7 +203,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid, pid, pAttributes, doNotReconnect); offloadInfo, uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed); } AudioTrack::AudioTrack( Loading @@ -221,7 +222,8 @@ AudioTrack::AudioTrack( int uid, pid_t pid, const audio_attributes_t* pAttributes, bool doNotReconnect) bool doNotReconnect, float maxRequiredSpeed) : mStatus(NO_INIT), mState(STATE_STOPPED), mPreviousPriority(ANDROID_PRIORITY_NORMAL), Loading @@ -232,7 +234,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid, pid, pAttributes, doNotReconnect); uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed); } AudioTrack::~AudioTrack() Loading Loading @@ -281,7 +283,8 @@ status_t AudioTrack::set( int uid, pid_t pid, const audio_attributes_t* pAttributes, bool doNotReconnect) bool doNotReconnect, float maxRequiredSpeed) { ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " "flags #%x, notificationFrames %u, sessionId %d, transferType %d, uid %d, pid %d", Loading Loading @@ -422,6 +425,8 @@ status_t AudioTrack::set( mSampleRate = sampleRate; mOriginalSampleRate = sampleRate; mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT; // 1.0 <= mMaxRequiredSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX mMaxRequiredSpeed = min(max(maxRequiredSpeed, 1.0f), AUDIO_TIMESTRETCH_SPEED_MAX); // Make copy of input parameter offloadInfo so that in the future: // (a) createTrack_l doesn't need it as an input parameter Loading Loading @@ -824,6 +829,9 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) if (mFlags & AUDIO_OUTPUT_FLAG_FAST) { return INVALID_OPERATION; } ALOGV("setPlaybackRate (input): mSampleRate:%u mSpeed:%f mPitch:%f", mSampleRate, playbackRate.mSpeed, playbackRate.mPitch); // pitch is emulated by adjusting speed and sampleRate const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch); const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch); Loading @@ -832,12 +840,18 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) playbackRateTemp.mSpeed = effectiveSpeed; playbackRateTemp.mPitch = effectivePitch; ALOGV("setPlaybackRate (effective): mSampleRate:%u mSpeed:%f mPitch:%f", effectiveRate, effectiveSpeed, effectivePitch); if (!isAudioPlaybackRateValid(playbackRateTemp)) { ALOGV("setPlaybackRate(%f, %f) failed (effective rate out of bounds)", playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; } // Check if the buffer size is compatible. if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) { ALOGV("setPlaybackRate(%f, %f) failed", playbackRate.mSpeed, playbackRate.mPitch); ALOGV("setPlaybackRate(%f, %f) failed (buffer size)", playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; } Loading Loading @@ -1275,9 +1289,11 @@ status_t AudioTrack::createTrack_l() if ((mFlags & AUDIO_OUTPUT_FLAG_FAST) == 0) { // for normal tracks precompute the frame count based on speed. const float speed = !isPurePcmData_l() || isOffloadedOrDirect_l() ? 1.0f : max(mMaxRequiredSpeed, mPlaybackRate.mSpeed); const size_t minFrameCount = calculateMinFrameCount( mAfLatency, mAfFrameCount, mAfSampleRate, mSampleRate, mPlaybackRate.mSpeed); speed); if (frameCount < minFrameCount) { frameCount = minFrameCount; } Loading
media/libmediaplayerservice/MediaPlayerService.cpp +12 −1 Original line number Diff line number Diff line Loading @@ -94,6 +94,8 @@ using android::Parcel; // Max number of entries in the filter. const int kMaxFilterSize = 64; // I pulled that out of thin air. const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup. // FIXME: Move all the metadata related function in the Metadata.cpp Loading Loading @@ -1749,6 +1751,14 @@ status_t MediaPlayerService::AudioOutput::open( mAttributes, doNotReconnect); } else { // TODO: Due to buffer memory concerns, we use a max target playback speed // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed), // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed. const float targetSpeed = std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed); ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed, "track target speed:%f clamped from playback speed:%f", targetSpeed, mPlaybackRate.mSpeed); t = new AudioTrack( mStreamType, sampleRate, Loading @@ -1765,7 +1775,8 @@ status_t MediaPlayerService::AudioOutput::open( mUid, mPid, mAttributes, doNotReconnect); doNotReconnect, targetSpeed); } if ((t == 0) || (t->initCheck() != NO_ERROR)) { Loading
media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -1876,6 +1876,10 @@ status_t NuPlayer::Renderer::onOpenAudioSink( // NuPlayer a chance to switch from non-offload mode to offload mode. // So we only set doNotReconnect when there's no video. const bool doNotReconnect = !hasVideo; // We should always be able to set our playback settings if the sink is closed. LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK, "onOpenAudioSink: can't set playback rate on closed sink"); status_t err = mAudioSink->open( sampleRate, numChannels, Loading @@ -1888,9 +1892,6 @@ status_t NuPlayer::Renderer::onOpenAudioSink( NULL, doNotReconnect, frameCount); if (err == OK) { err = mAudioSink->setPlaybackRate(mPlaybackSettings); } if (err != OK) { ALOGW("openAudioSink: non offloaded open failed status: %d", err); mAudioSink->close(); Loading