动手入门第三方算法集成系列:
【Camera专题】HAL层- 实现第三方算法并集成到Android系统
【Camera专题】HAL层- 以SO库的方式集成第三方算法
上篇文章,我们自己实现了算法,并直接集成到系统中。
但是,我们集成第三方算法的时候,厂商给的是so库,
具体实现你是看不到的,因此,我们也以so库的方式进行集成。
本文知识点:
1.算法集成的步骤
参考我同事的文章: Android调用第三方C++算法库
2.如何生成so库
融合到知识点3里一起写
3.动手实践
a.创建文件
external/hello_algo/
hello_algo.c
#include
void YUV2Gray(unsigned char* srcYuv,int w,int h) {
int mid = w*h/2;
unsigned char* startP = srcYuv + mid;
printf("zcf YUV2Gray is call\n");
for(int i=0;i<mid;i++) {
*startP = 0x80;//128
startP++;
}
}
这个算法很简单,就不多逼逼了!
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
//库的名称:lib_helloalgo
LOCAL_MODULE := lib_helloalgo
LOCAL_SRC_FILES := $(call all-subdir-c-files)
#指定生成so库
include $(BUILD_SHARED_LIBRARY)
b.编译生成so库
编译命令:
mmm external/hello_algo/
编译完成后,会在以下路径生成so库
库的名称就是我们在Android.mk里面指定的名称:
LOCAL_MODULE := lib_helloalgo
到此,我们自己写的算法就变成so库了。
算法库名称:lib_helloalgo.so
头文件:hello_algo.h
可调用方法:YUV2Gray
a.在Android源码中预编译算法库
创建目录hello_algo及子文件
h a r d w a r e / q c o m / c a m e r a / Q C a m e r a 2 / H A L / h e l l o _ a l g o \color{red}{hardware/qcom/camera/QCamera2/HAL/hello\_algo} hardware/qcom/camera/QCamera2/HAL/hello_algo
│─Android.mk
│
├─include/
│── hello_algo.h
│
├─lib/
│── lib_helloalgo.so
Android.mk内容
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#默认不会加上lib前缀
LOCAL_MODULE := lib_helloalgo
#不管是release还是debug版本, 都编译这个模块
LOCAL_MODULE_TAGS := optional
#so文件路径以及名字
LOCAL_SRC_FILES := lib/lib_helloalgo.so
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
#需要指定文件后缀
LOCAL_MODULE_SUFFIX := $(suffix $(LOCAL_SRC_FILES))
#编译32位算法库
LOCAL_MULTILIB := 32
#表明预编译的是动态库
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
include $(BUILD_PREBUILT)
hello_algo.h内容
extern "C" void YUV2Gray(unsigned char* srcYuv,int w,int h);
注意前面一点要加入extern “C”,不然编译的时候,会报错:undefined reference to xxx
b.在调用的模块Android.mk中加入依赖库
h a r d w a r e / q c o m / c a m e r a / Q C a m e r a 2 / H A L / A n d r o i d . m k \color{red}{hardware/qcom/camera/QCamera2/HAL/Android.mk} hardware/qcom/camera/QCamera2/HAL/Android.mk
# 表明引入的头文件
++LOCAL_C_INCLUDES += $(LOCAL_PATH)/hello_algo/include
# 表明当前HAL模块依赖我们要调用的算法库
++LOCAL_SHARED_LIBRARIES += lib_helloalgo
#在最末尾出引入我们预编译的Android.mk, 不然默认系统不会执行我们写的预编译用的Android.mk
++include $(LOCAL_PATH)/hello_algo/Android.mk
c.调用算法库
h a r d w a r e / q c o m / c a m e r a / Q C a m e r a 2 / H A L / Q C a m e r a 2 H W I C a l l b a c k s . c p p \color{red}{hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp} hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp
#include
#include
#include "QCamera2HWI.h"
//引入头文件
++#include "hello_algo.h"
void QCamera2HardwareInterface::preview_stream_cb_routine(mm_camera_super_buf_t *super_frame,
QCameraStream * stream,
void *userdata)
{
ATRACE_CALL();
CDBG("[KPI Perf] %s : BEGIN", __func__);
int err = NO_ERROR;
QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info;
if (pme == NULL) {
ALOGE("%s: Invalid hardware object", __func__);
free(super_frame);
return;
}
if (memory == NULL) {
ALOGE("%s: Invalid memory object", __func__);
free(super_frame);
return;
}
mm_camera_buf_def_t *frame = super_frame->bufs[0];
if (NULL == frame) {
ALOGE("%s: preview frame is NLUL", __func__);
free(super_frame);
return;
}
//获取YUV数据地址
++ unsigned char* yuv = (unsigned char *)frame->buffer;
++ cam_dimension_t dim;
//获取实际宽高
++ stream->getFrameDimension(dim);
++ cam_frame_len_offset_t offset;
//获取对齐后宽高
++ stream->getFrameOffset(offset);
++ ALOGE("%s: zcf frame_len=%d dim.w=%d,diw.h=%d,对齐后w=%d,高=%d",
__func__,
frame->frame_len,dim.width,dim.height,
offset.mp[0].stride,offset.mp[0].scanline);
//获取调用第三方算法
++ YUV2Gray(yuv,offset.mp[0].offset.mp[0].scanline);
···
}
我们在代码里并没有YUV2Gray函数的实现,而是引入了头文件hello_algo.h,
最终会调用到lib_helloalgo.so里面的实现!
编译
你也可以编译整个系统:
make -j32 2>&1 | tee mlog
然后刷机验证。
或者
mmm hardware/qcom/camera/QCamera2/HAL/
编译完成后会在以下目录:
out/target/product/【项目名】/system/lib/hw
生成camera.msm8909.so库
adb push camera.msm8909.so system/lib/hw
adb push lib_helloalgo.so system/lib
然后重启生效
可以看到,屏幕的一半变成了灰色!
学到这,以so库的形式集成第三方算法就ok了!
你应该清楚 第三方算法集成 的基本套路了!
后续有更好的干货,再分享吧!