summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2015-04-24 17:10:07 -0700
committerLajos Molnar <lajos@google.com>2015-04-30 16:56:10 -0700
commit3a474aa67fc31505740526dd249d96204c08bf79 (patch)
tree4db784ee57ffad037fa2ded86d0fd8b3a40173d5 /media/libmedia
parenta8df0b716bdfda1e10790e6f7297eeff83d2e52a (diff)
downloadframeworks_av-3a474aa67fc31505740526dd249d96204c08bf79.zip
frameworks_av-3a474aa67fc31505740526dd249d96204c08bf79.tar.gz
frameworks_av-3a474aa67fc31505740526dd249d96204c08bf79.tar.bz2
stagefright: support setting/getting playback/sync config in MediaSync
Bug: 18249558 Bug: 19666434 Bug: 20057497 Change-Id: I5868b17423d7c20cfaf4a399f3eb67bfba440605
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/AudioTrack.cpp11
-rw-r--r--media/libmedia/IMediaPlayer.cpp108
-rw-r--r--media/libmedia/mediaplayer.cpp54
3 files changed, 156 insertions, 17 deletions
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 <binder/Parcel.h>
+#include <media/AudioResamplerPublic.h>
+#include <media/AVSyncSettings.h>
+
#include <media/IDataSource.h>
#include <media/IMediaHTTPService.h>
#include <media/IMediaPlayer.h>
@@ -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 <gui/Surface.h>
#include <media/mediaplayer.h>
+#include <media/AudioResamplerPublic.h>
#include <media/AudioSystem.h>
+#include <media/AVSyncSettings.h>
#include <media/IDataSource.h>
#include <binder/MemoryBase.h>
@@ -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)