From 5e49afd05566820517747b9a8071c99ec0918328 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 26 Jul 2013 17:16:50 -0700 Subject: update offloaded audio track sampling rate AudioPlayer must read the sampling rate from offloaded audio sinks whenever a new time position is computed as the decoder can update the sampling rate on the fly. Change-Id: I997e5248cfd4017aeceb4e11689324ded2a5bc88 --- include/media/AudioTrack.h | 2 +- include/media/MediaPlayerInterface.h | 1 + include/media/stagefright/AudioPlayer.h | 2 +- libvideoeditor/lvpp/VideoEditorPlayer.cpp | 7 +++++++ libvideoeditor/lvpp/VideoEditorPlayer.h | 1 + media/libmedia/AudioTrack.cpp | 13 +++++++++++++ media/libmediaplayerservice/MediaPlayerService.cpp | 14 ++++++++++++++ media/libmediaplayerservice/MediaPlayerService.h | 2 ++ media/libstagefright/AudioPlayer.cpp | 15 +++++++++++++-- 9 files changed, 53 insertions(+), 4 deletions(-) diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index f379ee5..f6646ab 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -661,7 +661,7 @@ protected: sp mAudioTrackThread; float mVolume[2]; float mSendLevel; - uint32_t mSampleRate; + mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it. size_t mFrameCount; // corresponds to current IAudioTrack size_t mReqFrameCount; // frame count to request the next time a new // IAudioTrack is needed diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index cc244f0..26d8729 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -100,6 +100,7 @@ public: virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0; virtual int getSessionId() const = 0; virtual audio_stream_type_t getAudioStreamType() const = 0; + virtual uint32_t getSampleRate() const = 0; // If no callback is specified, use the "write" API below to submit // audio data. diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h index 912a43c..14afb85 100644 --- a/include/media/stagefright/AudioPlayer.h +++ b/include/media/stagefright/AudioPlayer.h @@ -129,7 +129,7 @@ private: void reset(); uint32_t getNumFramesPendingPlayout() const; - int64_t getOutputPlayPositionUs_l() const; + int64_t getOutputPlayPositionUs_l(); bool allowDeepBuffering() const { return (mCreateFlags & ALLOW_DEEP_BUFFERING) != 0; } bool useOffload() const { return (mCreateFlags & USE_OFFLOAD) != 0; } diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp index 5aeba4f..8d656c4 100755 --- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp +++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp @@ -585,4 +585,11 @@ int VideoEditorPlayer::VeAudioOutput::getSessionId() const { return mSessionId; } +uint32_t VideoEditorPlayer::VeAudioOutput::getSampleRate() const { + if (mMsecsPerFrame == 0) { + return 0; + } + return (uint32_t)(1.e3 / mMsecsPerFrame); +} + } // namespace android diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.h b/libvideoeditor/lvpp/VideoEditorPlayer.h index 5862c08..b8c1254 100755 --- a/libvideoeditor/lvpp/VideoEditorPlayer.h +++ b/libvideoeditor/lvpp/VideoEditorPlayer.h @@ -48,6 +48,7 @@ class VideoEditorPlayer : public MediaPlayerInterface { virtual status_t getPosition(uint32_t *position) const; virtual status_t getFramesWritten(uint32_t*) const; virtual int getSessionId() const; + virtual uint32_t getSampleRate() const; virtual status_t open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 9730b03..42516bc 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -603,6 +603,19 @@ uint32_t AudioTrack::getSampleRate() const } AutoMutex lock(mLock); + + // sample rate can be updated during playback by the offloaded decoder so we need to + // query the HAL and update if needed. +// FIXME use Proxy return channel to update the rate from server and avoid polling here + if (isOffloaded()) { + if (mOutput != 0) { + uint32_t sampleRate = 0; + status_t status = AudioSystem::getSamplingRate(mOutput, mStreamType, &sampleRate); + if (status == NO_ERROR) { + mSampleRate = sampleRate; + } + } + } return mSampleRate; } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index cd052e6..9ac9105 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1813,6 +1813,12 @@ int MediaPlayerService::AudioOutput::getSessionId() const return mSessionId; } +uint32_t MediaPlayerService::AudioOutput::getSampleRate() const +{ + if (mTrack == 0) return 0; + return mTrack->getSampleRate(); +} + #undef LOG_TAG #define LOG_TAG "AudioCache" MediaPlayerService::AudioCache::AudioCache(const sp& heap) : @@ -2015,6 +2021,14 @@ int MediaPlayerService::AudioCache::getSessionId() const return 0; } +uint32_t MediaPlayerService::AudioCache::getSampleRate() const +{ + if (mMsecsPerFrame == 0) { + return 0; + } + return (uint32_t)(1.e3 / mMsecsPerFrame); +} + void MediaPlayerService::addBatteryData(uint32_t params) { Mutex::Autolock lock(mLock); diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index a486cb5..9c084e1 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -86,6 +86,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual status_t getPosition(uint32_t *position) const; virtual status_t getFramesWritten(uint32_t *frameswritten) const; virtual int getSessionId() const; + virtual uint32_t getSampleRate() const; virtual status_t open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, @@ -195,6 +196,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual status_t getPosition(uint32_t *position) const; virtual status_t getFramesWritten(uint32_t *frameswritten) const; virtual int getSessionId() const; + virtual uint32_t getSampleRate() const; virtual status_t open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp index a8a8786..05ee34e 100644 --- a/media/libstagefright/AudioPlayer.cpp +++ b/media/libstagefright/AudioPlayer.cpp @@ -721,16 +721,27 @@ int64_t AudioPlayer::getRealTimeUsLocked() const { return result + diffUs; } -int64_t AudioPlayer::getOutputPlayPositionUs_l() const +int64_t AudioPlayer::getOutputPlayPositionUs_l() { uint32_t playedSamples = 0; + uint32_t sampleRate; if (mAudioSink != NULL) { mAudioSink->getPosition(&playedSamples); + sampleRate = mAudioSink->getSampleRate(); } else { mAudioTrack->getPosition(&playedSamples); + sampleRate = mAudioTrack->getSampleRate(); + } + if (sampleRate != 0) { + mSampleRate = sampleRate; } - const int64_t playedUs = (static_cast(playedSamples) * 1000000 ) / mSampleRate; + int64_t playedUs; + if (mSampleRate != 0) { + playedUs = (static_cast(playedSamples) * 1000000 ) / mSampleRate; + } else { + playedUs = 0; + } // HAL position is relative to the first buffer we sent at mStartPosUs const int64_t renderedDuration = mStartPosUs + playedUs; -- cgit v1.1