Skip to content

feat(build): decode AV1 with libdav1d in the web and decode presets - #84

Merged
Project516 merged 2 commits into
masterfrom
feat/dav1d-web-decode
Oct 6, 2026
Merged

Project516 merged 2 commits into
masterfrom
feat/dav1d-web-decode

Conversation

@Project516

@Project516 Project516 commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

What and why

Adds AV1 decoding through libdav1d to the web and decode presets. FFmpeg's own AV1 decoder needs hardware acceleration, so without libdav1d no core can decode AV1 in software. Backported from upstream ffmpegwasm#982.

  • build/dav1d.sh and build/meson-cross.ini: dav1d 1.5.4 (commit 54706fc6bc0cdecab7e9593974a4039cc038fca7) built static with meson, asm and tools off, default bitdepths (8 and 16). Upstream's /meson-cross.ini is not in our tree, so the cross file is included here.
  • Dockerfile: a dav1d-builder stage pinned with DAV1D_BRANCH and DAV1D_COMMIT (tag dereferenced via git ls-remote), copied into ffmpeg-base like every other library.
  • web.env and decode.env: --enable-libdav1d, -ldav1d, the libdav1d decoder (and the av1 parser in web).
  • Docs: presets table, Libraries table in overview, scripts/check-doc-versions.mjs row, CHANGELOG.
  • scripts/preset-check.mjs (run by the build-preset jobs): both presets must list libdav1d and decode tests/fixtures/av1.webm. The fixture is the 1.5 KB, 4 frame, 64x64 testsrc clip from upstream Decode AV1 with libdav1d; parity with native FFmpeg 9 on FATE ffmpegwasm/ffmpeg.wasm#982, encoded with SVT-AV1 (generated video, no third-party content).

Threading

dav1d is built with its default pthread support for both cores. The st core forces av_cpu_count() to 1, so libdav1d runs with one thread and spawns no workers; the mutex and condvar calls it still makes go through the existing fiber shim. The mt core gets real threads. This is untested here, so the st AV1 decode in preset-check is the check to watch.

full is unchanged on purpose

The published packages use full, which neither enables nor links libdav1d. It follows after the size is measured. Library stages build for every preset in this repo, so libdav1d.a lands in the shared install dir, but --disable-autodetect keeps full from using it.

Size

Read the wasm delta for web and decode from the build-preset job summaries (each prints a size row) and compare with the table in apps/website/docs/presets.md. I did not update that table.

Not run locally

Nothing was built or run; this is a Raspberry Pi and core builds are CI-only. Only node scripts/check-doc-versions.mjs ran, and it passes.

Noticed, not fixed

Review

review-bot's verification step failed on this head, and its Dockerfile note is answered in a comment. A Sonnet reviewer found nothing blocking. It checked the meson cross file, the 1.5.4 commit pin, and the st link (with av_cpu_count() at 1, libdav1d runs without threads). It also ran the AV1 fixture through a local ffmpeg: 4 frames decode. At its suggestion, the full preset check now fails if libdav1d is linked. Size cost from the first CI run, against the presets.md table: web st +0.74 MB wasm (+0.27 MB gzip), web mt +0.68 MB (+0.26 MB gzip), decode st +0.10 MB (+0.07 MB gzip).

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: bb5b48c0-055b-4ec8-8393-c06c9346d4a7
📥 Commits

Reviewing files that changed from the base of the PR and between 6e7a13d and c0f1055.

⛔ Files ignored due to path filters (1)
  • tests/fixtures/av1.webm is excluded by !**/*.webm
📒 Files selected for processing (10)
  • CHANGELOG.md
  • Dockerfile
  • apps/website/docs/overview.md
  • apps/website/docs/presets.md
  • build/dav1d.sh
  • build/meson-cross.ini
  • build/presets/decode.env
  • build/presets/web.env
  • scripts/check-doc-versions.mjs
  • scripts/preset-check.mjs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (11)
  • GitHub Check: build
  • GitHub Check: build-preset (web, st)
  • GitHub Check: build-preset (decode, mt)
  • GitHub Check: build-core
  • GitHub Check: build-preset (web, mt)
  • GitHub Check: js
  • GitHub Check: build-preset (decode, st)
  • GitHub Check: build-core-mt
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (c-cpp)
🧰 Additional context used
📚 Code guidelines (1)
apps/website/docs/presets.md — auto-discovered
📓 Path-based instructions (2)
Source excerpt: CI builds `web` and `decode` for both cores, checks that each core has the codecs its preset lists and none that it leaves out, and runs a short decode and encode (`scripts/preset-check.mjs`).

📄 CodeRabbit inference engine (apps/website/docs/presets.md)

Files:

  • scripts/preset-check.mjs
Source excerpt: The preset files are `build/presets/.env`.

📄 CodeRabbit inference engine (apps/website/docs/presets.md)

Files:

  • build/presets/decode.env
  • build/presets/web.env
🪛 Checkov (3.3.17)
Dockerfile

[low] 200-200: Ensure that COPY is used instead of ADD in Dockerfiles

(CKV_DOCKER_4)


[low] 1-267: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-267: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 Shellcheck (0.11.0)
build/dav1d.sh

[info] 6-6: Double quote to prevent globbing and word splitting.

(SC2086)

🔇 Additional comments (2)
build/dav1d.sh (2)

5-5: 🩺 Stability & Availability

The pinned emscripten/emsdk image sets WorkingDir to /src on both listed platforms. The dav1d stage inherits that directory and adds the source tree at /src, so meson setup build uses the intended source directory. Passing /src explicitly is not needed.


5-7: 🩺 Stability & Availability

The decoder-list-only concern is refuted: the preset checker also decodes tests/fixtures/av1.webm, and CI invokes it for both st presets. The separate pthread-compatibility concern remains undecidable because the effective Meson thread dependency flags and resulting link or decode outcome are not available. The evidence does not establish that dav1d’s flags conflict with the st link.


📝 Summary

Summary by CodeRabbit

  • New Features
    • Added AV1 video decoding via libdav1d 1.5.4 to the web and decode presets.
    • Added an AV1 playback check for presets that support libdav1d.
  • Documentation
    • Updated the preset descriptions and library listings to reflect AV1 decoding support.
    • Clarified that the full preset and published cores do not yet include libdav1d.

Walkthrough

The change adds an Emscripten build of dav1d 1.5.4 and enables AV1 decoding through libdav1d in the web and decode presets. It also adds an AV1 fixture check and updates documentation.

Changes

AV1 decoding with dav1d

Layer / File(s) Summary
Build and install dav1d
Dockerfile, build/dav1d.sh, build/meson-cross.ini
The Docker build compiles pinned dav1d source with Meson for Emscripten and copies the installed files into ffmpeg-base.
Enable dav1d in FFmpeg presets
build/presets/decode.env, build/presets/web.env
The web and decode presets enable and link libdav1d. The web preset also enables the AV1 parser and related libraries.
Check and document AV1 support
scripts/preset-check.mjs, scripts/check-doc-versions.mjs, apps/website/docs/*, CHANGELOG.md
The preset checker decodes an AV1 fixture for web and decode. Documentation and the changelog describe dav1d 1.5.4 and its preset availability.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant DockerBuild
  participant Dav1dBuilder
  participant FFmpegBuild
  participant PresetChecker
  DockerBuild->>Dav1dBuilder: build and install dav1d for Emscripten
  DockerBuild->>FFmpegBuild: copy dav1d installation
  FFmpegBuild->>FFmpegBuild: link dav1d in web and decode presets
  PresetChecker->>FFmpegBuild: decode AV1 fixture with applicable presets
Loading

Merge Risk: ⚪ Minimal · up to c0f10

No concrete issue is identified that blocks merging. The configured AV1 preset checks should run as part of normal CI validation.

Security Architecture Review

Security architecture risk: 🔵 Low · up to c0f10

The new decoder expands media-processing exposure, but its source is commit-pinned, existing network restrictions remain, and the default published preset does not enable it. No introduced vulnerability was established. Decoder cleanup and recovery after malformed input or interruption remain unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — Runtime exposure expands for applications choosing web or decode and supplying AV1 media. A decoder fault would affect the consuming core's memory, virtual files and availability. Build-time dependency exposure extends to every preset because all consume the dav1d builder output; cross-tenant access or host escape is not established.

Trust Boundaries and Controls

  • observed — The new dependency crosses an upstream-source-to-build boundary under a fixed commit pin. The new validation input remains repository-owned; the checker's existing ability to load a caller-selected core is unchanged by the PR.

Resilience and Maintainability Implications

  • observed — The existing exec binding frees constructed arguments and restores the Wasm stack in a finally block, and initializes st fiber state before each invocation. Reset only clears return status and timeout; these controls do not prove cleanup of dav1d's internal state after abnormal execution.

Hardening Proposals

  • proposed — Validate malformed AV1 input and interruption followed by another execution on both st and mt cores, checking decoder-thread and allocation cleanup. This would resolve the specific recovery uncertainty; it is not evidence of a present defect.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 5 files. (5 skipped: 5 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: adding libdav1d AV1 decoding to the web and decode presets.
Description check ✅ Passed The description explains the libdav1d build, preset changes, documentation updates, and AV1 decode checks. It is directly related to the changeset.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 5 files. (5 skipped: 5 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch feat/dav1d-web-decode
✨ Simplify code
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit hears the AV1 stream,
And builds dav1d to decode the gleam.
The web and decode presets join the play,
A fixture checks the frames along the way.
I nibble greens and hop away.

Comment @coderabbitai help to get the list of available commands.

@project516-review-bot project516-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The pull request adds AV1 decoding via libdav1d to the web and decode presets. It updates the Dockerfile to build libdav1d, modifies the preset environment files to enable the libdav1d decoder, and updates documentation and tests to reflect the change.

Not approved: the check on these comments could not run, so they are unverified.

Other notes

  • Dockerfile: The ADD command with a fragment (#$DAV1D_COMMIT) is not standard for Git over HTTP and may not fetch the desired commit. Instead, use the same pattern as other libraries in this Dockerfile: clone with the branch and then verify the commit. Replace this line and the subsequent RUN line (line 203) with:

RUN git clone --recursive -b $DAV1D_BRANCH https://code.videolan.org/videolan/dav1d.git /src &&
test "$(git -C /src rev-parse HEAD)" = "$DAV1D_COMMIT"
COPY build/meson-cross.ini /meson-cross.ini
COPY build/dav1d.sh /src/build.sh
RUN bash -x /src/build.sh


review-bot, model nvidia/nemotron-3-super-120b-a12b:free, verdict comment

@Project516

Copy link
Copy Markdown
Owner Author

On review-bot's Dockerfile note: ADD <repo>.git#<commit> does fetch that exact commit. Since #80, every library stage in master's Dockerfile uses this pattern, and #80's CI built both cores and all presets with it. dav1d follows the same pattern, so I'm keeping it.

@Project516
Project516 force-pushed the feat/dav1d-web-decode branch from c0f1055 to 4ccb6fa Compare October 6, 2026 01:37

@project516-review-bot project516-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The PR integrates libdav1d 1.5.4 as an AV1 decoder for the web and decode presets via dedicated build stages and environment flags. Preset documentation is updated to reflect the new AV1 decoding capability, and the preset-check script gains an AV1 decode verification step using a generated test fixture.


review-bot, model nvidia/nemotron-3.5-lightning:free, verdict approve

@Project516
Project516 merged commit 99a5cc5 into master Oct 6, 2026
19 checks passed
@Project516
Project516 deleted the feat/dav1d-web-decode branch October 6, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant