NuPlayer: Notify if drain message time is unexpectedly long
Bug: 27940058
Change-Id: Id8897c30e21b6b9de545a710e7766ffceb491455
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index eaaef4a..69232b7 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -333,6 +333,10 @@
*/
ssize_t getBufferSizeInFrames();
+ /* Returns the buffer duration in microseconds at current playback rate.
+ */
+ status_t getBufferDurationInUs(int64_t *duration);
+
/* Set the effective size of audio buffer that an application writes to.
* This is used to determine the amount of available room in the buffer,
* which determines when a write will block.
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 54862d1..4977efd 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -104,6 +104,7 @@
virtual audio_session_t getSessionId() const = 0;
virtual audio_stream_type_t getAudioStreamType() const = 0;
virtual uint32_t getSampleRate() const = 0;
+ virtual int64_t getBufferDurationInUs() const = 0;
// If no callback is specified, use the "write" API below to submit
// audio data.
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index a4cc3d7..b135466 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -875,6 +875,24 @@
return (ssize_t) mProxy->getBufferSizeInFrames();
}
+status_t AudioTrack::getBufferDurationInUs(int64_t *duration)
+{
+ if (duration == nullptr) {
+ return BAD_VALUE;
+ }
+ AutoMutex lock(mLock);
+ if (mOutput == AUDIO_IO_HANDLE_NONE || mProxy.get() == 0) {
+ return NO_INIT;
+ }
+ ssize_t bufferSizeInFrames = (ssize_t) mProxy->getBufferSizeInFrames();
+ if (bufferSizeInFrames < 0) {
+ return (status_t)bufferSizeInFrames;
+ }
+ *duration = (int64_t)((double)bufferSizeInFrames * 1000000
+ / ((double)mSampleRate * mPlaybackRate.mSpeed));
+ return NO_ERROR;
+}
+
ssize_t AudioTrack::setBufferSizeInFrames(size_t bufferSizeInFrames)
{
AutoMutex lock(mLock);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 1a3013a..da965e5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -2127,6 +2127,19 @@
return mTrack->getSampleRate();
}
+int64_t MediaPlayerService::AudioOutput::getBufferDurationInUs() const
+{
+ Mutex::Autolock lock(mLock);
+ if (mTrack == 0) {
+ return 0;
+ }
+ int64_t duration;
+ if (mTrack->getBufferDurationInUs(&duration) != OK) {
+ return 0;
+ }
+ return duration;
+}
+
////////////////////////////////////////////////////////////////////////////////
struct CallbackThread : public Thread {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 1581b49..80593b2 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -92,6 +92,7 @@
virtual status_t getFramesWritten(uint32_t *frameswritten) const;
virtual audio_session_t getSessionId() const;
virtual uint32_t getSampleRate() const;
+ virtual int64_t getBufferDurationInUs() const;
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index cbb9d95..167b9a0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include "NuPlayerRenderer.h"
+#include <algorithm>
#include <cutils/properties.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -487,8 +488,14 @@
// Let's give it more data after about half that time
// has elapsed.
+ delayUs /= 2;
+ // check the buffer size to estimate maximum delay permitted.
+ const int64_t maxDrainDelayUs = std::max(
+ mAudioSink->getBufferDurationInUs(), (int64_t)500000 /* half second */);
+ ALOGD_IF(delayUs > maxDrainDelayUs, "postDrainAudioQueue long delay: %lld > %lld",
+ (long long)delayUs, (long long)maxDrainDelayUs);
Mutex::Autolock autoLock(mLock);
- postDrainAudioQueue_l(delayUs / 2);
+ postDrainAudioQueue_l(delayUs);
}
break;
}