scaffold: CMake + API skeleton + smoke test #2

Merged
marfrit merged 1 commits from noether/repo-scaffold into main 2026-05-24 20:10:26 +00:00
Owner

First code on daedalus-decoder per the Phase 1 decisions merged 2026-05-24. Repo skeleton only — no Vulkan pipeline yet, no shaders, no libavcodec intercept. Establishes the build shape so subsequent work has a place to land.

What's in

File Purpose
LICENSE BSD-2-Clause (matches daedalus-fourier)
.gitignore build/, CMake artefacts, *.spv
CMakeLists.txt finds daedalus-fourier ≥0.1.0 via pkg-config (per §9.6 decision: find_package, pinned tagged release; pkg_check_modules until we ship a CMake config), Vulkan via find_package, builds static lib + smoke test, GNUInstallDirs install
include/daedalus_decoder.h Public API surface: create/destroy/has_qpu/version, append_mb + mb_input struct matching §3, flush_frame, export_dmabuf (Vulkan-native VkImage per §9.4), set_output_format (NV12 default, RGBA opt-in per §5)
src/internal.h internal mb_desc struct + per-ctx state
src/daedalus_decoder.c stub bodies: real lifecycle, append_mb validates + writes CPU staging buffer, flush_frame returns -2 (not implemented), export_dmabuf returns -1, has_qpu / version diagnostics
tests/test_smoke.c link + lifecycle test

Verified on hertz (Pi 5 / V3D 7.1 / daedalus-fourier 0.1.0)

$ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
$ cmake --build build
$ ctest --test-dir build --output-on-failure
  Test #1: smoke ... Passed

$ ./build/test_smoke
daedalus-decoder version: 0.0.1
ctx created: 1920x1088, has_qpu=1
smoke OK

Smoke covers: bad-dim reject, OOB MB reject, null inputs reject, raster-order enforcement (Phase 1 wavefront precondition), mid-frame format-change reject, incomplete-frame flush reject. On hosts without V3D7 Vulkan the test SKIPs gracefully (returns 0) so CI on non-Pi runners doesn't false-fail.

API note: coded vs displayed dims

The scaffold uncovered a real trap: H.264's coded frame for displayed 1080p is 1920×1088 (8 cropped rows in SPS frame_cropping_*). daedalus_decoder_create() takes coded dims; header docstring spells this out so future callers don't hit the mod-16 reject. The smoke test using (1920, 1080) caught it before commit.

What's NOT in (intentional, follow-ons)

  • Vulkan pipeline construction (Phase 1)
  • IDCT 4×4 / 8×8 dispatch at frame scale (Phase 1)
  • Intra prediction wavefront (Phase 1)
  • Reconstruct stage (Phase 1)
  • NV12 output via dmabuf export (Phase 1)
  • Motion compensation, deblock at frame scale, Stage 5 RGBA — Phases 2+
  • libavcodec intercept patch in marfrit-packages — staged once the API stabilises
  • CMake config exports + .pc file — once API stabilises pre-0.1 → 0.1

Next: Phase 1 implementation against this baseline.

First code on daedalus-decoder per the Phase 1 decisions merged 2026-05-24. Repo skeleton only — no Vulkan pipeline yet, no shaders, no libavcodec intercept. Establishes the build shape so subsequent work has a place to land. ## What's in | File | Purpose | |---|---| | `LICENSE` | BSD-2-Clause (matches daedalus-fourier) | | `.gitignore` | build/, CMake artefacts, *.spv | | `CMakeLists.txt` | finds daedalus-fourier ≥0.1.0 via pkg-config (per §9.6 decision: find_package, pinned tagged release; `pkg_check_modules` until we ship a CMake config), Vulkan via `find_package`, builds static lib + smoke test, GNUInstallDirs install | | `include/daedalus_decoder.h` | Public API surface: create/destroy/has_qpu/version, append_mb + mb_input struct matching §3, flush_frame, export_dmabuf (Vulkan-native VkImage per §9.4), set_output_format (NV12 default, RGBA opt-in per §5) | | `src/internal.h` | internal mb_desc struct + per-ctx state | | `src/daedalus_decoder.c` | stub bodies: real lifecycle, append_mb validates + writes CPU staging buffer, flush_frame returns -2 (not implemented), export_dmabuf returns -1, has_qpu / version diagnostics | | `tests/test_smoke.c` | link + lifecycle test | ## Verified on hertz (Pi 5 / V3D 7.1 / daedalus-fourier 0.1.0) ``` $ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release $ cmake --build build $ ctest --test-dir build --output-on-failure Test #1: smoke ... Passed $ ./build/test_smoke daedalus-decoder version: 0.0.1 ctx created: 1920x1088, has_qpu=1 smoke OK ``` Smoke covers: bad-dim reject, OOB MB reject, null inputs reject, raster-order enforcement (Phase 1 wavefront precondition), mid-frame format-change reject, incomplete-frame flush reject. On hosts without V3D7 Vulkan the test SKIPs gracefully (returns 0) so CI on non-Pi runners doesn't false-fail. ## API note: coded vs displayed dims The scaffold uncovered a real trap: H.264's coded frame for displayed 1080p is **1920×1088** (8 cropped rows in SPS `frame_cropping_*`). `daedalus_decoder_create()` takes coded dims; header docstring spells this out so future callers don't hit the mod-16 reject. The smoke test using `(1920, 1080)` caught it before commit. ## What's NOT in (intentional, follow-ons) - Vulkan pipeline construction (Phase 1) - IDCT 4×4 / 8×8 dispatch at frame scale (Phase 1) - Intra prediction wavefront (Phase 1) - Reconstruct stage (Phase 1) - NV12 output via dmabuf export (Phase 1) - Motion compensation, deblock at frame scale, Stage 5 RGBA — Phases 2+ - libavcodec intercept patch in marfrit-packages — staged once the API stabilises - CMake config exports + .pc file — once API stabilises pre-0.1 → 0.1 Next: Phase 1 implementation against this baseline.
marfrit added 1 commit 2026-05-24 20:09:14 +00:00
First code on daedalus-decoder per the Phase 1 decisions merged 2026-05-24.
Repo skeleton only — no Vulkan pipeline yet, no shaders, no libavcodec
intercept.  Establishes the build shape so subsequent work has a place
to land.

Layout:

  LICENSE                          BSD-2-Clause (matches daedalus-fourier)
  .gitignore                       build/, CMake artefacts, *.spv
  CMakeLists.txt                   top-level — finds daedalus-fourier
                                   ≥0.1.0 via pkg-config (per §9.6
                                   decision: find_package, pinned to
                                   tagged release; .pc consumed via
                                   pkg_check_modules until we ship a
                                   CMake config), Vulkan via
                                   find_package, builds static lib
                                   + smoke test, GNUInstallDirs install
  include/daedalus_decoder.h       public API surface:
                                     - daedalus_decoder_{create,destroy,
                                                         version,has_qpu}
                                     - daedalus_decoder_set_output_format
                                       (NV12 default, RGBA opt-in per §5)
                                     - daedalus_decoder_append_mb +
                                       struct daedalus_decoder_mb_input
                                       (matches §3 per-MB descriptor)
                                     - daedalus_decoder_flush_frame
                                       (per-frame submit + wait)
                                     - daedalus_decoder_export_dmabuf
                                       (Vulkan-native VkImage export per
                                       §9.4 decision)
                                   Dimensions are CODED frame size
                                   (mod-16), not displayed — caller
                                   translates from SPS + crop offsets.
  src/internal.h                   internal mb_desc struct (matches
                                   shader std430 layout, to be nailed
                                   down once shaders exist) + per-ctx
                                   state
  src/daedalus_decoder.c           stub bodies:
                                     - create/destroy with proper resource
                                       lifecycle
                                     - append_mb validates + writes CPU
                                       staging buffers (no GPU yet)
                                     - flush_frame returns -2 (not
                                       implemented) — Phase 1 work
                                     - export_dmabuf returns -1
                                     - has_qpu / version diagnostics
  tests/test_smoke.c               link + lifecycle test: bad dims
                                   reject, OOB MB reject, null inputs
                                   reject, raster-order enforcement,
                                   mid-frame format-change reject,
                                   incomplete-frame flush reject.
                                   On hosts without V3D7 Vulkan,
                                   SKIPs gracefully (returns 0).

Verified on hertz (Pi 5 / V3D 7.1 / Mesa V3DV via daedalus-fourier
0.1.0):

  $ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
  $ cmake --build build
  $ ctest --test-dir build --output-on-failure
  Test #1: smoke ... Passed

  $ ./build/test_smoke
  daedalus-decoder version: 0.0.1
  ctx created: 1920x1088, has_qpu=1
  smoke OK

Note the coded-vs-displayed dims trap: 1080p H.264 has coded height
1088 with 8 rows cropped via SPS frame_cropping_*.  Header docstring
on daedalus_decoder_create() spells this out so future callers don't
hit the multiple-of-16 reject (smoke test caught it during scaffold
write).

Next: Phase 1 implementation begins — IDCT 4×4 / 8×8 frame-scaled
dispatch (reusing daedalus-fourier shaders per Appendix A), intra
prediction wavefront, reconstruct stage, NV12 output via dmabuf
export.  Smoke test grows from "ctx lifecycle works" to
"I-frame-only Baseline decode bit-exact vs FFmpeg reference".
marfrit merged commit 90d7c546bd into main 2026-05-24 20:10:26 +00:00
marfrit deleted branch noether/repo-scaffold 2026-05-24 20:10:26 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marfrit/daedalus-decoder#2