diff options
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 80 |
1 files changed, 71 insertions, 9 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 8a75f83..bf5271e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -20,6 +20,8 @@ #include "NuPlayerRenderer.h" +#include "SoftwareRenderer.h" + #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> @@ -31,9 +33,12 @@ const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; NuPlayer::Renderer::Renderer( const sp<MediaPlayerBase::AudioSink> &sink, - const sp<AMessage> ¬ify) + const sp<AMessage> ¬ify, + uint32_t flags) : mAudioSink(sink), + mSoftRenderer(NULL), mNotify(notify), + mFlags(flags), mNumFramesWritten(0), mDrainAudioQueuePending(false), mDrainVideoQueuePending(false), @@ -48,11 +53,19 @@ NuPlayer::Renderer::Renderer( mSyncQueues(false), mPaused(false), mVideoRenderingStarted(false), + mVideoRenderingStartGeneration(0), + mAudioRenderingStartGeneration(0), mLastPositionUpdateUs(-1ll), mVideoLateByUs(0ll) { } NuPlayer::Renderer::~Renderer() { + delete mSoftRenderer; +} + +void NuPlayer::Renderer::setSoftRenderer(SoftwareRenderer *softRenderer) { + delete mSoftRenderer; + mSoftRenderer = softRenderer; } void NuPlayer::Renderer::queueBuffer( @@ -93,11 +106,11 @@ void NuPlayer::Renderer::flush(bool audio) { } void NuPlayer::Renderer::signalTimeDiscontinuity() { - CHECK(mAudioQueue.empty()); - CHECK(mVideoQueue.empty()); + // CHECK(mAudioQueue.empty()); + // CHECK(mVideoQueue.empty()); mAnchorTimeMediaUs = -1; mAnchorTimeRealUs = -1; - mSyncQueues = mHasAudio && mHasVideo; + mSyncQueues = false; } void NuPlayer::Renderer::pause() { @@ -218,6 +231,23 @@ void NuPlayer::Renderer::signalAudioSinkChanged() { (new AMessage(kWhatAudioSinkChanged, id()))->post(); } +void NuPlayer::Renderer::prepareForMediaRenderingStart() { + mAudioRenderingStartGeneration = mAudioQueueGeneration; + mVideoRenderingStartGeneration = mVideoQueueGeneration; +} + +void NuPlayer::Renderer::notifyIfMediaRenderingStarted() { + if (mVideoRenderingStartGeneration == mVideoQueueGeneration && + mAudioRenderingStartGeneration == mAudioQueueGeneration) { + mVideoRenderingStartGeneration = -1; + mAudioRenderingStartGeneration = -1; + + sp<AMessage> notify = mNotify->dup(); + notify->setInt32("what", kWhatMediaRenderingStart); + notify->post(); + } +} + bool NuPlayer::Renderer::onDrainAudioQueue() { uint32_t numFramesPlayed; if (mAudioSink->getPosition(&numFramesPlayed) != OK) { @@ -297,6 +327,8 @@ bool NuPlayer::Renderer::onDrainAudioQueue() { numBytesAvailableToWrite -= copy; size_t copiedFrames = copy / mAudioSink->frameSize(); mNumFramesWritten += copiedFrames; + + notifyIfMediaRenderingStarted(); } notifyPosition(); @@ -323,6 +355,11 @@ void NuPlayer::Renderer::postDrainVideoQueue() { if (entry.mBuffer == NULL) { // EOS doesn't carry a timestamp. delayUs = 0; + } else if (mFlags & FLAG_REAL_TIME) { + int64_t mediaTimeUs; + CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); + + delayUs = mediaTimeUs - ALooper::GetNowUs(); } else { int64_t mediaTimeUs; CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); @@ -368,19 +405,29 @@ void NuPlayer::Renderer::onDrainVideoQueue() { return; } - int64_t mediaTimeUs; - CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); + int64_t realTimeUs; + if (mFlags & FLAG_REAL_TIME) { + CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs)); + } else { + int64_t mediaTimeUs; + CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); - int64_t realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs; - mVideoLateByUs = ALooper::GetNowUs() - realTimeUs; + realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs; + } + mVideoLateByUs = ALooper::GetNowUs() - realTimeUs; bool tooLate = (mVideoLateByUs > 40000); if (tooLate) { ALOGV("video late by %lld us (%.2f secs)", mVideoLateByUs, mVideoLateByUs / 1E6); } else { - ALOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6); + ALOGV("rendering video at media time %.2f secs", + (mFlags & FLAG_REAL_TIME ? realTimeUs : + (realTimeUs + mAnchorTimeMediaUs - mAnchorTimeRealUs)) / 1E6); + if (mSoftRenderer != NULL) { + mSoftRenderer->render(entry->mBuffer->data(), entry->mBuffer->size(), NULL); + } } entry->mNotifyConsumed->setInt32("render", !tooLate); @@ -393,6 +440,8 @@ void NuPlayer::Renderer::onDrainVideoQueue() { notifyVideoRenderingStart(); } + notifyIfMediaRenderingStarted(); + notifyPosition(); } @@ -512,9 +561,15 @@ void NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) { entry.mFinalResult = finalResult; if (audio) { + if (mAudioQueue.empty() && mSyncQueues) { + syncQueuesDone(); + } mAudioQueue.push_back(entry); postDrainAudioQueue(); } else { + if (mVideoQueue.empty() && mSyncQueues) { + syncQueuesDone(); + } mVideoQueue.push_back(entry); postDrainVideoQueue(); } @@ -534,6 +589,7 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { // is flushed. syncQueuesDone(); + ALOGV("flushing %s", audio ? "audio" : "video"); if (audio) { flushQueue(&mAudioQueue); @@ -542,6 +598,8 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { mDrainAudioQueuePending = false; ++mAudioQueueGeneration; + + prepareForMediaRenderingStart(); } else { flushQueue(&mVideoQueue); @@ -550,6 +608,8 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { mDrainVideoQueuePending = false; ++mVideoQueueGeneration; + + prepareForMediaRenderingStart(); } notifyFlushComplete(audio); @@ -640,6 +700,8 @@ void NuPlayer::Renderer::onPause() { mDrainVideoQueuePending = false; ++mVideoQueueGeneration; + prepareForMediaRenderingStart(); + if (mHasAudio) { mAudioSink->pause(); } |