xref: /aosp_15_r20/external/virtio-media/TRY_IT_OUT.md (revision 1b4853f54772485c5dd4001ae33a7a958bcc97a1)
1*1b4853f5SAndroid Build Coastguard Worker# Trying out virtio-media
2*1b4853f5SAndroid Build Coastguard Worker
3*1b4853f5SAndroid Build Coastguard WorkerThis document demonstrates how to quickly try virtio-media by controlling a
4*1b4853f5SAndroid Build Coastguard Workervirtual host device through a Debian guest image using the
5*1b4853f5SAndroid Build Coastguard Worker[crosvm](https://crosvm.dev/book/) VMM.
6*1b4853f5SAndroid Build Coastguard Worker
7*1b4853f5SAndroid Build Coastguard WorkerThrough this document, we will build and run the following components:
8*1b4853f5SAndroid Build Coastguard Worker
9*1b4853f5SAndroid Build Coastguard Worker- A guest Linux kernel with virtio-media support enabled
10*1b4853f5SAndroid Build Coastguard Worker- The virtio-media guest kernel module
11*1b4853f5SAndroid Build Coastguard Worker- A Debian guest image with v4l-utils installed
12*1b4853f5SAndroid Build Coastguard Worker- Crosvm with virtio-media support
13*1b4853f5SAndroid Build Coastguard Worker
14*1b4853f5SAndroid Build Coastguard Worker## Prerequisites
15*1b4853f5SAndroid Build Coastguard Worker
16*1b4853f5SAndroid Build Coastguard Worker- A C compiler toolchain
17*1b4853f5SAndroid Build Coastguard Worker- The [Rust toolchain](https://rustup.rs/) version 1.75 or later
18*1b4853f5SAndroid Build Coastguard Worker- The `virt-builder utility` (usually available in the `libguestfs-tools`
19*1b4853f5SAndroid Build Coastguard Worker  package)
20*1b4853f5SAndroid Build Coastguard Worker
21*1b4853f5SAndroid Build Coastguard Worker## Directory Setup
22*1b4853f5SAndroid Build Coastguard Worker
23*1b4853f5SAndroid Build Coastguard WorkerCreate a workspace directory and get into it:
24*1b4853f5SAndroid Build Coastguard Worker
25*1b4853f5SAndroid Build Coastguard Worker```console
26*1b4853f5SAndroid Build Coastguard Workermkdir virtio_media_playground
27*1b4853f5SAndroid Build Coastguard Workercd virtio_media_playground
28*1b4853f5SAndroid Build Coastguard Worker```
29*1b4853f5SAndroid Build Coastguard Worker
30*1b4853f5SAndroid Build Coastguard WorkerThis directory can be erased in order to remove everything we will build here.
31*1b4853f5SAndroid Build Coastguard Worker
32*1b4853f5SAndroid Build Coastguard Worker## Guest Kernel Image
33*1b4853f5SAndroid Build Coastguard Worker
34*1b4853f5SAndroid Build Coastguard WorkerThe virtio-media guest driver works with a regular mainline Linux kernel, as
35*1b4853f5SAndroid Build Coastguard Workerlong as the required virtio and V4L2 options are enabled.
36*1b4853f5SAndroid Build Coastguard Worker
37*1b4853f5SAndroid Build Coastguard Worker1. Clone the kernel repository:
38*1b4853f5SAndroid Build Coastguard Worker
39*1b4853f5SAndroid Build Coastguard Worker   ```console
40*1b4853f5SAndroid Build Coastguard Worker   git clone --branch virtio-media --depth=2 https://github.com/Gnurou/linux
41*1b4853f5SAndroid Build Coastguard Worker   cd linux
42*1b4853f5SAndroid Build Coastguard Worker   ```
43*1b4853f5SAndroid Build Coastguard Worker
44*1b4853f5SAndroid Build Coastguard Worker   This branch is just a regular Linux mainline release with a commit on top
45*1b4853f5SAndroid Build Coastguard Worker   that adds the configuration we will use.
46*1b4853f5SAndroid Build Coastguard Worker
47*1b4853f5SAndroid Build Coastguard Worker2. Build the kernel:
48*1b4853f5SAndroid Build Coastguard Worker
49*1b4853f5SAndroid Build Coastguard Worker   ```console
50*1b4853f5SAndroid Build Coastguard Worker   mkdir build_virtio_media
51*1b4853f5SAndroid Build Coastguard Worker   make O=build_virtio_media virtio_crosvm_defconfig
52*1b4853f5SAndroid Build Coastguard Worker   make O=build_virtio_media -j16 bzImage modules
53*1b4853f5SAndroid Build Coastguard Worker   ```
54*1b4853f5SAndroid Build Coastguard Worker
55*1b4853f5SAndroid Build Coastguard Worker   (Adjust `-j16` to match your number of CPU cores)
56*1b4853f5SAndroid Build Coastguard Worker
57*1b4853f5SAndroid Build Coastguard Worker## Virtio-media Guest Kernel Module
58*1b4853f5SAndroid Build Coastguard Worker
59*1b4853f5SAndroid Build Coastguard Worker1. Clone the virtio-media repository:
60*1b4853f5SAndroid Build Coastguard Worker
61*1b4853f5SAndroid Build Coastguard Worker   ```console
62*1b4853f5SAndroid Build Coastguard Worker   cd ..  # Back to the workspace root
63*1b4853f5SAndroid Build Coastguard Worker   git clone https://github.com/chromeos/virtio-media
64*1b4853f5SAndroid Build Coastguard Worker   cd virtio-media/driver
65*1b4853f5SAndroid Build Coastguard Worker   ```
66*1b4853f5SAndroid Build Coastguard Worker
67*1b4853f5SAndroid Build Coastguard Worker2. Build the module:
68*1b4853f5SAndroid Build Coastguard Worker
69*1b4853f5SAndroid Build Coastguard Worker   ```console
70*1b4853f5SAndroid Build Coastguard Worker   make -C ../../linux/build_virtio_media/ M=$PWD
71*1b4853f5SAndroid Build Coastguard Worker   ```
72*1b4853f5SAndroid Build Coastguard Worker
73*1b4853f5SAndroid Build Coastguard Worker## Guest System Image
74*1b4853f5SAndroid Build Coastguard Worker
75*1b4853f5SAndroid Build Coastguard WorkerCreate the Debian image:
76*1b4853f5SAndroid Build Coastguard Worker
77*1b4853f5SAndroid Build Coastguard Worker```console
78*1b4853f5SAndroid Build Coastguard Workercd ../..  # Back to the workspace root
79*1b4853f5SAndroid Build Coastguard Workervirt-builder debian-12 \
80*1b4853f5SAndroid Build Coastguard Worker  --install v4l-utils \
81*1b4853f5SAndroid Build Coastguard Worker  --root-password password:"" \
82*1b4853f5SAndroid Build Coastguard Worker  --mkdir /root/vmedia \
83*1b4853f5SAndroid Build Coastguard Worker  --append-line '/etc/fstab:vmedia /root/vmedia virtiofs'
84*1b4853f5SAndroid Build Coastguard Worker```
85*1b4853f5SAndroid Build Coastguard Worker
86*1b4853f5SAndroid Build Coastguard WorkerThis command does the following:
87*1b4853f5SAndroid Build Coastguard Worker
88*1b4853f5SAndroid Build Coastguard Worker- Download a Debian 12 image,
89*1b4853f5SAndroid Build Coastguard Worker- Install the `v4l-utils` package into it,
90*1b4853f5SAndroid Build Coastguard Worker- Set the root password to be empty,
91*1b4853f5SAndroid Build Coastguard Worker- Ensures that the shared virtiofs filesystem labeled `vmedia` (that we will use
92*1b4853f5SAndroid Build Coastguard Worker  to share the host directory containing the virtio-media kernel module) is
93*1b4853f5SAndroid Build Coastguard Worker  mounted into `/root/vmedia`.
94*1b4853f5SAndroid Build Coastguard Worker
95*1b4853f5SAndroid Build Coastguard Worker## Crosvm
96*1b4853f5SAndroid Build Coastguard Worker
97*1b4853f5SAndroid Build Coastguard Worker1. Clone and checkout the crosvm branch containing the work-in-progress
98*1b4853f5SAndroid Build Coastguard Worker   virtio-media support:
99*1b4853f5SAndroid Build Coastguard Worker
100*1b4853f5SAndroid Build Coastguard Worker   ```console
101*1b4853f5SAndroid Build Coastguard Worker   git clone --depth=1 https://chromium.googlesource.com/crosvm/crosvm
102*1b4853f5SAndroid Build Coastguard Worker   cd crosvm
103*1b4853f5SAndroid Build Coastguard Worker   git fetch --depth=10 origin refs/changes/29/5065329/9
104*1b4853f5SAndroid Build Coastguard Worker   git checkout FETCH_HEAD
105*1b4853f5SAndroid Build Coastguard Worker   git submodule update --init
106*1b4853f5SAndroid Build Coastguard Worker   ```
107*1b4853f5SAndroid Build Coastguard Worker
108*1b4853f5SAndroid Build Coastguard Worker2. Build the crosvm binary:
109*1b4853f5SAndroid Build Coastguard Worker
110*1b4853f5SAndroid Build Coastguard Worker   ```console
111*1b4853f5SAndroid Build Coastguard Worker   cargo build --release --features "media"
112*1b4853f5SAndroid Build Coastguard Worker   ```
113*1b4853f5SAndroid Build Coastguard Worker
114*1b4853f5SAndroid Build Coastguard WorkerIf everything goes well, the binary should be in `target/release/crosvm`, and we
115*1b4853f5SAndroid Build Coastguard Workernow are ready to run our VM and try out some virtual media devices!
116*1b4853f5SAndroid Build Coastguard Worker
117*1b4853f5SAndroid Build Coastguard Worker## Start the VM
118*1b4853f5SAndroid Build Coastguard Worker
119*1b4853f5SAndroid Build Coastguard Worker```console
120*1b4853f5SAndroid Build Coastguard Workercd ..  # Back to the workspace root
121*1b4853f5SAndroid Build Coastguard Worker./crosvm/target/release/crosvm run \
122*1b4853f5SAndroid Build Coastguard Worker  linux/build_virtio_media/arch/x86/boot/bzImage \
123*1b4853f5SAndroid Build Coastguard Worker  --rwdisk debian-12.img \
124*1b4853f5SAndroid Build Coastguard Worker  -p "root=/dev/vda1" \
125*1b4853f5SAndroid Build Coastguard Worker  --shared-dir "$PWD/virtio-media:vmedia:type=fs" \
126*1b4853f5SAndroid Build Coastguard Worker  --simple-media
127*1b4853f5SAndroid Build Coastguard Worker```
128*1b4853f5SAndroid Build Coastguard Worker
129*1b4853f5SAndroid Build Coastguard WorkerThis command does the following:
130*1b4853f5SAndroid Build Coastguard Worker
131*1b4853f5SAndroid Build Coastguard Worker- Start the kernel image we built,
132*1b4853f5SAndroid Build Coastguard Worker- Adds the Debian guest image as a virtual disk,
133*1b4853f5SAndroid Build Coastguard Worker- Passes the kernel parameter to use this virtual disk as root partition,
134*1b4853f5SAndroid Build Coastguard Worker- Shares the folder containing the virtio-media kernel module as a virtiofs
135*1b4853f5SAndroid Build Coastguard Worker  filesystem labeled `vmedia`,
136*1b4853f5SAndroid Build Coastguard Worker- Adds a simple, dummy virtio-media test device that is entirely emulated in
137*1b4853f5SAndroid Build Coastguard Worker  crosvm.
138*1b4853f5SAndroid Build Coastguard Worker
139*1b4853f5SAndroid Build Coastguard WorkerYou should see the system booting. After a few seconds, press `<enter>` to get
140*1b4853f5SAndroid Build Coastguard Workerthe login prompt. Login as `root` with an empty password.
141*1b4853f5SAndroid Build Coastguard Worker
142*1b4853f5SAndroid Build Coastguard WorkerWe will now want to insert the `virtio-media` kernel module:
143*1b4853f5SAndroid Build Coastguard Worker
144*1b4853f5SAndroid Build Coastguard Worker```console
145*1b4853f5SAndroid Build Coastguard Workerinsmod /root/vmedia/driver/virtio-media.ko
146*1b4853f5SAndroid Build Coastguard Worker```
147*1b4853f5SAndroid Build Coastguard Worker
148*1b4853f5SAndroid Build Coastguard Worker## Test the Virtual Device
149*1b4853f5SAndroid Build Coastguard Worker
150*1b4853f5SAndroid Build Coastguard WorkerThe simple virtio-media device should have been detected and become visible as
151*1b4853f5SAndroid Build Coastguard Worker`/dev/video0`. Let's see if it works:
152*1b4853f5SAndroid Build Coastguard Worker
153*1b4853f5SAndroid Build Coastguard Worker```console
154*1b4853f5SAndroid Build Coastguard Workerv4l2-compliance -d0 -s
155*1b4853f5SAndroid Build Coastguard Worker```
156*1b4853f5SAndroid Build Coastguard Worker
157*1b4853f5SAndroid Build Coastguard WorkerThis should display a long list of tests ending with:
158*1b4853f5SAndroid Build Coastguard Worker
159*1b4853f5SAndroid Build Coastguard Worker```console
160*1b4853f5SAndroid Build Coastguard Worker...
161*1b4853f5SAndroid Build Coastguard WorkerTotal for virtio_media device /dev/video0: 54, Succeeded: 54, Failed: 0, Warnings: 1
162*1b4853f5SAndroid Build Coastguard Worker```
163*1b4853f5SAndroid Build Coastguard Worker
164*1b4853f5SAndroid Build Coastguard WorkerWe can also check its supported capture formats:
165*1b4853f5SAndroid Build Coastguard Worker
166*1b4853f5SAndroid Build Coastguard Worker```console
167*1b4853f5SAndroid Build Coastguard Workerv4l2-ctl -d0 --list-formats
168*1b4853f5SAndroid Build Coastguard Worker```
169*1b4853f5SAndroid Build Coastguard Worker
170*1b4853f5SAndroid Build Coastguard WorkerWhich informs us that our device only supports `RGB3`:
171*1b4853f5SAndroid Build Coastguard Worker
172*1b4853f5SAndroid Build Coastguard Worker```console
173*1b4853f5SAndroid Build Coastguard Workerioctl: VIDIOC_ENUM_FMT
174*1b4853f5SAndroid Build Coastguard Worker        Type: Video Capture
175*1b4853f5SAndroid Build Coastguard Worker
176*1b4853f5SAndroid Build Coastguard Worker        [0]: 'RGB3' (24-bit RGB 8-8-8)
177*1b4853f5SAndroid Build Coastguard Worker```
178*1b4853f5SAndroid Build Coastguard Worker
179*1b4853f5SAndroid Build Coastguard WorkerAnd we can also capture frames from it:
180*1b4853f5SAndroid Build Coastguard Worker
181*1b4853f5SAndroid Build Coastguard Worker```console
182*1b4853f5SAndroid Build Coastguard Workerv4l2-ctl -d0 --stream-mmap --stream-count 30 --stream-to /root/vmedia/simple.rgb
183*1b4853f5SAndroid Build Coastguard Worker```
184*1b4853f5SAndroid Build Coastguard Worker
185*1b4853f5SAndroid Build Coastguard WorkerThis writes 30 640x480 RGB frames (all filled with a single color) into the
186*1b4853f5SAndroid Build Coastguard Worker`simple.rgb` file of our `virtio-media` directory on the host. You can visualize
187*1b4853f5SAndroid Build Coastguard Workerthe output using a dedicated tool like [YUView](https://github.com/IENT/YUView).
188*1b4853f5SAndroid Build Coastguard Worker
189*1b4853f5SAndroid Build Coastguard WorkerThat's enough for this simple example. Next we will see how to proxy a V4L2
190*1b4853f5SAndroid Build Coastguard Workerdevice on the host into the guest. Let's exit the guest:
191*1b4853f5SAndroid Build Coastguard Worker
192*1b4853f5SAndroid Build Coastguard Worker```console
193*1b4853f5SAndroid Build Coastguard Workerpoweroff
194*1b4853f5SAndroid Build Coastguard Worker```
195*1b4853f5SAndroid Build Coastguard Worker
196*1b4853f5SAndroid Build Coastguard Worker## Proxy a host V4L2 device into a guest
197*1b4853f5SAndroid Build Coastguard Worker
198*1b4853f5SAndroid Build Coastguard WorkerThis next example uses virtio-media's V4L2 proxy device to make a host V4L2
199*1b4853f5SAndroid Build Coastguard Workerdevice visible almost as-is into a guest. We will need a working V4L2 device on
200*1b4853f5SAndroid Build Coastguard Workerthe host, for this example we will assume a regular USB camera using the
201*1b4853f5SAndroid Build Coastguard Worker`uvcvideo` driver. With the camera plugged, use `v4l2-ctl` on the host to find
202*1b4853f5SAndroid Build Coastguard Workerout the number of the device:
203*1b4853f5SAndroid Build Coastguard Worker
204*1b4853f5SAndroid Build Coastguard Worker```console
205*1b4853f5SAndroid Build Coastguard Workerv4l2-ctl -d0 --info
206*1b4853f5SAndroid Build Coastguard Worker```
207*1b4853f5SAndroid Build Coastguard Worker
208*1b4853f5SAndroid Build Coastguard WorkerIf the output lines look something like
209*1b4853f5SAndroid Build Coastguard Worker
210*1b4853f5SAndroid Build Coastguard Worker```console
211*1b4853f5SAndroid Build Coastguard WorkerDriver Info:
212*1b4853f5SAndroid Build Coastguard Worker        Driver name      : uvcvideo
213*1b4853f5SAndroid Build Coastguard Worker        Card type        : <Camera name>
214*1b4853f5SAndroid Build Coastguard Worker```
215*1b4853f5SAndroid Build Coastguard Worker
216*1b4853f5SAndroid Build Coastguard WorkerThen you have found the correct device. If not, replace `-d0` with `-d1`, `-d2`,
217*1b4853f5SAndroid Build Coastguard Worker... until you find a device which driver name is `uvcvideo`.
218*1b4853f5SAndroid Build Coastguard Worker
219*1b4853f5SAndroid Build Coastguard WorkerNow that we have found the device, we can start `crosvm` with a proxy device for
220*1b4853f5SAndroid Build Coastguard Workerit:
221*1b4853f5SAndroid Build Coastguard Worker
222*1b4853f5SAndroid Build Coastguard Worker```console
223*1b4853f5SAndroid Build Coastguard Worker./crosvm/target/release/crosvm run \
224*1b4853f5SAndroid Build Coastguard Worker  linux/build_virtio_media/arch/x86/boot/bzImage \
225*1b4853f5SAndroid Build Coastguard Worker  --rwdisk debian-12.img \
226*1b4853f5SAndroid Build Coastguard Worker  -p "root=/dev/vda1" \
227*1b4853f5SAndroid Build Coastguard Worker  --shared-dir "$PWD/virtio-media:vmedia:type=fs" \
228*1b4853f5SAndroid Build Coastguard Worker  --v4l2-proxy /dev/video0
229*1b4853f5SAndroid Build Coastguard Worker```
230*1b4853f5SAndroid Build Coastguard Worker
231*1b4853f5SAndroid Build Coastguard WorkerThe `/dev/video0` assumes that the `-d0` argument of `v4l2-ctl` returned the
232*1b4853f5SAndroid Build Coastguard Workerright device - adjust the argument for the actual device on your host.
233*1b4853f5SAndroid Build Coastguard Worker
234*1b4853f5SAndroid Build Coastguard WorkerWith the guest booted, we can insert the `v4l2-media` module again:
235*1b4853f5SAndroid Build Coastguard Worker
236*1b4853f5SAndroid Build Coastguard Worker```console
237*1b4853f5SAndroid Build Coastguard Workerinsmod /root/vmedia/driver/virtio-media.ko
238*1b4853f5SAndroid Build Coastguard Worker```
239*1b4853f5SAndroid Build Coastguard Worker
240*1b4853f5SAndroid Build Coastguard WorkerAnd check that our device is indeed recognized:
241*1b4853f5SAndroid Build Coastguard Worker
242*1b4853f5SAndroid Build Coastguard Worker```console
243*1b4853f5SAndroid Build Coastguard Workerv4l2-ctl -d0 --info
244*1b4853f5SAndroid Build Coastguard Worker```
245*1b4853f5SAndroid Build Coastguard Worker
246*1b4853f5SAndroid Build Coastguard WorkerThis should return sensibly the same output as when the command was run on the
247*1b4853f5SAndroid Build Coastguard Workerhost, with the exception that the driver name is now `virtio_media`.
248*1b4853f5SAndroid Build Coastguard Worker
249*1b4853f5SAndroid Build Coastguard WorkerMost USB cameras support streaming into motion-JPEG, so let's try to capture a
250*1b4853f5SAndroid Build Coastguard Workerstream:
251*1b4853f5SAndroid Build Coastguard Worker
252*1b4853f5SAndroid Build Coastguard Worker```console
253*1b4853f5SAndroid Build Coastguard Workerv4l2-ctl -d0 --stream-mmap --set-fmt-video pixelformat=MJPG --stream-to /root/vmedia/out.mpg
254*1b4853f5SAndroid Build Coastguard Worker```
255*1b4853f5SAndroid Build Coastguard Worker
256*1b4853f5SAndroid Build Coastguard WorkerUse `Ctrl-C` to stop the capture. The stream has been recorded into the
257*1b4853f5SAndroid Build Coastguard Workerdirectory shared with the host, so let's exit the guest in order to check it
258*1b4853f5SAndroid Build Coastguard Workerout:
259*1b4853f5SAndroid Build Coastguard Worker
260*1b4853f5SAndroid Build Coastguard Worker```console
261*1b4853f5SAndroid Build Coastguard Workerpoweroff
262*1b4853f5SAndroid Build Coastguard Worker```
263*1b4853f5SAndroid Build Coastguard Worker
264*1b4853f5SAndroid Build Coastguard WorkerThen on the host, use your media player of choice to view the captured file:
265*1b4853f5SAndroid Build Coastguard Worker
266*1b4853f5SAndroid Build Coastguard Worker```console
267*1b4853f5SAndroid Build Coastguard Workerffplay virtio-media/out.mpg
268*1b4853f5SAndroid Build Coastguard Worker```
269