android8,面试时答不出来怎么机智应答

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
img

正文

static status_t shutdown() { return NO_ERROR; }

private:

static void joinThreadPool() {

sp ps(ProcessState::self());

ps->startThreadPool();

ps->giveThreadPoolName();

IPCThreadState::self()->joinThreadPool();

}

};

}; // namespa

从这个文件可以看出,instantiate最终还是调用到了IServiceManager里的addService, 将我们的cameraService注册到了系统的服务管理器里去了.**

这里调用到CameraService后, 因为是开机第一次调用,它的引用计数为1,所以会调用到CameraService::onFirstRef()这个函数. 这个函数是从CameraService的父类RefBase里继承过来的.该函数在强引用sp新增引用计数时调用,什么意思?就是当 有sp包装的类初始化的时候调用.我们再看看cameraService::onFirstRef()

**frameworks\av\services\camera\libcameraservice\CameraService.cpp

void CameraService::onFirstRef()

{

ALOGI(“CameraService process starting”);

BnCameraService::onFirstRef();

// Update battery life tracking if service is restarting

BatteryNotifier& notifier(BatteryNotifier::getInstance());

notifier.noteResetCamera();

notifier.noteResetFlashlight();

status_t res = INVALID_OPERATION;

res = enumerateProviders();

if (res == OK) {

mInitialized = true;

}

CameraService::pingCameraServiceProxy();

}

在这个函数里,我们只关注enumerateProviders(),这里就到了列出所有cameraProvider.**

查找并列出所有的cameraProvider

**status_t CameraService::enumerateProviders() {

status_t res;

Mutex::Autolock l(mServiceLock);

if (nullptr == mCameraProviderManager.get()) {

mCameraProviderManager = new CameraProviderManager();

res = mCameraProviderManager->initialize(this);

}

}

这个函数里,创建了一个CameraProviderManager对象,并调进行了初始化.**

**frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp

status_t CameraProviderManager::initialize(wpCameraProviderManager::StatusListener listener,

ServiceInteractionProxy* proxy) {

std::lock_guardstd::mutex lock(mInterfaceMutex);

if (proxy == nullptr) {

ALOGE(“%s: No valid service interaction proxy provided”, __FUNCTION__);

return BAD_VALUE;

}

mListener = listener;

mServiceProxy = proxy;

// Registering will trigger notifications for all already-known providers

bool success = mServiceProxy->registerForNotifications(

/* instance name, empty means no filter */ “”,

this);

if (!success) {

ALOGE("%s: Unable to register with hardware service manager for notifications "

“about camera providers”, __FUNCTION__);

return INVALID_OPERATION;

}

// See if there’s a passthrough HAL, but let’s not complain if there’s not

addProviderLocked(kLegacyProviderName, /*expected*/ false);

return OK;

}

在这个初始化函数里,我们只关注addProviderLocked, 我们可以看到,这个函数传进了一个kLegacyProviderName, 它的值定义在这个文件的上面:**

const std::string kLegacyProviderName(“legacy/0”);

大家注意到了没有,它的值和我们之前hardware\interfaces\camera\provider\2.4\default\service.cpp里注册服务时return defaultPassthroughServiceImplementation(“legacy/0”, /*maxThreads*/ 6); 以及manifest.xml里legacy/0的值都是一致的. 如果这个值不致,则会调用不成功.

好了,再回到addProviderLocked这个函数来, 这个函数的作用, 就是去加载camera对应的hal层代码, 并将它的信息保存在ProviderInfo里,后面我们就可以通过这个ProviderInfo, 去实行addDevice、getCameraInfo等操作。

**status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {

for (const auto& providerInfo : mProviders) {

if (providerInfo->mProviderName == newProvider) {

ALOGW(“%s: Camera provider HAL with name ‘%s’ already registered”, __FUNCTION__,

newProvider.c_str());

return ALREADY_EXISTS;

}

}

spprovider::V2\_4::ICameraProvider interface;

interface = mServiceProxy->getService(newProvider);

if (interface == nullptr) {

if (expected) {

ALOGE(“%s: Camera provider HAL ‘%s’ is not actually available”, __FUNCTION__,

newProvider.c_str());

return BAD_VALUE;

} else {

return OK;

}

}

sp providerInfo =

new ProviderInfo(newProvider, interface, this);

status_t res = providerInfo->initialize();

if (res != OK) {

return res;

}

mProviders.push_back(providerInfo);

return OK;

}

这里先检查一下,传进来的newProvider是不是已经添加过,如果已经添加了,就不再处理,直接返回。如果没添加过,就会进行下一步的操作。这里的interface = mServiceProxy->getService(newProvider);,会调用到hardware\interfaces\camera\provider\2.4\default\CameraProvider.cpp的HIDL_FETCH_ICameraProvider函数。**

**ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {

if (strcmp(name, kLegacyProviderName) != 0) {

return nullptr;

}

CameraProvider* provider = new CameraProvider();

if (provider == nullptr) {

ALOGE(“%s: cannot allocate camera provider!”, __FUNCTION__);

return nullptr;

}

if (provider->isInitFailed()) {

ALOGE(“%s: camera provider init failed!”, __FUNCTION__);

delete provider;

return nullptr;

}

return provider;

}

在这个函数里,会创建一个CameraProvider对象。**

**CameraProvider::CameraProvider() :

camera_module_callbacks_t({sCameraDeviceStatusChange,

sTorchModeStatusChange}) {

mInitFailed = initialize();

}

bool CameraProvider::initialize() {

camera_module_t *rawModule;

int err = hw_get_module(“camera”, (const hw_module_t **)&rawModule);

if (err < 0) {

ALOGE(“Could not load camera HAL module: %d (%s)”, err, strerror(-err));

return true;

}

mModule = new CameraModule(rawModule);

err = mModule->init();

}

在这个初始化函数中,会看到一个我们非常熟悉的函数hw_get_module。到这里,就跟我们android8.0之前的流程一模一样的了,都是去直接和hal层打交道了。**

在CameraProvider里有一个地方值得大家注意

**std::string cameraId, int deviceVersion) {

// Maybe consider create a version check method and SortedVec to speed up?

if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&

deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&

deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&

deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {

return hidl_string(“”);

}

bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;

int versionMajor = isV1 ? 1 : 3;

int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;

char deviceName[kMaxCameraDeviceNameLen];

snprintf(deviceName, sizeof(deviceName), “device@%d.%d/legacy/%s”,

versionMajor, versionMinor, cameraId.c_str());

return deviceName;

}

从这里看来,如果我们的camera使用了hidl和hal打交道的话,我们hal里的版本号,必须是1.0或者是大于3.2的,如果我们的hal层的的版本号为3.0或3.1的话,是不能正确的加载成功的。**

上面用到的图片,引用了https://blog.csdn.net/qq_16775897/article/details/81240600这个博客的,大家也可以去这篇博客看看。启动流程都是一致的,这博主也讲得比较详细。

好了,上面就将android8.0上camera hal层代码的加载流程基本讲完了。有了上面的基础,下面我们再来一步步的讲下,怎么去新增一个camera hal。

###############################################################################################################################################################################################################################################################################################################

移植一个camera hal,需要做的有以下几点:

1.)在device\mediatek\mt6580\manifest.xml里新增要增加的camera的instance

2.)在frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp里,将要添加的camera provider给addProviderLocked进来

3.)在hardware\interfaces\camera\provider\2.4\default\CameraProvider.cpp里将要增加的camera,通过hw_get_module这样给load进来。

4.)准备好对应的camera hal代码

配置manifest.xml

**

android.hardware.camera.provider

hwbinder

2.4

ICameraProvider

internal/0

legacy/1

 

因为mtkcamera已经有了一个camera hal1,名字为internal/0, 所以我们的usbcamera对应的名字跟在它的后面即可。注意,“legacy/1”这个名字的前面“legacy”这串,可以随便取,比如可以叫”abc/1",只要其他用到的地方都叫这个名字就可以。但是这个后面的“1”,不能弄错。前面已经为0了,这个就必须为1,同理,如果还有一个摄像头,就要为2了。因为在CameraProviderManager.cpp里的ProviderInfo::parseDeviceName,是通过后面这个数字,来取对应的id值的。如果我们将这个usbcamera的id也写为0,即名字为“legacy/0”,那么在ProviderInfo::parseDeviceName这里取出来的id,就会和前面的已经有了的主摄冲突。**

添加camera的ProviderInfo

在frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp的initialize函数里,将kLegacyProviderName改成"legacy/1"

**status_t CameraProviderManager::initialize(wpCameraProviderManager::StatusListener listener,

ServiceInteractionProxy* proxy) {

// See if there’s a passthrough HAL, but let’s not complain if there’s not

addProviderLocked(“legacy/1”, /*expected*/ false);

return OK;

}

在hardware\interfaces\camera\provider\2.4\default\service.cpp里的main函数里,将"legacy/1"注册上来**

**int main()

{

ALOGI(“Camera provider Service is starting.”);

// The camera HAL may communicate to other vendor components via

// /dev/vndbinder

android::ProcessState::initWithDriver(“/dev/vndbinder”);

return defaultPassthroughServiceImplementation(“legacy/1”, /*maxThreads*/ 6);

}

在hardware\interfaces\camera\provider\2.4\default\CameraProvider.cpp里,将kLegacyProviderName改成"legacy/1";它会被HIDL_FETCH_ICameraProvider调用。**

hw_get_module对应camera的hal代码

在hardware\interfaces\camera\provider\2.4\default\CameraProvider.cpp里的initialize()函数里,hw_get_module参数传进去的名字,改成我们usbcamera hal里指定的名字

int err = hw_get_module(“usbcamera”, (const hw_module_t **)&rawModule);

准备好对应的camera hal代码

我们的usbcamera hal代码,我们放在hardware\libhardware\modules\camera\libuvccamera下面。在这个目录里,有个HalModule.cpp文件,里面定义了camera_module_t的结构体,它的id就是"usbcamera", 在CameraProvider.cpp里hw_get_module时,发现这里定义的id和它要找的id一致,就会load到我们的usbcamera了。

**#include <hardware/camera_common.h>

#include <cutils/log.h>

#include <utils/misc.h>

#include

#include

#include “Camera.h”

/******************************************************************************\

DECLARATIONS

Not used in any other project source files, header file is redundant

\******************************************************************************/

extern camera_module_t HAL_MODULE_INFO_SYM;

namespace android {

namespace HalModule {

/* Available cameras */

extern Camera *cams[];

static int getNumberOfCameras();

static int getCameraInfo(int cameraId, struct camera_info *info);

static int setCallbacks(const camera_module_callbacks_t *callbacks);

static void getVendorTagOps(vendor_tag_ops_t* ops);

static int openDevice(const hw_module_t *module, const char *name, hw_device_t **device);

static struct hw_module_methods_t moduleMethods = {

.open = openDevice

};

}; /* namespace HalModule */

}; /* namespace android */

/******************************************************************************\

DEFINITIONS

\******************************************************************************/

camera_module_t HAL_MODULE_INFO_SYM = {

.common = {

.tag                = HARDWARE_MODULE_TAG,

.module_api_version = CAMERA_MODULE_API_VERSION_2_3,

.hal_api_version    = HARDWARE_HAL_API_VERSION,

.id                 = “usbcamera”,

.name               = “V4l2 Camera”,

.author             = “Antmicro Ltd.”,

.methods            = &android::HalModule::moduleMethods,

.dso                = NULL,

.reserved           = {0}

},

.get_number_of_cameras  = android::HalModule::getNumberOfCameras,

.get_camera_info        = android::HalModule::getCameraInfo,

.set_callbacks          = android::HalModule::setCallbacks,

};

namespace android {

namespace HalModule {

static Camera mainCamera;

Camera *cams[] = {

&mainCamera

};

static int getNumberOfCameras() {

return NELEM(cams);

};

static int getCameraInfo(int cameraId, struct camera_info *info) {

cameraId = 0;//cameraId - 1;

if(cameraId < 0 || cameraId >= getNumberOfCameras()) {

return -ENODEV;

}

if(!cams[cameraId]->isValid()) {

return -ENODEV;

}

return cams[cameraId]->cameraInfo(info);

}

int setCallbacks(const camera_module_callbacks_t * /*callbacks*/) {

ALOGI(“%s: lihb setCallbacks”, __FUNCTION__);

/* TODO: Implement for hotplug support */

return OK;

}

static int openDevice(const hw_module_t *module, const char *name, hw_device_t **device) {

if (module != &HAL_MODULE_INFO_SYM.common) {

return -EINVAL;

}

if (name == NULL) {

return -EINVAL;

}

errno = 0;

int cameraId = (int)strtol(name, NULL, 10);

cameraId = 0;

if(errno || cameraId < 0 || cameraId >= getNumberOfCameras()) {

return -EINVAL;

}

if(!cams[cameraId]->isValid()) {

*device = NULL;

return -ENODEV;

}

return cams[cameraId]->openDevice(device);

}

}; /* namespace HalModule */

}; /* namespace android */

大家可能会发现,在getCameraInfo函数里,我将cameraId写死成了0,但是前面我们不是刚说过,我们的usbcamera是第二个摄像头,id要为1么?其实这里的id,和前面说的那个id,不是同一个意思。在这里之所以写成0,是因为我们这套usbcamera hal代码上面,只挂了一个摄像头,这个摄像头对应的代码放在Camera *cams[]数组里,这个数组里只放了一个对象,所以id自然就要为0了。然后我们在我们的halModule.cpp里操作getCameraInfo或openDevice时,就会通过这个数组调用到static Camera mainCamera;这里定义的这个Camera对象了。这个Camera,也是我们自己写的代码:**

**//Camera.h

#ifndef CAMERA_H

#define CAMERA_H

#include <utils/Errors.h>

#include <hardware/camera_common.h>

#include <V4l2Device.h>

#include <hardware/camera3.h>

#include <camera/CameraMetadata.h>

#include <utils/Mutex.h>

#include “Workers.h”

#include “ImageConverter.h”

#include “DbgUtils.h”

#include <cutils/ashmem.h>

#include <cutils/log.h>

#include <sys/mman.h>

#include “VGA_YUV422.h”

namespace android {

class Camera: public camera3_device {

public:

Camera();

virtual ~Camera();

bool isValid() { return mValid; }

virtual status_t cameraInfo(struct camera_info *info);

virtual int openDevice(hw_device_t **device);

virtual int closeDevice();

protected:

virtual camera_metadata_t * staticCharacteristics();

virtual int initialize(const camera3_callback_ops_t *callbackOps);

virtual int configureStreams(camera3_stream_configuration_t *streamList);

virtual const camera_metadata_t * constructDefaultRequestSettings(int type);

virtual int registerStreamBuffers(const camera3_stream_buffer_set_t *bufferSet);

virtual int processCaptureRequest(camera3_capture_request_t *request);

/* HELPERS/SUBPROCEDURES */

void notifyShutter(uint32_t frameNumber, uint64_t timestamp);

void processCaptureResult(uint32_t frameNumber, const camera_metadata_t *result, const Vector<camera3_stream_buffer> &buffers);

camera_metadata_t *mStaticCharacteristics;

camera_metadata_t *mDefaultRequestSettings[CAMERA3_TEMPLATE_COUNT];

CameraMetadata mLastRequestSettings;

V4l2Device *mDev;

bool mValid;

const camera3_callback_ops_t *mCallbackOps;

size_t mJpegBufferSize;

private:

ImageConverter mConverter;

Mutex mMutex;

uint8_t* mFrameBuffer;

uint8_t* rszbuffer;

int mProperty_enableTimesTamp = -1;

/* STATIC WRAPPERS */

static int sClose(hw_device_t *device);

static int sInitialize(const struct camera3_device *device, const camera3_callback_ops_t *callback_ops);

static int sConfigureStreams(const struct camera3_device *device, camera3_stream_configuration_t *stream_list);

static int sRegisterStreamBuffers(const struct camera3_device *device, const camera3_stream_buffer_set_t *buffer_set);

static const camera_metadata_t * sConstructDefaultRequestSettings(const struct camera3_device *device, int type);

static int sProcessCaptureRequest(const struct camera3_device *device, camera3_capture_request_t *request);

static void sGetMetadataVendorTagOps(const struct camera3_device *device, vendor_tag_query_ops_t* ops);

static void sDump(const struct camera3_device *device, int fd);

static int sFlush(const struct camera3_device *device);

static void _AddTimesTamp(uint8_t* buffer, int32_t width, int32_t height);

static camera3_device_ops_t sOps;

};

}; /* namespace android */

#endif // CAMERA_H**

**/*

* Copyright © 2015-2016 Antmicro

*

* Licensed under the Apache License, Version 2.0 (the “License”);

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

*      http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an “AS IS” BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

#define LOG_TAG “usb-Camera”

#define LOG_NDEBUG 0

#include <hardware/camera3.h>

#include <camera/CameraMetadata.h>

#include <utils/misc.h>

#include <utils/Log.h>

#include <hardware/gralloc.h>

#include <ui/Rect.h>

#include <ui/GraphicBufferMapper.h>

#include <ui/Fence.h>

#include <assert.h>

#include “DbgUtils.h”

#include “Camera.h”

#include “ImageConverter.h”

#include “libyuv.h”

//#include <sprd_exvideo.h>

#include <cutils/properties.h>

#include

#include

namespace android {

/**

* \class Camera

*

* Android’s Camera 3 device implementation.

*

* Declaration of camera capabilities, frame request handling, etc. This code

* is what Android framework talks to.

*/

Camera::Camera()
mStaticCharacteristics(NULL)

, mCallbackOps(NULL)

, mJpegBufferSize(0) {

ALOGI(“Camera() start”);

DBGUTILS_AUTOLOGCALL(__func__);

for(size_t i = 0; i < NELEM(mDefaultRequestSettings); i++) {

mDefaultRequestSettings[i] = NULL;

}

common.tag      = HARDWARE_DEVICE_TAG;

common.version  = CAMERA_DEVICE_API_VERSION_3_2;//CAMERA_DEVICE_API_VERSION_3_0;

common.module   = &HAL_MODULE_INFO_SYM.common;

common.close    = Camera::sClose;

ops             = &sOps;

priv            = NULL;

mValid = true;

mFrameBuffer = new uint8_t[640*480*4];

rszbuffer = new uint8_t[640*480*4];

mDev = new V4l2Device();

if(!mDev) {

mValid = false;

}

}

Camera::~Camera() {

DBGUTILS_AUTOLOGCALL(__func__);

gWorkers.stop();

mDev->disconnect();

delete[] mFrameBuffer;

delete[] rszbuffer;

delete mDev;

}

status_t Camera::cameraInfo(struct camera_info *info) {

DBGUTILS_AUTOLOGCALL(__func__);

ALOGI(“Camera::cameraInfo entry”);

ALOGE(“Camera::cameraInfo entry”);

Mutex::Autolock lock(mMutex);

info->facing = CAMERA_FACING_FRONT;//BACK;//FRONT;

info->orientation = 0;

info->device_version = CAMERA_DEVICE_API_VERSION_3_2;//CAMERA_DEVICE_API_VERSION_3_0;//CAMERA_DEVICE_API_VERSION_3_4;

info->static_camera_characteristics = staticCharacteristics();

return NO_ERROR;

}

int Camera::openDevice(hw_device_t **device) {

ALOGI(“%s”,__FUNCTION__);

DBGUTILS_AUTOLOGCALL(__func__);

Mutex::Autolock lock(mMutex);

char enableTimesTamp[PROPERTY_VALUE_MAX];

char enableAVI[PROPERTY_VALUE_MAX];

mDev->connect();

*device = &common;

gWorkers.start();

return NO_ERROR;

}

int Camera::closeDevice() {

ALOGI(“%s”,__FUNCTION__);

DBGUTILS_AUTOLOGCALL(__func__);

Mutex::Autolock lock(mMutex);

gWorkers.stop();

mDev->disconnect();

return NO_ERROR;

}

camera_metadata_t *Camera::staticCharacteristics() {

if(mStaticCharacteristics)

return mStaticCharacteristics;

CameraMetadata cm;

auto &resolutions = mDev->availableResolutions();

auto &previewResolutions = resolutions;

auto sensorRes = mDev->sensorResolution();

/***********************************\

|* START OF CAMERA CHARACTERISTICS *|

\***********************************/

/* fake, but valid aspect ratio */

const float sensorInfoPhysicalSize[] = {

5.0f,

5.0f * (float)sensorRes.height / (float)sensorRes.width

};

cm.update(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, sensorInfoPhysicalSize, NELEM(sensorInfoPhysicalSize));

/* fake */

static const float lensInfoAvailableFocalLengths[] = {3.30f};

cm.update(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, lensInfoAvailableFocalLengths, NELEM(lensInfoAvailableFocalLengths));

static const uint8_t lensFacing = ANDROID_LENS_FACING_FRONT;

cm.update(ANDROID_LENS_FACING, &lensFacing, 1);

const int32_t sensorInfoPixelArraySize[] = {

(int32_t)sensorRes.width,

(int32_t)sensorRes.height

};

cm.update(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, sensorInfoPixelArraySize, NELEM(sensorInfoPixelArraySize));

const int32_t sensorInfoActiveArraySize[] = {

0,                          0,

(int32_t)sensorRes.width,   (int32_t)sensorRes.height

};

cm.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, sensorInfoActiveArraySize, NELEM(sensorInfoActiveArraySize));

static const int32_t scalerAvailableFormats[] = {

HAL_PIXEL_FORMAT_RGBA_8888, //预览流

HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,//预览流

/* Non-preview one, must be last - see following code */

HAL_PIXEL_FORMAT_BLOB//拍照流

};

cm.update(ANDROID_SCALER_AVAILABLE_FORMATS, scalerAvailableFormats, NELEM(scalerAvailableFormats));

/* Only for HAL_PIXEL_FORMAT_BLOB */

const size_t mainStreamConfigsCount = resolutions.size();

/* For all other supported pixel formats */

const size_t previewStreamConfigsCount = previewResolutions.size() * (NELEM(scalerAvailableFormats) - 1);

const size_t streamConfigsCount = mainStreamConfigsCount + previewStreamConfigsCount;

int32_t scalerAvailableStreamConfigurations[streamConfigsCount * 4];

int64_t scalerAvailableMinFrameDurations[streamConfigsCount * 4];

int32_t scalerAvailableProcessedSizes[previewResolutions.size() * 2];

int64_t scalerAvailableProcessedMinDurations[previewResolutions.size()];

int32_t scalerAvailableJpegSizes[resolutions.size() * 2];

int64_t scalerAvailableJpegMinDurations[resolutions.size()];

size_t i4 = 0;

size_t i2 = 0;

size_t i1 = 0;

/* Main stream configurations */

for(size_t resId = 0; resId < resolutions.size(); ++resId) {

scalerAvailableStreamConfigurations[i4 + 0] = HAL_PIXEL_FORMAT_BLOB;

scalerAvailableStreamConfigurations[i4 + 1] = (int32_t)resolutions[resId].width;

scalerAvailableStreamConfigurations[i4 + 2] = (int32_t)resolutions[resId].height;

scalerAvailableStreamConfigurations[i4 + 3] = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;

scalerAvailableMinFrameDurations[i4 + 0] = HAL_PIXEL_FORMAT_BLOB;

scalerAvailableMinFrameDurations[i4 + 1] = (int32_t)resolutions[resId].width;

scalerAvailableMinFrameDurations[i4 + 2] = (int32_t)resolutions[resId].height;

scalerAvailableMinFrameDurations[i4 + 3] = 1000000000 / 30; /* TODO: read from the device */

scalerAvailableJpegSizes[i2 + 0] = (int32_t)resolutions[resId].width;

scalerAvailableJpegSizes[i2 + 1] = (int32_t)resolutions[resId].height;

scalerAvailableJpegMinDurations[i1] = 1000000000 / 30; /* TODO: read from the device */

i4 += 4;

i2 += 2;

i1 += 1;

}

i2 = 0;

i1 = 0;

/* Preview stream configurations */

for(size_t resId = 0; resId < previewResolutions.size(); ++resId) {

for(size_t fmtId = 0; fmtId < NELEM(scalerAvailableFormats) - 1; ++fmtId) {

scalerAvailableStreamConfigurations[i4 + 0] = scalerAvailableFormats[fmtId];

scalerAvailableStreamConfigurations[i4 + 1] = (int32_t)previewResolutions[resId].width;

scalerAvailableStreamConfigurations[i4 + 2] = (int32_t)previewResolutions[resId].height;

scalerAvailableStreamConfigurations[i4 + 3] = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;

scalerAvailableMinFrameDurations[i4 + 0] = scalerAvailableFormats[fmtId];

scalerAvailableMinFrameDurations[i4 + 1] = (int32_t)previewResolutions[resId].width;

scalerAvailableMinFrameDurations[i4 + 2] = (int32_t)previewResolutions[resId].height;

scalerAvailableMinFrameDurations[i4 + 3] = 1000000000 / 10; /* TODO: read from the device */

i4 += 4;

}

scalerAvailableProcessedSizes[i2 + 0] = (int32_t)previewResolutions[resId].width;

scalerAvailableProcessedSizes[i2 + 1] = (int32_t)previewResolutions[resId].height;

scalerAvailableProcessedMinDurations[i1] = 1000000000 / 10; /* TODO: read from the device */

i2 += 2;

i1 += 1;

}

cm.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, scalerAvailableStreamConfigurations, (size_t)NELEM(scalerAvailableStreamConfigurations));

cm.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, scalerAvailableMinFrameDurations, (size_t)NELEM(scalerAvailableMinFrameDurations));

/* Probably fake */

cm.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, scalerAvailableMinFrameDurations, (size_t)NELEM(scalerAvailableMinFrameDurations));

cm.update(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, scalerAvailableJpegSizes, (size_t)NELEM(scalerAvailableJpegSizes));

cm.update(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS, scalerAvailableJpegMinDurations, (size_t)NELEM(scalerAvailableJpegMinDurations));

cm.update(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, scalerAvailableProcessedSizes, (size_t)NELEM(scalerAvailableProcessedSizes));

cm.update(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS, scalerAvailableProcessedMinDurations, (size_t)NELEM(scalerAvailableProcessedMinDurations));

//添加capabilities集,否则api2的接口,在调用getStreamConfigurationMap去获取REQUEST_AVAILABLE_CAPABILITIES值时会失败。

Vector<uint8_t> available_capabilities;

available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS);

available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);

available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);

cm.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,

available_capabilities.array(),

available_capabilities.size());

/* ~8.25 bit/px (https://en.wikipedia.org/wiki/JPEG#Sample_photographs) */

/* Use 9 bit/px, add buffer info struct size, round up to page size */

mJpegBufferSize = sensorRes.width * sensorRes.height * 9 + sizeof(camera3_jpeg_blob);

mJpegBufferSize = (mJpegBufferSize + PAGE_SIZE - 1u) & ~(PAGE_SIZE - 1u);

const int32_t jpegMaxSize = (int32_t)mJpegBufferSize;

cm.update(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);

static const int32_t jpegAvailableThumbnailSizes[] = {

0, 0,

320, 240

};

cm.update(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegAvailableThumbnailSizes, NELEM(jpegAvailableThumbnailSizes));

static const int32_t sensorOrientation = 90;

cm.update(ANDROID_SENSOR_ORIENTATION, &sensorOrientation, 1);

static const uint8_t flashInfoAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;

cm.update(ANDROID_FLASH_INFO_AVAILABLE, &flashInfoAvailable, 1);

static const float scalerAvailableMaxDigitalZoom = 1;

cm.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &scalerAvailableMaxDigitalZoom, 1);

static const uint8_t statisticsFaceDetectModes[] = {

ANDROID_STATISTICS_FACE_DETECT_MODE_OFF

};

cm.update(ANDROID_STATISTICS_FACE_DETECT_MODE, statisticsFaceDetectModes, NELEM(statisticsFaceDetectModes));

static const int32_t statisticsInfoMaxFaceCount = 0;

cm.update(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &statisticsInfoMaxFaceCount, 1);

static const uint8_t controlAvailableSceneModes[] = {

ANDROID_CONTROL_SCENE_MODE_DISABLED

};

cm.update(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, controlAvailableSceneModes, NELEM(controlAvailableSceneModes));

static const uint8_t controlAvailableEffects[] = {

ANDROID_CONTROL_EFFECT_MODE_OFF

};

cm.update(ANDROID_CONTROL_AVAILABLE_EFFECTS, controlAvailableEffects, NELEM(controlAvailableEffects));

static const int32_t controlMaxRegions[] = {

0, /* AE */

0, /* AWB */

0  /* AF */

};

cm.update(ANDROID_CONTROL_MAX_REGIONS, controlMaxRegions, NELEM(controlMaxRegions));

static const uint8_t controlAeAvailableModes[] = {

ANDROID_CONTROL_AE_MODE_OFF

};

cm.update(ANDROID_CONTROL_AE_AVAILABLE_MODES, controlAeAvailableModes, NELEM(controlAeAvailableModes));

static const camera_metadata_rational controlAeCompensationStep = {1, 3};

cm.update(ANDROID_CONTROL_AE_COMPENSATION_STEP, &controlAeCompensationStep, 1);

int32_t controlAeCompensationRange[] = {-9, 9};

cm.update(ANDROID_CONTROL_AE_COMPENSATION_RANGE, controlAeCompensationRange, NELEM(controlAeCompensationRange));

static const int32_t controlAeAvailableTargetFpsRanges[] = {

10, 20

};

cm.update(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, controlAeAvailableTargetFpsRanges, NELEM(controlAeAvailableTargetFpsRanges));

static const uint8_t controlAeAvailableAntibandingModes[] = {

ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF

};

cm.update(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, controlAeAvailableAntibandingModes, NELEM(controlAeAvailableAntibandingModes));

static const uint8_t controlAwbAvailableModes[] = {

ANDROID_CONTROL_AWB_MODE_AUTO,

ANDROID_CONTROL_AWB_MODE_OFF

};

cm.update(ANDROID_CONTROL_AWB_AVAILABLE_MODES, controlAwbAvailableModes, NELEM(controlAwbAvailableModes));

static const uint8_t controlAfAvailableModes[] = {

ANDROID_CONTROL_AF_MODE_OFF

};

cm.update(ANDROID_CONTROL_AF_AVAILABLE_MODES, controlAfAvailableModes, NELEM(controlAfAvailableModes));

static const uint8_t controlAvailableVideoStabilizationModes[] = {

ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF

};

cm.update(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, controlAvailableVideoStabilizationModes, NELEM(controlAvailableVideoStabilizationModes));

const uint8_t infoSupportedHardwareLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;

cm.update(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &infoSupportedHardwareLevel, 1);

/***********************************\

|*  END OF CAMERA CHARACTERISTICS  *|

\***********************************/

mStaticCharacteristics = cm.release();

return mStaticCharacteristics;

}

int Camera::initialize(const camera3_callback_ops_t *callbackOps) {

DBGUTILS_AUTOLOGCALL(__func__);

Mutex::Autolock lock(mMutex);

mCallbackOps = callbackOps;

return NO_ERROR;

}

const camera_metadata_t * Camera::constructDefaultRequestSettings(int type) {

DBGUTILS_AUTOLOGCALL(__func__);

Mutex::Autolock lock(mMutex);

/* TODO: validate type */

if(mDefaultRequestSettings[type]) {

return mDefaultRequestSettings[type];

}

CameraMetadata cm;

static const int32_t requestId = 0;

cm.update(ANDROID_REQUEST_ID, &requestId, 1);

static const float lensFocusDistance = 0.0f;

cm.update(ANDROID_LENS_FOCUS_DISTANCE, &lensFocusDistance, 1);

auto sensorSize = mDev->sensorResolution();

const int32_t scalerCropRegion[] = {

0,                          0,

(int32_t)sensorSize.width,  (int32_t)sensorSize.height

};

cm.update(ANDROID_SCALER_CROP_REGION, scalerCropRegion, NELEM(scalerCropRegion));

static const int32_t jpegThumbnailSize[] = {

0, 0

};

cm.update(ANDROID_JPEG_THUMBNAIL_SIZE, jpegThumbnailSize, NELEM(jpegThumbnailSize));

static const uint8_t jpegThumbnailQuality = 50;

cm.update(ANDROID_JPEG_THUMBNAIL_QUALITY, &jpegThumbnailQuality, 1);

static const double jpegGpsCoordinates[] = {

0, 0

};

cm.update(ANDROID_JPEG_GPS_COORDINATES, jpegGpsCoordinates, NELEM(jpegGpsCoordinates));

static const uint8_t jpegGpsProcessingMethod[32] = “None”;

cm.update(ANDROID_JPEG_GPS_PROCESSING_METHOD, jpegGpsProcessingMethod, NELEM(jpegGpsProcessingMethod));

static const int64_t jpegGpsTimestamp = 0;

cm.update(ANDROID_JPEG_GPS_TIMESTAMP, &jpegGpsTimestamp, 1);

static const int32_t jpegOrientation = 0;

cm.update(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);

/** android.stats */

static const uint8_t statisticsFaceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;

cm.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &statisticsFaceDetectMode, 1);

static const uint8_t statisticsHistogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF;

cm.update(ANDROID_STATISTICS_HISTOGRAM_MODE, &statisticsHistogramMode, 1);

static const uint8_t statisticsSharpnessMapMode = ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF;

cm.update(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &statisticsSharpnessMapMode, 1);

uint8_t controlCaptureIntent = 0;

switch (type) {

case CAMERA3_TEMPLATE_PREVIEW:          controlCaptureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;             break;

case CAMERA3_TEMPLATE_STILL_CAPTURE:    controlCaptureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;       break;

case CAMERA3_TEMPLATE_VIDEO_RECORD:     controlCaptureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;        break;

case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:   controlCaptureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;      break;

case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG: controlCaptureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;    break;

default:                                controlCaptureIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;              break;

}

cm.update(ANDROID_CONTROL_CAPTURE_INTENT, &controlCaptureIntent, 1);

static const uint8_t controlMode = ANDROID_CONTROL_MODE_OFF;

cm.update(ANDROID_CONTROL_MODE, &controlMode, 1);

static const uint8_t controlEffectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;

cm.update(ANDROID_CONTROL_EFFECT_MODE, &controlEffectMode, 1);

static const uint8_t controlSceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;

cm.update(ANDROID_CONTROL_SCENE_MODE, &controlSceneMode, 1);

static const uint8_t controlAeMode = ANDROID_CONTROL_AE_MODE_OFF;

cm.update(ANDROID_CONTROL_AE_MODE, &controlAeMode, 1);

static const uint8_t controlAeLock = ANDROID_CONTROL_AE_LOCK_OFF;

cm.update(ANDROID_CONTROL_AE_LOCK, &controlAeLock, 1);

static const int32_t controlAeRegions[] = {

0,                          0,

(int32_t)sensorSize.width,  (int32_t)sensorSize.height,

1000

};

cm.update(ANDROID_CONTROL_AE_REGIONS, controlAeRegions, NELEM(controlAeRegions));

cm.update(ANDROID_CONTROL_AWB_REGIONS, controlAeRegions, NELEM(controlAeRegions));

cm.update(ANDROID_CONTROL_AF_REGIONS, controlAeRegions, NELEM(controlAeRegions));

static const int32_t controlAeExposureCompensation = 0;

cm.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &controlAeExposureCompensation, 1);

static const int32_t controlAeTargetFpsRange[] = {

10, 20

};

cm.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, controlAeTargetFpsRange, NELEM(controlAeTargetFpsRange));

static const uint8_t controlAeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;

cm.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &controlAeAntibandingMode, 1);

static const uint8_t controlAwbMode = ANDROID_CONTROL_AWB_MODE_OFF;

cm.update(ANDROID_CONTROL_AWB_MODE, &controlAwbMode, 1);

static const uint8_t controlAwbLock = ANDROID_CONTROL_AWB_LOCK_OFF;

cm.update(ANDROID_CONTROL_AWB_LOCK, &controlAwbLock, 1);

uint8_t controlAfMode = ANDROID_CONTROL_AF_MODE_OFF;

cm.update(ANDROID_CONTROL_AF_MODE, &controlAfMode, 1);

static const uint8_t controlAeState = ANDROID_CONTROL_AE_STATE_CONVERGED;

cm.update(ANDROID_CONTROL_AE_STATE, &controlAeState, 1);

static const uint8_t controlAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;

最后送福利了,现在关注我可以获取包含源码解析,自定义View,动画实现,架构分享等。
内容难度适中,篇幅精炼,每天只需花上十几分钟阅读即可。
大家可以跟我一起探讨,有flutter—底层开发—性能优化—移动架构—资深UI工程师 —NDK相关专业人员和视频教学资料,还有更多面试题等你来拿

录播视频图.png

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

update(ANDROID_CONTROL_AWB_REGIONS, controlAeRegions, NELEM(controlAeRegions));

cm.update(ANDROID_CONTROL_AF_REGIONS, controlAeRegions, NELEM(controlAeRegions));

static const int32_t controlAeExposureCompensation = 0;

cm.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &controlAeExposureCompensation, 1);

static const int32_t controlAeTargetFpsRange[] = {

10, 20

};

cm.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, controlAeTargetFpsRange, NELEM(controlAeTargetFpsRange));

static const uint8_t controlAeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;

cm.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &controlAeAntibandingMode, 1);

static const uint8_t controlAwbMode = ANDROID_CONTROL_AWB_MODE_OFF;

cm.update(ANDROID_CONTROL_AWB_MODE, &controlAwbMode, 1);

static const uint8_t controlAwbLock = ANDROID_CONTROL_AWB_LOCK_OFF;

cm.update(ANDROID_CONTROL_AWB_LOCK, &controlAwbLock, 1);

uint8_t controlAfMode = ANDROID_CONTROL_AF_MODE_OFF;

cm.update(ANDROID_CONTROL_AF_MODE, &controlAfMode, 1);

static const uint8_t controlAeState = ANDROID_CONTROL_AE_STATE_CONVERGED;

cm.update(ANDROID_CONTROL_AE_STATE, &controlAeState, 1);

static const uint8_t controlAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;

最后送福利了,现在关注我可以获取包含源码解析,自定义View,动画实现,架构分享等。
内容难度适中,篇幅精炼,每天只需花上十几分钟阅读即可。
大家可以跟我一起探讨,有flutter—底层开发—性能优化—移动架构—资深UI工程师 —NDK相关专业人员和视频教学资料,还有更多面试题等你来拿

[外链图片转存中…(img-TgF4nHm8-1713699940257)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-pnhXUsZg-1713699940257)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值