Skip to content

fix(export): normalize WebCodecs decoder codec strings#675

Open
bernardopg wants to merge 2 commits into
webadderallorg:mainfrom
bernardopg:fix/h264-decoder-codec-normalization
Open

fix(export): normalize WebCodecs decoder codec strings#675
bernardopg wants to merge 2 commits into
webadderallorg:mainfrom
bernardopg:fix/h264-decoder-codec-normalization

Conversation

@bernardopg

@bernardopg bernardopg commented Jun 11, 2026

Copy link
Copy Markdown

Description

Adds a shared WebCodecs decoder configuration helper used by both the main streaming export decoder and the forward frame source.

The helper normalizes bare codec names returned by web-demuxer:

  • av01 to a complete AV1 codec string
  • vp08 to vp8
  • vp09 to vp9
  • h264 and bare avc1 to avc1.640033

It checks each candidate with VideoDecoder.isConfigSupported() before configuration and falls back to avc1.640033 when a malformed or unsupported AVC codec string is reported.

Motivation

H.264 recordings in WebM containers can produce codec strings such as h264, avc1, or avc1.2420032. Passing these directly to WebCodecs can fail with VideoDecoder error: Unknown or ambiguous codec name, preventing MP4 export.

Type of Change

  • Bug Fix
  • New Feature
  • Refactor / Code Cleanup
  • Documentation Update
  • Other

Related Issue(s)

Closes #674

Screenshots / Video

Not applicable; this changes decoder configuration and has unit-test coverage.

Testing Guide

  1. npm test -- src/lib/exporter/videoDecoderConfig.test.ts src/lib/exporter/streamingDecoder.test.ts
  2. npx biome check src/lib/exporter/videoDecoderConfig.ts src/lib/exporter/videoDecoderConfig.test.ts src/lib/exporter/streamingDecoder.ts src/lib/exporter/forwardFrameSource.ts
  3. Export an H.264 WebM recording whose demuxer codec is bare or malformed.

Focused result: 17 tests passed and all changed files pass Biome.

Full-suite result: 778 of 779 tests passed. The remaining Windows helper-path test requires a staged native Windows binary and fails on the Linux checkout. The repository-wide TypeScript and Biome checks also report existing diagnostics in files outside this change.

Checklist

  • I have performed a self-review of my code.
  • I have added necessary tests.
  • I have linked the related issue.

Summary by CodeRabbit

  • Refactor

    • Consolidated video decoder configuration to improve codec normalization and selection, providing broader codec compatibility and more reliable fallback behavior for export and streaming.
  • Tests

    • Added unit tests covering codec normalization and decoder configuration to ensure consistent playback and decoding behavior across formats.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7964f5e3-48e9-4ad2-a90f-80cec265ee29

📥 Commits

Reviewing files that changed from the base of the PR and between 1fa5197 and 41017b0.

📒 Files selected for processing (2)
  • src/lib/exporter/videoDecoderConfig.test.ts
  • src/lib/exporter/videoDecoderConfig.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/exporter/videoDecoderConfig.test.ts
  • src/lib/exporter/videoDecoderConfig.ts

📝 Walkthrough

Walkthrough

This PR consolidates video decoder configuration logic into a shared module. It extracts codec normalization and fallback handling from two decoder implementations into a reusable configureVideoDecoder helper, fixing H.264 WebM export failures by properly normalizing bare codec identifiers and applying strategic fallbacks.

Changes

Video decoder configuration extraction

Layer / File(s) Summary
Codec normalization and decoder configuration helper
src/lib/exporter/videoDecoderConfig.ts
Exports normalizeVideoDecoderConfig to rewrite codec strings (av01→AV1, vp08→vp8, vp09→vp9, avc1/h264→normalized AVC), defines FALLBACK_H264_CODEC, and exports configureVideoDecoder which builds prioritized decoder candidates (optional hardwareAcceleration: "prefer-software" and H.264 fallback), probes VideoDecoder.isConfigSupported, and configures the decoder with the first supported candidate or throws.
Decoder configuration tests
src/lib/exporter/videoDecoderConfig.test.ts
Vitest tests for codec normalization mappings and configureVideoDecoder fallback behavior, including H.264 fallback for unsupported avc1 strings and VP9 software-preference detection/normalization.
ForwardFrameSource integration
src/lib/exporter/forwardFrameSource.ts
Replaces inline codec-selection and try/fallback logic in startDecoder with an import and awaited call to configureVideoDecoder(this.decoder, decoderConfig).
StreamingVideoDecoder integration
src/lib/exporter/streamingDecoder.ts
Removes inline codec-based decision and try/catch fallback in decodeAll() and replaces it with an awaited call to configureVideoDecoder(this.decoder, decoderConfig).

Sequence Diagram

sequenceDiagram
  participant Caller as Decoder callsite
  participant ConfigHelper as configureVideoDecoder
  participant VideoDecoder as VideoDecoder API
  Caller->>ConfigHelper: configureVideoDecoder(decoder, decoderConfig)
  ConfigHelper->>ConfigHelper: normalizeVideoDecoderConfig(config)
  ConfigHelper->>ConfigHelper: build candidate list (prefer-software?, H.264 fallback)
  loop candidates
    ConfigHelper->>VideoDecoder: isConfigSupported(candidate)
    alt supported
      ConfigHelper->>VideoDecoder: decoder.configure(candidate)
      VideoDecoder-->>ConfigHelper: configured
      ConfigHelper-->>Caller: return chosen candidate
    else
      ConfigHelper-->>ConfigHelper: try next
    end
  end
Loading

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • webadderallorg/Recordly#452: Related changes to ForwardFrameSource initialization and decoder fallback behavior that interact with decoder configuration.

🐰 A codec tangle, once spread wide,
Now neatly bundled, side by side,
H.264 falls back with grace,
One helper shepherds every case,
I hop and clap for tidy place! 🎬

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately summarizes the main change: normalization of WebCodecs decoder codec strings to handle ambiguous codec identifiers.
Description check ✅ Passed Description covers all essential sections: purpose, motivation, type of change, linked issue, testing guide, and checklist. Properly documents the codec normalization mappings and fallback behavior.
Linked Issues check ✅ Passed All coding objectives from #674 are met: codec normalization (av01, vp08, vp09, h264/avc1), VideoDecoder.isConfigSupported() validation, and H.264 fallback to avc1.640033.
Out of Scope Changes check ✅ Passed All changes are directly scoped to resolving #674: decoder configuration helper, codec normalization mappings, and integration into StreamingVideoDecoder and ForwardFrameSource.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/exporter/videoDecoderConfig.ts`:
- Around line 14-20: The prefersSoftwareDecode helper currently only matches the
exact "vp9" string; update it to recognize full VP9 codec identifiers (e.g.
"vp09.00.10.08") by testing the normalizedCodec against a prefix/regex for VP9
(e.g. /^vp09?/ or startsWith("vp9")/startsWith("vp09")), so it returns true for
both "vp9" and "vp09..." forms; apply the same change to the other occurrence
referenced around lines 27-29 and keep the existing AV1 checks unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d042dc4-b4d5-4d41-8f48-7f7cb7105358

📥 Commits

Reviewing files that changed from the base of the PR and between 52dd842 and 1fa5197.

📒 Files selected for processing (4)
  • src/lib/exporter/forwardFrameSource.ts
  • src/lib/exporter/streamingDecoder.ts
  • src/lib/exporter/videoDecoderConfig.test.ts
  • src/lib/exporter/videoDecoderConfig.ts

Comment thread src/lib/exporter/videoDecoderConfig.ts
@bernardopg

Copy link
Copy Markdown
Author

Addressed the review feedback in 41017b0:

  • Recognize fully qualified VP9 codec identifiers such as vp09.00.10.08 in the software-decode preference.
  • Added regression coverage for both bare and fully qualified VP9 identifiers.
  • Added documentation comments to the decoder configuration helper functions.

Validation:

  • 18 focused tests passed.
  • Biome passes for all four files changed by this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: H.264 WebM export fails with ambiguous codec name

1 participant