summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice/nuplayer
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/libmediaplayerservice/nuplayer
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/libmediaplayerservice/nuplayer')
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp176
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h18
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp29
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDriver.h5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp197
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h27
6 files changed, 408 insertions, 44 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index b670d68..cb8579b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -37,6 +37,9 @@
#include <cutils/properties.h>
+#include <media/AudioResamplerPublic.h>
+#include <media/AVSyncSettings.h>
+
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -180,7 +183,8 @@ NuPlayer::NuPlayer()
mFlushingVideo(NONE),
mResumePending(false),
mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
- mPlaybackRate(1.0),
+ mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
+ mVideoFpsHint(-1.f),
mStarted(false),
mPaused(false),
mPausedByClient(false) {
@@ -331,10 +335,61 @@ void NuPlayer::start() {
(new AMessage(kWhatStart, this))->post();
}
-void NuPlayer::setPlaybackRate(float rate) {
- sp<AMessage> msg = new AMessage(kWhatSetRate, this);
- msg->setFloat("rate", rate);
- msg->post();
+status_t NuPlayer::setPlaybackSettings(const AudioPlaybackRate &rate) {
+ // do some cursory validation of the settings here. audio modes are
+ // only validated when set on the audiosink.
+ if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN)
+ || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
+ || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
+ || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
+ return BAD_VALUE;
+ }
+ sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
+ writeToAMessage(msg, rate);
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ }
+ return err;
+}
+
+status_t NuPlayer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
+ sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ if (err == OK) {
+ readFromAMessage(response, rate);
+ }
+ }
+ return err;
+}
+
+status_t NuPlayer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
+ sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
+ writeToAMessage(msg, sync, videoFpsHint);
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ }
+ return err;
+}
+
+status_t NuPlayer::getSyncSettings(
+ AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
+ sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ if (err == OK) {
+ readFromAMessage(response, sync, videoFps);
+ }
+ }
+ return err;
}
void NuPlayer::pause() {
@@ -627,12 +682,28 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- case kWhatSetRate:
+ case kWhatConfigPlayback:
{
- ALOGV("kWhatSetRate");
- CHECK(msg->findFloat("rate", &mPlaybackRate));
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ AudioPlaybackRate rate /* sanitized */;
+ readFromAMessage(msg, &rate);
+ status_t err = OK;
if (mRenderer != NULL) {
- mRenderer->setPlaybackRate(mPlaybackRate);
+ err = mRenderer->setPlaybackSettings(rate);
+ }
+ if (err == OK) {
+ if (rate.mSpeed == 0.f) {
+ onPause();
+ // save all other settings (using non-paused speed)
+ // so we can restore them on start
+ AudioPlaybackRate newRate = rate;
+ newRate.mSpeed = mPlaybackSettings.mSpeed;
+ mPlaybackSettings = newRate;
+ } else { /* rate.mSpeed != 0.f */
+ onResume();
+ mPlaybackSettings = rate;
+ }
}
if (mVideoDecoder != NULL) {
@@ -640,11 +711,86 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
int32_t rate;
if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
sp<AMessage> params = new AMessage();
- params->setFloat("operating-rate", rate * mPlaybackRate);
+ params->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
mVideoDecoder->setParameters(params);
}
}
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatGetPlaybackSettings:
+ {
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ AudioPlaybackRate rate = mPlaybackSettings;
+ status_t err = OK;
+ if (mRenderer != NULL) {
+ err = mRenderer->getPlaybackSettings(&rate);
+ }
+ if (err == OK) {
+ // get playback settings used by renderer, as it may be
+ // slightly off due to audiosink not taking small changes.
+ mPlaybackSettings = rate;
+ if (mPaused) {
+ rate.mSpeed = 0.f;
+ }
+ }
+ sp<AMessage> response = new AMessage;
+ if (err == OK) {
+ writeToAMessage(response, rate);
+ }
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatConfigSync:
+ {
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ ALOGV("kWhatConfigSync");
+ AVSyncSettings sync;
+ float videoFpsHint;
+ readFromAMessage(msg, &sync, &videoFpsHint);
+ status_t err = OK;
+ if (mRenderer != NULL) {
+ err = mRenderer->setSyncSettings(sync, videoFpsHint);
+ }
+ if (err == OK) {
+ mSyncSettings = sync;
+ mVideoFpsHint = videoFpsHint;
+ }
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatGetSyncSettings:
+ {
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ AVSyncSettings sync = mSyncSettings;
+ float videoFps = mVideoFpsHint;
+ status_t err = OK;
+ if (mRenderer != NULL) {
+ err = mRenderer->getSyncSettings(&sync, &videoFps);
+ if (err == OK) {
+ mSyncSettings = sync;
+ mVideoFpsHint = videoFps;
+ }
+ }
+ sp<AMessage> response = new AMessage;
+ if (err == OK) {
+ writeToAMessage(response, sync, videoFps);
+ }
+ response->setInt32("err", err);
+ response->postReply(replyID);
break;
}
@@ -1114,8 +1260,12 @@ void NuPlayer::onStart() {
mRendererLooper->setName("NuPlayerRenderer");
mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
mRendererLooper->registerHandler(mRenderer);
- if (mPlaybackRate != 1.0) {
- mRenderer->setPlaybackRate(mPlaybackRate);
+
+ status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
+ if (err != OK) {
+ mSource->stop();
+ notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ return;
}
sp<MetaData> meta = getFileMeta();
@@ -1282,7 +1432,7 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
sp<MetaData> meta = getFileMeta();
int32_t rate;
if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
- format->setFloat("operating-rate", rate * mPlaybackRate);
+ format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
}
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 14bdb01..88e929d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -18,6 +18,7 @@
#define NU_PLAYER_H_
+#include <media/AudioResamplerPublic.h>
#include <media/MediaPlayerInterface.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/NativeWindowWrapper.h>
@@ -26,6 +27,8 @@ namespace android {
struct ABuffer;
struct AMessage;
+struct AudioPlaybackRate;
+struct AVSyncSettings;
class IDataSource;
class MetaData;
struct NuPlayerDriver;
@@ -54,7 +57,11 @@ struct NuPlayer : public AHandler {
const sp<IGraphicBufferProducer> &bufferProducer);
void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink);
- void setPlaybackRate(float rate);
+ status_t setPlaybackSettings(const AudioPlaybackRate &rate);
+ status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
+ status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
+ status_t getSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
+
void start();
void pause();
@@ -108,7 +115,10 @@ private:
kWhatSetVideoNativeWindow = '=NaW',
kWhatSetAudioSink = '=AuS',
kWhatMoreDataQueued = 'more',
- kWhatSetRate = 'setR',
+ kWhatConfigPlayback = 'cfPB',
+ kWhatConfigSync = 'cfSy',
+ kWhatGetPlaybackSettings = 'gPbS',
+ kWhatGetSyncSettings = 'gSyS',
kWhatStart = 'strt',
kWhatScanSources = 'scan',
kWhatVideoNotify = 'vidN',
@@ -180,7 +190,9 @@ private:
int32_t mVideoScalingMode;
- float mPlaybackRate;
+ AudioPlaybackRate mPlaybackSettings;
+ AVSyncSettings mSyncSettings;
+ float mVideoFpsHint;
bool mStarted;
// Actual pause state, either as requested by client or due to buffering.
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 04a324c..231f2e1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -360,9 +360,32 @@ bool NuPlayerDriver::isPlaying() {
return mState == STATE_RUNNING && !mAtEOS;
}
-status_t NuPlayerDriver::setPlaybackRate(float rate) {
- mPlayer->setPlaybackRate(rate);
- return OK;
+status_t NuPlayerDriver::setPlaybackSettings(const AudioPlaybackRate &rate) {
+ Mutex::Autolock autoLock(mLock);
+ status_t err = mPlayer->setPlaybackSettings(rate);
+ if (err == OK) {
+ if (rate.mSpeed == 0.f && mState == STATE_RUNNING) {
+ mState = STATE_PAUSED;
+ // try to update position
+ (void)mPlayer->getCurrentPosition(&mPositionUs);
+ notifyListener_l(MEDIA_PAUSED);
+ } else if (rate.mSpeed != 0.f && mState == STATE_PAUSED) {
+ mState = STATE_RUNNING;
+ }
+ }
+ return err;
+}
+
+status_t NuPlayerDriver::getPlaybackSettings(AudioPlaybackRate *rate) {
+ return mPlayer->getPlaybackSettings(rate);
+}
+
+status_t NuPlayerDriver::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
+ return mPlayer->setSyncSettings(sync, videoFpsHint);
+}
+
+status_t NuPlayerDriver::getSyncSettings(AVSyncSettings *sync, float *videoFps) {
+ return mPlayer->getSyncSettings(sync, videoFps);
}
status_t NuPlayerDriver::seekTo(int msec) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 65f170e..9da7fc1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -49,7 +49,10 @@ struct NuPlayerDriver : public MediaPlayerInterface {
virtual status_t stop();
virtual status_t pause();
virtual bool isPlaying();
- virtual status_t setPlaybackRate(float rate);
+ virtual status_t setPlaybackSettings(const AudioPlaybackRate &rate);
+ virtual status_t getPlaybackSettings(AudioPlaybackRate *rate);
+ virtual status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
+ virtual status_t getSyncSettings(AVSyncSettings *sync, float *videoFps);
virtual status_t seekTo(int msec);
virtual status_t getCurrentPosition(int *msec);
virtual status_t getDuration(int *msec);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index f229452..ae01cfc 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -66,7 +66,7 @@ NuPlayer::Renderer::Renderer(
mVideoQueueGeneration(0),
mAudioDrainGeneration(0),
mVideoDrainGeneration(0),
- mPlaybackRate(1.0),
+ mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
mAudioFirstAnchorTimeMediaUs(-1),
mAnchorTimeMediaUs(-1),
mAnchorNumFramesWritten(-1),
@@ -89,6 +89,8 @@ NuPlayer::Renderer::Renderer(
mLastAudioBufferDrained(0),
mWakeLock(new AWakeLock()) {
mMediaClock = new MediaClock;
+ mPlaybackRate = mPlaybackSettings.mSpeed;
+ mMediaClock->setPlaybackRate(mPlaybackRate);
}
NuPlayer::Renderer::~Renderer() {
@@ -121,10 +123,111 @@ void NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) {
msg->post();
}
-void NuPlayer::Renderer::setPlaybackRate(float rate) {
- sp<AMessage> msg = new AMessage(kWhatSetRate, this);
- msg->setFloat("rate", rate);
- msg->post();
+status_t NuPlayer::Renderer::setPlaybackSettings(const AudioPlaybackRate &rate) {
+ sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
+ writeToAMessage(msg, rate);
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ }
+ return err;
+}
+
+status_t NuPlayer::Renderer::onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */) {
+ if (rate.mSpeed == 0.f) {
+ onPause();
+ // don't call audiosink's setPlaybackRate if pausing, as pitch does not
+ // have to correspond to the any non-0 speed (e.g old speed). Keep
+ // settings nonetheless, using the old speed, in case audiosink changes.
+ AudioPlaybackRate newRate = rate;
+ newRate.mSpeed = mPlaybackSettings.mSpeed;
+ mPlaybackSettings = newRate;
+ return OK;
+ }
+
+ if (mAudioSink != NULL) {
+ status_t err = mAudioSink->setPlaybackRate(rate);
+ if (err != OK) {
+ return err;
+ }
+ }
+ mPlaybackSettings = rate;
+ mPlaybackRate = rate.mSpeed;
+ mMediaClock->setPlaybackRate(mPlaybackRate);
+ return OK;
+}
+
+status_t NuPlayer::Renderer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
+ sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ if (err == OK) {
+ readFromAMessage(response, rate);
+ }
+ }
+ return err;
+}
+
+status_t NuPlayer::Renderer::onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
+ if (mAudioSink != NULL) {
+ status_t err = mAudioSink->getPlaybackRate(rate);
+ if (err == OK) {
+ if (!isAudioPlaybackRateEqual(*rate, mPlaybackSettings)) {
+ ALOGW("correcting mismatch in internal/external playback rate");
+ }
+ // get playback settings used by audiosink, as it may be
+ // slightly off due to audiosink not taking small changes.
+ mPlaybackSettings = *rate;
+ if (mPaused) {
+ rate->mSpeed = 0.f;
+ }
+ }
+ return err;
+ }
+ *rate = mPlaybackSettings;
+ return OK;
+}
+
+status_t NuPlayer::Renderer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
+ sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
+ writeToAMessage(msg, sync, videoFpsHint);
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ }
+ return err;
+}
+
+status_t NuPlayer::Renderer::onConfigSync(const AVSyncSettings &sync, float videoFpsHint __unused) {
+ if (sync.mSource != AVSYNC_SOURCE_DEFAULT) {
+ return BAD_VALUE;
+ }
+ // TODO: support sync sources
+ return INVALID_OPERATION;
+}
+
+status_t NuPlayer::Renderer::getSyncSettings(AVSyncSettings *sync, float *videoFps) {
+ sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ if (err == OK) {
+ readFromAMessage(response, sync, videoFps);
+ }
+ }
+ return err;
+}
+
+status_t NuPlayer::Renderer::onGetSyncSettings(
+ AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
+ *sync = mSyncSettings;
+ *videoFps = -1.f;
+ return OK;
}
void NuPlayer::Renderer::flush(bool audio, bool notifyComplete) {
@@ -365,13 +468,63 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- case kWhatSetRate:
+ case kWhatConfigPlayback:
{
- CHECK(msg->findFloat("rate", &mPlaybackRate));
- int32_t ratePermille = (int32_t)(0.5f + 1000 * mPlaybackRate);
- mPlaybackRate = ratePermille / 1000.0f;
- mMediaClock->setPlaybackRate(mPlaybackRate);
- mAudioSink->setPlaybackRatePermille(ratePermille);
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ AudioPlaybackRate rate;
+ readFromAMessage(msg, &rate);
+ status_t err = onConfigPlayback(rate);
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatGetPlaybackSettings:
+ {
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
+ status_t err = onGetPlaybackSettings(&rate);
+ sp<AMessage> response = new AMessage;
+ if (err == OK) {
+ writeToAMessage(response, rate);
+ }
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatConfigSync:
+ {
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ AVSyncSettings sync;
+ float videoFpsHint;
+ readFromAMessage(msg, &sync, &videoFpsHint);
+ status_t err = onConfigSync(sync, videoFpsHint);
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatGetSyncSettings:
+ {
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ ALOGV("kWhatGetSyncSettings");
+ AVSyncSettings sync;
+ float videoFps = -1.f;
+ status_t err = onGetSyncSettings(&sync, &videoFps);
+ sp<AMessage> response = new AMessage;
+ if (err == OK) {
+ writeToAMessage(response, sync, videoFps);
+ }
+ response->setInt32("err", err);
+ response->postReply(replyID);
break;
}
@@ -1176,7 +1329,6 @@ void NuPlayer::Renderer::onEnableOffloadAudio() {
void NuPlayer::Renderer::onPause() {
if (mPaused) {
- ALOGW("Renderer::onPause() called while already paused!");
return;
}
@@ -1214,6 +1366,12 @@ void NuPlayer::Renderer::onResume() {
{
Mutex::Autolock autoLock(mLock);
mPaused = false;
+
+ // configure audiosink as we did not do it when pausing
+ if (mAudioSink != NULL) {
+ mAudioSink->setPlaybackRate(mPlaybackSettings);
+ }
+
mMediaClock->setPlaybackRate(mPlaybackRate);
if (!mAudioQueue.empty()) {
@@ -1433,10 +1591,10 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
&offloadInfo);
if (err == OK) {
- if (mPlaybackRate != 1.0) {
- mAudioSink->setPlaybackRatePermille(
- (int32_t)(mPlaybackRate * 1000 + 0.5f));
- }
+ err = mAudioSink->setPlaybackRate(mPlaybackSettings);
+ }
+
+ if (err == OK) {
// If the playback is offloaded to h/w, we pass
// the HAL some metadata information.
// We don't want to do this for PCM because it
@@ -1486,16 +1644,15 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
NULL,
NULL,
(audio_output_flags_t)pcmFlags);
+ if (err == OK) {
+ err = mAudioSink->setPlaybackRate(mPlaybackSettings);
+ }
if (err != OK) {
ALOGW("openAudioSink: non offloaded open failed status: %d", err);
mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
return err;
}
mCurrentPcmInfo = info;
- if (mPlaybackRate != 1.0) {
- mAudioSink->setPlaybackRatePermille(
- (int32_t)(mPlaybackRate * 1000 + 0.5f));
- }
mAudioSink->start();
}
if (audioSinkChanged) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 38843d5..928b71b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -18,6 +18,9 @@
#define NUPLAYER_RENDERER_H_
+#include <media/AudioResamplerPublic.h>
+#include <media/AVSyncSettings.h>
+
#include "NuPlayer.h"
namespace android {
@@ -48,7 +51,10 @@ struct NuPlayer::Renderer : public AHandler {
void queueEOS(bool audio, status_t finalResult);
- void setPlaybackRate(float rate);
+ status_t setPlaybackSettings(const AudioPlaybackRate &rate /* sanitized */);
+ status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
+ status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
+ status_t getSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
void flush(bool audio, bool notifyComplete);
@@ -102,7 +108,10 @@ private:
kWhatPostDrainVideoQueue = 'pDVQ',
kWhatQueueBuffer = 'queB',
kWhatQueueEOS = 'qEOS',
- kWhatSetRate = 'setR',
+ kWhatConfigPlayback = 'cfPB',
+ kWhatConfigSync = 'cfSy',
+ kWhatGetPlaybackSettings = 'gPbS',
+ kWhatGetSyncSettings = 'gSyS',
kWhatFlush = 'flus',
kWhatPause = 'paus',
kWhatResume = 'resm',
@@ -141,7 +150,12 @@ private:
int32_t mVideoDrainGeneration;
sp<MediaClock> mMediaClock;
- float mPlaybackRate;
+ float mPlaybackRate; // audio track rate
+
+ AudioPlaybackRate mPlaybackSettings;
+ AVSyncSettings mSyncSettings;
+ float mVideoFpsHint;
+
int64_t mAudioFirstAnchorTimeMediaUs;
int64_t mAnchorTimeMediaUs;
int64_t mAnchorNumFramesWritten;
@@ -217,6 +231,11 @@ private:
void onAudioSinkChanged();
void onDisableOffloadAudio();
void onEnableOffloadAudio();
+ status_t onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */);
+ status_t onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
+ status_t onConfigSync(const AVSyncSettings &sync, float videoFpsHint);
+ status_t onGetSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
+
void onPause();
void onResume();
void onSetVideoFrameRate(float fps);
@@ -252,6 +271,6 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(Renderer);
};
-} // namespace android
+} // namespace android
#endif // NUPLAYER_RENDERER_H_