Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
496 changes: 338 additions & 158 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"vhost-device-gpu",
"vhost-device-i2c",
"vhost-device-input",
"vhost-device-media",
"vhost-device-rng",
"vhost-device-scsi",
"vhost-device-scmi",
Expand Down
14 changes: 14 additions & 0 deletions vhost-device-media/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Changelog
## Unreleased

### Added

### Changed

### Fixed

### Deprecated

## v0.1.0

First release
48 changes: 48 additions & 0 deletions vhost-device-media/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[package]
name = "vhost-device-media"
version = "0.1.0"
authors = ["Albert Esteve <aesteve@redhat.com>"]
description = "A virtio-media device using the vhost-user protocol."
repository = "https://github.com/rust-vmm/vhost-device"
keywords = ["vhost", "media", "virt", "backend"]
license = "Apache-2.0 OR BSD-3-Clause"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = ["v4l2-proxy"]
v4l2-proxy = ["v4l2r"]
ffmpeg = ["v4l2r", "virtio-media-ffmpeg-decoder"]
simple-capture = ["v4l2r"]

[dependencies]
bitflags = "2.6.0"
clap = { version = "4.5.20", features = ["derive"] }
env_logger = "0.11.5"
epoll = "4.3.3"
num_enum = "0.7.3"
log = "0.4.22"
libc = "0.2.162"
thiserror = "2.0.3"
anyhow = "1.0.93"
futures-executor = { version = "0.3.31", features = ["thread-pool"] }
vhost = { git = "https://github.com/rust-vmm/vhost", branch = "main", features = ["vhost-user-backend"] }
vhost-user-backend = { git = "https://github.com/rust-vmm/vhost", branch = "main"}
virtio-bindings = "0.2.5"
virtio-queue = "0.17.0"
vm-memory = { version = "0.17.1", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = "0.15.0"
ref-cast = "1.0.23"
virtio-media = { git = "https://github.com/chromeos/virtio-media", rev = "c6cc93a"}
virtio-media-ffmpeg-decoder = { git = "https://github.com/chromeos/virtio-media/", package = "virtio-media-ffmpeg-decoder", rev = "c6cc93a", optional = true}
v4l2r = { git = "https://github.com/Gnurou/v4l2r", rev = "7b44138", optional = true }
Comment on lines +37 to +39
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v4l2r and virtio-media are on crates.io, are they behind this revision? Maybe we can request new releases (and also publishing of virtio-media-ffmpeg-decoder)

Copy link
Contributor Author

@aesteve-rh aesteve-rh Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with virtio-media from crates.io is that ffmpeg-decoder has the dependency set with a relative path (https://github.com/chromeos/virtio-media/blob/main/extras/ffmpeg-decoder/Cargo.toml#L13).

Cargo treats these as different crates, so VideoDecoder expects VideoDecoderBackend from crates.io 0.0.7, but FfmpegDecoder implements VideoDecoderBackend from the git version. Rust sees these as different traits, causing E0277: the trait bound FfmpegDecoder: VideoDecoderBackend is not satisfied.

I did send this PR some time ago: chromeos/virtio-media#19
But I must confess I did not follow up. And maybe I did not explain the issue good enough.

Maybe I can use the crates.io version and patch it in the root Cargo.toml, as a workaround.

Asking them to publish virtio-media-ffmpeg-decoder sounds reasonable.

For v4l2r I tested and it works now with the latest released version, so that much is good. I will change it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could try to do that after this PR is merged then :) It's not that we need crates.io publishing anyway.

zerocopy = { version = "0.8.27", features = ["derive"] }

[dev-dependencies]
assert_matches = "1.5.0"
rstest = "0.26.1"
tempfile = "3.14.0"
virtio-queue = { version = "0.17.0", features = ["test-utils"] }
vm-memory = { version = "0.17.1", features = ["backend-mmap", "backend-atomic"] }
zerocopy = { version = "0.8.27", features = ["derive"] }
1 change: 1 addition & 0 deletions vhost-device-media/LICENSE-APACHE
1 change: 1 addition & 0 deletions vhost-device-media/LICENSE-BSD-3-Clause
72 changes: 72 additions & 0 deletions vhost-device-media/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# vhost-device-media

A virtio-media device using the vhost-user protocol.

This crate provides a vhost-user backend for virtio-media devices. It is an implementation of the VIRTIO Media Device specification, which can be found on [virtio-spec v1.4](https://docs.oasis-open.org/virtio/virtio/v1.4/virtio-v1.4.html). The purpose of this device is to provide a standardized way for virtual machines to access media devices on the host.

The low-level implementation of the virtio-media protocol is provided by the device crate from the [virtio-media](https://github.com/chromeos/virtio-media) repository.

## Synopsis

```console
vhost-device-media --socket-path <SOCKET> --v4l2-device <V4L2_DEVICE> --backend <BACKEND>
```

## Description


## Options

```text
--socket-path <SOCKET>
vhost-user Unix domain socket path

--v4l2-device <V4L2_DEVICE>
Path to the V4L2 media device file. Defaults to /dev/video0.

--backend <BACKEND>
Media backend to be used. [possible values: simple-capture, v4l2-proxy, ffmpeg-decoder]

-h, --help
Print help

-V, --version
Print version
```

## Examples

Launch the backend on the host machine:

```shell
host# vhost-device-media --socket-path /tmp/media.sock --v4l2-device /dev/video0 --backend v4l2-proxy
```

With QEMU, you can add a `virtio` device that uses the backend's socket with the following flags:

```text
-chardev socket,id=vmedia,path=/tmp/media.sock \
-device vhost-user-media-pci,chardev=vmedia,id=media
```

## Features

The following backends are available:

- **simple-capture**: A simple video capture device generating a pattern, purely software-based and thus not requiring any kind of hardware. Can be used for testing purposes.
- **v4l2-proxy**: A proxy device for host V4L2 devices, i.e. a device allowing to expose a host V4L2 device to the guest almost as-is.
- **ffmpeg-decoder**: A software-based video decoder backend using FFmpeg.

## Limitations

This crate is currently under active development.

- **dmabuf memory sharing**: DMA buffer (dmabuf) support for zero-copy memory sharing between guest and host and through multiple virtio devices using VirtIO shared objects is not yet implemented. Currently, all memory operations use regular memory mappings.
- **Kernel driver availability**: The virtio-media kernel driver is still being upstreamed to the Linux kernel and may not be available in all kernel versions. Check [virtio-media](https://github.com/chromeos/virtio-media) for instructions on how to build the OOT module.

## License

This project is licensed under either of

- [Apache License](http://www.apache.org/licenses/LICENSE-2.0), Version 2.0
- [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
Loading