• 虚拟摄像头之一: android8.1 移植 v4l2loopback 虚拟摄像头


    前言

    笔者计划通过虚拟摄像头系列文章、让读者完整掌握在android系统中实现过程和应用方法。以作备忘之用、再则让有需求朋友可以参考。

    第一步 移植 v4l2loopback 驱动至 android的 linux 内核

    在kernel/driver/ 创建 virtual_camera 文件夹,内容结构如下:

    robot@ubuntu:~/android_build/vendor/nxp-opensource/kernel_imx/drivers/virtual_camera$ tree -L 1
    .
    |-- Makefile
    |-- v4l2loopback.c
    |-- v4l2loopback.h
    `-- v4l2loopback_formats.h
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    编写 Makefile 文件,编译 v4l2loopback.ko 模块驱动涉及文件内容如下:

    include Kbuild
    ifeq ($(KBUILD_MODULES),)
    
    #KERNELRELEASE  ?= `uname -r`
    #KERNEL_DIR ?= /lib/modules/$(KERNELRELEASE)/build
    ARCH=arm64
    KERNEL_DIR=/home/robot/android_build/vendor/nxp-opensource/kernel_imx
    CROSS_COMPILE=/home/robot/android_build/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-
    
    PWD     := $(shell pwd)
    
    PREFIX ?= /usr/local
    BINDIR  = $(PREFIX)/bin
    MANDIR  = $(PREFIX)/share/man
    MAN1DIR = $(MANDIR)/man1
    INSTALL = install
    INSTALL_PROGRAM = $(INSTALL) -p -m 755
    INSTALL_DIR     = $(INSTALL) -p -m 755 -d
    INSTALL_DATA    = $(INSTALL) -m 644
    
    MODULE_OPTIONS = devices=2
    
    ##########################################
    # note on build targets
    #
    # module-assistant makes some assumptions about targets, namely
    #  <modulename>: must be present and build the module 
    #                <modulename>.ko is not enough
    # install: must be present (and should only install the module)
    #
    # we therefore make <modulename> a .PHONY alias to <modulename>.ko
    # and remove utils-installation from 'install'
    # call 'make install-all' if you want to install everything
    ##########################################
    
    
    .PHONY: all install clean distclean
    .PHONY: install-all install-utils install-man
    .PHONY: modprobe v4l2loopback
    
    # we don't control the .ko file dependencies, as it is done by kernel
    # makefiles. therefore v4l2loopback.ko is a phony target actually
    .PHONY: v4l2loopback.ko utils
    
    all: v4l2loopback.ko utils
    
    v4l2loopback: v4l2loopback.ko
    v4l2loopback.ko:
        @echo "Building v4l2-loopback driver..."
        $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
    
    install-all: install install-utils install-man
    install:
        $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
        @echo ""
        @echo "SUCCESS (if you got 'SSL errors' above, you can safely ignore them)"
        @echo ""
    
    install-utils: utils/v4l2loopback-ctl
        $(INSTALL_DIR) "$(DESTDIR)$(BINDIR)"
        $(INSTALL_PROGRAM) $< "$(DESTDIR)$(BINDIR)"
    
    install-man: man/v4l2loopback-ctl.1
        $(INSTALL_DIR) "$(DESTDIR)$(MAN1DIR)"
        $(INSTALL_DATA) $< "$(DESTDIR)$(MAN1DIR)"
    
    clean:
        rm -f *~
        rm -f Module.symvers Module.markers modules.order
        $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
        $(MAKE) -C utils clean
    
    distclean: clean
        rm -f man/v4l2loopback-ctl.1
    
    modprobe: v4l2loopback.ko
        chmod a+r v4l2loopback.ko
        sudo modprobe videodev
        -sudo rmmod v4l2loopback
        sudo insmod ./v4l2loopback.ko $(MODULE_OPTIONS)
    
    man/v4l2loopback-ctl.1: utils/v4l2loopback-ctl
        help2man -N --name "control v4l2 loopback devices" \
            --no-discard-stderr --help-option=-h --version-option=-v \
            $^ > $@
    
    utils: utils/v4l2loopback-ctl
    utils/v4l2loopback-ctl: utils/v4l2loopback-ctl.c
        $(MAKE) -C utils
    
    .clang-format:
        curl "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/.clang-format" > $@
    
    .PHONY: clang-format
    clang-format: .clang-format
        clang-format -i *.c *.h utils/*.c
    
    endif # !kbuild
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    此Makefile使用源码中文件,仅修改交叉编译工具内容。

    第二步 在 kernel/driver/Makefile 中添加增加的 v4l2loopback 设备:

    增加新增设备

    obj-$(CONFIG_MULTIPLEXER)       += mux/
    obj-y                           += virtual_camera/
    
    • 1
    • 2

    编译输出内容如下:

    robot@ubuntu:~/android_build/out/target/product/mek_8q/obj/KERNEL_OBJ$ ls drivers/virtual_camera/
    built-in.o  modules.builtin  modules.order  v4l2loopback.ko  v4l2loopback.mod.c  v4l2loopback.mod.o  v4l2loopback.o
    
    • 1
    • 2

    再次编译android源码后,v4l2loopback.ko 内核模块就添加打包至kernel.img的镜像中。

    第三步 加载并启动 v4l2loopback.ko 模块

    @device/fsl/imx8q/mek_8q/BoardConfig.mk 文件中包含 v4l2loopback.ko

    BOARD_VENDOR_KERNEL_MODULES += \
                                $(KERNEL_OUT)/drivers/net/wireless/qcacld-2.0/wlan.ko \
                                $(KERNEL_OUT)/drivers/virtual_camera/v4l2loopback.ko
    
    • 1
    • 2
    • 3

    @device/fsl/imx8q/mek_8q/init.rc 文件中增加insmod v4l2loopback.ko

    on boot
        start audioserver
        start mediadrm
        start media
        start drm
        chmod 0777 /vendor/lib/modules/v4l2loopback.ko
        insmod /vendor/lib/modules/v4l2loopback.ko
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    第四步 验证 v4l2loopback.ko 模块是否加载成功

    未加载 v4l2loopback.ko ,设备dev目录的video如下:

    mek_8q:/ # rmmod vendor/lib/modules/v4l2loopback.ko
    mek_8q:/ # ls /dev
    FreescaleAccelerometer block           event-log-tags gpiochip2 hwbinder iio:device0  memory_bandwidth   ppp    shm    tty10 tty18 tty25 tty32 tty4  tty47 tty54 tty61  ttyLP3   uinput        vga_arbiter video4
    FreescaleGyroscope     console         fd             gpiochip3 i2c-1    input        mxc_asrc           pps0   snd    tty11 tty19 tty26 tty33 tty40 tty48 tty55 tty62  ttyS0    urandom       vhci        vndbinder
    FreescaleMagnetometer  cpu_dma_latency fscklogs       gpiochip4 i2c-2    ion          mxc_hifi4          ptmx   socket tty12 tty2  tty27 tty34 tty41 tty49 tty56 tty63  ttyS1    usb-ffs       video0      watchdog
    __properties__         cpuctl          full           gpiochip5 i2c-3    isoc         mxc_mem            ptp0   stune  tty13 tty20 tty28 tty35 tty42 tty5  tty57 tty7   ttyS2    usb_accessory video1      watchdog0
    ashmem                 cpuset          fuse           gpiochip6 i2c-4    kmsg         mxc_sim            pts    sync   tty14 tty21 tty29 tty36 tty43 tty50 tty58 tty8   ttyS3    vcs           video12     xt_qtaguid
    async                  ctrl            galcore        gpiochip7 i2c-5    kvm          network_latency    random tty    tty15 tty22 tty3  tty37 tty44 tty51 tty59 tty9   tun      vcs1          video13     zero
    autofs                 device-mapper   gpiochip0      graphics  i2c-6    loop-control network_throughput rfkill tty0   tty16 tty23 tty30 tty38 tty45 tty52 tty6  ttyLP0 ubi_ctrl vcsa          video2
    binder                 dri             gpiochip1      hw_random i2c-7    memcg        null               rtc0   tty1   tty17 tty24 tty31 tty39 tty46 tty53 tty60 ttyLP1 uhid     vcsa1         video3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    加载 v4l2loopback.ko ,设备dev目录的video如下:

    mek_8q:/ # insmod vendor/lib/modules/v4l2loopback.ko
    mek_8q:/ # ls /dev/
    FreescaleAccelerometer block           event-log-tags gpiochip2 hwbinder iio:device0  memory_bandwidth   ppp    shm    tty10 tty18 tty25 tty32 tty4  tty47 tty54 tty61  ttyLP3   uinput        vcsa1       video3
    FreescaleGyroscope     console         fd             gpiochip3 i2c-1    input        mxc_asrc           pps0   snd    tty11 tty19 tty26 tty33 tty40 tty48 tty55 tty62  ttyS0    urandom       vga_arbiter video4
    FreescaleMagnetometer  cpu_dma_latency fscklogs       gpiochip4 i2c-2    ion          mxc_hifi4          ptmx   socket tty12 tty2  tty27 tty34 tty41 tty49 tty56 tty63  ttyS1    usb-ffs       vhci        video5
    __properties__         cpuctl          full           gpiochip5 i2c-3    isoc         mxc_mem            ptp0   stune  tty13 tty20 tty28 tty35 tty42 tty5  tty57 tty7   ttyS2    usb_accessory video0      vndbinder
    ashmem                 cpuset          fuse           gpiochip6 i2c-4    kmsg         mxc_sim            pts    sync   tty14 tty21 tty29 tty36 tty43 tty50 tty58 tty8   ttyS3    v4l2loopback  video1      watchdog
    async                  ctrl            galcore        gpiochip7 i2c-5    kvm          network_latency    random tty    tty15 tty22 tty3  tty37 tty44 tty51 tty59 tty9   tun      vcs           video12     watchdog0
    autofs                 device-mapper   gpiochip0      graphics  i2c-6    loop-control network_throughput rfkill tty0   tty16 tty23 tty30 tty38 tty45 tty52 tty6  ttyLP0 ubi_ctrl vcs1          video13     xt_qtaguid
    binder                 dri             gpiochip1      hw_random i2c-7    memcg        null               rtc0   tty1   tty17 tty24 tty31 tty39 tty46 tty53 tty60 ttyLP1 uhid     vcsa          video2      zero
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    设备 video5 就是 v4l2loopback.ko 模块驱动的设备,至此 v4l2loopback.ko 模块移植成功。

    接下来我们将把此设备配置为前置或后置摄像头、并配置sensor相关属性信息,以此通过android用户空间程序调用此虚拟摄像头实现拍照。

  • 相关阅读:
    VMware安装Android-x86示例
    Socket 服务端实例学习笔记
    【python养成】:案例(判断素数、统计字符串中的大写字母、小写字母、数字、其他字符的个数、整数之和、模拟内置函数)
    Micosotf SQL Server常用的SQL语句
    计算机网络学习笔记-计算机网络体系结构专用术语
    Git纯操作版 项目添加和提交、SSH keys添加、远程仓库控制、冲突解决、IDEA连接使用
    NLP模型(二)——GloVe实现
    面试:插件化相关---activity
    Qt 中 setModel 设置数据类型和 setView 函数设置视图
    14:00面试,14:06就出来了,问的问题有点变态。。。
  • 原文地址:https://blog.csdn.net/weixin_38387929/article/details/126118657