feat(apv): add APV (Advanced Professional Video) reader and writer - #5367
feat(apv): add APV (Advanced Professional Video) reader and writer#5367zachlewis wants to merge 3 commits into
Conversation
Add an apv.imageio plugin using the OpenAPV library (https://github.com/openapv/openapv, BSD-3-Clause). APV is an all-intra professional video codec, so a raw .apv bitstream is naturally addressable as a sequence of individual images: the reader exposes one subimage per access unit (decoding its primary frame), and the writer emits one access unit per subimage, so appending subimages produces a valid multi-frame bitstream. - 10/12-bit YCbCr 4:2:2 / 4:4:4 / 4:4:4:4 (alpha) / 4:0:0 presented as full-range uint16 RGB(A)/grayscale, converted with the matrix coefficients signaled in the bitstream (709/601/2020). - CICP round trip: bitstream color descriptions surface as the CICP attribute (and oiio:ColorSpace interop ID when known); a CICP attribute on output is signaled in the bitstream. - Output controls: apv:profile (default 422-10 / 4444-10 / 400-10 by channel count), apv:qp, apv:bitrate, apv:preset, FramesPerSecond. - FindAPV.cmake module (OpenAPV installs into lib/oapv and needs OAPV_STATIC_DEFINE for static libs), build_APV.cmake local-build recipe with pinned tag+commit, testsuite/apv round-trip tests, and builtinplugins.rst documentation. Auxiliary frames within an access unit (preview, depth, alpha, non-primary) are not yet exposed; chroma resampling is simple co-sited linear. Assisted-by: Claude Code (Fable 5) Signed-off-by: Zach Lewis <zachcanbereached@gmail.com>
Assisted-by: Claude Code (Fable 5) Signed-off-by: Zach Lewis <zachcanbereached@gmail.com>
Two Color Interop Forum alignment improvements to the writer: - If no explicit CICP attribute is present but oiio:ColorSpace names a color space the default ColorConfig can map to CICP code points (e.g. a color interop ID), derive the bitstream color description from it via ColorConfig::get_cicp(). Untagged input still writes no color description rather than guessing. - Choose the encode matrix coefficients to match the primaries (BT.2020 with the 2020 NCL matrix, BT.601 families with theirs, everything else including P3 with BT.709) instead of always BT.709, and signal the matrix actually used. Testsuite gains an interop-ID-only round trip. Assisted-by: Claude Code (Fable 5) Signed-off-by: Zach Lewis <zachcanbereached@gmail.com>
|
@zachlewis This is still marked as draft (as are a few others from you). What's your intent here? Are they placeholders, or do you want reviews and merges? |
|
Honestly, this and the JXL business were entirely llm-generated as a means for me to test metadata-translation stuff across containers and plugins -- I haven't had the bandwidth to actually look at any of this code yet, so I definitely don't feel comfortable putting my stamp of approval on this - this was generated in exactly (well, sort of) the kind of vibe-coded way that we don't want here. That being said, if you're still interested in reviewing a PR such as this, I'd be happy to take ownership and prioritize getting these suckers tied up and closed out so they're not dangling there..! |
|
I'm not really interested in reviewing or merging code that hasn't already been reviewed, tested, and understood by another human submitter. Let's close these PRs. But I would welcome JXL and APV plugin PRs in the future -- even if they were mostly written by bots, as long as there was a human who understands them enough to claim full responsibility and stand behind them. |
Motivation
APV is a royalty-free, all-intra professional video codec (via the BSD-3-Clause OpenAPV library). Because every frame is coded independently, a raw
.apvbitstream is naturally addressable as a sequence of individual images — a good fit for OIIO's subimage model, in both directions.What this does
apv.imageioplugin: the reader exposes one subimage per access unit (decoding its primary frame); the writer emits one access unit per subimage, so appending subimages produces a valid multi-frame bitstream.uint16RGB(A)/grayscale, converted with the matrix coefficients signaled in the bitstream (709 default, 601/2020 honored, limited/full range respected). Writing converts with BT.709.CICPattribute plus anoiio:ColorSpacecolor-interop ID when known (same pattern as the JPEG XL reader); aCICPattribute on output is signaled into the bitstream.apv:profile(defaults 422-10 / 4444-10 / 400-10 by channel count),apv:qp,apv:bitrate,apv:preset,FramesPerSecond.FindAPV.cmake(OpenAPV installs libraries intolib/oapvand static consumers must defineOAPV_STATIC_DEFINE), a pinnedbuild_APV.cmakelocal-build recipe, testsuite, andbuiltinplugins.rstdocs.What it deliberately does not do
Auxiliary AU frames (preview, depth, alpha-as-separate-PBU, non-primary) and metadata payloads (MDCV/CLL) are parsed past but not exposed yet; chroma resampling is simple co-sited linear. All noted in the code as future work.
Notes
oapvd_info()header probe misparses the color-description fields (reproducible with OpenAPV's own reference encoder; its full decoder parses them correctly). The reader therefore takes color metadata from the decode's frame info. Will report upstream.Testing
New
testsuite/apv: write/read round trips over 422/444/4444/400 profiles at 10 and 12 bits withoiiotool --diffthresholds, multi-subimage append, CICP carry-through (verified 9/16 →pq_rec2020_displayinterop ID). Also verified against a bitstream produced by OpenAPV's own reference encoder.Assisted-by: Claude Code (Fable 5)