From 76be2a3a4111636292f8cf480773edcb6cfe755f Mon Sep 17 00:00:00 2001 From: roshan-ku Date: Wed, 12 Aug 2026 14:34:56 +0530 Subject: [PATCH 1/7] docs: add pip --break-system-packages and nasm troubleshooting steps --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 7800cd8..1232712 100644 --- a/README.md +++ b/README.md @@ -680,6 +680,19 @@ sudo pkill -9 -f dvledtx # Group should be 'vfio' with rw permissions ``` +6. **`pip install` fails with `externally-managed-environment`** + - On newer systems (Ubuntu 24.04+, PEP 668) `pip` refuses to install packages system-wide, which breaks installing the Python build tools (`meson`, `ninja`, `pyelftools`) required by DPDK/MTL. Re-run the install with `--break-system-packages`: + ```bash + pip install --break-system-packages meson ninja pyelftools + ``` + +7. **FFmpeg `./configure` fails with `nasm/yasm not found or too old`** + - Building FFmpeg (and DPDK) requires the NASM assembler. If configuring FFmpeg errors out looking for `nasm`, install it: + ```bash + sudo apt install -y nasm + ``` + - Then re-run FFmpeg's `./configure`. + ## Contributing Contributions are welcome. Please open an issue or submit a pull request on [GitHub](https://github.com/OpenVisualCloud/directview-led-software-toolkit). From a383fb5981b13393398da9918411a29749a4b61f Mon Sep 17 00:00:00 2001 From: roshan-ku Date: Thu, 13 Aug 2026 11:33:03 +0530 Subject: [PATCH 2/7] docs: frame virtual-display packages as optional example, not a dependency --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1232712..4f304bd 100644 --- a/README.md +++ b/README.md @@ -106,10 +106,7 @@ FFmpeg is an open source project licensed under LGPL and GPL. See https://www.ff ``` If this prints nothing, FFmpeg needs to be reconfigured/rebuilt after installing the packages above — screen capture will otherwise fail at runtime with `x11grab input format not found`. - **`x11grab` only works against an X11 (Xorg) display, not Wayland** — see [Ensuring an X11 session](#ensuring-an-x11-session-required-for-screen-capture) below if you're capturing from a machine's own physical desktop session. - - **Headless machines (no physical monitor)** additionally need a virtual display to capture from — see [Screen capture on a headless machine](#screen-capture-on-a-headless-machine-no-physical-monitor) below, which requires: - ```bash - sudo apt-get install -y xserver-xorg-video-dummy ubuntu-desktop - ``` + - **Headless machines (no physical monitor)** additionally need a virtual display to capture from. This is an optional, environment-specific setup — not a dependency of dvledtx — so it is documented as an example in [Screen capture on a headless machine](#screen-capture-on-a-headless-machine-no-physical-monitor) below. - The stock `mtl_st20p` muxer only exposes `p_port`/`r_port` (2 physical NIC ports). To use more than 2 NICs with the default (non-`ENABLE_MTL_TX`) build, the plugin's `libavdevice/mtl_common.h` must be patched to add `p2_port`..`p7_port` (and matching `p2_sip`..`p7_sip`) AVOptions mapped to `devArgs.port[MTL_PORT_2..MTL_PORT_7]` / `devArgs.sip[...]`, then FFmpeg rebuilt and reinstalled. Without this patch, `nic_count` is effectively capped at 2 for the FFmpeg TX path (the `ENABLE_MTL_TX` direct-pipeline build already supports up to 8 NICs without any patch). ### Build Steps @@ -250,7 +247,12 @@ To capture from a machine's own physical display, make sure that desktop session `x11grab` needs a real X11 display to attach to — it does not work against a raw framebuffer or DRM device. On a machine with no monitor connected, create a virtual display using Xorg with the `dummy` video driver and run a desktop session on it so there's actual content to capture. Unlike Xvfb, a real Xorg server claims physical input devices — your keyboard and mouse work directly on the virtual display. -1. **Install prerequisites** (once): see [Software Requirements](#software-requirements) for the `xserver-xorg-video-dummy`/`ubuntu-desktop` packages and the `x11grab`-enabled FFmpeg build. +> The packages below are **not dvledtx dependencies** — they are only needed to construct a virtual display on a headless host. The following is an example of one way to set this up on Ubuntu; adapt it to your environment as needed. + +1. **Install the virtual-display packages** (once), along with the `x11grab`-enabled FFmpeg build. As an example, on Ubuntu: + ```bash + sudo apt-get install -y xserver-xorg-video-dummy ubuntu-desktop + ``` 2. **Create an Xorg config** for the dummy driver: ```bash From f2bf2e66134b9102679997f48b0b4bd4a70c355d Mon Sep 17 00:00:00 2001 From: roshan-ku Date: Wed, 19 Aug 2026 14:41:37 +0530 Subject: [PATCH 3/7] docs: add deployment assumptions and security model Document the dedicated-switch trust boundary raised in the SDLE review: - New docs/assumptions.md covering the TX host / dedicated L2 switch / receiver topology inside the locked cabinet, the deployment assumptions the security model depends on, the security properties the toolkit does not provide (security follows MTL and ST 2110, offloaded to physical and L2 isolation), and the residual risk with mitigations. - Link the new document from the README overview and from Security.md, which now also states the in-scope and out-of-scope components. --- README.md | 16 ++++++++ Security.md | 17 ++++++++ docs/assumptions.md | 94 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 docs/assumptions.md diff --git a/README.md b/README.md index 4f304bd..6d95edc 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ ## Table of Contents - [Overview](#overview) + - [Deployment Security Model](#deployment-security-model) - [Notices](#notices) - [Features](#features) - [Building](#building) @@ -56,6 +57,21 @@ dvledtx reads a video source file (e.g., MP4), decodes it using FFmpeg, and tran | **Memory** | Hugepages configured (typically 2GB+) | | **Kernel** | IOMMU and VFIO support enabled | +### Deployment Security Model + +dvledtx is intended for deployment on a physically secured, network-isolated media segment: the +TX host, a dedicated L2 switch and the receivers all sit inside a locked cabinet, with all NICs +on the TX host used for transmission onto that switch. + +The transport (SMPTE ST 2110-20) and its PTP timing provide no authentication, encryption or +integrity protection — security is delegated to MTL/ST 2110 and to physical and Layer 2 +isolation. Integrators must therefore verify the deployment assumptions before relying on this +model. + +See **[Deployment Assumptions and Security Model](docs/assumptions.md)** for the trust boundary, +the required deployment assumptions, the security properties the toolkit does not provide, and +the residual risk and mitigations. + ## Notices ### FFmpeg diff --git a/Security.md b/Security.md index d5f1e5e..21f1f88 100644 --- a/Security.md +++ b/Security.md @@ -1,6 +1,23 @@ # Security Policy Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. +## Security Model + +dvledtx is designed for deployment on a physically secured, network-isolated media segment. The +transport (SMPTE ST 2110-20) and its PTP timing provide no authentication, encryption or +integrity protection; security is delegated to MTL/ST 2110 and to the physical and Layer 2 +isolation of that segment. + +**In scope:** the dvledtx transmitter application, its JSON configuration parsing, and its use +of FFmpeg and the Media Transport Library. + +**Out of scope:** the receivers (customer-designed, typically FPGA-based, and not delivered with +this toolkit), the LED panels, and the physical and network controls of the installation site. + +The trust boundary, the deployment assumptions this model depends on, and the residual risk if +those assumptions are broken are documented in +[Deployment Assumptions and Security Model](docs/assumptions.md). + ## Reporting a Vulnerability Please report any security vulnerabilities in this project [utilizing the guidelines here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). diff --git a/docs/assumptions.md b/docs/assumptions.md new file mode 100644 index 0000000..b1f594a --- /dev/null +++ b/docs/assumptions.md @@ -0,0 +1,94 @@ +# Deployment Assumptions and Security Model + +dvledtx transmits uncompressed video using the SMPTE ST 2110-20 standard. That transport, and +the PTP timing it depends on, carry no authentication, encryption or integrity protection. The +security of a deployment therefore rests on the **physical and Layer 2 isolation of the media +segment**, not on controls inside this application. + +This document records that trust boundary, the assumptions it depends on, and the risk that +remains if those assumptions are broken. + +## Table of Contents + +- [Trust Boundary and Topology](#trust-boundary-and-topology) +- [Deployment Assumptions](#deployment-assumptions) +- [Security Properties Not Provided by This Toolkit](#security-properties-not-provided-by-this-toolkit) +- [Residual Risk and Defence in Depth](#residual-risk-and-defence-in-depth) + +## Trust Boundary and Topology + +``` + ┌───────────────────── locked cabinet ──────────────────────┐ + │ │ + │ TX host Dedicated Receivers │ + │ (dvledtx) ──▶ L2 switch ──▶ (FPGA) ──▶ LED wall + │ all NICs = TX media + PTP customer- │ + │ VLAN only designed │ + └───────────────────────────────────────────────────────────┘ + ▲ + └── isolation boundary: + no uplink to any other network +``` + +| Element | Role | Position relative to the boundary | +|---------|------|-----------------------------------| +| **TX host** (dvledtx) | Decodes, crops and transmits ST 2110-20 streams | Inside the locked cabinet | +| **Dedicated L2 switch** | Carries media (ST 2110-20) and PTP traffic only | The isolation boundary itself — no uplink to a corporate or building network | +| **Receivers** | Receive streams and drive the LED panels | Inside the cabinet; **customer-designed (typically FPGA-based) and out of scope for this toolkit** | +| **Administrator** | Configures and operates the TX host | Enters through the physical cabinet lock | + +**All NICs on the TX host are used for transmission.** `interfaces[]` may declare up to 8 NICs, +and every one of them is consumed by ST 2110-20 TX onto the dedicated switch. The TX host does +not bridge the media segment to any other network. + +## Deployment Assumptions + +The model above is only valid while all of the following hold. They are the responsibility of +the integrator, and should be verified at installation and after any change to the +installation: + +| # | Assumption | Why it matters | +|---|------------|----------------| +| 1 | The TX host, switch and receivers are installed in a **physically locked cabinet**, with keyed access restricted to authorised administrators | Physical access to the equipment is equivalent to full control over what is displayed on the wall | +| 2 | The switch is **dedicated to the media segment** and has **no uplink** to a corporate, building or guest network | An uplink extends the trust boundary to every network it reaches | +| 3 | **All unused switch ports are administratively disabled** | A live port reachable outside the cabinet — for example a patched wall socket believed to be disconnected — places an attacker directly inside the boundary | +| 4 | Media and PTP traffic run on a **dedicated VLAN**, with no DHCP server and no general-purpose hosts attached to it | Prevents an attached device from being addressed onto the media network, and keeps unrelated traffic off the transmission path | + +## Security Properties Not Provided by This Toolkit + +Transmission is delegated to the +[Media Transport Library (MTL)](https://github.com/OpenVisualCloud/Media-Transport-Library) and +follows the SMPTE ST 2110 standards. dvledtx hands decoded frames to MTL and does not add +security controls above it — the security of the wire is offloaded to physical and Layer 2 +isolation. + +State the following explicitly when assessing a deployment: + +- **No authentication** of ST 2110-20 senders or receivers. +- **No encryption** of the video payload on the wire. +- **No integrity or replay protection** on the media path. +- **No authentication on the PTP path** — PTP is a broadcast protocol with no grandmaster + validation. + +## Residual Risk and Defence in Depth + +Physical isolation reduces exposure but does not eliminate it. If an adversary obtains Layer 2 +access to the media VLAN — for example by connecting to an overlooked live switch port — the +following become feasible and are **not** mitigated in software: + +| Risk | Effect | Mitigation | +|------|--------|------------| +| Injection of a rogue ST 2110-20 stream | Unauthorised or offensive content displayed on the LED wall | Physically block access to the L2 media VLAN (locked cabinet, disabled unused ports, switch port security / 802.1X); operator visual detection of anomalous wall output | +| Rogue PTP grandmaster | TX pacing skew and stream disruption | Keep PTP on the isolated VLAN; leave PTP disabled (default TSC pacing) unless a trusted grandmaster is present | +| Traffic flooding on the media VLAN | Frame loss and visible artefacts on the wall | Dedicated switch with no other traffic; IGMP snooping | +| Passive capture of video | Loss of content confidentiality | Physical isolation only — no encryption is available on the ST 2110-20 path | + +**Detection and response are physical and visual.** There is no in-band alerting: an operator +observes anomalous output on the LED wall, and an administrator unlocks the cabinet to inspect, +disconnect or power-cycle the affected equipment. + +> **Known accepted risk.** Because all authentication and encryption are absent by design of the +> transport, an adversary who defeats the physical and L2 isolation has no further software +> barrier. This is accepted for the current deployment profile and is pending validation by an +> adversarial-testing exercise. This document will be revisited if authentication or encryption +> become available in the underlying transport. From f4a7296669130a213cf5e96e88945e8c124b609e Mon Sep 17 00:00:00 2001 From: roshan-ku Date: Fri, 21 Aug 2026 11:31:06 +0530 Subject: [PATCH 4/7] docs: pin MTL references to the merged commit id Replace the ffmpeg-plugin-extra-pixel-format tag with commit 7bee24231c864d12da6db2c2ffbfd3986717af5a in the clone instructions and in all MTL documentation links, so the build steps reference a fixed commit rather than a movable tag. Addresses PR review feedback. --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6d95edc..9374395 100644 --- a/README.md +++ b/README.md @@ -98,20 +98,20 @@ FFmpeg is an open source project licensed under LGPL and GPL. See https://www.ff > **Note:** This toolkit has been validated against **Ubuntu 22.04 LTS** but should work on Ubuntu 24.04 LTS and higher versions. - Ubuntu [22.04](https://releases.ubuntu.com/jammy/) or [24.04](https://releases.ubuntu.com/noble/) LTS -- [Media Transport Library (MTL) v26.01+](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/ffmpeg-plugin-extra-pixel-format/doc/build.md) +- [Media Transport Library (MTL) v26.01+](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/7bee24231c864d12da6db2c2ffbfd3986717af5a/doc/build.md) - Follow these steps - - [Install APT packages](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/ffmpeg-plugin-extra-pixel-format/doc/build.md#111-ubuntudebian) + - [Install APT packages](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/7bee24231c864d12da6db2c2ffbfd3986717af5a/doc/build.md#111-ubuntudebian) - Clone Media-Transport-Library ``` git clone https://github.com/OpenVisualCloud/Media-Transport-Library.git cd Media-Transport-Library - git checkout ffmpeg-plugin-extra-pixel-format + git checkout 7bee24231c864d12da6db2c2ffbfd3986717af5a cd .. export mtl_source_code=${PWD}/Media-Transport-Library ``` - - [Build and install DPDK](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/ffmpeg-plugin-extra-pixel-format/doc/build.md#2-dpdk-build-and-install) - - [Build and install MTL](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/ffmpeg-plugin-extra-pixel-format/doc/build.md#3-build-media-transport-library-and-app) -- [FFmpeg 7.0 with MTL Plugin](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/ffmpeg-plugin-extra-pixel-format/ecosystem/ffmpeg_plugin/README.md#1-build) + - [Build and install DPDK](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/7bee24231c864d12da6db2c2ffbfd3986717af5a/doc/build.md#2-dpdk-build-and-install) + - [Build and install MTL](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/7bee24231c864d12da6db2c2ffbfd3986717af5a/doc/build.md#3-build-media-transport-library-and-app) +- [FFmpeg 7.0 with MTL Plugin](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/7bee24231c864d12da6db2c2ffbfd3986717af5a/ecosystem/ffmpeg_plugin/README.md#1-build) - **Screen capture support (`input_mode: screen_capture`) requires FFmpeg's `x11grab` device.** It is auto-detected and compiled in by FFmpeg's `./configure` script, but only if these packages are installed *before* building FFmpeg: ```bash sudo apt-get install -y libx11-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev @@ -148,8 +148,8 @@ The built binary will be available at `build/dvledtx`. ### Binding Ethernet Controller to DPDK PMD and Hugepage Setup - Ensure VFIO group exists [follow](#vfio-group-setup) -- [DPDK PMD Setup](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/ffmpeg-plugin-extra-pixel-format/doc/run.md#3-dpdk-pmd-setup) -- [Hugepage Setup](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/ffmpeg-plugin-extra-pixel-format/doc/run.md#4-setup-hugepage) +- [DPDK PMD Setup](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/7bee24231c864d12da6db2c2ffbfd3986717af5a/doc/run.md#3-dpdk-pmd-setup) +- [Hugepage Setup](https://github.com/OpenVisualCloud/Media-Transport-Library/blob/7bee24231c864d12da6db2c2ffbfd3986717af5a/doc/run.md#4-setup-hugepage) ### JSON Configuration From 2d6cf2d92e0e784e50dd5c49bf61acc0869b5d46 Mon Sep 17 00:00:00 2001 From: roshan-ku Date: Fri, 21 Aug 2026 11:35:44 +0530 Subject: [PATCH 5/7] ci: pin MTL build to a commit id and extend daily libFuzzer run - environment-check: rename the mtl-version input to mtl-commit and default it to 7bee24231c864d12da6db2c2ffbfd3986717af5a, matching the commit the README now documents. The env cache key picks up the new value automatically, so runners rebuild instead of restoring a stale MTL. - daily_build: raise the libFuzzer run from 300s to 7200s per sanitizer mode and extend the job timeout to 300 minutes to cover both modes plus the builds. --- .github/actions/environment-check/action.yml | 22 ++++++++++---------- .github/workflows/daily_build.yml | 6 ++++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/actions/environment-check/action.yml b/.github/actions/environment-check/action.yml index 955e319..ec2b7ad 100644 --- a/.github/actions/environment-check/action.yml +++ b/.github/actions/environment-check/action.yml @@ -11,10 +11,10 @@ inputs: description: 'DPDK version to build' required: false default: '25.11' - mtl-version: - description: 'MTL release tag to build' + mtl-commit: + description: 'MTL commit ID to build' required: false - default: 'ffmpeg-plugin-extra-pixel-format' + default: '7bee24231c864d12da6db2c2ffbfd3986717af5a' ffmpeg-version: description: 'FFmpeg release branch to build' required: false @@ -37,7 +37,7 @@ runs: path: | ${{ runner.temp }}/dvledtx-deps ${{ runner.temp }}/mtl-source - key: env-dpdk-${{ inputs.dpdk-version }}-mtl-${{ inputs.mtl-version }}-ffmpeg-${{ inputs.ffmpeg-version }}-v${{ inputs.env-cache-version }}-${{ runner.os }} + key: env-dpdk-${{ inputs.dpdk-version }}-mtl-${{ inputs.mtl-commit }}-ffmpeg-${{ inputs.ffmpeg-version }}-v${{ inputs.env-cache-version }}-${{ runner.os }} - name: Deploy cache to system if: steps.env-cache.outputs.cache-hit == 'true' @@ -165,7 +165,7 @@ runs: shell: bash env: DPDK_VERSION: ${{ inputs.dpdk-version }} - MTL_VERSION: ${{ inputs.mtl-version }} + MTL_COMMIT: ${{ inputs.mtl-commit }} run: | echo "===== DPDK Setup =====" export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib/x86_64-linux-gnu/pkgconfig:${PKG_CONFIG_PATH:-} @@ -177,7 +177,7 @@ runs: MTL_SOURCE="$RUNNER_TEMP/mtl-source" if [ ! -d "$MTL_SOURCE" ]; then git clone https://github.com/OpenVisualCloud/Media-Transport-Library.git "$MTL_SOURCE" - cd "$MTL_SOURCE" && git checkout "$MTL_VERSION" + cd "$MTL_SOURCE" && git checkout "$MTL_COMMIT" fi cd "$RUNNER_TEMP" git clone https://github.com/DPDK/dpdk.git @@ -195,7 +195,7 @@ runs: - name: Build and install MTL shell: bash env: - MTL_VERSION: ${{ inputs.mtl-version }} + MTL_COMMIT: ${{ inputs.mtl-commit }} run: | echo "===== MTL Setup =====" export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib/x86_64-linux-gnu/pkgconfig:${PKG_CONFIG_PATH:-} @@ -203,11 +203,11 @@ runs: echo " [OK] mtl ($(pkg-config --modversion mtl)) — skipping build (cached)" exit 0 fi - echo " Building MTL $MTL_VERSION from source..." + echo " Building MTL $MTL_COMMIT from source..." MTL_SOURCE="$RUNNER_TEMP/mtl-source" if [ ! -d "$MTL_SOURCE" ]; then git clone https://github.com/OpenVisualCloud/Media-Transport-Library.git "$MTL_SOURCE" - cd "$MTL_SOURCE" && git checkout "$MTL_VERSION" + cd "$MTL_SOURCE" && git checkout "$MTL_COMMIT" fi cd "$MTL_SOURCE" ./build.sh @@ -241,7 +241,7 @@ runs: shell: bash env: FFMPEG_VERSION: ${{ inputs.ffmpeg-version }} - MTL_VERSION: ${{ inputs.mtl-version }} + MTL_COMMIT: ${{ inputs.mtl-commit }} run: | echo "===== FFmpeg Setup =====" export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib/x86_64-linux-gnu/pkgconfig:${PKG_CONFIG_PATH:-} @@ -347,4 +347,4 @@ runs: path: | ${{ runner.temp }}/dvledtx-deps ${{ runner.temp }}/mtl-source - key: env-dpdk-${{ inputs.dpdk-version }}-mtl-${{ inputs.mtl-version }}-ffmpeg-${{ inputs.ffmpeg-version }}-v${{ inputs.env-cache-version }}-${{ runner.os }} + key: env-dpdk-${{ inputs.dpdk-version }}-mtl-${{ inputs.mtl-commit }}-ffmpeg-${{ inputs.ffmpeg-version }}-v${{ inputs.env-cache-version }}-${{ runner.os }} diff --git a/.github/workflows/daily_build.yml b/.github/workflows/daily_build.yml index 409034d..ae4df75 100644 --- a/.github/workflows/daily_build.yml +++ b/.github/workflows/daily_build.yml @@ -107,7 +107,9 @@ jobs: libfuzzer: name: Daily libFuzzer runs-on: ubuntu-latest - timeout-minutes: 30 + # max-seconds applies per sanitizer mode (ASan + UBSan), so the fuzzing + # itself takes ~4h; allow headroom for the builds on top of that. + timeout-minutes: 300 permissions: contents: read @@ -122,7 +124,7 @@ jobs: - name: libFuzzer uses: ./.github/actions/analysis/libfuzzer with: - max-seconds: '300' + max-seconds: '7200' - name: Upload libFuzzer corpora uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 From 1ebf8f4e73d87b955b4375d285423a886330b12f Mon Sep 17 00:00:00 2001 From: roshan-ku Date: Fri, 21 Aug 2026 11:38:37 +0530 Subject: [PATCH 6/7] ci: set libFuzzer timeout to 2.3h; docs: 12-bit and multi-NIC build notes - daily_build: libFuzzer runs 3600s per sanitizer mode (~2h total) with a 138 minute job timeout. - README: 12-bit pix_fmts require MTL and FFmpeg to both be built from the pinned commit, since the plugin sources are compiled into libavdevice. - README: drop the stale instruction to hand-patch mtl_common.h for p2_port..p7_port; those AVOptions are present at the pinned commit, so 8 NICs work with the default FFmpeg TX path unpatched. --- .github/workflows/daily_build.yml | 6 +++--- README.md | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/daily_build.yml b/.github/workflows/daily_build.yml index ae4df75..ff12b61 100644 --- a/.github/workflows/daily_build.yml +++ b/.github/workflows/daily_build.yml @@ -108,8 +108,8 @@ jobs: name: Daily libFuzzer runs-on: ubuntu-latest # max-seconds applies per sanitizer mode (ASan + UBSan), so the fuzzing - # itself takes ~4h; allow headroom for the builds on top of that. - timeout-minutes: 300 + # itself takes ~2h; the rest covers the two builds. + timeout-minutes: 138 permissions: contents: read @@ -124,7 +124,7 @@ jobs: - name: libFuzzer uses: ./.github/actions/analysis/libfuzzer with: - max-seconds: '7200' + max-seconds: '3600' - name: Upload libFuzzer corpora uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/README.md b/README.md index 9374395..b230fcd 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,8 @@ FFmpeg is an open source project licensed under LGPL and GPL. See https://www.ff If this prints nothing, FFmpeg needs to be reconfigured/rebuilt after installing the packages above — screen capture will otherwise fail at runtime with `x11grab input format not found`. - **`x11grab` only works against an X11 (Xorg) display, not Wayland** — see [Ensuring an X11 session](#ensuring-an-x11-session-required-for-screen-capture) below if you're capturing from a machine's own physical desktop session. - **Headless machines (no physical monitor)** additionally need a virtual display to capture from. This is an optional, environment-specific setup — not a dependency of dvledtx — so it is documented as an example in [Screen capture on a headless machine](#screen-capture-on-a-headless-machine-no-physical-monitor) below. - - The stock `mtl_st20p` muxer only exposes `p_port`/`r_port` (2 physical NIC ports). To use more than 2 NICs with the default (non-`ENABLE_MTL_TX`) build, the plugin's `libavdevice/mtl_common.h` must be patched to add `p2_port`..`p7_port` (and matching `p2_sip`..`p7_sip`) AVOptions mapped to `devArgs.port[MTL_PORT_2..MTL_PORT_7]` / `devArgs.sip[...]`, then FFmpeg rebuilt and reinstalled. Without this patch, `nic_count` is effectively capped at 2 for the FFmpeg TX path (the `ENABLE_MTL_TX` direct-pipeline build already supports up to 8 NICs without any patch). + - **12-bit formats (`yuv422p12le`, `yuv444p12le`, `gbrp12le`) require both MTL and FFmpeg to be built from the pinned commit above.** The plugin sources are copied into FFmpeg's `libavdevice/` and compiled in, so rebuilding MTL alone is not enough — FFmpeg must be rebuilt against the same MTL commit or these formats are rejected at session setup. + - At the pinned commit the `mtl_st20p` muxer exposes `p_port`/`r_port` plus `p2_port`..`p7_port` (and matching `p2_sip`..`p7_sip`), so up to 8 NICs work with the default (non-`ENABLE_MTL_TX`) build with no local patching. Older MTL revisions exposed only `p_port`/`r_port`, which capped `nic_count` at 2 for the FFmpeg TX path; the `ENABLE_MTL_TX` direct-pipeline build has always supported up to 8 NICs. ### Build Steps @@ -404,7 +405,7 @@ pkill -f "gnome-session --session=ubuntu" sudo pkill -f "Xorg :99" ``` -`interfaces[]` supports up to 8 NICs (MTL's port limit); each `tx_sessions[]` entry picks its NIC via `nic_index` (see `config/tx_fullhd_multi_nic.json` for an 8-NIC/8-session example). Using more than 2 NICs with the default FFmpeg TX path requires the patched `mtl_st20p` muxer described above. +`interfaces[]` supports up to 8 NICs (MTL's port limit); each `tx_sessions[]` entry picks its NIC via `nic_index` (see `config/tx_fullhd_multi_nic.json` for an 8-NIC/8-session example). Using more than 2 NICs with the default FFmpeg TX path requires the `p2_port`..`p7_port` AVOptions described above, which are present at the pinned MTL commit. ## Logging From cff8a01caf196cca88da5d1439323894a69c4726 Mon Sep 17 00:00:00 2001 From: roshan-ku Date: Fri, 21 Aug 2026 21:23:39 +0530 Subject: [PATCH 7/7] ci: run daily AFL fuzzing for 2h and refresh the fuzz corpus - afl-fuzz job: max-seconds 300 -> 7200 (single AFL run, so 2h total) and timeout-minutes 25 -> 138 to leave headroom for install and build. - Corpus seeds were written against an older schema: fps/fmt were placed in the video object but the parser reads them from tx_video, so the tx_video branch was never exercised. Moved them and added scale_width/scale_height. - Added nic_index to interfaces[] and tx_sessions[]. - New seeds for parameters with no coverage: ptp_config.json (ptp enable/pi/ unicast booleans), screen_capture.json (input_mode/screen_input) and multi_nic.json (multiple interfaces, 12-bit fmt, session-to-NIC mapping). --- .github/workflows/daily_build.yml | 5 +++-- fuzz/corpus/multi_nic.json | 25 +++++++++++++++++++++++++ fuzz/corpus/multi_session.json | 2 +- fuzz/corpus/ptp_config.json | 26 ++++++++++++++++++++++++++ fuzz/corpus/screen_capture.json | 20 ++++++++++++++++++++ fuzz/corpus/valid_config.json | 11 +++++++++-- 6 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 fuzz/corpus/multi_nic.json create mode 100644 fuzz/corpus/ptp_config.json create mode 100644 fuzz/corpus/screen_capture.json diff --git a/.github/workflows/daily_build.yml b/.github/workflows/daily_build.yml index ff12b61..886f5aa 100644 --- a/.github/workflows/daily_build.yml +++ b/.github/workflows/daily_build.yml @@ -79,7 +79,8 @@ jobs: afl-fuzz: name: Daily AFL Fuzz runs-on: ubuntu-latest - timeout-minutes: 25 + # 2h of fuzzing plus headroom for dependency install and the harness build. + timeout-minutes: 138 permissions: contents: read @@ -94,7 +95,7 @@ jobs: - name: AFL Fuzz uses: ./.github/actions/analysis/afl-fuzz with: - max-seconds: '300' + max-seconds: '7200' - name: Upload AFL fuzzing results uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/fuzz/corpus/multi_nic.json b/fuzz/corpus/multi_nic.json new file mode 100644 index 0000000..03bbb9f --- /dev/null +++ b/fuzz/corpus/multi_nic.json @@ -0,0 +1,25 @@ +{ + "interfaces": [ + { "nic_index": 0, "name": "0000:06:00.0", "sip": "192.168.50.29", "dip": "239.168.85.20" }, + { "nic_index": 1, "name": "0000:06:00.1", "sip": "192.168.50.30", "dip": "239.168.85.21" }, + { "nic_index": 2, "name": "0000:06:00.2", "sip": "192.168.50.31", "dip": "239.168.85.22" } + ], + "video": { + "width": 3840, + "height": 2160, + "input_mode": "file", + "tx_url": "/dev/null" + }, + "tx_video": { + "scale_width": 3840, + "scale_height": 2160, + "fps": 50, + "fmt": "yuv444p12le" + }, + "ptp": { "enable": false }, + "tx_sessions": [ + { "nic_index": 0, "udp_port": 20000, "payload_type": 96, "crop": { "x": 0, "y": 0, "w": 1280, "h": 2160 } }, + { "nic_index": 1, "udp_port": 20002, "payload_type": 112, "crop": { "x": 1280, "y": 0, "w": 1280, "h": 2160 } }, + { "nic_index": 2, "udp_port": 20004, "crop": { "x": 2560, "y": 0, "w": 1280, "h": 2160 } } + ] +} diff --git a/fuzz/corpus/multi_session.json b/fuzz/corpus/multi_session.json index 20c9bdb..3770718 100644 --- a/fuzz/corpus/multi_session.json +++ b/fuzz/corpus/multi_session.json @@ -1 +1 @@ -{"tx_sessions": [{"udp_port": 20000, "payload_type": 96, "crop": {"x": 0, "y": 0, "w": 640, "h": 1080}}, {"udp_port": 20002, "payload_type": 96, "crop": {"x": 640, "y": 0, "w": 640, "h": 1080}}, {"udp_port": 20004, "payload_type": 96, "crop": {"x": 1280, "y": 0, "w": 640, "h": 1080}}], "interfaces": [{"name": "0000:06:00.0", "sip": "192.168.50.29", "dip": "239.168.85.20"}], "video": {"width": 1920, "height": 1080, "fps": 60, "fmt": "yuv420", "tx_url": "/dev/null"}} +{"tx_sessions": [{"nic_index": 0, "udp_port": 20000, "payload_type": 96, "crop": {"x": 0, "y": 0, "w": 640, "h": 1080}}, {"nic_index": 0, "udp_port": 20002, "payload_type": 96, "crop": {"x": 640, "y": 0, "w": 640, "h": 1080}}, {"nic_index": 0, "udp_port": 20004, "payload_type": 96, "crop": {"x": 1280, "y": 0, "w": 640, "h": 1080}}], "interfaces": [{"nic_index": 0, "name": "0000:06:00.0", "sip": "192.168.50.29", "dip": "239.168.85.20"}], "video": {"width": 1920, "height": 1080, "input_mode": "file", "tx_url": "/dev/null"}, "tx_video": {"scale_width": 1920, "scale_height": 1080, "fps": 60, "fmt": "yuv420"}} diff --git a/fuzz/corpus/ptp_config.json b/fuzz/corpus/ptp_config.json new file mode 100644 index 0000000..196647c --- /dev/null +++ b/fuzz/corpus/ptp_config.json @@ -0,0 +1,26 @@ +{ + "log_file": "dvledtx.log", + "interfaces": [ + { "nic_index": 0, "name": "0000:06:00.0", "sip": "192.168.50.29", "dip": "239.168.85.20" } + ], + "video": { + "width": 1920, + "height": 1080, + "input_mode": "file", + "tx_url": "/dev/null" + }, + "tx_video": { + "scale_width": 3840, + "scale_height": 2160, + "fps": 60, + "fmt": "gbrp12le" + }, + "ptp": { + "enable": true, + "pi": true, + "unicast": false + }, + "tx_sessions": [ + { "nic_index": 0, "udp_port": 20000, "payload_type": 96, "crop": { "x": 0, "y": 0, "w": 1920, "h": 1080 } } + ] +} diff --git a/fuzz/corpus/screen_capture.json b/fuzz/corpus/screen_capture.json new file mode 100644 index 0000000..9dd0739 --- /dev/null +++ b/fuzz/corpus/screen_capture.json @@ -0,0 +1,20 @@ +{ + "interfaces": [ + { "nic_index": 0, "name": "0000:06:00.0", "sip": "192.168.50.29", "dip": "239.168.85.20" } + ], + "video": { + "width": 1920, + "height": 1080, + "input_mode": "screen_capture", + "screen_input": ":0.0+0,0" + }, + "tx_video": { + "scale_width": 1920, + "scale_height": 1080, + "fps": 30, + "fmt": "yuv422p10le" + }, + "tx_sessions": [ + { "nic_index": 0, "udp_port": 20000, "payload_type": 96, "crop": { "x": 0, "y": 0, "w": 1920, "h": 1080 } } + ] +} diff --git a/fuzz/corpus/valid_config.json b/fuzz/corpus/valid_config.json index 6bddc6f..3fb980e 100644 --- a/fuzz/corpus/valid_config.json +++ b/fuzz/corpus/valid_config.json @@ -2,6 +2,7 @@ "log_file": "dvledtx.log", "interfaces": [ { + "nic_index": 0, "name": "0000:06:00.0", "sip": "192.168.50.29", "dip": "239.168.85.20" @@ -10,12 +11,18 @@ "video": { "width": 1920, "height": 1080, - "fps": 30, - "fmt": "yuv422p10le", + "input_mode": "file", "tx_url": "/dev/null" }, + "tx_video": { + "scale_width": 1920, + "scale_height": 1080, + "fps": 30, + "fmt": "yuv422p10le" + }, "tx_sessions": [ { + "nic_index": 0, "udp_port": 20000, "payload_type": 96, "crop": { "x": 0, "y": 0, "w": 1920, "h": 1080 }