summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2014-10-20 17:47:54 -0700
committerLajos Molnar <lajos@google.com>2014-10-20 21:04:33 -0700
commitd5923409bbcbb22954a92c2b497ef4492d7cb6a5 (patch)
treea1ace41b85fb97ea4e496e136abaacad91e69f09 /media
parenteecb7805bbbb712925d4372c505f8c7f5c4fb5ed (diff)
downloadframeworks_av-d5923409bbcbb22954a92c2b497ef4492d7cb6a5.zip
frameworks_av-d5923409bbcbb22954a92c2b497ef4492d7cb6a5.tar.gz
frameworks_av-d5923409bbcbb22954a92c2b497ef4492d7cb6a5.tar.bz2
mediaplayer: limit scheduling video frames into the future
This addresses when video timestamps jumps before an audio timestamp, but still works on slideshow video clips (<=1fps). This, however, will not skip time-changes on video-only live video streams, as we cannot distinguish live slideshow video clips from non-slideshow ones. Bug: 18032127 Change-Id: I959a714edfe1c8cf3b84704c693dcd1b3e5b7855
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp39
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h5
2 files changed, 43 insertions, 1 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 46a2590..638d9bc 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -82,7 +82,9 @@ NuPlayer::Renderer::Renderer(
mAudioRenderingStartGeneration(0),
mAudioOffloadPauseTimeoutGeneration(0),
mAudioOffloadTornDown(false),
- mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER) {
+ mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
+ mTotalBuffersQueued(0),
+ mLastAudioBufferDrained(0) {
readProperties();
}
@@ -361,6 +363,19 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatPostDrainVideoQueue:
+ {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+ if (generation != mVideoQueueGeneration) {
+ break;
+ }
+
+ mDrainVideoQueuePending = false;
+ postDrainVideoQueue();
+ break;
+ }
+
case kWhatQueueBuffer:
{
onQueueBuffer(msg);
@@ -580,6 +595,8 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) {
QueueEntry *entry = &*mAudioQueue.begin();
+ mLastAudioBufferDrained = entry->mBufferOrdinal;
+
if (entry->mBuffer == NULL) {
// EOS
int64_t postEOSDelayUs = 0;
@@ -716,6 +733,25 @@ void NuPlayer::Renderer::postDrainVideoQueue() {
} else {
realTimeUs = getRealTimeUs(mediaTimeUs, nowUs);
}
+
+ // Heuristics to handle situation when media time changed without a
+ // discontinuity. If we have not drained an audio buffer that was
+ // received after this buffer, repost in 10 msec. Otherwise repost
+ // in 500 msec.
+ delayUs = realTimeUs - nowUs;
+ if (delayUs > 500000) {
+ int64_t postDelayUs = 500000;
+ if (mHasAudio && (mLastAudioBufferDrained - entry.mBufferOrdinal) <= 0) {
+ postDelayUs = 10000;
+ }
+ msg->setWhat(kWhatPostDrainVideoQueue);
+ msg->post(postDelayUs);
+ mVideoScheduler->restart();
+ ALOGI("possible video time jump of %dms, retrying in %dms",
+ (int)(delayUs / 1000), (int)(postDelayUs / 1000));
+ mDrainVideoQueuePending = true;
+ return;
+ }
}
realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000;
@@ -855,6 +891,7 @@ void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
entry.mNotifyConsumed = notifyConsumed;
entry.mOffset = 0;
entry.mFinalResult = OK;
+ entry.mBufferOrdinal = ++mTotalBuffersQueued;
if (audio) {
Mutex::Autolock autoLock(mLock);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 7079f85..b15a266 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -101,6 +101,7 @@ private:
enum {
kWhatDrainAudioQueue = 'draA',
kWhatDrainVideoQueue = 'draV',
+ kWhatPostDrainVideoQueue = 'pDVQ',
kWhatQueueBuffer = 'queB',
kWhatQueueEOS = 'qEOS',
kWhatFlush = 'flus',
@@ -119,6 +120,7 @@ private:
sp<AMessage> mNotifyConsumed;
size_t mOffset;
status_t mFinalResult;
+ int32_t mBufferOrdinal;
};
static const int64_t kMinPositionUpdateDelayUs;
@@ -169,6 +171,9 @@ private:
bool mAudioOffloadTornDown;
audio_offload_info_t mCurrentOffloadInfo;
+ int32_t mTotalBuffersQueued;
+ int32_t mLastAudioBufferDrained;
+
size_t fillAudioBuffer(void *buffer, size_t size);
bool onDrainAudioQueue();