jjzjj

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

老理说的好 2024-01-13 原文

前言

笔者计划通过虚拟摄像头系列文章、让读者完整掌握在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

编写 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>
#                <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

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

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

增加新增设备

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

编译输出内容如下:

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

再次编译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

@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

第四步 验证 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

加载 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

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

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

有关虚拟摄像头之一: android8.1 移植 v4l2loopback 虚拟摄像头的更多相关文章

  1. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  2. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  3. ruby-on-rails - 可移植 Ruby on Rails 环境 - 2

    我给自己买了一个新的8gigUSBkey,我正在寻找一个合适的解决方案来拥有一个可移植RoR环境来学习。我在谷歌上搜索了一下,发现了一些可能性,但我很想听听一些现实生活中的经历和意见。谢谢! 最佳答案 我喜欢InstantRails,非常容易使用,无需安装程序,也不会修改您的系统环境。 关于ruby-on-rails-可移植RubyonRails环境,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/q

  4. ruby - 如何检查一个字符串是否是几个不同值之一? - 2

    我有一个字符串变量,它只能包含6个不同的值。我想检查它是否包含前4个值之一或2个第二值之一。有没有比这更优雅的方式:ifstring.eql?'val1'||string.eql?'val2'||string.eql?'val3'||string.eql?'val4'...elsifstring.eql?'val5'||string.eql?'val6'...end可能类似于ifstringisin['val1','val2','val3','val4']? 最佳答案 您可以使用include?:if['val1','val2','

  5. ruby-on-rails - Rails 验证虚拟属性 - 2

    我这个模型:classBunny每当我提交一个表单来创建这个模型时,我都会收到以下错误:#的未定义方法“number_before_type_cast” 最佳答案 我通过将此方法添加到我的Bunny模型中解决了这个问题:defnumber_before_type_castnumberend我不喜欢它,但我想在有人发布更好的解决方案之前它会起作用。 关于ruby-on-rails-Rails验证虚拟属性,我们在StackOverflow上找到一个类似的问题: h

  6. 【云计算】私有云在VMware下虚拟机的创建与配置(图文教程) - 2

    【适用平台】私有云   说明:完成私有云部分是需要两台虚拟机的,分别为controller、compute两个节点,但我们只需配置一台,然后克隆就方便多啦!需要用到的映射文件:关于vm的安装我就不介绍的,毕竟挺简单的,下面让我们看看基于私有云模块中,虚拟机的搭建吧。1、创建新的虚拟机,这里一般我会选择自定义,毕竟后面的配置都要根据私有云相关来进行搭建,会比较复杂。(如果是基础的可以选择典型,典型的满足一般虚拟机的配置) 2、选择稍后安装操作系统会比较方便后续的选择,这里你也可以自己选择自己的映像文件(但不建议)  3、我们是基于Linux下操作的,所以选择Linux客户机操作系统,版本选择自己

  7. ruby - rspec - 选择之一的匹配器 - 2

    我有从预定义数组返回随机值的方法(即:['value1','value2'])。我应该如何使用rspec进行测试?我想做这样的事情:expect(FooClass.new.value).tobe_in['value1','value2']有什么办法吗?谢谢。 最佳答案 使用这个expect(['value1','value2']).toinclude(FooClass.new.value)或者一个简单的bool匹配expect(['value1','value2'].include?FooClass.new.value).tobet

  8. VMware虚拟机与本地主机进行磁盘共享(详解) - 2

    VMware虚拟机与本地主机进行磁盘共享前提虚拟机版本为Windows10(专业版,不是可能有问题)本地主机为家庭版或学生版(此版本会有问题,但有替代方式)最好是专业版VMware操作1.关闭防火墙,全部关闭。2.打开电脑属性3.点击共享-》高级共享-》权限4.如果没有everyone,就添加权限选择完全控制,然后应用确定。5.打开cmd输入lusrmgr.msc(只有专业版可以打开)如果不是专业版,可以跳过这一步。点击用户-》administrator密码要复杂密码,否则不行。推荐admaiN@1234类型的密码。设置完密码,点击属性,将禁用解开。6.如果虚拟机的windows不是专业版,可

  9. 虚拟机上进行java项目部署 - 2

    🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀虚拟机上进行java项目部署,自己的一点总结,一起学习,一起进步,一起成长!🛸🛸🛸🛸🛸🛸🛸🛸🛸🛸目录文章目录虚拟机上进行java项目部署1.JDK安装2.TOMCAT安装3.DOCKER1、YUM安装2、docker部署java4、最后 【yzh2022.9】1.JDK安装1、我们安装VM的时候,使用命令java-version查看 java-version这里显示JDK的信息是openjdkversion"1.8.0_262",我们会发现这个JDK是VM自带的当然你也可以通过命令rpm-qa|grepjava来查看相关的java信息 rpm-qa|grepjava【如果不

  10. ruby - 如何在 Ruby 中构建可移植的绝对路径? - 2

    让我们假设一个脚本需要访问一个目录,比如在“任意”操作系统上的/some/where/abc。在Ruby中构建路径有几个选项:File.join('','some','where','abc')File.absolute_path("some#{File::SEPARATOR}where#{File::SEPARATOR}abc",File::SEPARATOR)标准API中的路径名我相信第一个解决方案足够清晰,但符合惯用语。根据我的经验,一些代码审查会要求评论来解释它的作用......问题有没有更好的方法来构建绝对路径是Ruby,其中更好的意思是“完成工作并为自己说话”?

随机推荐