diff options
author | Lajos Molnar <lajos@google.com> | 2015-07-14 00:23:36 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-07-14 00:23:37 +0000 |
commit | a7c2db7226b23dfe6ad0c7c1cccc073dab2f97bd (patch) | |
tree | fb6fff7f27ba212cba20fe9ac8f1565f259b75ad /media/libmediaplayerservice/nuplayer | |
parent | df31e36a225e3f036be379f4542d7d4992c7af4c (diff) | |
parent | a81c6229638a4db56752dd77a6610e0f0971e877 (diff) | |
download | frameworks_av-a7c2db7226b23dfe6ad0c7c1cccc073dab2f97bd.zip frameworks_av-a7c2db7226b23dfe6ad0c7c1cccc073dab2f97bd.tar.gz frameworks_av-a7c2db7226b23dfe6ad0c7c1cccc073dab2f97bd.tar.bz2 |
Merge "nuplayer: use codec->setSurface when possible to avoid seeking" into mnc-dev
Diffstat (limited to 'media/libmediaplayerservice/nuplayer')
5 files changed, 73 insertions, 3 deletions
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk index 20193c3..cc6f743 100644 --- a/media/libmediaplayerservice/nuplayer/Android.mk +++ b/media/libmediaplayerservice/nuplayer/Android.mk @@ -25,7 +25,8 @@ LOCAL_C_INCLUDES := \ $(TOP)/frameworks/av/media/libmediaplayerservice \ $(TOP)/frameworks/native/include/media/openmax -LOCAL_CFLAGS += -Werror -Wall +LOCAL_CFLAGS += -Werror -Wall -DENABLE_STAGEFRIGHT_EXPERIMENTS + LOCAL_CLANG := true LOCAL_MODULE:= libstagefright_nuplayer diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 4a1a34d..50a98d8 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -623,12 +623,19 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatSetVideoSurface: { - ALOGV("kWhatSetVideoSurface"); sp<RefBase> obj; CHECK(msg->findObject("surface", &obj)); sp<Surface> surface = static_cast<Surface *>(obj.get()); - if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) { + + ALOGD("onSetVideoSurface(%p, %s video decoder)", + surface.get(), + (mSource != NULL && mSource->getFormat(false /* audio */) != NULL + && mVideoDecoder != NULL) ? "have" : "no"); + + if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL + // NOTE: mVideoDecoder's mSurface is always non-null + || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) { performSetSurface(surface); break; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 99a2a84..dcc28c4 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -87,6 +87,22 @@ sp<AMessage> NuPlayer::Decoder::getStats() const { return mStats; } +status_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) { + if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) { + return BAD_VALUE; + } + + sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this); + + msg->setObject("surface", surface); + sp<AMessage> response; + status_t err = msg->postAndAwaitResponse(&response); + if (err == OK && response != NULL) { + CHECK(response->findInt32("err", &err)); + } + return err; +} + void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); @@ -169,6 +185,46 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatSetVideoSurface: + { + sp<AReplyToken> replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + + sp<RefBase> obj; + CHECK(msg->findObject("surface", &obj)); + sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null + int32_t err = INVALID_OPERATION; + // NOTE: in practice mSurface is always non-null, but checking here for completeness + if (mCodec != NULL && mSurface != NULL) { + // TODO: once AwesomePlayer is removed, remove this automatic connecting + // to the surface by MediaPlayerService. + // + // at this point MediaPlayerService::client has already connected to the + // surface, which MediaCodec does not expect + err = native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA); + if (err == OK) { + err = mCodec->setSurface(surface); + ALOGI_IF(err, "codec setSurface returned: %d", err); + if (err == OK) { + // reconnect to the old surface as MPS::Client will expect to + // be able to disconnect from it. + (void)native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); + mSurface = surface; + } + } + if (err != OK) { + // reconnect to the new surface on error as MPS::Client will expect to + // be able to disconnect from it. + (void)native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA); + } + } + + sp<AMessage> response = new AMessage; + response->setInt32("err", err); + response->postReply(replyID); + break; + } + default: DecoderBase::onMessageReceived(msg); break; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index ceccb7a..ed0be62 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -32,6 +32,9 @@ struct NuPlayer::Decoder : public DecoderBase { virtual sp<AMessage> getStats() const; + // sets the output surface of video decoders. + virtual status_t setVideoSurface(const sp<Surface> &surface); + protected: virtual ~Decoder(); @@ -50,6 +53,7 @@ private: enum { kWhatCodecNotify = 'cdcN', kWhatRenderBuffer = 'rndr', + kWhatSetVideoSurface = 'sSur' }; sp<Surface> mSurface; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h index 8f030f0..b0dc01d 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h @@ -27,6 +27,7 @@ namespace android { struct ABuffer; struct MediaCodec; class MediaBuffer; +class Surface; struct NuPlayer::DecoderBase : public AHandler { DecoderBase(const sp<AMessage> ¬ify); @@ -36,6 +37,7 @@ struct NuPlayer::DecoderBase : public AHandler { void setParameters(const sp<AMessage> ¶ms); void setRenderer(const sp<Renderer> &renderer); + virtual status_t setVideoSurface(const sp<Surface> &) { return INVALID_OPERATION; } status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const; void signalFlush(); |