summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
diff options
context:
space:
mode:
authorWei Jia <wjia@google.com>2014-11-11 16:33:20 -0800
committerWei Jia <wjia@google.com>2014-11-14 14:23:52 -0800
commitc6cfd70f24a11b946859485ce398a189c301a4e2 (patch)
tree47238c67d7cf5f6bfdf6845c64966e5e1692eb12 /media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
parent12acd3f0374e7707ff50c04f8075883be71b128c (diff)
downloadframeworks_av-c6cfd70f24a11b946859485ce398a189c301a4e2.zip
frameworks_av-c6cfd70f24a11b946859485ce398a189c301a4e2.tar.gz
frameworks_av-c6cfd70f24a11b946859485ce398a189c301a4e2.tar.bz2
NuPlayer: tunnel decoder with renderer for data buffer passing.
Bug: 18342383 Change-Id: I182928007814c146c01a86196c4fda1d46e74ea4
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp')
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp119
1 files changed, 99 insertions, 20 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 27f6131..e695c43 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -21,6 +21,9 @@
#include "NuPlayerDecoder.h"
+#include "NuPlayerRenderer.h"
+#include "NuPlayerSource.h"
+
#include <media/ICrypto.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -35,9 +38,14 @@ namespace android {
NuPlayer::Decoder::Decoder(
const sp<AMessage> &notify,
+ const sp<Source> &source,
+ const sp<Renderer> &renderer,
const sp<NativeWindowWrapper> &nativeWindow)
: mNotify(notify),
mNativeWindow(nativeWindow),
+ mSource(source),
+ mRenderer(renderer),
+ mSkipRenderingUntilMediaTimeUs(-1ll),
mBufferGeneration(0),
mPaused(true),
mComponentName("decoder") {
@@ -169,7 +177,9 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
mInputBuffers.size(),
mOutputBuffers.size());
- requestCodecNotification();
+ if (mRenderer != NULL) {
+ requestCodecNotification();
+ }
mPaused = false;
}
@@ -191,6 +201,7 @@ void NuPlayer::Decoder::releaseAndResetMediaBuffers() {
}
mPendingInputMessages.clear();
+ mSkipRenderingUntilMediaTimeUs = -1;
}
void NuPlayer::Decoder::requestCodecNotification() {
@@ -217,6 +228,12 @@ void NuPlayer::Decoder::configure(const sp<AMessage> &format) {
msg->post();
}
+void NuPlayer::Decoder::setRenderer(const sp<Renderer> &renderer) {
+ sp<AMessage> msg = new AMessage(kWhatSetRenderer, id());
+ msg->setObject("renderer", renderer);
+ msg->post();
+}
+
void NuPlayer::Decoder::signalUpdateFormat(const sp<AMessage> &format) {
sp<AMessage> msg = new AMessage(kWhatUpdateFormat, id());
msg->setMessage("format", format);
@@ -342,8 +359,6 @@ bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {
}
}
-
-
if (buffer == NULL /* includes !hasBuffer */) {
int32_t streamErr = ERROR_END_OF_STREAM;
CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
@@ -375,6 +390,17 @@ bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {
handleError(streamErr);
}
} else {
+ sp<AMessage> extra;
+ if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
+ int64_t resumeAtMediaTimeUs;
+ if (extra->findInt64(
+ "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
+ ALOGI("[%s] suppressing rendering until %lld us",
+ mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
+ mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
+ }
+ }
+
int64_t timeUs = 0;
uint32_t flags = 0;
CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
@@ -454,10 +480,27 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() {
return false;
}
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatOutputFormatChanged);
- notify->setMessage("format", format);
- notify->post();
+ if (isVideo()) {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatVideoSizeChanged);
+ notify->setMessage("format", format);
+ notify->post();
+ } else if (mRenderer != NULL) {
+ uint32_t flags;
+ int64_t durationUs;
+ bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
+ if (!hasVideo &&
+ mSource->getDuration(&durationUs) == OK &&
+ durationUs
+ > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
+ flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+ } else {
+ flags = AUDIO_OUTPUT_FLAG_NONE;
+ }
+
+ mRenderer->openAudioSink(
+ format, false /* offloadOnly */, hasVideo, flags);
+ }
return true;
} else if (res == INFO_DISCONTINUITY) {
// nothing to do
@@ -485,21 +528,26 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() {
reply->setSize("buffer-ix", bufferIx);
reply->setInt32("generation", mBufferGeneration);
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatDrainThisBuffer);
- notify->setBuffer("buffer", buffer);
- notify->setMessage("reply", reply);
- notify->post();
+ if (mSkipRenderingUntilMediaTimeUs >= 0) {
+ if (timeUs < mSkipRenderingUntilMediaTimeUs) {
+ ALOGV("[%s] dropping buffer at time %lld as requested.",
+ mComponentName.c_str(), (long long)timeUs);
- // FIXME: This should be handled after rendering is complete,
- // but Renderer needs it now
- if (flags & MediaCodec::BUFFER_FLAG_EOS) {
- ALOGV("queueing eos [%s]", mComponentName.c_str());
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatEOS);
- notify->setInt32("err", ERROR_END_OF_STREAM);
- notify->post();
+ reply->post();
+ return true;
+ }
+
+ mSkipRenderingUntilMediaTimeUs = -1;
+ }
+
+ if (mRenderer != NULL) {
+ // send the buffer to renderer.
+ mRenderer->queueBuffer(!isVideo(), buffer, reply);
+ if (flags & MediaCodec::BUFFER_FLAG_EOS) {
+ mRenderer->queueEOS(!isVideo(), ERROR_END_OF_STREAM);
+ }
}
+
return true;
}
@@ -508,6 +556,17 @@ void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
int32_t render;
size_t bufferIx;
CHECK(msg->findSize("buffer-ix", &bufferIx));
+
+ if (isVideo()) {
+ int64_t timeUs;
+ sp<ABuffer> buffer = mOutputBuffers[bufferIx];
+ buffer->meta()->findInt64("timeUs", &timeUs);
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatRenderBufferTime);
+ notify->setInt64("timeUs", timeUs);
+ notify->post();
+ }
+
if (msg->findInt32("render", &render) && render) {
int64_t timestampNs;
CHECK(msg->findInt64("timestampNs", &timestampNs));
@@ -523,6 +582,10 @@ void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
}
void NuPlayer::Decoder::onFlush() {
+ if (mRenderer != NULL) {
+ mRenderer->flush(!isVideo());
+ }
+
status_t err = OK;
if (mCodec != NULL) {
err = mCodec->flush();
@@ -594,6 +657,18 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatSetRenderer:
+ {
+ bool hadNoRenderer = (mRenderer == NULL);
+ sp<RefBase> obj;
+ CHECK(msg->findObject("renderer", &obj));
+ mRenderer = static_cast<Renderer *>(obj.get());
+ if (hadNoRenderer && mRenderer != NULL) {
+ requestCodecNotification();
+ }
+ break;
+ }
+
case kWhatUpdateFormat:
{
sp<AMessage> format;
@@ -772,6 +847,10 @@ bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetF
return seamless;
}
+bool NuPlayer::Decoder::isVideo() {
+ return mNativeWindow != NULL;
+}
+
struct CCData {
CCData(uint8_t type, uint8_t data1, uint8_t data2)
: mType(type), mData1(data1), mData2(data2) {