From 3a474aa67fc31505740526dd249d96204c08bf79 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Fri, 24 Apr 2015 17:10:07 -0700 Subject: stagefright: support setting/getting playback/sync config in MediaSync Bug: 18249558 Bug: 19666434 Bug: 20057497 Change-Id: I5868b17423d7c20cfaf4a399f3eb67bfba440605 --- media/libmedia/AudioTrack.cpp | 11 ++++ media/libmedia/IMediaPlayer.cpp | 108 +++++++++++++++++++++++++++++++++++++--- media/libmedia/mediaplayer.cpp | 54 ++++++++++++++++---- 3 files changed, 156 insertions(+), 17 deletions(-) (limited to 'media/libmedia') diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 36281c4..76d9169 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -393,6 +393,7 @@ status_t AudioTrack::set( return BAD_VALUE; } mSampleRate = sampleRate; + mOriginalSampleRate = sampleRate; mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT; // Make copy of input parameter offloadInfo so that in the future: @@ -759,6 +760,15 @@ uint32_t AudioTrack::getSampleRate() const return mSampleRate; } +uint32_t AudioTrack::getOriginalSampleRate() const +{ + if (mIsTimed) { + return 0; + } + + return mOriginalSampleRate; +} + status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) { AutoMutex lock(mLock); @@ -1106,6 +1116,7 @@ status_t AudioTrack::createTrack_l() } if (mSampleRate == 0) { mSampleRate = afSampleRate; + mOriginalSampleRate = afSampleRate; } // Client decides whether the track is TIMED (see below), but can only express a preference // for FAST. Server will perform additional tests. diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 0091078..bde35f2 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -21,6 +21,9 @@ #include +#include +#include + #include #include #include @@ -41,7 +44,10 @@ enum { START, STOP, IS_PLAYING, - SET_PLAYBACK_RATE, + SET_PLAYBACK_SETTINGS, + GET_PLAYBACK_SETTINGS, + SET_SYNC_SETTINGS, + GET_SYNC_SETTINGS, PAUSE, SEEK_TO, GET_CURRENT_POSITION, @@ -175,15 +181,63 @@ public: return reply.readInt32(); } - status_t setPlaybackRate(float rate) + status_t setPlaybackSettings(const AudioPlaybackRate& rate) + { + Parcel data, reply; + data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + data.writeFloat(rate.mSpeed); + data.writeFloat(rate.mPitch); + data.writeInt32((int32_t)rate.mFallbackMode); + data.writeInt32((int32_t)rate.mStretchMode); + remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply); + return reply.readInt32(); + } + + status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) + { + Parcel data, reply; + data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply); + status_t err = reply.readInt32(); + if (err == OK) { + *rate = AUDIO_PLAYBACK_RATE_DEFAULT; + rate->mSpeed = reply.readFloat(); + rate->mPitch = reply.readFloat(); + rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32(); + rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32(); + } + return err; + } + + status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeFloat(rate); - remote()->transact(SET_PLAYBACK_RATE, data, &reply); + data.writeInt32((int32_t)sync.mSource); + data.writeInt32((int32_t)sync.mAudioAdjustMode); + data.writeFloat(sync.mTolerance); + data.writeFloat(videoFpsHint); + remote()->transact(SET_SYNC_SETTINGS, data, &reply); return reply.readInt32(); } + status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) + { + Parcel data, reply; + data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + remote()->transact(GET_SYNC_SETTINGS, data, &reply); + status_t err = reply.readInt32(); + if (err == OK) { + AVSyncSettings settings; + settings.mSource = (AVSyncSource)reply.readInt32(); + settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32(); + settings.mTolerance = reply.readFloat(); + *sync = settings; + *videoFps = reply.readFloat(); + } + return err; + } + status_t pause() { Parcel data, reply; @@ -453,9 +507,51 @@ status_t BnMediaPlayer::onTransact( reply->writeInt32(ret); return NO_ERROR; } break; - case SET_PLAYBACK_RATE: { + case SET_PLAYBACK_SETTINGS: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT; + rate.mSpeed = data.readFloat(); + rate.mPitch = data.readFloat(); + rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32(); + rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32(); + reply->writeInt32(setPlaybackSettings(rate)); + return NO_ERROR; + } break; + case GET_PLAYBACK_SETTINGS: { CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(setPlaybackRate(data.readFloat())); + AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT; + status_t err = getPlaybackSettings(&rate); + reply->writeInt32(err); + if (err == OK) { + reply->writeFloat(rate.mSpeed); + reply->writeFloat(rate.mPitch); + reply->writeInt32((int32_t)rate.mFallbackMode); + reply->writeInt32((int32_t)rate.mStretchMode); + } + return NO_ERROR; + } break; + case SET_SYNC_SETTINGS: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + AVSyncSettings sync; + sync.mSource = (AVSyncSource)data.readInt32(); + sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32(); + sync.mTolerance = data.readFloat(); + float videoFpsHint = data.readFloat(); + reply->writeInt32(setSyncSettings(sync, videoFpsHint)); + return NO_ERROR; + } break; + case GET_SYNC_SETTINGS: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + AVSyncSettings sync; + float videoFps; + status_t err = getSyncSettings(&sync, &videoFps); + reply->writeInt32(err); + if (err == OK) { + reply->writeInt32((int32_t)sync.mSource); + reply->writeInt32((int32_t)sync.mAudioAdjustMode); + reply->writeFloat(sync.mTolerance); + reply->writeFloat(videoFps); + } return NO_ERROR; } break; case PAUSE: { diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 9a276ae..81a5e8c 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -32,7 +32,9 @@ #include #include +#include #include +#include #include #include @@ -60,7 +62,6 @@ MediaPlayer::MediaPlayer() mLoop = false; mLeftVolume = mRightVolume = 1.0; mVideoWidth = mVideoHeight = 0; - mPlaybackRate = 1.0; mLockThreadId = 0; mAudioSessionId = AudioSystem::newAudioUniqueId(); AudioSystem::acquireAudioSessionId(mAudioSessionId, -1); @@ -389,6 +390,9 @@ bool MediaPlayer::isPlaying() if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) { ALOGE("internal/external state mismatch corrected"); mCurrentState = MEDIA_PLAYER_PAUSED; + } else if ((mCurrentState & MEDIA_PLAYER_PAUSED) && temp) { + ALOGE("internal/external state mismatch corrected"); + mCurrentState = MEDIA_PLAYER_STARTED; } return temp; } @@ -396,22 +400,50 @@ bool MediaPlayer::isPlaying() return false; } -status_t MediaPlayer::setPlaybackRate(float rate) +status_t MediaPlayer::setPlaybackSettings(const AudioPlaybackRate& rate) { - ALOGV("setPlaybackRate: %f", rate); - if (rate <= 0.0) { + ALOGV("setPlaybackSettings: %f %f %d %d", + rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode); + // Negative speed and pitch does not make sense. Further validation will + // be done by the respective mediaplayers. + if (rate.mSpeed < 0.f || rate.mPitch < 0.f) { return BAD_VALUE; } Mutex::Autolock _l(mLock); - if (mPlayer != 0) { - if (mPlaybackRate == rate) { - return NO_ERROR; + if (mPlayer == 0) return INVALID_OPERATION; + status_t err = mPlayer->setPlaybackSettings(rate); + if (err == OK) { + if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER_STARTED) { + mCurrentState = MEDIA_PLAYER_PAUSED; + } else if (rate.mSpeed != 0.f && mCurrentState == MEDIA_PLAYER_PAUSED) { + mCurrentState = MEDIA_PLAYER_STARTED; } - mPlaybackRate = rate; - return mPlayer->setPlaybackRate(rate); } - ALOGV("setPlaybackRate: no active player"); - return INVALID_OPERATION; + return err; +} + +status_t MediaPlayer::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) +{ + Mutex::Autolock _l(mLock); + if (mPlayer == 0) return INVALID_OPERATION; + return mPlayer->getPlaybackSettings(rate); +} + +status_t MediaPlayer::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) +{ + ALOGV("setSyncSettings: %u %u %f %f", + sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint); + Mutex::Autolock _l(mLock); + if (mPlayer == 0) return INVALID_OPERATION; + return mPlayer->setSyncSettings(sync, videoFpsHint); +} + +status_t MediaPlayer::getSyncSettings( + AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) +{ + Mutex::Autolock _l(mLock); + if (mPlayer == 0) return INVALID_OPERATION; + return mPlayer->getSyncSettings(sync, videoFps); } status_t MediaPlayer::getVideoWidth(int *w) -- cgit v1.1