1*bb4ee6a4SAndroid Build Coastguard Worker# Video (experimental) 2*bb4ee6a4SAndroid Build Coastguard Worker 3*bb4ee6a4SAndroid Build Coastguard WorkerThe virtio video decoder and encoder devices allow a guest to leverage the host's 4*bb4ee6a4SAndroid Build Coastguard Workerhardware-accelerated video decoding and encoding capabilities. The specification ([v3], [v5]) for 5*bb4ee6a4SAndroid Build Coastguard Workerthese devices is still a work-in-progress, so testing them requires an out-of-tree kernel driver on 6*bb4ee6a4SAndroid Build Coastguard Workerthe guest. 7*bb4ee6a4SAndroid Build Coastguard Worker 8*bb4ee6a4SAndroid Build Coastguard WorkerThe virtio-video host device uses backends to perform the actual decoding. The currently supported 9*bb4ee6a4SAndroid Build Coastguard Workerbackends are: 10*bb4ee6a4SAndroid Build Coastguard Worker 11*bb4ee6a4SAndroid Build Coastguard Worker- `libvda`, a hardware-accelerated backend that supports both decoding and encoding by delegating 12*bb4ee6a4SAndroid Build Coastguard Worker the work to a running instance of Chrome. It can only be built and used in a ChromeOS environment. 13*bb4ee6a4SAndroid Build Coastguard Worker- `ffmpeg`, a software-based backend that supports encoding and decoding. It exists to make testing 14*bb4ee6a4SAndroid Build Coastguard Worker and development of virtio-video easier, as it does not require any particular hardware and is 15*bb4ee6a4SAndroid Build Coastguard Worker based on a reliable codec library. 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard WorkerThe rest of this document will solely focus on the `ffmpeg` backend. More accelerated backends will 18*bb4ee6a4SAndroid Build Coastguard Workerbe added in the future. 19*bb4ee6a4SAndroid Build Coastguard Worker 20*bb4ee6a4SAndroid Build Coastguard Worker## Guest kernel requirements 21*bb4ee6a4SAndroid Build Coastguard Worker 22*bb4ee6a4SAndroid Build Coastguard WorkerThe `virtio_video` branch of this [kernel git repository](https://github.com/Gnurou/linux) contains 23*bb4ee6a4SAndroid Build Coastguard Workera work-in-progress version of the `virtio-video` guest kernel driver, based on a (hopefully) recent 24*bb4ee6a4SAndroid Build Coastguard Workerversion of mainline Linux. If you use this as your guest kernel, the `virtio_video_defconfig` 25*bb4ee6a4SAndroid Build Coastguard Workerconfiguration should allow you to easily boot from crosvm, with the video (and a few other) virtio 26*bb4ee6a4SAndroid Build Coastguard Workerdevices support built-in. 27*bb4ee6a4SAndroid Build Coastguard Worker 28*bb4ee6a4SAndroid Build Coastguard WorkerQuick building guide after checking out this branch: 29*bb4ee6a4SAndroid Build Coastguard Worker 30*bb4ee6a4SAndroid Build Coastguard Worker```sh 31*bb4ee6a4SAndroid Build Coastguard Workermkdir build_crosvm_x86 32*bb4ee6a4SAndroid Build Coastguard Workermake O=build_crosvm_x86 virtio_video_defconfig 33*bb4ee6a4SAndroid Build Coastguard Workermake O=build_crosvm_x86 -j16 34*bb4ee6a4SAndroid Build Coastguard Worker``` 35*bb4ee6a4SAndroid Build Coastguard Worker 36*bb4ee6a4SAndroid Build Coastguard WorkerThe resulting kernel image that can be passed to `crosvm` will be in 37*bb4ee6a4SAndroid Build Coastguard Worker`build_crosvm_x86/arch/x86/boot/bzImage`. 38*bb4ee6a4SAndroid Build Coastguard Worker 39*bb4ee6a4SAndroid Build Coastguard Worker## Crosvm requirements 40*bb4ee6a4SAndroid Build Coastguard Worker 41*bb4ee6a4SAndroid Build Coastguard WorkerThe virtio-video support is experimental and needs to be opted-in through the `"video-decoder"` or 42*bb4ee6a4SAndroid Build Coastguard Worker`"video-encoder"` Cargo feature. In the instruction below we'll be using the FFmpeg backend which 43*bb4ee6a4SAndroid Build Coastguard Workerrequires the `"ffmpeg"` feature to be enabled as well. 44*bb4ee6a4SAndroid Build Coastguard Worker 45*bb4ee6a4SAndroid Build Coastguard WorkerThe following example builds crosvm with FFmpeg encoder and decoder backend support: 46*bb4ee6a4SAndroid Build Coastguard Worker 47*bb4ee6a4SAndroid Build Coastguard Worker```sh 48*bb4ee6a4SAndroid Build Coastguard Workercargo build --features "video-encoder,video-decoder,ffmpeg" 49*bb4ee6a4SAndroid Build Coastguard Worker``` 50*bb4ee6a4SAndroid Build Coastguard Worker 51*bb4ee6a4SAndroid Build Coastguard WorkerTo enable the **decoder** device, start crosvm with the `--video-decoder=ffmpeg` command-line 52*bb4ee6a4SAndroid Build Coastguard Workerargument: 53*bb4ee6a4SAndroid Build Coastguard Worker 54*bb4ee6a4SAndroid Build Coastguard Worker```sh 55*bb4ee6a4SAndroid Build Coastguard Workercrosvm run --disable-sandbox --video-decoder=ffmpeg -c 4 -m 2048 --block /path/to/disk.img,root --serial type=stdout,hardware=virtio-console,console=true,stdin=true /path/to/bzImage 56*bb4ee6a4SAndroid Build Coastguard Worker``` 57*bb4ee6a4SAndroid Build Coastguard Worker 58*bb4ee6a4SAndroid Build Coastguard WorkerAlternatively, to enable the **encoder** device, start crosvm with the `--video-encoder=ffmpeg` 59*bb4ee6a4SAndroid Build Coastguard Workercommand-line argument: 60*bb4ee6a4SAndroid Build Coastguard Worker 61*bb4ee6a4SAndroid Build Coastguard Worker```sh 62*bb4ee6a4SAndroid Build Coastguard Workercrosvm run --disable-sandbox --video-encoder=ffmpeg -c 4 -m 2048 --block /path/to/disk.img,root --serial type=stdout,hardware=virtio-console,console=true,stdin=true /path/to/bzImage 63*bb4ee6a4SAndroid Build Coastguard Worker``` 64*bb4ee6a4SAndroid Build Coastguard Worker 65*bb4ee6a4SAndroid Build Coastguard WorkerIf the guest kernel includes the virtio-video driver, then the device should be probed and show up. 66*bb4ee6a4SAndroid Build Coastguard Worker 67*bb4ee6a4SAndroid Build Coastguard Worker## Testing the device from the guest 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard WorkerVideo capabilities are exposed to the guest using V4L2. The encoder or decoder device should appear 70*bb4ee6a4SAndroid Build Coastguard Workeras `/dev/videoX`, probably `/dev/video0` if there are no additional V4L2 devices. 71*bb4ee6a4SAndroid Build Coastguard Worker 72*bb4ee6a4SAndroid Build Coastguard Worker### Checking capabilities and formats 73*bb4ee6a4SAndroid Build Coastguard Worker 74*bb4ee6a4SAndroid Build Coastguard Worker`v4l2-ctl`, part of the `v4l-utils` package, can be used to test the device's existence. 75*bb4ee6a4SAndroid Build Coastguard Worker 76*bb4ee6a4SAndroid Build Coastguard WorkerExample output for the decoder is shown below. 77*bb4ee6a4SAndroid Build Coastguard Worker 78*bb4ee6a4SAndroid Build Coastguard Worker```sh 79*bb4ee6a4SAndroid Build Coastguard Workerv4l2-ctl -d/dev/video0 --info 80*bb4ee6a4SAndroid Build Coastguard WorkerDriver Info: 81*bb4ee6a4SAndroid Build Coastguard Worker Driver name : virtio-video 82*bb4ee6a4SAndroid Build Coastguard Worker Card type : ffmpeg 83*bb4ee6a4SAndroid Build Coastguard Worker Bus info : virtio:stateful-decoder 84*bb4ee6a4SAndroid Build Coastguard Worker Driver version : 5.17.0 85*bb4ee6a4SAndroid Build Coastguard Worker Capabilities : 0x84204000 86*bb4ee6a4SAndroid Build Coastguard Worker Video Memory-to-Memory Multiplanar 87*bb4ee6a4SAndroid Build Coastguard Worker Streaming 88*bb4ee6a4SAndroid Build Coastguard Worker Extended Pix Format 89*bb4ee6a4SAndroid Build Coastguard Worker Device Capabilities 90*bb4ee6a4SAndroid Build Coastguard Worker Device Caps : 0x04204000 91*bb4ee6a4SAndroid Build Coastguard Worker Video Memory-to-Memory Multiplanar 92*bb4ee6a4SAndroid Build Coastguard Worker Streaming 93*bb4ee6a4SAndroid Build Coastguard Worker Extended Pix Format 94*bb4ee6a4SAndroid Build Coastguard Worker``` 95*bb4ee6a4SAndroid Build Coastguard Worker 96*bb4ee6a4SAndroid Build Coastguard WorkerNote that the `Card type` is `ffmpeg`, indicating that decoding will be performed in software on the 97*bb4ee6a4SAndroid Build Coastguard Workerhost. We can then query the support input (`OUTPUT` in V4L2-speak) formats, i.e. the encoded formats 98*bb4ee6a4SAndroid Build Coastguard Workerwe can send to the decoder: 99*bb4ee6a4SAndroid Build Coastguard Worker 100*bb4ee6a4SAndroid Build Coastguard Worker```sh 101*bb4ee6a4SAndroid Build Coastguard Workerv4l2-ctl -d/dev/video0 --list-formats-out 102*bb4ee6a4SAndroid Build Coastguard Workerioctl: VIDIOC_ENUM_FMT 103*bb4ee6a4SAndroid Build Coastguard Worker Type: Video Output Multiplanar 104*bb4ee6a4SAndroid Build Coastguard Worker 105*bb4ee6a4SAndroid Build Coastguard Worker [0]: 'VP90' (VP9, compressed) 106*bb4ee6a4SAndroid Build Coastguard Worker [1]: 'VP80' (VP8, compressed) 107*bb4ee6a4SAndroid Build Coastguard Worker [2]: 'HEVC' (HEVC, compressed) 108*bb4ee6a4SAndroid Build Coastguard Worker [3]: 'H264' (H.264, compressed) 109*bb4ee6a4SAndroid Build Coastguard Worker``` 110*bb4ee6a4SAndroid Build Coastguard Worker 111*bb4ee6a4SAndroid Build Coastguard WorkerSimilarly, you can check the supported output (or CAPTURE) pixel formats for decoded frames: 112*bb4ee6a4SAndroid Build Coastguard Worker 113*bb4ee6a4SAndroid Build Coastguard Worker```sh 114*bb4ee6a4SAndroid Build Coastguard Workerv4l2-ctl -d/dev/video0 --list-formats 115*bb4ee6a4SAndroid Build Coastguard Workerioctl: VIDIOC_ENUM_FMT 116*bb4ee6a4SAndroid Build Coastguard Worker Type: Video Capture Multiplanar 117*bb4ee6a4SAndroid Build Coastguard Worker 118*bb4ee6a4SAndroid Build Coastguard Worker [0]: 'NV12' (Y/CbCr 4:2:0) 119*bb4ee6a4SAndroid Build Coastguard Worker``` 120*bb4ee6a4SAndroid Build Coastguard Worker 121*bb4ee6a4SAndroid Build Coastguard Worker### Test decoding with ffmpeg 122*bb4ee6a4SAndroid Build Coastguard Worker 123*bb4ee6a4SAndroid Build Coastguard Worker[FFmpeg](https://ffmpeg.org/) can be used to decode video streams with the virtio-video device. 124*bb4ee6a4SAndroid Build Coastguard Worker 125*bb4ee6a4SAndroid Build Coastguard WorkerSimple VP8 stream: 126*bb4ee6a4SAndroid Build Coastguard Worker 127*bb4ee6a4SAndroid Build Coastguard Worker```sh 128*bb4ee6a4SAndroid Build Coastguard Workerwget https://github.com/chromium/chromium/raw/main/media/test/data/test-25fps.vp8 129*bb4ee6a4SAndroid Build Coastguard Workerffmpeg -codec:v vp8_v4l2m2m -i test-25fps.vp8 test-25fps-%d.png 130*bb4ee6a4SAndroid Build Coastguard Worker``` 131*bb4ee6a4SAndroid Build Coastguard Worker 132*bb4ee6a4SAndroid Build Coastguard WorkerThis should create 250 PNG files each containing a decoded frame from the stream. 133*bb4ee6a4SAndroid Build Coastguard Worker 134*bb4ee6a4SAndroid Build Coastguard WorkerWEBM VP9 stream: 135*bb4ee6a4SAndroid Build Coastguard Worker 136*bb4ee6a4SAndroid Build Coastguard Worker```sh 137*bb4ee6a4SAndroid Build Coastguard Workerwget https://test-videos.co.uk/vids/bigbuckbunny/webm/vp9/720/Big_Buck_Bunny_720_10s_1MB.webm 138*bb4ee6a4SAndroid Build Coastguard Workerffmpeg -codec:v vp9_v4l2m2m -i Big_Buck_Bunny_720_10s_1MB.webm Big_Buck_Bunny-%d.png 139*bb4ee6a4SAndroid Build Coastguard Worker``` 140*bb4ee6a4SAndroid Build Coastguard Worker 141*bb4ee6a4SAndroid Build Coastguard WorkerShould create 300 PNG files at 720p resolution. 142*bb4ee6a4SAndroid Build Coastguard Worker 143*bb4ee6a4SAndroid Build Coastguard Worker### Test decoding with v4l2r 144*bb4ee6a4SAndroid Build Coastguard Worker 145*bb4ee6a4SAndroid Build Coastguard WorkerThe [v4l2r](https://github.com/Gnurou/v4l2r) Rust crate also features an example program that can 146*bb4ee6a4SAndroid Build Coastguard Workeruse this driver to decode simple H.264 streams: 147*bb4ee6a4SAndroid Build Coastguard Worker 148*bb4ee6a4SAndroid Build Coastguard Worker```sh 149*bb4ee6a4SAndroid Build Coastguard Workergit clone https://github.com/Gnurou/v4l2r 150*bb4ee6a4SAndroid Build Coastguard Workercd v4l2r 151*bb4ee6a4SAndroid Build Coastguard Workerwget https://github.com/chromium/chromium/raw/main/media/test/data/test-25fps.h264 152*bb4ee6a4SAndroid Build Coastguard Workercargo run --example simple_decoder test-25fps.h264 /dev/video0 --input_format h264 --save test-25fps.nv12 153*bb4ee6a4SAndroid Build Coastguard Worker``` 154*bb4ee6a4SAndroid Build Coastguard Worker 155*bb4ee6a4SAndroid Build Coastguard WorkerThis will decode `test-25fps.h264` and write the raw decoded frames in `NV12` format into 156*bb4ee6a4SAndroid Build Coastguard Worker`test-25fps.nv12`. You can check the result with e.g. [YUView](https://github.com/IENT/YUView). 157*bb4ee6a4SAndroid Build Coastguard Worker 158*bb4ee6a4SAndroid Build Coastguard Worker### Test encoding with ffmpeg 159*bb4ee6a4SAndroid Build Coastguard Worker 160*bb4ee6a4SAndroid Build Coastguard Worker[FFmpeg](https://ffmpeg.org/) can be used to encode video streams with the virtio-video device. 161*bb4ee6a4SAndroid Build Coastguard Worker 162*bb4ee6a4SAndroid Build Coastguard WorkerThe following examples generates a test clip through libavfilter and encode it using the virtual 163*bb4ee6a4SAndroid Build Coastguard WorkerH.264, H.265 and VP8 encoder, respectively. (VP9 v4l2m2m support is missing in FFmpeg for some 164*bb4ee6a4SAndroid Build Coastguard Workerreason.) 165*bb4ee6a4SAndroid Build Coastguard Worker 166*bb4ee6a4SAndroid Build Coastguard Worker```sh 167*bb4ee6a4SAndroid Build Coastguard Worker# H264 168*bb4ee6a4SAndroid Build Coastguard Workerffmpeg -f lavfi -i smptebars=duration=10:size=640x480:rate=30 \ 169*bb4ee6a4SAndroid Build Coastguard Worker -pix_fmt nv12 -c:v h264_v4l2m2m smptebars.h264.mp4 170*bb4ee6a4SAndroid Build Coastguard Worker# H265 171*bb4ee6a4SAndroid Build Coastguard Workerffmpeg -f lavfi -i smptebars=duration=10:size=640x480:rate=30 \ 172*bb4ee6a4SAndroid Build Coastguard Worker -pix_fmt yuv420p -c:v hevc_v4l2m2m smptebars.h265.mp4 173*bb4ee6a4SAndroid Build Coastguard Worker# VP8 174*bb4ee6a4SAndroid Build Coastguard Workerffmpeg -f lavfi -i smptebars=duration=10:size=640x480:rate=30 \ 175*bb4ee6a4SAndroid Build Coastguard Worker -pix_fmt yuv420p -c:v vp8_v4l2m2m smptebars.vp8.webm 176*bb4ee6a4SAndroid Build Coastguard Worker``` 177*bb4ee6a4SAndroid Build Coastguard Worker 178*bb4ee6a4SAndroid Build Coastguard Worker[v3]: https://markmail.org/message/dmw3pr4fuajvarth 179*bb4ee6a4SAndroid Build Coastguard Worker[v5]: https://markmail.org/message/zqxmuf5x7aosbmmm 180