summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2015-07-10 19:17:45 -0700
committerLajos Molnar <lajos@google.com>2015-07-13 16:33:59 -0700
commita81c6229638a4db56752dd77a6610e0f0971e877 (patch)
treeb43408970894d5a5979ed0087ab1ee213144ac7c /media
parent4b33e0838fdb1b5e545449add02005916b512c99 (diff)
downloadframeworks_av-a81c6229638a4db56752dd77a6610e0f0971e877.zip
frameworks_av-a81c6229638a4db56752dd77a6610e0f0971e877.tar.gz
frameworks_av-a81c6229638a4db56752dd77a6610e0f0971e877.tar.bz2
nuplayer: use codec->setSurface when possible to avoid seeking
Bug: 22414719 Change-Id: I0442e12af960f86a0fc090b4a469c62ba638a1a0
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/nuplayer/Android.mk3
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp11
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp56
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h4
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h2
-rw-r--r--media/libstagefright/MediaCodec.cpp1
6 files changed, 74 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> &notify);
@@ -36,6 +37,7 @@ struct NuPlayer::DecoderBase : public AHandler {
void setParameters(const sp<AMessage> &params);
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();
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 69f44ed..fb32d3a 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2528,6 +2528,7 @@ status_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
if (err == BAD_VALUE) {
ALOGI("native window already connected. Assuming no change of surface");
+ return err;
} else if (err == OK) {
// Require a fresh set of buffers after each connect by using a unique generation
// number. Rely on the fact that max supported process id by Linux is 2^22.