Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57a339cd authored by Andreas Huber's avatar Andreas Huber
Browse files

setVideoSurfaceTexture is now synchronous and applied dynamically

while playing.

Change-Id: If9f08659a01bdc7dac0999730368e9dfa5e58d36
related-to-bug: 5666482
parent ece53e01
Loading
Loading
Loading
Loading
+67 −10
Original line number Diff line number Diff line
@@ -74,6 +74,21 @@ private:
    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
};

struct NuPlayer::SetSurfaceAction : public Action {
    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
        : mWrapper(wrapper) {
    }

    virtual void execute(NuPlayer *player) {
        player->performSetSurface(mWrapper);
    }

private:
    sp<NativeWindowWrapper> mWrapper;

    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
};

// Use this if there's no state necessary to save in order to execute
// the action.
struct NuPlayer::SimpleAction : public Action {
@@ -111,7 +126,8 @@ NuPlayer::NuPlayer()
      mVideoLateByUs(0ll),
      mNumFramesTotal(0ll),
      mNumFramesDropped(0ll),
      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW) {
      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
      mStarted(false) {
}

NuPlayer::~NuPlayer() {
@@ -181,11 +197,19 @@ void NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
    msg->post();
}

void NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
void NuPlayer::setVideoSurfaceTextureAsync(
        const sp<ISurfaceTexture> &surfaceTexture) {
    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
    sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
                new SurfaceTextureClient(surfaceTexture) : NULL);
    msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient));

    if (surfaceTexture == NULL) {
        msg->setObject("native-window", NULL);
    } else {
        msg->setObject(
                "native-window",
                new NativeWindowWrapper(
                    new SurfaceTextureClient(surfaceTexture)));
    }

    msg->post();
}

@@ -278,13 +302,24 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
        {
            ALOGV("kWhatSetVideoNativeWindow");

            mDeferredActions.push_back(
                    new SimpleAction(&NuPlayer::performDecoderShutdown));

            sp<RefBase> obj;
            CHECK(msg->findObject("native-window", &obj));

            mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
            mDeferredActions.push_back(
                    new SetSurfaceAction(
                        static_cast<NativeWindowWrapper *>(obj.get())));

            // XXX - ignore error from setVideoScalingMode for now
            setVideoScalingMode(mVideoScalingMode);
            if (obj != NULL) {
                // If there is a new surface texture, instantiate decoders
                // again if possible.
                mDeferredActions.push_back(
                        new SimpleAction(&NuPlayer::performScanSources));
            }

            processDeferredActions();
            break;
        }

@@ -311,6 +346,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
            mVideoLateByUs = 0;
            mNumFramesTotal = 0;
            mNumFramesDropped = 0;
            mStarted = true;

            mSource->start();

@@ -986,8 +1022,7 @@ sp<AMessage> NuPlayer::Source::getFormat(bool audio) {

status_t NuPlayer::setVideoScalingMode(int32_t mode) {
    mVideoScalingMode = mode;
    if (mNativeWindow != NULL
            && mNativeWindow->getNativeWindow() != NULL) {
    if (mNativeWindow != NULL) {
        status_t ret = native_window_set_scaling_mode(
                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
        if (ret != OK) {
@@ -1122,14 +1157,36 @@ void NuPlayer::performReset() {
            driver->notifyResetComplete();
        }
    }

    mStarted = false;
}

void NuPlayer::performScanSources() {
    ALOGV("performScanSources");

    if (!mStarted) {
        return;
    }

    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
        postScanSources();
    }
}

void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
    ALOGV("performSetSurface");

    mNativeWindow = wrapper;

    // XXX - ignore error from setVideoScalingMode for now
    setVideoScalingMode(mVideoScalingMode);

    if (mDriver != NULL) {
        sp<NuPlayerDriver> driver = mDriver.promote();
        if (driver != NULL) {
            driver->notifySetSurfaceComplete();
        }
    }
}

}  // namespace android
+7 −1
Original line number Diff line number Diff line
@@ -42,7 +42,9 @@ struct NuPlayer : public AHandler {

    void setDataSource(int fd, int64_t offset, int64_t length);

    void setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
    void setVideoSurfaceTextureAsync(
            const sp<ISurfaceTexture> &surfaceTexture);

    void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink);
    void start();

@@ -75,6 +77,7 @@ private:
    struct StreamingSource;
    struct Action;
    struct SeekAction;
    struct SetSurfaceAction;
    struct SimpleAction;

    enum {
@@ -140,6 +143,8 @@ private:

    int32_t mVideoScalingMode;

    bool mStarted;

    status_t instantiateDecoder(bool audio, sp<Decoder> *decoder);

    status_t feedDecoderInputData(bool audio, const sp<AMessage> &msg);
@@ -165,6 +170,7 @@ private:
    void performDecoderShutdown();
    void performReset();
    void performScanSources();
    void performSetSurface(const sp<NativeWindowWrapper> &wrapper);

    DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
};
+21 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ namespace android {

NuPlayerDriver::NuPlayerDriver()
    : mResetInProgress(false),
      mSetSurfaceInProgress(false),
      mDurationUs(-1),
      mPositionUs(-1),
      mNumFramesTotal(0),
@@ -97,7 +98,19 @@ status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {

status_t NuPlayerDriver::setVideoSurfaceTexture(
        const sp<ISurfaceTexture> &surfaceTexture) {
    mPlayer->setVideoSurfaceTexture(surfaceTexture);
    Mutex::Autolock autoLock(mLock);

    if (mResetInProgress) {
        return INVALID_OPERATION;
    }

    mSetSurfaceInProgress = true;

    mPlayer->setVideoSurfaceTextureAsync(surfaceTexture);

    while (mSetSurfaceInProgress) {
        mCondition.wait(mLock);
    }

    return OK;
}
@@ -308,6 +321,13 @@ void NuPlayerDriver::notifyResetComplete() {
    mCondition.broadcast();
}

void NuPlayerDriver::notifySetSurfaceComplete() {
    Mutex::Autolock autoLock(mLock);
    CHECK(mSetSurfaceInProgress);
    mSetSurfaceInProgress = false;
    mCondition.broadcast();
}

void NuPlayerDriver::notifyDuration(int64_t durationUs) {
    Mutex::Autolock autoLock(mLock);
    mDurationUs = durationUs;
+2 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ struct NuPlayerDriver : public MediaPlayerInterface {
    virtual status_t dump(int fd, const Vector<String16> &args) const;

    void notifyResetComplete();
    void notifySetSurfaceComplete();
    void notifyDuration(int64_t durationUs);
    void notifyPosition(int64_t positionUs);
    void notifySeekComplete();
@@ -78,6 +79,7 @@ private:
    // The following are protected through "mLock"
    // >>>
    bool mResetInProgress;
    bool mSetSurfaceInProgress;
    int64_t mDurationUs;
    int64_t mPositionUs;
    int64_t mNumFramesTotal;