前言
笔者计划通过虚拟摄像头系列文章、让读者完整掌握在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 <span class="token operator">-</span>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 < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ( < / s p a n > K E R N E L D I R < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ) < / s p a n > M < s p a n c l a s s = " t o k e n o p e r a t o r " > = < / s p a n > <span class="token punctuation">(</span>KERNEL_DIR<span class="token punctuation">)</span> M<span class="token operator">=</span> <spanclass="tokenpunctuation">(</span>KERNELDIR<spanclass="tokenpunctuation">)</span>M<spanclass="tokenoperator">=</span>(PWD) modules
install-all: install install-utils install-man
install:
$(MAKE) -C < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ( < / s p a n > K E R N E L D I R < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ) < / s p a n > M < s p a n c l a s s = " t o k e n o p e r a t o r " > = < / s p a n > <span class="token punctuation">(</span>KERNEL_DIR<span class="token punctuation">)</span> M<span class="token operator">=</span> <spanclass="tokenpunctuation">(</span>KERNELDIR<spanclass="tokenpunctuation">)</span>M<spanclass="tokenoperator">=</span>(PWD) modules_install
@echo “”
@echo “SUCCESS (if you got ‘SSL errors’ above, you can safely ignore them)”
@echo “”
install-utils: utils/v4l2loopback-ctl
< s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ( < / s p a n > I N S T A L L D I R < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ) < / s p a n > < s p a n c l a s s = " t o k e n s t r i n g " > " <span class="token punctuation">(</span>INSTALL_DIR<span class="token punctuation">)</span> <span class="token string">" <spanclass="tokenpunctuation">(</span>INSTALLDIR<spanclass="tokenpunctuation">)</span><spanclass="tokenstring">"(DESTDIR)$(BINDIR)“
$(INSTALL_PROGRAM) KaTeX parse error: Expected 'EOF', got '&' at position 30: …oken operator">&̲lt;</span> <spa…(DESTDIR)$(BINDIR)”
install-man: man/v4l2loopback-ctl.1
< s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ( < / s p a n > I N S T A L L D I R < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ) < / s p a n > < s p a n c l a s s = " t o k e n s t r i n g " > " <span class="token punctuation">(</span>INSTALL_DIR<span class="token punctuation">)</span> <span class="token string">" <spanclass="tokenpunctuation">(</span>INSTALLDIR<spanclass="tokenpunctuation">)</span><spanclass="tokenstring">"(DESTDIR)$(MAN1DIR)“
$(INSTALL_DATA) KaTeX parse error: Expected 'EOF', got '&' at position 30: …oken operator">&̲lt;</span> <spa…(DESTDIR)$(MAN1DIR)”
clean:
rm -f *~
rm -f Module.symvers Module.markers modules.order
$(MAKE) -C < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ( < / s p a n > K E R N E L D I R < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ) < / s p a n > M < s p a n c l a s s = " t o k e n o p e r a t o r " > = < / s p a n > <span class="token punctuation">(</span>KERNEL_DIR<span class="token punctuation">)</span> M<span class="token operator">=</span> <spanclass="tokenpunctuation">(</span>KERNELDIR<spanclass="tokenpunctuation">)</span>M<spanclass="tokenoperator">=</span>(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用户空间程序调用此虚拟摄像头实现拍照。
前言
笔者计划通过虚拟摄像头系列文章、让读者完整掌握在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),)