MediaPlayer2: use ANativeWindow to replace Surface and IGraphicBufferProducer

Test: MediaPlayer2 plays video files
Bug: 63934228
Change-Id: Id655aa19125cfc5554dbf36c223d0a27318ebb24
gugelfrei
Wei Jia 7 years ago
parent 8074715204
commit 28288fb0b1

@ -246,6 +246,7 @@ cc_library_shared {
"IStreamSource.cpp",
"MediaUtils.cpp",
"Metadata.cpp",
"NdkWrapper.cpp",
],
shared_libs: [
@ -254,6 +255,8 @@ cc_library_shared {
"libgui",
"liblog",
"libmediaextractor",
"libmediandk",
"libnativewindow",
"libstagefright_foundation",
"libui",
"libutils",
@ -261,6 +264,7 @@ cc_library_shared {
export_shared_lib_headers: [
"libbinder",
"libmediandk",
],
header_libs: [
@ -328,6 +332,7 @@ cc_library_shared {
"libmediandk",
"libmediautils",
"libmemunreachable",
"libnativewindow",
"libpowermanager",
"libstagefright_httplive",
"libstagefright_player2",

@ -38,7 +38,6 @@
#include <binder/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>
#include <gui/Surface.h>
#include <utils/Errors.h> // for status_t
#include <utils/String8.h>
#include <utils/SystemClock.h>
@ -52,6 +51,8 @@
#include <media/Metadata.h>
#include <media/AudioTrack.h>
#include <media/MemoryLeakTrackUtil.h>
#include <media/NdkWrapper.h>
#include <media/stagefright/InterfaceUtils.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaErrors.h>
@ -737,9 +738,9 @@ status_t MediaPlayer2Manager::Client::setDataSource(
}
void MediaPlayer2Manager::Client::disconnectNativeWindow_l() {
if (mConnectedWindow != NULL) {
if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) {
status_t err = nativeWindowDisconnect(
mConnectedWindow.get(), "disconnectNativeWindow");
mConnectedWindow->getANativeWindow(), "disconnectNativeWindow");
if (err != OK) {
ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
@ -750,21 +751,20 @@ void MediaPlayer2Manager::Client::disconnectNativeWindow_l() {
}
status_t MediaPlayer2Manager::Client::setVideoSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer)
const sp<ANativeWindowWrapper>& nww)
{
ALOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, bufferProducer.get());
ALOGV("[%d] setVideoSurfaceTexture(%p)",
mConnId,
(nww == NULL ? NULL : nww->getANativeWindow()));
sp<MediaPlayer2Base> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
sp<IBinder> binder(IInterface::asBinder(bufferProducer));
if (mConnectedWindowBinder == binder) {
return OK;
}
sp<ANativeWindow> anw;
if (bufferProducer != NULL) {
anw = new Surface(bufferProducer, true /* controlledByApp */);
status_t err = nativeWindowConnect(anw.get(), "setVideoSurfaceTexture");
if (nww != NULL && nww->getANativeWindow() != NULL) {
if (mConnectedWindow != NULL
&& mConnectedWindow->getANativeWindow() == nww->getANativeWindow()) {
return OK;
}
status_t err = nativeWindowConnect(nww->getANativeWindow(), "setVideoSurfaceTexture");
if (err != OK) {
ALOGE("setVideoSurfaceTexture failed: %d", err);
@ -783,19 +783,18 @@ status_t MediaPlayer2Manager::Client::setVideoSurfaceTexture(
// Note that we must set the player's new GraphicBufferProducer before
// disconnecting the old one. Otherwise queue/dequeue calls could be made
// on the disconnected ANW, which may result in errors.
status_t err = p->setVideoSurfaceTexture(bufferProducer);
status_t err = p->setVideoSurfaceTexture(nww);
mLock.lock();
disconnectNativeWindow_l();
if (err == OK) {
mConnectedWindow = anw;
mConnectedWindowBinder = binder;
mConnectedWindow = nww;
mLock.unlock();
} else {
} else if (nww != NULL) {
mLock.unlock();
status_t err = nativeWindowDisconnect(
anw.get(), "disconnectNativeWindow");
nww->getANativeWindow(), "disconnectNativeWindow");
if (err != OK) {
ALOGW("nativeWindowDisconnect returned an error: %s (%d)",

@ -35,6 +35,7 @@
namespace android {
struct ANativeWindowWrapper;
struct AudioPlaybackRate;
class AudioTrack;
struct AVSyncSettings;
@ -244,7 +245,7 @@ private:
// MediaPlayer2Engine interface
virtual void disconnect();
virtual status_t setVideoSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer);
const sp<ANativeWindowWrapper>& nww) override;
virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
virtual status_t getBufferingSettings(
BufferingSettings* buffering /* nonnull */) override;
@ -286,7 +287,7 @@ private:
const sp<media::VolumeShaper::Operation>& operation) override;
virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;
sp<MediaPlayer2Base> createPlayer(player2_type playerType);
sp<MediaPlayer2Base> createPlayer(player2_type playerType);
virtual status_t setDataSource(
const sp<MediaHTTPService> &httpService,
@ -299,7 +300,7 @@ private:
virtual status_t setDataSource(const sp<IDataSource> &source);
sp<MediaPlayer2Base> setDataSource_pre(player2_type playerType);
sp<MediaPlayer2Base> setDataSource_pre(player2_type playerType);
status_t setDataSource_post(const sp<MediaPlayer2Base>& p,
status_t status);
@ -375,8 +376,7 @@ private:
audio_session_t mAudioSessionId;
audio_attributes_t * mAudioAttributes;
uid_t mUid;
sp<ANativeWindow> mConnectedWindow;
sp<IBinder> mConnectedWindowBinder;
sp<ANativeWindowWrapper> mConnectedWindow;
struct sockaddr_in mRetransmitEndpoint;
bool mRetransmitEndpointValid;
sp<Client> mNextClient;

@ -17,9 +17,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "NdkWrapper"
#include "NdkWrapper.h"
#include <media/NdkWrapper.h>
#include <gui/Surface.h>
#include <android/native_window.h>
#include <log/log.h>
#include <media/NdkMediaCodec.h>
#include <media/NdkMediaCrypto.h>
@ -473,6 +473,31 @@ void AMediaFormatWrapper::setBuffer(const char* name, void* data, size_t size) {
}
//////////// ANativeWindowWrapper
ANativeWindowWrapper::ANativeWindowWrapper(ANativeWindow *aNativeWindow)
: mANativeWindow(aNativeWindow) {
if (aNativeWindow != NULL) {
ANativeWindow_acquire(aNativeWindow);
}
}
ANativeWindowWrapper::~ANativeWindowWrapper() {
release();
}
status_t ANativeWindowWrapper::release() {
if (mANativeWindow != NULL) {
ANativeWindow_release(mANativeWindow);
mANativeWindow = NULL;
}
return OK;
}
ANativeWindow *ANativeWindowWrapper::getANativeWindow() const {
return mANativeWindow;
}
//////////// AMediaDrmWrapper
AMediaDrmWrapper::AMediaDrmWrapper(const uint8_t uuid[16]) {
mAMediaDrm = AMediaDrm_createByUUID(uuid);
@ -838,7 +863,7 @@ status_t AMediaCodecWrapper::getName(AString *outComponentName) const {
status_t AMediaCodecWrapper::configure(
const sp<AMediaFormatWrapper> &format,
const sp<Surface> &surface,
const sp<ANativeWindowWrapper> &nww,
const sp<AMediaCryptoWrapper> &crypto,
uint32_t flags) {
if (mAMediaCodec == NULL) {
@ -848,7 +873,7 @@ status_t AMediaCodecWrapper::configure(
media_status_t err = AMediaCodec_configure(
mAMediaCodec,
format->getAMediaFormat(),
surface.get(),
(nww == NULL ? NULL : nww->getANativeWindow()),
crypto == NULL ? NULL : crypto->getAMediaCrypto(),
flags);
@ -969,12 +994,13 @@ status_t AMediaCodecWrapper::releaseOutputBuffer(size_t idx, bool render) {
AMediaCodec_releaseOutputBuffer(mAMediaCodec, idx, render));
}
status_t AMediaCodecWrapper::setOutputSurface(const sp<Surface> &surface) {
status_t AMediaCodecWrapper::setOutputSurface(const sp<ANativeWindowWrapper> &nww) {
if (mAMediaCodec == NULL) {
return DEAD_OBJECT;
}
return translateErrorCode(
AMediaCodec_setOutputSurface(mAMediaCodec, surface.get()));
AMediaCodec_setOutputSurface(mAMediaCodec,
(nww == NULL ? NULL : nww->getANativeWindow())));
}
status_t AMediaCodecWrapper::releaseOutputBufferAtTime(size_t idx, int64_t timestampNs) {

@ -78,7 +78,7 @@ class TestPlayerStub : public MediaPlayer2Interface {
// All the methods below wrap the mPlayer instance.
virtual status_t setVideoSurfaceTexture(
const android::sp<android::IGraphicBufferProducer>& st) {
const android::sp<android::ANativeWindowWrapper>& st) {
return mPlayer->setVideoSurfaceTexture(st);
}
virtual status_t prepare() {return mPlayer->prepare();}

@ -31,11 +31,10 @@ struct sockaddr_in;
namespace android {
struct ANativeWindowWrapper;
class Parcel;
class Surface;
class IDataSource;
struct IStreamSource;
class IGraphicBufferProducer;
struct MediaHTTPService;
struct AudioPlaybackRate;
struct AVSyncSettings;
@ -56,8 +55,7 @@ public:
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
virtual status_t setDataSource(const sp<IStreamSource>& source) = 0;
virtual status_t setDataSource(const sp<IDataSource>& source) = 0;
virtual status_t setVideoSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer) = 0;
virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) = 0;
virtual status_t getBufferingSettings(
BufferingSettings* buffering /* nonnull */) = 0;
virtual status_t setBufferingSettings(const BufferingSettings& buffering) = 0;

@ -43,8 +43,7 @@ namespace android {
class DataSource;
struct MediaHTTPService;
class Parcel;
class Surface;
class IGraphicBufferProducer;
struct ANativeWindowWrapper;
template<typename T> class SortedVector;
@ -183,9 +182,8 @@ public:
return INVALID_OPERATION;
}
// pass the buffered IGraphicBufferProducer to the media player service
virtual status_t setVideoSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer) = 0;
// pass the buffered native window to the media player service
virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) = 0;
virtual status_t getBufferingSettings(
BufferingSettings* buffering /* nonnull */) {

@ -33,13 +33,13 @@ struct AMediaCrypto;
struct AMediaDrm;
struct AMediaFormat;
struct AMediaExtractor;
struct ANativeWindow;
struct PsshInfo;
namespace android {
struct AMessage;
class MetaData;
class Surface;
struct AMediaFormatWrapper : public RefBase {
static sp<AMediaFormatWrapper> Create(const sp<AMessage> &message);
@ -84,6 +84,23 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(AMediaFormatWrapper);
};
struct ANativeWindowWrapper : public RefBase {
ANativeWindowWrapper(ANativeWindow *aNativeWindow);
// the returned ANativeWindow is still owned by this wrapper.
ANativeWindow *getANativeWindow() const;
status_t release();
protected:
virtual ~ANativeWindowWrapper();
private:
ANativeWindow *mANativeWindow;
DISALLOW_EVIL_CONSTRUCTORS(ANativeWindowWrapper);
};
struct AMediaDrmWrapper : public RefBase {
AMediaDrmWrapper(const uint8_t uuid[16]);
AMediaDrmWrapper(AMediaDrm *aMediaDrm);
@ -205,7 +222,7 @@ struct AMediaCodecWrapper : public RefBase {
status_t configure(
const sp<AMediaFormatWrapper> &format,
const sp<Surface> &surface,
const sp<ANativeWindowWrapper> &nww,
const sp<AMediaCryptoWrapper> &crypto,
uint32_t flags);
@ -239,7 +256,7 @@ struct AMediaCodecWrapper : public RefBase {
status_t releaseOutputBuffer(size_t idx, bool render);
status_t setOutputSurface(const sp<Surface> &surface);
status_t setOutputSurface(const sp<ANativeWindowWrapper> &nww);
status_t releaseOutputBufferAtTime(size_t idx, int64_t timestampNs);

@ -31,13 +31,10 @@
#include <utils/String8.h>
#include <utils/ThreadDefs.h>
struct ANativeWindow;
namespace android {
struct AVSyncSettings;
class IGraphicBufferProducer;
class Surface;
struct ANativeWindowWrapper;
enum media2_event_type {
MEDIA2_NOP = 0, // interface test message
@ -212,8 +209,7 @@ public:
status_t setDataSource(int fd, int64_t offset, int64_t length);
status_t setDataSource(const sp<IDataSource> &source);
status_t setVideoSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer);
status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww);
status_t setListener(const sp<MediaPlayer2Listener>& listener);
status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */);
status_t setBufferingSettings(const BufferingSettings& buffering);

@ -29,14 +29,13 @@
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <gui/Surface.h>
#include <media/mediaplayer2.h>
#include <media/AudioResamplerPublic.h>
#include <media/AudioSystem.h>
#include <media/AVSyncSettings.h>
#include <media/IDataSource.h>
#include <media/MediaAnalyticsItem.h>
#include <media/NdkWrapper.h>
#include <binder/MemoryBase.h>
@ -231,13 +230,12 @@ status_t MediaPlayer2::getMetadata(bool update_only, bool apply_filter, Parcel *
return mPlayer->getMetadata(update_only, apply_filter, metadata);
}
status_t MediaPlayer2::setVideoSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer)
status_t MediaPlayer2::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww)
{
ALOGV("setVideoSurfaceTexture");
Mutex::Autolock _l(mLock);
if (mPlayer == 0) return NO_INIT;
return mPlayer->setVideoSurfaceTexture(bufferProducer);
return mPlayer->setVideoSurfaceTexture(nww);
}
status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */)

@ -4,7 +4,6 @@ cc_library_static {
"JWakeLock.cpp",
"GenericSource.cpp",
"HTTPLiveSource.cpp",
"NdkWrapper.cpp",
"NuPlayer2.cpp",
"NuPlayer2CCDecoder.cpp",
"NuPlayer2Decoder.cpp",
@ -23,6 +22,7 @@ cc_library_static {
],
include_dirs: [
"frameworks/av/media/libmedia/include",
"frameworks/av/media/libstagefright",
"frameworks/av/media/libstagefright/httplive",
"frameworks/av/media/libstagefright/include",

@ -18,7 +18,6 @@
#define LOG_TAG "GenericSource"
#include "GenericSource.h"
#include "NdkWrapper.h"
#include "NuPlayer2Drm.h"
#include "AnotherPacketSource.h"
@ -29,6 +28,7 @@
#include <media/MediaHTTPService.h>
#include <media/MediaExtractor.h>
#include <media/MediaSource.h>
#include <media/NdkWrapper.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>

@ -24,7 +24,6 @@
#include "NuPlayer2.h"
#include "HTTPLiveSource.h"
#include "NdkWrapper.h"
#include "NuPlayer2CCDecoder.h"
#include "NuPlayer2Decoder.h"
#include "NuPlayer2DecoderBase.h"
@ -45,6 +44,7 @@
#include <media/AudioResamplerPublic.h>
#include <media/AVSyncSettings.h>
#include <media/MediaCodecBuffer.h>
#include <media/NdkWrapper.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ABuffer.h>
@ -57,13 +57,11 @@
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/Surface.h>
#include "ESDS.h"
#include <media/stagefright/Utils.h>
#include <system/window.h>
namespace android {
static status_t sendMetaDataToHal(sp<MediaPlayer2Base::AudioSink>& sink,
@ -143,16 +141,16 @@ private:
};
struct NuPlayer2::SetSurfaceAction : public Action {
explicit SetSurfaceAction(const sp<Surface> &surface)
: mSurface(surface) {
explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
: mNativeWindow(nww) {
}
virtual void execute(NuPlayer2 *player) {
player->performSetSurface(mSurface);
player->performSetSurface(mNativeWindow);
}
private:
sp<Surface> mSurface;
sp<ANativeWindowWrapper> mNativeWindow;
DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
};
@ -407,14 +405,13 @@ void NuPlayer2::prepareAsync() {
(new AMessage(kWhatPrepare, this))->post();
}
void NuPlayer2::setVideoSurfaceTextureAsync(
const sp<IGraphicBufferProducer> &bufferProducer) {
void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
if (bufferProducer == NULL) {
if (nww == NULL || nww->getANativeWindow() == NULL) {
msg->setObject("surface", NULL);
} else {
msg->setObject("surface", new Surface(bufferProducer, true /* controlledByApp */));
msg->setObject("surface", nww);
}
msg->post();
@ -792,10 +789,10 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
sp<RefBase> obj;
CHECK(msg->findObject("surface", &obj));
sp<Surface> surface = static_cast<Surface *>(obj.get());
sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
ALOGD("onSetVideoSurface(%p, %s video decoder)",
surface.get(),
(nww == NULL ? NULL : nww->getANativeWindow()),
(mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
&& mVideoDecoder != NULL) ? "have" : "no");
@ -803,9 +800,9 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
// be in preparing state and it could take long time.
// When mStarted is true, mSource must have been set.
if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
// NOTE: mVideoDecoder's mSurface is always non-null
|| (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) {
performSetSurface(surface);
// NOTE: mVideoDecoder's mNativeWindow is always non-null
|| (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
performSetSurface(nww);
break;
}
@ -814,7 +811,7 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
(obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
FLUSH_CMD_SHUTDOWN /* video */));
mDeferredActions.push_back(new SetSurfaceAction(surface));
mDeferredActions.push_back(new SetSurfaceAction(nww));
if (obj != NULL) {
if (mStarted) {
@ -1033,7 +1030,7 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
// initialize video before audio because successful initialization of
// video may change deep buffer mode of audio.
if (mSurface != NULL) {
if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
rescan = true;
}
@ -1219,7 +1216,8 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
if (mSource != nullptr) {
if (audio) {
if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
|| mSurface == NULL || mVideoDecoder == NULL) {
|| mNativeWindow == NULL || mNativeWindow->getANativeWindow() == NULL
|| mVideoDecoder == NULL) {
// When both audio and video have error, or this stream has only audio
// which has error, notify client of error.
notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
@ -1505,7 +1503,7 @@ status_t NuPlayer2::onInstantiateSecureDecoders() {
// TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
// data on instantiation.
if (mSurface != NULL) {
if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
err = instantiateDecoder(false, &mVideoDecoder);
if (err != OK) {
return err;
@ -1934,7 +1932,7 @@ status_t NuPlayer2::instantiateDecoder(
notify->setInt32("generation", mVideoDecoderGeneration);
*decoder = new Decoder(
notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder);
notify, mSource, mPID, mUID, mRenderer, mNativeWindow, mCCDecoder);
mVideoDecoderError = false;
// enable FRC if high-quality AV sync is requested, even if not
@ -2141,8 +2139,9 @@ void NuPlayer2::queueDecoderShutdown(
status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
mVideoScalingMode = mode;
if (mSurface != NULL) {
status_t ret = native_window_set_scaling_mode(mSurface.get(), mVideoScalingMode);
if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
status_t ret = native_window_set_scaling_mode(
mNativeWindow->getANativeWindow(), mVideoScalingMode);
if (ret != OK) {
ALOGE("Failed to set scaling mode (%d): %s",
-ret, strerror(-ret));
@ -2375,10 +2374,10 @@ void NuPlayer2::performScanSources() {
}
}
void NuPlayer2::performSetSurface(const sp<Surface> &surface) {
void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
ALOGV("performSetSurface");
mSurface = surface;
mNativeWindow = nww;
// XXX - ignore error from setVideoScalingMode for now
setVideoScalingMode(mVideoScalingMode);

@ -27,6 +27,7 @@ namespace android {
struct ABuffer;
struct AMediaCryptoWrapper;
struct AMessage;
struct ANativeWindowWrapper;
struct AudioPlaybackRate;
struct AVSyncSettings;
class IDataSource;
@ -58,8 +59,7 @@ struct NuPlayer2 : public AHandler {
void prepareAsync();
void setVideoSurfaceTextureAsync(
const sp<IGraphicBufferProducer> &bufferProducer);
void setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww);
void setAudioSink(const sp<MediaPlayer2Base::AudioSink> &sink);
status_t setPlaybackSettings(const AudioPlaybackRate &rate);
@ -167,7 +167,7 @@ private:
Mutex mSourceLock; // guard |mSource|.
sp<Source> mSource;
uint32_t mSourceFlags;
sp<Surface> mSurface;
sp<ANativeWindowWrapper> mNativeWindow;
sp<MediaPlayer2Base::AudioSink> mAudioSink;
sp<DecoderBase> mVideoDecoder;
bool mOffloadAudio;
@ -320,7 +320,7 @@ private:
void performDecoderFlush(FlushCommand audio, FlushCommand video);
void performReset();
void performScanSources();
void performSetSurface(const sp<Surface> &wrapper);
void performSetSurface(const sp<ANativeWindowWrapper> &nw);
void performResumeDecoders(bool needNotify);
void onSourceNotify(const sp<AMessage> &msg);

@ -21,7 +21,6 @@
#include <algorithm>
#include "NdkWrapper.h"
#include "NuPlayer2CCDecoder.h"
#include "NuPlayer2Decoder.h"
#include "NuPlayer2Drm.h"
@ -31,6 +30,7 @@
#include <cutils/properties.h>
#include <media/MediaCodecBuffer.h>
#include <media/NdkMediaCodec.h>
#include <media/NdkWrapper.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@ -39,7 +39,6 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/SurfaceUtils.h>
#include <gui/Surface.h>
#include "ATSParser.h"
@ -61,10 +60,10 @@ NuPlayer2::Decoder::Decoder(
pid_t pid,
uid_t uid,
const sp<Renderer> &renderer,
const sp<Surface> &surface,
const sp<ANativeWindowWrapper> &nww,
const sp<CCDecoder> &ccDecoder)
: DecoderBase(notify),
mSurface(surface),
mNativeWindow(nww),
mSource(source),
mRenderer(renderer),
mCCDecoder(ccDecoder),
@ -109,14 +108,15 @@ sp<AMessage> NuPlayer2::Decoder::getStats() const {
return mStats;
}
status_t NuPlayer2::Decoder::setVideoSurface(const sp<Surface> &surface) {
if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) {
status_t NuPlayer2::Decoder::setVideoSurface(const sp<ANativeWindowWrapper> &nww) {
if (nww == NULL || nww->getANativeWindow() == NULL
|| ADebug::isExperimentEnabled("legacy-setsurface")) {
return BAD_VALUE;
}
sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
msg->setObject("surface", surface);
msg->setObject("surface", nww);
sp<AMessage> response;
status_t err = msg->postAndAwaitResponse(&response);
if (err == OK && response != NULL) {
@ -226,30 +226,37 @@ void NuPlayer2::Decoder::onMessageReceived(const sp<AMessage> &msg) {
sp<RefBase> obj;
CHECK(msg->findObject("surface", &obj));
sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null
sp<ANativeWindowWrapper> nww =
static_cast<ANativeWindowWrapper *>(obj.get()); // non-null
if (nww == NULL || nww->getANativeWindow() == NULL) {
break;
}
int32_t err = INVALID_OPERATION;
// NOTE: in practice mSurface is always non-null, but checking here for completeness
if (mCodec != NULL && mSurface != NULL) {
// NOTE: in practice mNativeWindow is always non-null,
// but checking here for completeness
if (mCodec != NULL
&& mNativeWindow != NULL && mNativeWindow->getANativeWindow() != 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
// at this point MediaPlayer2Manager::client has already connected to the
// surface, which MediaCodec does not expect
err = nativeWindowDisconnect(surface.get(), "kWhatSetVideoSurface(surface)");
err = nativeWindowDisconnect(nww->getANativeWindow(), "kWhatSetVideoSurface(nww)");
if (err == OK) {
err = mCodec->setOutputSurface(surface);
err = mCodec->setOutputSurface(nww);
ALOGI_IF(err, "codec setOutputSurface returned: %d", err);
if (err == OK) {
// reconnect to the old surface as MPS::Client will expect to
// be able to disconnect from it.
(void)nativeWindowConnect(mSurface.get(), "kWhatSetVideoSurface(mSurface)");
mSurface = surface;
(void)nativeWindowConnect(mNativeWindow->getANativeWindow(),
"kWhatSetVideoSurface(mNativeWindow)");
mNativeWindow = nww;
}
}
if (err != OK) {
// reconnect to the new surface on error as MPS::Client will expect to
// be able to disconnect from it.
(void)nativeWindowConnect(surface.get(), "kWhatSetVideoSurface(err)");
(void)nativeWindowConnect(nww->getANativeWindow(), "kWhatSetVideoSurface(err)");
}
}
@ -289,7 +296,8 @@ void NuPlayer2::Decoder::onConfigure(const sp<AMessage> &format) {
mComponentName = mime;
mComponentName.append(" decoder");
ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
ALOGV("[%s] onConfigure (nww=%p)", mComponentName.c_str(),
(mNativeWindow == NULL ? NULL : mNativeWindow->getANativeWindow()));
mCodec = AMediaCodecWrapper::CreateDecoderByType(mime);
int32_t secure = 0;
@ -316,9 +324,9 @@ void NuPlayer2::Decoder::onConfigure(const sp<AMessage> &format) {
mCodec->getName(&mComponentName);
status_t err;
if (mSurface != NULL) {
if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
// disconnect from surface as MediaCodec will reconnect
err = nativeWindowDisconnect(mSurface.get(), "onConfigure");
err = nativeWindowDisconnect(mNativeWindow->getANativeWindow(), "onConfigure");
// We treat this as a warning, as this is a preparatory step.
// Codec will try to connect to the surface, which is where
// any error signaling will occur.
@ -337,7 +345,7 @@ void NuPlayer2::Decoder::onConfigure(const sp<AMessage> &format) {
err = mCodec->configure(
AMediaFormatWrapper::Create(format),
mSurface,
mNativeWindow,
crypto,
0 /* flags */);
@ -530,9 +538,9 @@ void NuPlayer2::Decoder::onShutdown(bool notifyComplete) {
mCodec = NULL;
++mBufferGeneration;
if (mSurface != NULL) {
if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
// reconnect to surface as MediaCodec disconnected from it
status_t error = nativeWindowConnect(mSurface.get(), "onShutdown");
status_t error = nativeWindowConnect(mNativeWindow->getANativeWindow(), "onShutdown");
ALOGW_IF(error != NO_ERROR,
"[%s] failed to connect to native window, error=%d",
mComponentName.c_str(), error);

@ -34,13 +34,13 @@ struct NuPlayer2::Decoder : public DecoderBase {
pid_t pid,
uid_t uid,
const sp<Renderer> &renderer = NULL,
const sp<Surface> &surface = NULL,
const sp<ANativeWindowWrapper> &nww = NULL,
const sp<CCDecoder> &ccDecoder = NULL);
virtual sp<AMessage> getStats() const;
// sets the output surface of video decoders.
virtual status_t setVideoSurface(const sp<Surface> &surface);
virtual status_t setVideoSurface(const sp<ANativeWindowWrapper> &nww);
virtual status_t releaseCrypto();
@ -70,7 +70,7 @@ private:
kMaxNumVideoTemporalLayers = 32,
};
sp<Surface> mSurface;
sp<ANativeWindowWrapper> mNativeWindow;
sp<Source> mSource;
sp<Renderer> mRenderer;

@ -25,10 +25,10 @@
namespace android {
struct ABuffer;
struct ANativeWindowWrapper;
struct MediaCodec;
class MediaBuffer;
class MediaCodecBuffer;
class Surface;
struct NuPlayer2::DecoderBase : public AHandler {
explicit DecoderBase(const sp<AMessage> &notify);
@ -41,7 +41,7 @@ struct NuPlayer2::DecoderBase : public AHandler {
void pause();
void setRenderer(const sp<Renderer> &renderer);
virtual status_t setVideoSurface(const sp<Surface> &) { return INVALID_OPERATION; }
virtual status_t setVideoSurface(const sp<ANativeWindowWrapper> &) { return INVALID_OPERATION; }
void signalFlush();
void signalResume(bool notifyComplete);

@ -219,8 +219,7 @@ status_t NuPlayer2Driver::setDataSource(const sp<DataSource> &source) {
return mAsyncResult;
}
status_t NuPlayer2Driver::setVideoSurfaceTexture(
const sp<IGraphicBufferProducer> &bufferProducer) {
status_t NuPlayer2Driver::setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww) {
ALOGV("setVideoSurfaceTexture(%p)", this);
Mutex::Autolock autoLock(mLock);
@ -239,7 +238,7 @@ status_t NuPlayer2Driver::setVideoSurfaceTexture(
mSetSurfaceInProgress = true;
mPlayer->setVideoSurfaceTextureAsync(bufferProducer);
mPlayer->setVideoSurfaceTextureAsync(nww);
while (mSetSurfaceInProgress) {
mCondition.wait(mLock);

@ -43,8 +43,7 @@ struct NuPlayer2Driver : public MediaPlayer2Interface {
virtual status_t setDataSource(const sp<DataSource>& dataSource);
virtual status_t setVideoSurfaceTexture(
const sp<IGraphicBufferProducer> &bufferProducer);
virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww);
virtual status_t getBufferingSettings(
BufferingSettings* buffering /* nonnull */) override;

@ -19,7 +19,7 @@
#include "NuPlayer2Drm.h"
#include "NdkWrapper.h"
#include <media/NdkWrapper.h>
#include <utils/Log.h>

Loading…
Cancel
Save