设为首页 加入收藏

TOP

Android Camera HAL3中预览preview模式下的数据流(七)
2016-01-29 16:31:55 】 浏览:6692
Tags:Android Camera HAL3 预览 preview 模式 数据流
ue操作

上述步骤2主要是将每一个Stream下全部的buffer信息全部register到下层的HAL3中,为后续对buffer的数据流读写操作奠定基础。

那么preview模式下我们又是如何去获得一帧完成的视频流的呢?

触发点就是preview模式下的Request,前面提到过一个mPreviewRequest至少包含一个StreamProcessor和一个CallbackProcessor的两路stream,每路stream拥有不同的buffer数量。比如要从HAL3获取一帧图像数据,最简单的思路就是从StreamProcessor下的Outputstream流中下发一个可用的buffer地址,然后HAL3填充下数据,Framework就可以拥有一帧数据了。

根据这个思路,回顾到前一博文中每次会不断的下发一个Request命令包到HAL3中,在这里我们就可以看到这个buffer地址身影。

Camera3Device::RequestThread::threadLoop() 下的部分代码:

    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
            nextRequest->mOutputStreams.size());//Streamprocess,Callbackprocessor
    request.output_buffers = outputBuffers.array();//camera3_stream_buffer_t
    for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
        res = nextRequest->mOutputStreams.editItemAt(i)->
                getBuffer(&outputBuffers.editItemAt(i));//等待获取buffer,内部是dequeue一根buffer填充到camera3_stream_buffer_t
        if (res != OK) {
            // Can't get output buffer from gralloc queue - this could be due to
            // abandoned queue or other consumer misbehavior, so not a fatal
            // error
            ALOGE(RequestThread: Can't get output buffer, skipping request:
                     %s (%d), strerror(-res), res);
            Mutex::Autolock l(mRequestLock);
            if (mListener != NULL) {
                mListener->notifyError(
                        ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
                        nextRequest->mResultExtras);
            }
            cleanUpFailedRequest(request, nextRequest, outputBuffers);
            return true;
        }
        request.num_output_buffers++;//一般一根OutStream对应一个buffer,故总的out_buffer数目
    }
在这个下发到HAL3的camera3_capture_request中,可以看到 const camera3_stream_buffer_t *output_buffers,下面的代码可以说明这一次的Request的output_buffers是打包了当前Camera3Device所拥有的mOutputStreams。

    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
            nextRequest->mOutputStreams.size());//Streamprocess,Callbackprocessor
对于每一个OutputStream他会给她分配一个buffer handle。关注下面的处理代码:

nextRequest->mOutputStreams.editItemAt(i)->
                getBuffer(&outputBuffers.editItemAt(i))
nextRequest->mOutputStreams.editItemAt(i)是获取一个Camera3OutputStream对象,然后对getBuffer而言传入的是这个Camera3OutputStream所对应的这次buffer的输入位置,这个camera3_stream_buffer是需要从Camera3OutputStream对象中去获取的。

status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) {
    ATRACE_CALL();
    Mutex::Autolock l(mLock);
    status_t res = OK;

    // This function should be only called when the stream is configured already.
    if (mState != STATE_CONFIGURED) {
        ALOGE(%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d,
                __FUNCTION__, mId, mState);
        return INVALID_OPERATION;
    }

    // Wait for new buffer returned back if we are running into the limit.
    if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) {//dequeue过多时等待queue的释放
        ALOGV(%s: Already dequeued max output buffers (%d), wait for next returned one.,
                __FUNCTION__, camera3_stream::max_buffers);
        res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
        if (res != OK) {
            if (res == TIMED_OUT) {
                ALOGE(%s: wait for output buffer return timed out after %lldms, __FUNCTION__,
                        kWaitForBufferDuration / 1000000LL);
            }
            return res;
        }
    }

    res = getBufferLocked(buffer);
    if (res == OK) {
        fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
    }

    return res;
}
上述的代码先是检查dequeue了的buffe
首页 上一页 4 5 6 7 8 下一页 尾页 7/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇LeetCode -- Edit Distance 下一篇LeetCode 10 Regular Expression ..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目