美文网首页
【Camera专题】HAL1- 以SO库或a库的方式集成第三方算

【Camera专题】HAL1- 以SO库或a库的方式集成第三方算

作者: c枫_撸码的日子 | 来源:发表于2019-09-16 17:38 被阅读0次

系列文章

动手入门第三方算法集成系列:
【Camera专题】HAL1- 实现第三方算法并集成到Android系统
【Camera专题】HAL1- 以SO库或a库的方式集成第三方算法
【Camera专题】HAL1- 多帧降噪算法的集成(实战1)

一、前言

上篇文章,我们自己实现了算法,并直接集成到系统中。
但是,我们集成第三方算法的时候,厂商给的是so库,
具体实现你是看不到的,因此,我们也以so库的方式进行集成。

本文知识点:

1.算法集成的步骤
参考我同事的文章: Android调用第三方C++算法库
2.如何生成so库
融合到知识点3里一起写
3.动手实践

二、动手实践

1.把自己写的算法编译成so库

a.创建文件

external/hello_algo/

  • hello_algo.c
    这里是自己实现的算法:Yuv2Gray
  • Android.mk
    这里面指定编译规则

hello_algo.c

#include <stdio.h>

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库了。

2.以so库或者a库的方式集成第三方算法

算法库名称:lib_helloalgo.so 或者 lib_helloalgo.a
头文件:hello_algo.h
可调用方法:YUV2Gray

a.在Android源码中预编译算法库

创建目录hello_algo及子文件

\color{red}{hardware/qcom/camera/QCamera2/HAL/hello\_algo}

│─Android.mk
│
├─include/  
│── hello_algo.h
│
如果是so库
├─lib/
│── lib_helloalgo.so

如果是a库
├─lib/
│── lib_helloalgo.a

Android.mk内容

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#默认不会加上lib前缀
LOCAL_MODULE := lib_helloalgo
#不管是release还是debug版本, 都编译这个模块
LOCAL_MODULE_TAGS := optional
-------------------so库---------------------
#so文件路径以及名字 
LOCAL_SRC_FILES := lib/lib_helloalgo.so

-------------------a库---------------------
LOCAL_SRC_FILES := lib/lib_helloalgo.a

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中加入依赖库
\color{red}{hardware/qcom/camera/QCamera2/HAL/Android.mk}

# 表明引入的头文件
++LOCAL_C_INCLUDES += $(LOCAL_PATH)/hello_algo/include
# 表明当前HAL模块依赖我们要调用的算法库
-------------如果是so库------------------------------------
++LOCAL_SHARED_LIBRARIES += lib_helloalgo
-------------如果是a库-----------------
++LOCAL_STATIC_LIBRARIES+= lib_helloalgo

#在最末尾出引入我们预编译的Android.mk, 不然默认系统不会执行我们写的预编译用的Android.mk
++include $(LOCAL_PATH)/hello_algo/Android.mk
(ps:这一行看情况,有些系统不用加,如果报错 already defined xxx)

so库是动态库:使用 LOCAL_SHARED_LIBRARIES
a库是动静态库:使用 LOCAL_STATIC_LIBRARIES

c.调用算法库
\color{red}{hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp}

  #include <utils/Trace.h>
  #include <utils/Timers.h>
  #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了!
你应该清楚 第三方算法集成 的基本套路了!

继续当一名咸鱼(* ̄︶ ̄)!

Stay Hungry,Stay Foolish!

相关文章

网友评论

      本文标题:【Camera专题】HAL1- 以SO库或a库的方式集成第三方算

      本文链接:https://www.haomeiwen.com/subject/eojxuctx.html