Files
punktfunk/crates/pf-bitstream/vendor/cros-codecs/PROVENANCE.md
enricobuehler 55bc664eca docs(pf-bitstream): the two upstream cros-codecs bugs are now reported
PROVENANCE deviations #6 and #7 carried 'report upstream' — done:
- chromeos/cros-codecs#99: h264 PictureData display_resolution
  double-counts the left/top crop and underflow-panics on
  parser-valid crop offsets (answers their open #81).
- chromeos/cros-codecs#100: h265 parse_slice_header index-OOB panic
  when num_long_term_sps + num_long_term_pics > 16 — a hostile-input
  panic on the LTR path (an instance of their #78).

Both reports offer the downstream patch for the AOSP tree.
2026-08-06 00:44:18 +02:00

73 lines
4.5 KiB
Markdown

# Vendored: cros-codecs (parser layer only)
- **Upstream:** <https://android.googlesource.com/platform/system/cros-codecs/> (the
authoritative AOSP tree). Snapshot taken from the read-only GitHub mirror
<https://github.com/chromeos/cros-codecs>, branch `main`,
commit **`5ff6d693ffae0b36935b8fc13092c733b4c2646f`**, fetched 2026-08-05.
- **License:** BSD-3-Clause (`LICENSE`, copied verbatim). Attribution headers retained
in every source file.
- **Why vendored, not a crates.io dependency:** the GitHub repo is a read-only mirror
and the crates.io release lags it; a pinned, reviewed snapshot is the supply-chain
posture punktfunk already uses elsewhere (`clients/android/native/vendor/ndk`,
`punktfunk-host/vendor/usbip-sim`). Decision of record:
punktfunk-planning `design/client-native-decode.md` §8.1.
## What was taken
`src/codec/{h264,h265,av1,vp9}` (parsers, DPBs, picture types, NALU/OBU machinery,
their `test_data` vectors — they double as punktfunk's conformance corpus),
`src/bitstream_utils.rs`, `LICENSE`. Upstream designed the `codec` module for exactly
this extraction — its module doc: "There shall be no dependencies from other modules of
this crate to this module, so that it can be turned into a crate of its own if needed
in the future."
## What was left behind
- `decoder/`, `encoder/`, `backend/`, `c2_wrapper/`, `video_frame`, `image_processing`,
`utils` — the Linux-only halves (libva/v4l2/gbm/nix). punktfunk's `pf-bitstream` +
`pf-vkdecode` occupy that layer.
- `codec/vp8` — VP9 has no dependency on it (verified) and no punktfunk host will ever
emit VP8.
## Deviations from pristine upstream
1. `src/lib.rs` — rewritten: keeps only the module decls and `Resolution` /
`ResolutionRoundMode` (the sole root items `codec` references), both copied verbatim;
adds crate-level `#![allow(clippy::all, mismatched_lifetime_syntaxes)]` — vendored
code is not held to the workspace lint bar (CI's `-D warnings` legs would fail on
upstream style otherwise).
2. `src/codec.rs` — one line removed (`pub mod vp8;`).
3. `Cargo.toml` — rewritten: `log` is the only dependency the vendored subset needs,
plus `env_logger`/`serde_json` dev-dependencies for upstream's in-tree tests.
4. `cargo fmt` normalization under the workspace's rustfmt config (mechanical only).
5. **Zero-unsafe, enforced**: `#![forbid(unsafe_code)]` added to lib.rs. Upstream's codec
module had exactly one production `unsafe` (h264/dpb.rs `build_ref_pic_lists`: ref→index
via pointer `offset_from`) — replaced with a safe `position(ptr::eq)` over the ≤16-entry
DPB — and three test-only `mem::zeroed()` asserts, replaced with `Default::default()`
(`PredWeightTable` derives `Default`; all-integer struct, identical value). The layer
facing untrusted bytes is now compiler-verified free of unsafe — the property that
motivates replacing libavcodec's C parsers in the first place.
6. `src/codec/h264/picture.rs``PictureData::new_from_slice`: `display_resolution`
computed as `visible_rect.max` instead of `max - min`. `Sps::visible_rectangle()`
returns the crop offset in `min` and the visible *size* in `max` (see its
definition: `max.x = width - crop_left - crop_right`); upstream's subtraction
double-counts the left/top crop and, worse, panics on u32 underflow for a
large-but-parser-valid `frame_crop_left_offset` (e.g. 100 crop units on a 320-wide
SPS). Found by pf-bitstream's conformance-window tests; upstream never hits it
because real encoders crop right/bottom only. **Reported upstream 2026-08-06:
<https://github.com/chromeos/cros-codecs/issues/99>.**
7. `src/codec/h265/parser.rs``parse_slice_header`: reject
`num_long_term_sps + num_long_term_pics > 16` before the long-term RPS loop.
Upstream bounds the pair only by `MAX_LONG_TERM_REF_PIC_SETS` (32) combined, while
every long-term array in `SliceHeader` (`poc_lsb_lt`, `used_by_curr_pic_lt`,
`delta_poc_msb_present_flag`, `delta_poc_msb_cycle_lt`, `lt_idx_sps`) is `[_; 16]`
— a hostile slice header with 17+ entries panics the parser with an
index-out-of-bounds (bounds checks stay on in release). Found by pf-bitstream's
H.265 planner review; regression-tested there
(`a_hostile_long_term_count_is_a_parse_error_not_a_panic`). **Reported upstream
2026-08-06: <https://github.com/chromeos/cros-codecs/issues/100>.**
Re-sync procedure: fetch the AOSP tree, re-apply this trim, diff `codec/` +
`bitstream_utils.rs` (expect near-zero conflicts), update the commit pin above.