Camera API2在不开启录像的情况下实现HFR功能的学习总结

1. SnapDragonCamera 开启HFR功能时流配置信息查看

通过抓取log,获取了如下log:

06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:855 configure_streams() Number of streams: 2
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:871 configure_streams()   stream[0] = 0xe5fad694 - info:
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:874 configure_streams()             format       : 34, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:876 configure_streams()             width        : 640
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:878 configure_streams()             height       : 480
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:881 configure_streams()             stream_type  : 00000000, CAMERA3_STREAM_OUTPUT
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:883 configure_streams()             usage        : 00000900
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:885 configure_streams()             max_buffers  : 0
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:888 configure_streams()             rotation     : 00000000, CAMERA3_STREAM_ROTATION_0
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:891 configure_streams()             data_space   : 00000000, HAL_DATASPACE_UNKNOWN
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:893 configure_streams()             priv         : 0x0
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:871 configure_streams()   stream[1] = 0xe5fad6f4 - info:
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:874 configure_streams()             format       : 34, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:876 configure_streams()             width        : 640
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:878 configure_streams()             height       : 480
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:881 configure_streams()             stream_type  : 00000000, CAMERA3_STREAM_OUTPUT
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:883 configure_streams()             usage        : 00010000
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:885 configure_streams()             max_buffers  : 0
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:888 configure_streams()             rotation     : 00000000, CAMERA3_STREAM_ROTATION_0
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:891 configure_streams()             data_space   : 00000103, HAL_DATASPACE_BT601_525
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:893 configure_streams()             priv         : 0x0
06-22 12:33:54.059   586  1032 I CamX    : [ INFO][HAL    ] camxhal3.cpp:901 configure_streams()   operation_mode: 1

stream[0]为预览流
预览流usage为: GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER
stream[1]为录像流
录像流usage为:GRALLOC_USAGE_HW_VIDEO_ENCODER

2、HFR配置流时,surface的准备

2.1 预览流surface中准备

//参考代码见frameworks\av\media\libstagefright\omx\GraphicBufferSource.cpp
void configPreviewSurface()
{
    ALOGD("%s,%d E .", __FUNCTION__,__LINE__);
    // Setup a buffer queue
    BufferQueue::createBufferQueue(&mspGbProducer, &mspGbConsumer);

    mPreviewSurface = new Surface(mspGbProducer);

    String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d",
            m_iWidth, m_iHeight, m_iFormat, MAX_BUFFER_NUM, getpid());
    mspGbConsumer->setConsumerName(consumerName);
    // Set default size and format
    mspGbConsumer->setDefaultBufferSize(640, 480);
    mspGbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_YCbCr_420_888);
   uint32_t consumerUsage;
   consumerUsage |= GRALLOC_USAGE_HW_TEXTURE|GRALLOC_USAGE_HW_COMPOSER;
   mspGbConsumer->setConsumerUsageBits(consumerUsage);
   int32_t dataSpace= 0;
   ALOGD("setting dataspace: %#x, acquired=%d", dataSpace, mNumOutstandingAcquires);
   mspGbConsumer->setDefaultBufferDataSpace((android_dataspace)dataSpace);
   
    wp<BufferQueue::ConsumerListener> listener =
            static_cast<BufferQueue::ConsumerListener*>(this);
    sp<IConsumerListener> proxy =
            new BufferQueue::ProxyConsumerListener(listener);
    mInitCheck = mspGbConsumer->consumerConnect(proxy, false);
    ALOGD("%s,%d X .", __FUNCTION__,__LINE__);
}

2.2 录像流surface中准备

//参考代码见frameworks\av\media\libstagefright\omx\GraphicBufferSource.cpp
void configVideoSurface()
{
    ALOGD("%s,%d E .", __FUNCTION__,__LINE__);
    // Setup a buffer queue
    BufferQueue::createBufferQueue(&mspGbProducer, &mspGbConsumer);
    mVideoSurface = new Surface(mspGbProducer);
    String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d",
            m_iWidth, m_iHeight, m_iFormat, MAX_BUFFER_NUM, getpid());
    mspGbConsumer->setConsumerName(consumerName);
    // Set default size and format
    mspGbConsumer->setDefaultBufferSize(640, 480);
    mspGbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_YCbCr_420_888);
   uint32_t consumerUsage;
   consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
   mspGbConsumer->setConsumerUsageBits(consumerUsage);
   int32_t dataSpace= HAL_DATASPACE_BT601_525;
   ALOGD("setting dataspace: %#x, acquired=%d", dataSpace, mNumOutstandingAcquires);
   mspGbConsumer->setDefaultBufferDataSpace((android_dataspace)dataSpace);
    wp<BufferQueue::ConsumerListener> listener =
            static_cast<BufferQueue::ConsumerListener*>(this);
    sp<IConsumerListener> proxy =
            new BufferQueue::ProxyConsumerListener(listener);
    mInitCheck = mspGbConsumer->consumerConnect(proxy, false);
    ALOGD("%s,%d X .", __FUNCTION__,__LINE__);
}

3. 配置ConstrainedHighSpeed Stream

int configureDevice()
{
    binder::Status res;
    setupPreviewSurface();
#ifdef ENABLE_FEATURE_HFR
        setupVideoSurface();
#endif
    ALOGD("waitUntilIdle E");
    res = mspDevice->waitUntilIdle();
    ALOGD("waitUntilIdle X");
    res = mspDevice->beginConfigure();
    ALOGD("create preview Stream E");
    OutputConfiguration previewOutPut(mspGbProducer, /*rotation*/ 0);
    res = mspDevice->createStream(previewOutPut, &mPreviewStreamId);
    ALOGD("create preview Stream mPreviewStreamId = %d X",mPreviewStreamId);
#ifdef ENABLE_FEATURE_HFR
        ALOGD("create video Stream E");
        OutputConfiguration videoOutPut = OutputConfiguration(mspVideoGbpProducer,  /*rotation*/ 0);
        res = mspDevice->createStream(videoOutPut, &mVideoStreamId);
        ALOGD("create video Stream  mCaptureStreamId = %d X",mVideoStreamId);
#endif
    ALOGD("endConfigure E .");
#ifdef ENABLE_FEATURE_HFR
    res = mspDevice->endConfigure(/*isConstrainedHighSpeed*/true);
#else
    res = mspDevice->endConfigure(/*isConstrainedHighSpeed*/false);
#endif
    ALOGD("endConfigure X .");
    return 0;
}

4. HFR预览和录像数据申请

配置完成高速流,就可以申请预览和录像数据,
HFR 预览流的帧率和录像流的帧率是成倍关系,倍数被称为batchSize,其相关信息是在HAL层做的定义:

//vendor\qcom\proprietary\camx\src\hwl\titan17x/camxtitan17xcontext.cpp
CamxResult Titan17xContext::GetStaticCaps(
    PlatformStaticCaps* pCaps)
{
    CamxResult          result        = CamxResultSuccess;
    CSLCameraPlatform   CSLPlatform   = {};
    UINT32              size          = 0;
    UINT32              numIPEs       = 2;
    UINT32              HFRPreviewFPS = 30;
    // Initialize platform specific static capabilities
    ...
    CAMX_LOG_INFO(CamxLogGroupHWL, "HFR Preview FPS %d", HFRPreviewFPS);
    // Availiable HFR configurations
    pCaps->numDefaultHFRVideoSizes = NumSupportedHFRVideoSizes;
    for (UINT8 i = 0; i < pCaps->numDefaultHFRVideoSizes; i++)
    {
        pCaps->defaultHFRVideoSizes[i].width        = SupportedHFRVideoSizes[i].width;
        pCaps->defaultHFRVideoSizes[i].height       = SupportedHFRVideoSizes[i].height;
        pCaps->defaultHFRVideoSizes[i].minFPS       = SupportedHFRVideoSizes[i].minFPS;
        pCaps->defaultHFRVideoSizes[i].maxFPS       = SupportedHFRVideoSizes[i].maxFPS;
        pCaps->defaultHFRVideoSizes[i].batchSizeMax = SupportedHFRVideoSizes[i].maxFPS / HFRPreviewFPS;
    }
    ...
    return result;
}

通过上边的信息可以得出的结论是:
HFR(high frame rate:高帧率)高的其实是录像流的帧率,对预览流的帧率并没啥影响。

为实现录像流是预览流的batchSize倍数,cameraAPI2 的实现方案是:
通过调用submitRequestList(每次同时提交多个request申请。代码如下:

    camera2::CaptureRequest singleTargetRequest;//recoding
    singleTargetRequest.mMetadata = mRequestTemplate;
    //request.mSurfaceList.add(mspSurface);
    singleTargetRequest.mSurfaceList.add(videoSurface);
    singleTargetRequest.mIsReprocess = false;
    camera2::CaptureRequest doubleTargetRequest;//recording+preview
    doubleTargetRequest.mMetadata = mRequestTemplate;
    doubleTargetRequest.mSurfaceList.add(mspSurface);
    doubleTargetRequest.mSurfaceList.add(videoSurface);
    doubleTargetRequest.mIsReprocess = false;
    //我做的Demo中preview为30fps,videorecording为120fps,batchsize是4,
    //就是一次submitRequestList需要提交4个request,
    //一个preview+recording,三个recording
    const ::std::vector< ::android::hardware::camera2::CaptureRequest>requestList{
                    doubleTargetRequestBuilder/*first Request must be doubleTargetRequest*/,
                    singleTargetRequestBuilder,singleTargetRequestBuilder,singleTargetRequestBuilder};
    camera2::utils::SubmitInfo info;
    res = mspDevice->submitRequestList(requestList, /*streaming*/ true, /*out*/ &info);

至此HFR学习总结完成

你可能感兴趣的:(Android,camera)