summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/MediaPlayerInterface.h6
-rw-r--r--include/media/stagefright/AudioPlayer.h3
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPlayer.cpp7
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPlayer.h2
-rw-r--r--media/libmedia/AudioTrack.cpp4
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp19
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h7
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp20
-rw-r--r--media/libstagefright/AudioPlayer.cpp9
-rw-r--r--media/libstagefright/AwesomePlayer.cpp13
10 files changed, 74 insertions, 16 deletions
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 9a8f4b0..a70fe8c 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -63,6 +63,9 @@ enum player_type {
// when the channel mask isn't known, use the channel count to derive a mask in AudioSink::open()
#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
+// duration below which we do not allow deep audio buffering
+#define AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US 5000000
+
// callback mechanism for passing messages to MediaPlayer object
typedef void (*notify_callback_f)(void* cookie,
int msg, int ext1, int ext2, const Parcel *obj);
@@ -98,7 +101,8 @@ public:
audio_format_t format=AUDIO_FORMAT_PCM_16_BIT,
int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT,
AudioCallback cb = NULL,
- void *cookie = NULL) = 0;
+ void *cookie = NULL,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE) = 0;
virtual void start() = 0;
virtual ssize_t write(const void* buffer, size_t size) = 0;
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index 70c47ae..9e8e4bb 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -37,6 +37,7 @@ public:
};
AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink,
+ bool allowDeepBuffering = false,
AwesomePlayer *audioObserver = NULL);
virtual ~AudioPlayer();
@@ -95,6 +96,8 @@ private:
MediaBuffer *mFirstBuffer;
sp<MediaPlayerBase::AudioSink> mAudioSink;
+ bool mAllowDeepBuffering; // allow audio deep audio buffers. Helps with low power audio
+ // playback but implies high latency
AwesomePlayer *mObserver;
static void AudioCallback(int event, void *user, void *info);
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
index c9cff81..fc9fb49 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
@@ -392,7 +392,7 @@ status_t VideoEditorPlayer::VeAudioOutput::getFramesWritten(uint32_t *written) c
status_t VideoEditorPlayer::VeAudioOutput::open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie) {
+ AudioCallback cb, void *cookie, audio_output_flags_t flags) {
mCallback = cb;
mCallbackCookie = cookie;
@@ -442,7 +442,7 @@ status_t VideoEditorPlayer::VeAudioOutput::open(
format,
channelMask,
frameCount,
- AUDIO_OUTPUT_FLAG_NONE,
+ flags,
CallbackWrapper,
this);
} else {
@@ -451,7 +451,8 @@ status_t VideoEditorPlayer::VeAudioOutput::open(
sampleRate,
format,
channelMask,
- frameCount);
+ frameCount,
+ flags);
}
if ((t == 0) || (t->initCheck() != NO_ERROR)) {
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.h b/libvideoeditor/lvpp/VideoEditorPlayer.h
index 350b384..2ab4eef 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.h
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.h
@@ -52,7 +52,7 @@ class VideoEditorPlayer : public MediaPlayerInterface {
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie);
+ AudioCallback cb, void *cookie, audio_output_flags_t flags);
virtual void start();
virtual ssize_t write(const void* buffer, size_t size);
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 092b516..25d79d6 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -225,6 +225,10 @@ status_t AudioTrack::set(
flags = (audio_output_flags_t)
((flags | AUDIO_OUTPUT_FLAG_DIRECT) & ~AUDIO_OUTPUT_FLAG_FAST);
}
+ // only allow deep buffering for music stream type
+ if (streamType != AUDIO_STREAM_MUSIC) {
+ flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
+ }
if (!audio_is_output_channel(channelMask)) {
ALOGE("Invalid channel mask");
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 7254599..bfdf250 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1412,7 +1412,8 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
mCallbackCookie(NULL),
mCallbackData(NULL),
mBytesWritten(0),
- mSessionId(sessionId) {
+ mSessionId(sessionId),
+ mFlags(AUDIO_OUTPUT_FLAG_NONE) {
ALOGV("AudioOutput(%d)", sessionId);
mTrack = 0;
mRecycledTrack = 0;
@@ -1506,7 +1507,8 @@ status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritt
status_t MediaPlayerService::AudioOutput::open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie)
+ AudioCallback cb, void *cookie,
+ audio_output_flags_t flags)
{
mCallback = cb;
mCallbackCookie = cookie;
@@ -1521,7 +1523,7 @@ status_t MediaPlayerService::AudioOutput::open(
format, bufferCount, mSessionId);
int afSampleRate;
int afFrameCount;
- int frameCount;
+ uint32_t frameCount;
if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
return NO_INIT;
@@ -1539,6 +1541,7 @@ status_t MediaPlayerService::AudioOutput::open(
return NO_INIT;
}
}
+
if (mRecycledTrack) {
// check if the existing track can be reused as-is, or if a new track needs to be created.
@@ -1553,6 +1556,9 @@ status_t MediaPlayerService::AudioOutput::open(
(mRecycledTrack->frameCount() != frameCount)) {
ALOGV("samplerate, channelcount or framecount differ");
reuse = false;
+ } if (flags != mFlags) {
+ ALOGV("output flags differ");
+ reuse = false;
}
if (reuse) {
ALOGV("chaining to next output");
@@ -1587,7 +1593,7 @@ status_t MediaPlayerService::AudioOutput::open(
format,
channelMask,
frameCount,
- AUDIO_OUTPUT_FLAG_NONE,
+ flags,
CallbackWrapper,
mCallbackData,
0, // notification frames
@@ -1599,7 +1605,7 @@ status_t MediaPlayerService::AudioOutput::open(
format,
channelMask,
frameCount,
- AUDIO_OUTPUT_FLAG_NONE,
+ flags,
NULL,
NULL,
0,
@@ -1616,6 +1622,7 @@ status_t MediaPlayerService::AudioOutput::open(
t->setVolume(mLeftVolume, mRightVolume);
mSampleRateHz = sampleRate;
+ mFlags = flags;
mMsecsPerFrame = mPlaybackRatePermille / (float) sampleRate;
uint32_t pos;
if (t->getPosition(&pos) == OK) {
@@ -1891,7 +1898,7 @@ bool CallbackThread::threadLoop() {
status_t MediaPlayerService::AudioCache::open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie)
+ AudioCallback cb, void *cookie, audio_output_flags_t flags)
{
ALOGV("open(%u, %d, 0x%x, %d, %d)", sampleRate, channelCount, channelMask, format, bufferCount);
if (mHeap->getHeapID() < 0) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 2a8cfd2..95b1b05 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -91,7 +91,8 @@ class MediaPlayerService : public BnMediaPlayerService
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie);
+ AudioCallback cb, void *cookie,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE);
virtual void start();
virtual ssize_t write(const void* buffer, size_t size);
@@ -135,6 +136,7 @@ class MediaPlayerService : public BnMediaPlayerService
int mAuxEffectId;
static bool mIsOnEmulator;
static int mMinBufferCount; // 12 for emulator; otherwise 4
+ audio_output_flags_t mFlags;
// CallbackData is what is passed to the AudioTrack as the "user" data.
// We need to be able to target this to a different Output on the fly,
@@ -190,7 +192,8 @@ class MediaPlayerService : public BnMediaPlayerService
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount = 1,
- AudioCallback cb = NULL, void *cookie = NULL);
+ AudioCallback cb = NULL, void *cookie = NULL,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE);
virtual void start();
virtual ssize_t write(const void* buffer, size_t size);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 11cea3b..f1467c4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -390,12 +390,30 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
sampleRate, numChannels);
mAudioSink->close();
+
+ audio_output_flags_t flags;
+ int64_t durationUs;
+ // FIXME: we should handle the case where the video decoder is created after
+ // we receive the format change indication. Current code will just make that
+ // we select deep buffer with video which should not be a problem as it should
+ // not prevent from keeping A/V sync.
+ if (mVideoDecoder == NULL &&
+ mSource->getDuration(&durationUs) == OK &&
+ durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
+ flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+ } else {
+ flags = AUDIO_OUTPUT_FLAG_NONE;
+ }
+
CHECK_EQ(mAudioSink->open(
sampleRate,
numChannels,
CHANNEL_MASK_USE_CHANNEL_ORDER,
AUDIO_FORMAT_PCM_16_BIT,
- 8 /* bufferCount */),
+ 8 /* bufferCount */,
+ NULL,
+ NULL,
+ flags),
(status_t)OK);
mAudioSink->start();
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 468fe2c..2e0b013 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -33,6 +33,7 @@ namespace android {
AudioPlayer::AudioPlayer(
const sp<MediaPlayerBase::AudioSink> &audioSink,
+ bool allowDeepBuffering,
AwesomePlayer *observer)
: mAudioTrack(NULL),
mInputBuffer(NULL),
@@ -50,6 +51,7 @@ AudioPlayer::AudioPlayer(
mFirstBufferResult(OK),
mFirstBuffer(NULL),
mAudioSink(audioSink),
+ mAllowDeepBuffering(allowDeepBuffering),
mObserver(observer) {
}
@@ -120,10 +122,15 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
}
if (mAudioSink.get() != NULL) {
+
status_t err = mAudioSink->open(
mSampleRate, numChannels, channelMask, AUDIO_FORMAT_PCM_16_BIT,
DEFAULT_AUDIOSINK_BUFFERCOUNT,
- &AudioPlayer::AudioSinkCallback, this);
+ &AudioPlayer::AudioSinkCallback,
+ this,
+ (mAllowDeepBuffering ?
+ AUDIO_OUTPUT_FLAG_DEEP_BUFFER :
+ AUDIO_OUTPUT_FLAG_NONE));
if (err != OK) {
if (mFirstBuffer != NULL) {
mFirstBuffer->release();
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index b67476b..b15cb67 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -870,7 +870,18 @@ status_t AwesomePlayer::play_l() {
if (mAudioSource != NULL) {
if (mAudioPlayer == NULL) {
if (mAudioSink != NULL) {
- mAudioPlayer = new AudioPlayer(mAudioSink, this);
+ bool allowDeepBuffering;
+ int64_t cachedDurationUs;
+ bool eos;
+ if (mVideoSource == NULL && (mDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US ||
+ getCachedDuration_l(&cachedDurationUs, &eos) &&
+ cachedDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
+ allowDeepBuffering = true;
+ } else {
+ allowDeepBuffering = false;
+ }
+
+ mAudioPlayer = new AudioPlayer(mAudioSink, allowDeepBuffering, this);
mAudioPlayer->setSource(mAudioSource);
mTimeSource = mAudioPlayer;