Camera3BufferManager onBufferReleased

Camera3BufferManager::onBufferReleased

了解了这几个Map之间的关系,也不难理解如下逻辑。这里需要特别注意所有的操作都是用的友元方法,会直接更新到本体类。

加入知识星球与更多Camera同学交流
– 星球名称:深入浅出Android Camera
– 星球ID: 17296815

status_t Camera3BufferManager::onBufferReleased(int streamId, int streamSetId) {
    Mutex::Autolock l(mLock);
    // Camera3BufferManager会在收到这个回调时候,统计当前的stream的handout的buffer count。此处也是释放。
        StreamSet& streamSet = mStreamSetMap.editValueFor(streamSetId);
        BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
        size_t& bufferCount = handOutBufferCounts.editValueFor(streamId);
        bufferCount--;
        /*  
         * 此处只是handout的buffer count减一,注意此处的attachedbuffer count并没有减一.
         * 这就是这两者的不同,attached buffer count包含”handout”给client的,
         * 也包含client release回来的.        
         * */
    return OK;
}

那么什么时候会调用onBufferReleased呢?

第一步,在configureQueueLocked中添加release时候的listener。即mBufferReleasedListener描述的Camera3OutputStream::BufferReleasedListener类。这个类含有onBufferReleaseed函数。

status_t Camera3OutputStream::configureQueueLocked() {
    res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/mBufferReleasedListener);//注册一个release时候consuemr可以调用Camera3OutputStream的回调函数.
}

那个listener去哪儿了?

  • Connect中有记录listener的部分
status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
        int api/*4*/, bool producerControlledByApp, QueueBufferOutput *output) {

    Mutex::Autolock lock(mCore->mMutex);
    mConsumerName = mCore->mConsumerName;

    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
            mDequeueTimeout < 0 ?
            mCore->mConsumerControlledByApp && producerControlledByApp : false,
            mCore->mMaxBufferCount) -
            mCore->getMaxBufferCountLocked();
    switch (api) {
        case NATIVE_WINDOW_API_EGL:
        case NATIVE_WINDOW_API_CPU:
        case NATIVE_WINDOW_API_MEDIA:
        case NATIVE_WINDOW_API_CAMERA:
            mCore->mConnectedApi = api;
            output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
                    mCore->mTransformHint,
                    static_cast<uint32_t>(mCore->mQueue.size()),
                    mCore->mFrameCounter + 1);

            // Set up a death notification so that we can disconnect
            // automatically if the remote producer dies
            if (listener != NULL &&
                    IInterface::asBinder(listener)->remoteBinder() != NULL) {
                status = IInterface::asBinder(listener)->linkToDeath(
                        static_cast<IBinder::DeathRecipient*>(this));
            }
            //把Camera3OutputStream类的mBufferReleasedListener结构的listener暂存起来
            mCore->mConnectedProducerListener = listener;
            break;
        default:

    }
    mCore->mConnectedPid = IPCThreadState::self()->getCallingPid();
    mCore->mBufferHasBeenQueued = false;
    mCore->mDequeueBufferCannotBlock = false;
}
  • 那listener我直到它被保存起来了,可是什么时候使用listener呢?
    • 在comsumer使用完buffer需要release时,从mActiveBuffers中取出来一个slot,放到mFreeBuffers中,并调用listener的onReleaseBuffer函数。

BufferQueue's Slots arch

status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
        const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
        EGLSyncKHR eglFence) {

    sp<IProducerListener> listener;
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);

        // 如果在release前时候,buf又被重新alloc了,那忽略这次release行为。
        // 特别对于shared类型的buf,高概率在release过程中出现的queue和acquire请求。这时候忽略这次的release行为。
        if (frameNumber != mSlots[slot].mFrameNumber &&
                !mSlots[slot].mBufferState.isShared()) {
            return STALE_BUFFER_SLOT;
        }

        mSlots[slot].mEglDisplay = eglDisplay;
        mSlots[slot].mEglFence = eglFence;
        mSlots[slot].mFence = releaseFence;
        mSlots[slot].mBufferState.release();

        // After leaving shared buffer mode, the shared buffer will
        // still be around. Mark it as no longer shared if this
        // operation causes it to be free.
        if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
            mSlots[slot].mBufferState.mShared = false;
        }
        // Don't put the shared buffer on the free list.
        if (!mSlots[slot].mBufferState.isShared()) {
            mCore->mActiveBuffers.erase(slot);
            mCore->mFreeBuffers.push_back(slot); // 把待释放的buf放到freeBuffers中
        }
    // 此时正好取出暂存的回调函数.
        listener = mCore->mConnectedProducerListener;//取出connect时候准备的Listener
        mCore->mDequeueCondition.broadcast();

    } // Autolock scope
    //  调用回调.
    if (listener != NULL) {
        listener->onBufferReleased();// 执行Camera3BufferManage的onBufferReleased
    }

    return NO_ERROR;
}
  • 说了半天的那个神秘的listener是什么?
    • Listener是Camera3OutputStream::BufferReleasedListener 类,Camera3OutputStream::BufferReleasedListener类是Camera3OutputStream类的子类,而Camera3OutputStream::BufferReleasedListener类的成员函数onReleaseBuffer 即为在release时候调用的回调函数。
void Camera3OutputStream::BufferReleasedListener::onBufferReleased() {
    sp<Camera3OutputStream> stream = mParent.promote();
    Mutex::Autolock l(stream->mLock);
   status_t res = stream->mBufferManager->onBufferReleased(
        stream->getId(), stream->getStreamSetId());
  }

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程