通过抓取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
//参考代码见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__);
}
//参考代码见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__);
}
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;
}
配置完成高速流,就可以申请预览和录像数据,
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学习总结完成