android camera 预览 数据流,Android Camera HAL3中预览preview模式下的数据流

Android Camera HAL3中预览preview模式下的数据流

前沿:

为了更好的梳理preview下buffer数据流的操作过程,前一文中对surface下的buffer相关的操作架构进行了描述。本文主要以此为基础,重点分析再Camera2Client和Camera3Device下是如何维护并读写这些视频帧缓存的。

1. Camera3Device::convertMetadataListToRequestListLocked函数

结合上一博文中关于preview的控制流,定位到数据流主要的操作主要是对preview模式下将CameraMetadata mPreviewRequest转换为CaptureRequest的过程之中,回顾到mPreviewRequest是主要包含了当前preview下所需要Camera3Device来操作的OutputStream的index值。

2. Camera3Device::configureStreamsLocked函数

在configureStreamsLocked的函数中,主要关注的是Camera3Device对当前所具有的所有的mInputStreams和mOutputStreams进行Config的操作,分别包括startConfiguration/finishConfiguration两个状态。

2.1 mOutputStreams.editValueAt(i)->startConfiguration()

这里的遍历所有输出stream即最终调用的函数入口为Camera3Stream::startConfiguration(),这里需要先看下Camera3OutputStream的整个结构,出现了Camera3Stream和Camera3IOStreamBase,两者是Input和Output stream所共有的,前者提供的更多的是对buffer的config、get/retrun buffer的操作,后者以维护当前的stream所拥有的buffer数目。另一个支路camera3_stream_t是一个和Camera HAL3底层进行stream信息交互的入口。

87917343_1

startConfiguration函数首先是判断当前stream的状态,对于已经config的不作处理,config的主要操作是getEndpointUsage:

status_t Camera3OutputStream::getEndpointUsage(uint32_t *usage) { status_t res; int32_t u = 0; res = mConsumer->query(mConsumer.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &u); *usage = u; return res;}这里的mConsumer其实就是之前创建的Surface的本体,每一个Stream在建立时createStream,都会传入一个ANativeWIndow类似的Consumer绑定到当前的stream中去。这里主要是完成当前window所管理的buffer的USAGE值,可参看grallo.h中的定义,由Gralloc模块负责指定当前buffer操作是由HW还是SW来完成以及不同的应用场合,在Gralloc模块中不同模块需求的buffer亦会有不同的分配、定义与处理方式:

/* buffer will be used as an OpenGL ES texture */ GRALLOC_USAGE_HW_TEXTURE = 0x00000100, /* buffer will be used as an OpenGL ES render target */ GRALLOC_USAGE_HW_RENDER = 0x00000200, /* buffer will be used by the 2D hardware blitter */ GRALLOC_USAGE_HW_2D = 0x00000400, /* buffer will be used by the HWComposer HAL module */ GRALLOC_USAGE_HW_COMPOSER = 0x00000800, /* buffer will be used with the framebuffer device */ GRALLOC_USAGE_HW_FB = 0x00001000, /* buffer will be used with the HW video encoder */ GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000, /* buffer will be written by the HW camera pipeline */ GRALLOC_USAGE_HW_CAMERA_WRITE = 0x00020000, /* buffer will be read by the HW camera pipeline */ GRALLOC_USAGE_HW_CAMERA_READ = 0x00040000, /* buffer will be used as part of zero-shutter-lag queue */ GRALLOC_USAGE_HW_CAMERA_ZSL = 0x00060000, /* mask for the camera access values */ GRALLOC_USAGE_HW_CAMERA_MASK = 0x00060000, /* mask for the software usage bit-mask */ GRALLOC_USAGE_HW_MASK = 0x00071F00,

2.2 mHal3Device->ops->configure_streams(mHal3Device, &config);

config是一个camera3_stream_configuration数据结构,他记录了一次和HAL3交互的stream的数量,已经当前每一个stream的属性配置相关的信息camer3_stream_t,包括stream中每一个buffer的属性值,stream的类型值等等,提交这些信息供hal3去分析处理。在高通平台中你可以看到,对于每一个stream在HAL3平台下均以一个Channel的形式存在。

typedef struct camera3_stream_configuration { uint32_t num_streams; camera3_stream_t **streams;} camera3_stream_configuration_t;

87917343_2

stream_type包括:CAMERA3_STREAM_OUTPUT、CAMERA3_STREAM_INPUT、CAMERA3_STREAM_BIDIRECTIONAL。

format主要是指当前buffer支持的像素点存储格式,以HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED居多,表明数据格式是由Gralloc模块来决定的。

对于HAL3中对configureStreams接口的实现会放在后续介绍高通平台的实现机制时再做分析。

2.3 Camera3Stream::finishConfiguration

该函数主要执行configureQueueLocked和registerBuffersLocked两个函数

status_t Camera3OutputStream::configureQueueLocked() { status_t res; mTraceFirstBuffer = true; if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) { return res; } ALOG_ASSERT(mConsumer != 0, mConsumer should never be NULL); // Configure consumer-side ANativeWindow interface res = native_window_api_connect(mConsumer.get(), NATIVE_WINDOW_API_CAMERA); if (res != OK) { ALOGE(%s: Unable to connect to native window for stream %d, __FUNCTION__, mId); return res; } res = native_window_set_usage(mConsumer.get(), camera3_stream::usage); if (res != OK) { ALOGE(%s: Unable to configure usage %08x for stream %d, __FUNCTION__, camera3_stream::usage, mId); return res; } res = native_window_set_scaling_mode(mConsumer.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); if (res != OK) { ALOGE(%s: Unable to configure stream scaling: %s (%d), __FUNCTION__, strerror(-res), res); return res; } if (mMaxSize == 0) { // For buffers of known size res = native_window_set_buffers_dimensions(mConsumer.get(), camera3_stream::width, camera3_stream::height); } else { // For buffers with bounded size res = native_window_set_buffers_dimensions(mConsumer.get(), mMaxSize, 1); } if (res != OK) { ALOGE(%s: Unable to configure stream buffer dimensions %d x %d (maxSize %zu) for stream %d, __FUNCTIO

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
# NDK Camera [![Build Status](https://travis-ci.org/luncliff/NdkCamera.svg?branch=master)](https://travis-ci.org/luncliff/NdkCamera) > If there is an issue with this library, please mail to [email protected] Simplified [Android Camera 2 API](https://www.youtube.com/watch?v=Bi4QjMfSOE0). Available for both Java/JNI. - API level: 24+ - NDK ### Reference - Personal Template Project: https://github.com/luncliff/Muffin - [API Reference](https://developer.android.com/ndk/reference/group/camera) - [Android Camera Overview](https://source.android.com/devices/camera) - Camera HAL3: https://source.android.com/devices/camera/camera3 - HAL Subsystem: https://source.android.com/devices/camera/camera3_requests_hal - Multi-Camera Support: https://source.android.com/devices/camera/multi-camera - Version Support: https://source.android.com/devices/camera/versioning - Android Media - https://source.android.com/devices/media/framework-hardening ## How to ### Build For **Windows** environment, latest [Android Studio](https://developer.android.com/studio/) is recommended. For **Linux/MacOS**, [Gradle 4.10.2](https://gradle.org/) will be enough. ```console $ git clone https://github.com/luncliff/NdkCamera $ cd ./NdkCamera $ gradle assemble # Build: libndk_camera.so & NdkCamera.aar ``` ### Test Connect your device and run the test with Gradle. Please reference the [test codes](./android/test/ndcam/). ```console $ gradle connectedAndroidTest # Run test ``` ### Use The following code shows working with `SurfaceView` class. ```java package dev.example; // ... import dev.ndcam.*; // Expect we already have a camera permission public class SurfaceDisplay implements SurfaceHolder.Callback { SurfaceView surfaceView; Surface surface; ndcam.Device camera; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... // Load/Init library ndcam.CameraModel.Init(); surfaceView = findViewById(R.id.surfaceView); SurfaceHolder holder = surfaceView.getHolder(); holder.setFixedSize(1920, 1080); holder.setFormat(ImageFormat.YUV_420_888); holder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { // Get all devices in array form for(ndcam.Device device : ndcam.CameraModel.GetDevices()) if(device.facing() == CameraCharacteristics.LENS_FACING_BACK) camera = device; } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { // Make a repeating caputre request with surface surface = surfaceHolder.getSurface(); camera.repeat(surface); } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { // No more capture if(camera != null) camera.stopRepeat(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值