diff options
author | Andreas Huber <andih@google.com> | 2011-09-15 12:25:04 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2011-09-16 10:44:02 -0700 |
commit | 078cfcf7cce9185ec7559910d08b0bc02bfc88a3 (patch) | |
tree | d4fb458318a3f0b3982b05e0c79a2cfc447dd732 /media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | |
parent | 5dc2812abddde309234edc786a541d251c4f820a (diff) | |
download | frameworks_av-078cfcf7cce9185ec7559910d08b0bc02bfc88a3.zip frameworks_av-078cfcf7cce9185ec7559910d08b0bc02bfc88a3.tar.gz frameworks_av-078cfcf7cce9185ec7559910d08b0bc02bfc88a3.tar.bz2 |
Various improvements to nuplayer playback
- Drastically cut down the number of times we supply the AudioSink with data
by estimating the time until the sink would run out of data and then scheduling
a refill in advance of that.
- Use a dedicated looper for video decoders since they are currently taking
too long to return from OMX_FillThisBuffer (bug 5325201)
- Revise thread priorities for the OMX dispatcher and software codecs, instead
of running them at ANDROID_PRIORITY_AUDIO, they now only run at
ANDROID_PRIORITY_FOREGROUND
- Since threads created by pthread_create inherit all of the parent threads
attributes including thread priority, briefly reset thread priority to
ANDROID_PRIORITY_FOREGROUND before instantiating OMX components and then
restore it.
Change-Id: If9332a3a20dad5485333d68c11de0d2d5d3fffc3
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 79 |
1 files changed, 53 insertions, 26 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index bf83849..3b3fca2 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -118,9 +118,24 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { mDrainAudioQueuePending = false; - onDrainAudioQueue(); - - postDrainAudioQueue(); + if (onDrainAudioQueue()) { + uint32_t numFramesPlayed; + CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), + (status_t)OK); + + uint32_t numFramesPendingPlayout = + mNumFramesWritten - numFramesPlayed; + + // This is how long the audio sink will have data to + // play back. + int64_t delayUs = + mAudioSink->msecsPerFrame() + * numFramesPendingPlayout * 1000ll; + + // Let's give it more data after about half that time + // has elapsed. + postDrainAudioQueue(delayUs / 2); + } break; } @@ -182,7 +197,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { } } -void NuPlayer::Renderer::postDrainAudioQueue() { +void NuPlayer::Renderer::postDrainAudioQueue(int64_t delayUs) { if (mDrainAudioQueuePending || mSyncQueues || mPaused) { return; } @@ -194,19 +209,33 @@ void NuPlayer::Renderer::postDrainAudioQueue() { mDrainAudioQueuePending = true; sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id()); msg->setInt32("generation", mAudioQueueGeneration); - msg->post(); + msg->post(delayUs); } void NuPlayer::Renderer::signalAudioSinkChanged() { (new AMessage(kWhatAudioSinkChanged, id()))->post(); } -void NuPlayer::Renderer::onDrainAudioQueue() { - for (;;) { - if (mAudioQueue.empty()) { - break; - } +bool NuPlayer::Renderer::onDrainAudioQueue() { + uint32_t numFramesPlayed; + CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); + + ssize_t numFramesAvailableToWrite = + mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); + +#if 0 + if (numFramesAvailableToWrite == mAudioSink->frameCount()) { + LOGI("audio sink underrun"); + } else { + LOGV("audio queue has %d frames left to play", + mAudioSink->frameCount() - numFramesAvailableToWrite); + } +#endif + size_t numBytesAvailableToWrite = + numFramesAvailableToWrite * mAudioSink->frameSize(); + + while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) { QueueEntry *entry = &*mAudioQueue.begin(); if (entry->mBuffer == NULL) { @@ -216,20 +245,7 @@ void NuPlayer::Renderer::onDrainAudioQueue() { mAudioQueue.erase(mAudioQueue.begin()); entry = NULL; - return; - } - - uint32_t numFramesPlayed; - CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); - - ssize_t numFramesAvailableToWrite = - mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); - - size_t numBytesAvailableToWrite = - numFramesAvailableToWrite * mAudioSink->frameSize(); - - if (numBytesAvailableToWrite == 0) { - break; + return false; } if (entry->mOffset == 0) { @@ -274,10 +290,14 @@ void NuPlayer::Renderer::onDrainAudioQueue() { entry = NULL; } - mNumFramesWritten += copy / mAudioSink->frameSize(); + numBytesAvailableToWrite -= copy; + size_t copiedFrames = copy / mAudioSink->frameSize(); + mNumFramesWritten += copiedFrames; } notifyPosition(); + + return !mAudioQueue.empty(); } void NuPlayer::Renderer::postDrainVideoQueue() { @@ -344,7 +364,14 @@ void NuPlayer::Renderer::onDrainVideoQueue() { int64_t mediaTimeUs; CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); - LOGI("rendering video at media time %.2f secs", mediaTimeUs / 1E6); + int64_t realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs; + int64_t lateByUs = ALooper::GetNowUs() - realTimeUs; + + if (lateByUs > 40000) { + LOGI("video late by %lld us (%.2f secs)", lateByUs, lateByUs / 1E6); + } else { + LOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6); + } #endif entry->mNotifyConsumed->setInt32("render", true); |