6. Android MultiMedia框架完全解析 - NuPlayerDriver与NuPlayer的通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yanbixing123/article/details/88927268

先解决NuPlayer与NuPlayerDriver的通信过程,在之前的文章中,都说了NuPlayerDriver是NuPlayer的一个Wrapper,上层的指令发送给NuPlayerDriver后,NuPlayer作为NuPlayerDriver的一个成员变量,NuPlayerDriver想调用NuPlayer的话,就相当简单。当NuPlayer完成一个指令后,如何通知NuPlayerDriver呢?下面我们就以setVideoSurfaceTexture为例来讲解一下(虽然这个函数的历程还没有追过,但是不影响这里的讨论):

当上层调用setVideoSurfaceTexture()时,根据之前的分析,最终会传递到NuPlayerDriver这里,来看看NuPlayerDriver是如何实现的:

status_t NuPlayerDriver::setVideoSurfaceTexture(
        const sp<IGraphicBufferProducer> &bufferProducer) {
......

    mPlayer->setVideoSurfaceTextureAsync(bufferProducer);

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

    return OK;
}

在这里,sp<NuPlayer> mPlayer作为NuPlayerDriver中的一个成员变量,在NuPlayerDriver的构造函数中,就已经为他赋值,就是NuPlayer,所以,通过mPlayer->setVideoSurfaceTextureAsync(bufferProducer);这个命令,就可以跳转到NuPlayer中去执行它的setVideoSurfaceTextureAsync()函数,同时,NuPlayerDriver中会通过一个条件变量 mCondition 去等待这个函数的执行完毕。

我们再到NuPlayer中看看setVideoSurfaceTextureAsync这个函数:

void NuPlayer::setVideoSurfaceTextureAsync(
        const sp<IGraphicBufferProducer> &bufferProducer) {
    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);

    if (bufferProducer == NULL) {
        msg->setObject("surface", NULL);
    } else {
        msg->setObject("surface", new Surface(bufferProducer, true /* controlledByApp */));
    }

    msg->post();
}

它使用了AHanlder-ALooper-AMessage机制(NuPlayer中使用的一种机制,在7.中讲解),最终就会执行到NuPlayer::onMessageReceived函数的kWhatSetVideoSurface case中:

void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
case kWhatSetVideoSurface:
        {
......

if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) {
                performSetSurface(surface);
                break;
            }

看看这个performSetSurface函数的过程:

void NuPlayer::performSetSurface(const sp<Surface> &surface) {
    ALOGV("performSetSurface");

    mSurface = surface;

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

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

看到这里,应该就有点概念了,NuPlayer以mPlayer这个成员变量存在于NuPlayerDriver结构体中,同样的,NuPlayerDriver以 wp<NuPlayerDriver> mDriver; 的形式存在于NuPlayer中,它也是在NuPlayer的构造函数中赋值的。通过mDriver.promote()的方法就可以使弱指针升级成强指针sp<NuPlayerDriver> driver,这时候这个driver就是NuPlayerDriver了,下面的driver->notifySetSurfaceComplete()函数就是在NuPlayerDriver中实现的了:

void NuPlayerDriver::notifySetSurfaceComplete() {
    ALOGV("notifySetSurfaceComplete(%p)", this);
    Mutex::Autolock autoLock(mLock);

    CHECK(mSetSurfaceInProgress);
    mSetSurfaceInProgress = false;

    mCondition.broadcast();
}

通过发送广播,来通知NuPlayerDriver::setVideoSurfaceTexture()函数,NuPlayer执行完SetVideoSurfaceTexture了。

猜你喜欢

转载自blog.csdn.net/yanbixing123/article/details/88927268