fix(processing): correct the board-identification message and the codec-map claims - #3335
vpetersson-bot wants to merge 21 commits into
Conversation
From the Copilot pass, and it checks out: the message sent every operator to "check that anthias-host-agent is running", which balena devices have never shipped. It also read a running agent as proof the board was unprofiled, when an unreachable Redis looks identical. The two deployments fail here for different reasons and only one is actionable: - compose / bare metal: the subtype comes from anthias_host_agent via Redis, so a stopped agent and an unreachable Redis both land here. The message names both. - balena: no host_agent at all, and the in-container device-tree fallback reads nothing because Docker masks /sys/firmware in the unprivileged server container (the caveat c6e5a95 just corrected in the hardware skill). There is no subtype source on that fleet, so there is nothing for the operator to check — saying so beats sending them after a service their device has never had. The message now leads with "could not identify this board" rather than the internal word "subtype", names Redis alongside the agent for compose, states the balena situation plainly, and keeps "unprofiled, open an issue" as the remaining case instead of the default conclusion. The catch-all test asserted the old wording; it now asserts those properties instead, with the reason for each spelled out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
From the Copilot pass. The map and its accessor both claimed every codec they return is hardware-decoded, which this branch made false: rk3566 accepts H.264 on measured software throughput, and pi5's h264 entry was already the same exception. Left as-is, the next person to add a board reads "hardware-decode set" and adds a codec on the assumption the silicon handles it. Both now say the set is what the board accepts for *playback*, name pi5 and rk3566 as the software-decoded entries, and point at _SW_DECODE_MAX_PIXELS for the resolution ceiling those entries need and hardware-decoded ones do not. Kept the _HW_DECODE_VIDEO_CODECS / _hw_decoded_codecs names and flagged them as historical in the comment. Renaming reaches into two committed knowledge-base skills and docs/board-enablement.md, which carry their own stale claims about this map and deserve their own pass rather than a drive-by rename on a stacked PR. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate findings remain around generic balena messaging and Rock Pi 4 HEVC acceptance.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR updates board-identification messaging and clarifies codec playback support versus hardware decoding.
Changes:
- Improves Compose and balena diagnostic guidance.
- Documents software-decoded Pi 5 and RK3566 playback paths.
- Updates related test assertions and documentation.
File summaries
| File | Summary |
|---|---|
tests/test_processing.py |
Revises catch-all message assertions and playback terminology. |
src/anthias_server/processing.py |
Updates board messaging and codec-map documentation; remaining findings concern balena scope, HEVC acceptance, and related decoder contracts. |
Review details
Suppressed comments (7)
src/anthias_server/processing.py:1385
- The updated docstring says
_pixel_cap_rejectionholds the resolution ceiling needed by these software-decoded entries, but Pi 5 has no entry in_SW_DECODE_MAX_PIXELS; it is only subject to the separate low-RAM cap when applicable. Please describe this as applying measured/applicable caps, or explicitly limit the software-throughput claim to RK3566.
exclusively: ``pi5`` and ``rk3566`` accept H.264 on measured
software throughput, so a codec coming back from here is certified
to *play*, not certified to decode in hardware. Pair it with
``_pixel_cap_rejection``, which holds the resolution ceiling those
software-decoded entries need.
src/anthias_server/processing.py:1246
- The new playback-set definition is immediately followed by a claim that a missing entry proves the device has no hardware-decoding codec. For an unprofiled
arm64board, the code only knows that no codec is certified, which is the distinction this change is meant to document; the current wording still makes an unsupported hardware claim. Change this to describe the conservative rejection rather than the board's capabilities.
# not safe — check the entry's own note.
src/anthias_server/processing.py:1746
- This branch handles the generic
arm64catch-all, but balena also haspi3-64,pi4-64, andpi5fleets with specificDEVICE_TYPEvalues and non-empty codec sets. Saying that aarch64 boards on balena "always land here" is therefore misleading; scope the statement to generic aarch64 boards so Pi operators are not told their profiled devices are unidentifiable.
'and have no other way to identify the board, so aarch64 '
'boards there always land here. Otherwise this board has '
src/anthias_server/processing.py:1231
- After the Qt6 media-player migration, playback is in-process QtMultimedia/libavcodec;
MPVMediaPlayeris only a legacy class name and there is no mpv subprocess. Keepingmpv/QtMultimediain this newly rewritten source-of-truth comment can send future codec changes toward a nonexistent decoder path; please describe the actual pipeline here.
# Per-board set of video codecs accepted at upload. This gate must
# stay in sync with what each board's player can actually keep up
# with: pi2/pi3 through GStreamer's V4L2 elements
src/anthias_server/processing.py:1231
- The new header defines this map as an acceptance set for real-time playback, but the existing
rockpi4entry still includes HEVC. On the supported Rock Pi 4 path, 1080p30 HEVC is software-decoded and drops about 22% even with idle cores, so a 1080p HEVC upload passes this gate and then plays poorly. Please removehevcfrom that entry until a working decode path exists, or add a measured playback envelope that rejects it.
# Per-board set of video codecs accepted at upload. This gate must
# stay in sync with what each board's player can actually keep up
# with: pi2/pi3 through GStreamer's V4L2 elements
src/anthias_server/processing.py:1383
- Changing
_hw_decoded_codecs()to return playback-acceptable codecs leaves its consumers documented as hardware-only:_run_video_normalisationstill says the codec must be hardware-decoded (1595–1607), andUnsupportedVideoCodecErrordoes too (1571). With Pi 5/RK3566 H.264 now intentionally passing via software, these are false contracts that can reintroduce the old assumption. Update the related docstrings/comments in this change so future callers use the playback semantics.
def _hw_decoded_codecs(device_key: str) -> frozenset[str]:
"""Video codecs the board named by ``device_key`` accepts.
Mostly the board's hardware-decode set — hence the name — but not
exclusively: ``pi5`` and ``rk3566`` accept H.264 on measured
software throughput, so a codec coming back from here is certified
to *play*, not certified to decode in hardware. Pair it with
tests/test_processing.py:1107
- This updated test docstring still describes the unknown board in terms of an
mpvdecoder, but the generic arm64 Qt6 viewer uses the in-process QtMultimedia path rather than an mpv binary. It also calls the table a hardware-decode map even though this PR changes its contract to an accepted-playback set; describe the viewer-facing decoder and playback map instead.
v4l2-request decoder mpv can address). Without a resolved subtype
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Self-inflicted, caught by Copilot. The text I added said both software-decoded entries carry a ceiling in _SW_DECODE_MAX_PIXELS, twenty lines above the note explaining that pi5 is deliberately absent from that map until someone times 4K H.264 on a Cortex-A76. A maintainer reading the new guidance would have gone looking for a Pi 5 ceiling that is missing on purpose. Both passages now say a software-decoded entry *wants* a measured ceiling, and name rk3566 as the one that has it and pi5 as the one still unmeasured. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved findings remain in codec semantics and deployment-specific board guidance.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (5)
Previously missed (1) — in code that hasn't changed since the last review.
src/anthias_server/processing.py:1748
- This new text overgeneralizes balena: the empty-set branch is reached by the generic
arm64image, while the balena Pi fleets use explicitpi2/pi3/pi3-64/pi4-64/pi5keys and do not land here. Saying all balena aarch64 boards "always land here" misdirects those operators; scope the statement to generic-arm64 devices (or otherwise to boards without a resolved subtype).
src/anthias_server/processing.py:1387
- Although
_hw_decoded_codecs()now documents playback certification,_run_video_normalisation()'s docstring at lines 1600-1610 still says every accepted codec is hardware-decoded and calls this a hardware set. Withpi5andrk3566deliberately in the returned set via software decode, that source-file documentation remains false and can recreate the exact misinterpretation this change is meant to prevent. Update the function docstring and its adjacent rejection comments to use the playback/certification terminology as well.
Mostly the board's hardware-decode set — hence the name — but not
exclusively: ``pi5`` and ``rk3566`` accept H.264 on software
throughput, so a codec coming back from here is certified to
*play*, not certified to decode in hardware. A software-decoded
entry also wants a resolution ceiling, which ``_pixel_cap_rejection``
applies from ``_SW_DECODE_MAX_PIXELS`` — for the boards measured so
far, which is ``rk3566`` and not yet ``pi5``.
src/anthias_server/processing.py:1233
- By defining this map as codecs the player can keep up with, this hunk makes the existing
rockpi4entry part of that invariant, but it still accepts HEVC. The checked-in board notes report about 22% frame drops for 1080p HEVC on 1 GB Rock Pi 4s (docs/board-enablement.md:217-223), while the resolution guard only rejects above 1080p, so 1080p HEVC can pass this gate and play poorly. Remove HEVC from that entry or add a measured board/RAM-specific limit before asserting that every accepted codec is real-time playable.
# Per-board set of video codecs accepted at upload. This gate must
# stay in sync with what each board's player can actually keep up
# with: pi2/pi3 through GStreamer's V4L2 elements
# (``GstFbdevMediaPlayer`` — bcm2835 codec, H.264 only), every other
# board through mpv/QtMultimedia + libavcodec. If the gate accepts a
src/anthias_server/processing.py:1724
supportedis also empty whenresolve_device_key()returns an unset or unrecognisedDEVICE_TYPE, not only when the arm64 subtype lookup misses. Because this new text is used for every empty set, a misconfigured x86 or development install is told to checkanthias-host-agent/Redis and is given balena-specific guidance; restrict this deployment-specific message to the arm64/generic-arm64 keys and use a generic unknown-configuration message otherwise.
# fleet (see docs/board-enablement.md).
src/anthias_server/processing.py:1724
- This new link sends operators to
docs/board-enablement.md, whose current balena section still saysanthias_common.boardreads/proc/device-tree/modelfrom inside the container (lines 165-169). That directly contradicts the explanation here that Docker masks the device tree and leaves balena without a subtype source, so following the link gives the wrong diagnosis. Update the documentation alongside this change or remove the reference until it is corrected.
# fleet (see docs/board-enablement.md).
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
Copilot spotted that the code comment I touched points at this doc, whose balena section still said anthias_common.board reads /proc/device-tree/model from inside the container — so an operator following the link got the opposite diagnosis to the error message. Same correction c6e5a95 made in the anthias-hardware skill: the fallback reads nothing in server/celery because Docker masks /sys/firmware in unprivileged containers. Only the host and the privileged viewer can do it, which makes the host_agent's Redis publish the only working source on the server side — and leaves the balena Rock Pi 4 fleet with none at all. Also spells out the consequence the doc had left implicit: video upload is rejected outright on that fleet today, which is what the operator message now says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved moderate findings concern codec playback guarantees and board-identification scope.
Review details
Suppressed comments (5)
Previously missed (1) — in code that hasn't changed since the last review.
src/anthias_server/processing.py:1384
- Please update the remaining processing docs that describe this
supportedset as hardware-only._run_video_normalisation()below still says it rejects codecs that are not hardware-decoded and that every accepted codec is hardware-decoded, but this function now intentionally returns Pi 5/RK3566 H.264 based on software throughput. Leaving those claims in the same module defeats the new maintainer guidance and can make the next codec entry look like a silicon guarantee.
src/anthias_server/processing.py:1233
- The new header treats this codec-only map as a guarantee that accepted codecs keep up, but that is not true for the existing entries:
rockpi4accepts HEVC whiledocs/board-enablement.mdreports about 22% dropped frames at 1080p30, and a 2 GB Pi 4 can accept 4K H.264 even though its hardware path is limited to 1080p. Please either add measured codec/resolution caps for these cases or qualify this as an upload allowlist rather than a real-time playback guarantee.
# Per-board set of video codecs accepted at upload. This gate must
# stay in sync with what each board's player can actually keep up
# with: pi2/pi3 through GStreamer's V4L2 elements
# (``GstFbdevMediaPlayer`` — bcm2835 codec, H.264 only), every other
# board through mpv/QtMultimedia + libavcodec. If the gate accepts a
src/anthias_server/processing.py:1385
- This docstring says a codec returned here is certified to play, but the function only returns codec membership and the resolution check is separate. That overstates Pi 5 H.264 (its ceiling is intentionally unmeasured) and Rock Pi 4 HEVC (known to drop frames); describe the result as accepted by the upload gate, subject to measured limits, rather than as a playback certificate.
Mostly the board's hardware-decode set — hence the name — but not
exclusively: ``pi5`` and ``rk3566`` accept H.264 on software
throughput, so a codec coming back from here is certified to
*play*, not certified to decode in hardware. A software-decoded
entry also wants a resolution ceiling, which ``_pixel_cap_rejection``
src/anthias_server/processing.py:1748
- This wording is broader than the unresolved path: the repository ships separate balena Pi 3-64, Pi 4, and Pi 5 fleets with static
DEVICE_TYPEvalues, so those aarch64 boards do not need a subtype and do not permanently land in this empty-set branch. Limit the sentence to generic-arm64 devices/the Rock Pi 4 fleet; otherwise the operator-facing diagnosis is false for other balena boards.
'docker-compose install, check that anthias-host-agent and '
'Redis are both running. balena devices ship no host agent '
'and have no other way to identify the board, so aarch64 '
'boards there always land here. Otherwise this board has '
tests/test_processing.py:1107
- The updated test docstring still says the decoder is one that mpv can address, but arm64 playback now runs in-process QtMultimedia/libavcodec and has no mpv binary. Since this test is documenting the codec-map contract, keeping that stale player reference makes the new explanation misleading; refer to the viewer/player path instead.
v4l2-request decoder mpv can address). Without a resolved subtype
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
Copilot flagged the test docstring; the same stale claim was in four other places in the file, so all five are corrected together rather than leaving it self-contradictory. There is no mpv binary on any of these boards. MPVMediaPlayer keeps the name for history but drives in-process QtMultimedia over D-Bus (src/anthias_viewer/media_player.py says so at the class and at the dispatch), and arm64 routes there via force_mpv. References to "mpv hwdec dispatch", "a decoder mpv can address" and "mpv's software decode" now name the viewer or libavcodec instead, and the one remaining mention of MPVMediaPlayer is explicitly labelled a legacy name so the next reader does not go looking for the binary. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
|
Fixed in 2cd008e — and you were right to check the claim, The same stale claim was in four other places in Full non-integration suite still green — 1779 passed. |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved review findings remain in codec documentation and board-identification messaging.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (7)
Previously missed (2) — in code that hasn't changed since the last review.
src/anthias_server/processing.py:1751
- This operator message overgeneralizes the catch-all case: balena Pi 5 and other board-specific images have a baked
DEVICE_TYPEand do not enter this empty-set branch. Saying “aarch64 boards there always land here” conflicts with the board matrix and can mislead operators; scope this to balena devices using the genericarm64image (or the Rock Pi 4 fleet).
src/anthias_server/processing.py:1247 - The new disclaimer calls out Pi 5 and RK3566, but it omits Rock Pi 4 even though its current QtMultimedia path software-decodes both codecs (and the
rockpi4map entry has no explanatory note). Since this paragraph tells maintainers to check each entry's note before adding a codec, the unannotated Rock Pi entry can still be read as hardware-safe. Add its software path and measured limits here or give the entry an explicit note.
This issue also appears on line 1611 of the same file.
docs/board-enablement.md:180
- The codec map is now documented as certifying playback rather than hardware decoding, but this paragraph still explains the empty
arm64set as being unable to certify "a decoder." That can imply the unknown board has no decoder at all; say that no codec is certified for playback instead.
a decoder on an unknown SBC). Read together with the paragraph above,
src/anthias_server/processing.py:1611
- Although the map now includes codecs accepted via software decode, this docstring still calls the accepted set the board's "HW set". On Pi 5 and RK3566 that wording is false and reintroduces the exact misreading this change is meant to remove; please refer to the playback/accepted set instead.
Uploading a codec outside the board's HW set is rejected — the
src/anthias_server/processing.py:1234
- This wording makes the map sound like a real-time-capability allowlist, but the existing
rockpi4entry accepts HEVC even thoughdocs/board-enablement.md:227-234records about 22% dropped frames for 1080p HEVC software decode, and no software-resolution cap covers it. That makes “actually keep up” false for a returned codec; either narrow this to the upload-acceptance contract or change the Rock Pi entry/cap to match the promised behavior.
# stay in sync with what each board's player can actually keep up
# with: pi2/pi3 through GStreamer's V4L2 elements
# (``GstFbdevMediaPlayer`` — bcm2835 codec, H.264 only), every other
# board through the viewer's in-process QtMultimedia + libavcodec
# pipeline (``MPVMediaPlayer`` — a legacy name; there is no mpv
src/anthias_server/processing.py:1256
- The playback-oriented contract is still contradicted here: an empty or missing entry does not prove that no codec decodes in hardware. For the catch-all
arm64, it means Anthias cannot certify real-time playback, and the map intentionally contains software-decoded entries such aspi5/rk3566. Please describe the empty set in certification/playback terms so maintainers do not infer a hardware capability from it.
# guaranteed to have a v4l2_request decoder the viewer can address,
# so we
src/anthias_server/processing.py:19
- This module-level contract still describes the viewer as handling codecs "in hardware", but the map this PR documents intentionally accepts software-decoded H.264 on Pi 5 and RK3566. A maintainer reading this entry can still infer the old hardware-only guarantee; describe the gate as certifying playable codecs and call out the software cases/cap instead.
does not transcode video on-device: the viewer's per-board hwdec
dispatch already handles every codec a modern board can play in
hardware (H.264, HEVC, plus VAAPI's wider set on x86), and the
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
Last place still describing the gate as hardware-only. It said the viewer's hwdec dispatch handles every codec a board can play in hardware, which reads as the old guarantee and contradicts the pi5 and rk3566 entries two hundred lines down. Now says what the gate actually is: a per-board playability envelope, mostly hardware decode but with named software-decoded exceptions that carry a resolution ceiling, pointing at the two maps that hold the halves. Also corrects the stale claim that an unplayable codec merely stutters — it is rejected at upload with a re-encode recipe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🟡 Changes recommended
The codec-map documentation and fallback semantics still need the identified corrections.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (3)
src/anthias_server/processing.py:1617
- The function docstring still describes the accepted set as hardware-only, even though this change defines a playback envelope and explicitly allows software-decoded H.264 on Pi 5 and RK3566. That leaves the function-level guidance contradictory and can cause a future maintainer to restore the old assumption; describe it in terms of the accepted playback set and the risk of slow software fallback instead.
Uploading a codec outside the board's HW set is rejected — the
viewer would otherwise fall through to libavcodec's software
decode and show drops the operator paid for hardware to avoid. The metadata
src/anthias_server/processing.py:1251
- The current
rockpi4entry accepts both H.264 and HEVC, butdocs/board-enablement.md:215-234records that this path is native software decode and that 1080p30 HEVC drops about 22% of frames (with 4K OOM on 1 GB SKUs). The new exception guidance names onlypi5andrk3566, so it still overstates the Rock Pi playback envelope and can make an operator ship a visibly failing codec. Reconcile the Rock Pi entry with measured per-codec limits before presenting this as a playability map.
# ``pi5``'s h264 (Cortex-A76) and all of ``rk3566`` (Cortex-A55), both
# noted at their entries. Software decode runs out of headroom with
# pixel count in a way hardware decode does not, so such an entry also
# wants a measured ceiling in ``_SW_DECODE_MAX_PIXELS`` — ``rk3566``
# has one; ``pi5`` is still unmeasured and deliberately unlisted there,
src/anthias_server/processing.py:1256
- After introducing the playability-envelope contract above, this comment still says that an empty entry proves no codec on the device decodes in hardware. For the catch-all
arm64, an empty set only means that no playback envelope has been certified; the unknown board may still have a hardware decoder. Please reword this fallback in terms of playback certification so the historical hardware claim is not reintroduced.
# Empty / missing entry means "no codec on this device decodes in
# hardware" — every video upload is rejected. The catch-all ``arm64``
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
Last fragment of the hardware-only framing in that comment block. It said an empty set proves no codec on the device decodes in hardware, which for the catch-all arm64 is exactly backwards: such a board may well have a working v4l2_request decoder, we just have no model match or measurement to say which codecs it handles. That distinction is load-bearing, not pedantic — it is why the operator message says the board could not be identified rather than "Supported: none.", which reads like the board has no decoder at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved codec-envelope qualification and test-terminology findings remain.
Review details
Suppressed comments (3)
src/anthias_server/processing.py:1242
- These lines imply the map prevents real-time playback failures, but the existing
rockpi4entry accepts both H.264 and HEVC while the board-enablement measurements report software decoding there and about 22% drops for 1080p HEVC;_SW_DECODE_MAX_PIXELShas norockpi4entry. An accepted upload can therefore still degrade on this supported board. Please either update the Rock Pi playback envelope or qualify this as an intended/certified rule rather than a guarantee.
# codec the board cannot decode in real time, playback degrades
# silently at the viewer (drops / black screen) — which this gate
# exists to prevent.
src/anthias_server/processing.py:28
- This overview still implies that every software-decoded entry carries a resolution ceiling, while
_SW_DECODE_MAX_PIXELSintentionally contains onlyrk3566and leaves the unmeasuredpi5entry absent. It also reads the wider VAAPI capability as part of what this gate accepts, although the x86 map is onlyh264/hevc. Please distinguish accepted codecs from hardware capability and qualify the ceiling as applying once measured.
hardware-decode guarantee: mostly hardware decode (H.264, HEVC, plus
VAAPI's wider set on x86), but ``pi5`` and ``rk3566`` accept H.264 on
measured software throughput, which is why a software-decoded entry
also carries a resolution ceiling. ``_HW_DECODE_VIDEO_CODECS`` and
``_SW_DECODE_MAX_PIXELS`` below hold the two halves. For codecs the
tests/test_processing.py:1110
- The test docstring still describes this as the “HW decode map,” even though the PR changes
_HW_DECODE_VIDEO_CODECSto a certified playback envelope that deliberately includes software-decoded entries. That leaves the regression test preserving the stale contract this change is meant to remove; refer to the accepted-playback map instead (or call the symbol name historical).
v4l2-request decoder the viewer can address). Without a subtype
every video upload is rejected, and the message has to explain why
in terms the operator can act on — which differs by deployment, so
it names both of them rather than one."""
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
It still called _HW_DECODE_VIDEO_CODECS "the HW decode map", which is the stale contract this branch removes — leaving the regression test documenting the thing the change corrects. Now describes it as the map of codecs a board accepts, flags the symbol name as historical, and states what an empty entry actually means: not that the SBC decodes nothing, but that nothing is certified for it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
The black screen isn't only recorded in a test docstring — issue #3072 tracks it, with QMediaPlayer emitting FormatError and decoding zero frames under cage. Worth naming there so the next person reading the allowlist finds the ticket rather than rediscovering it, and worth saying plainly that this is the worst of the three: x86 is the recommended tier and the failure is silent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🟡 Changes recommended
The review identified incorrect balena profiling guidance and remaining documentation that implies a codec playability guarantee.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (3)
src/anthias_server/processing.py:1439
- This helper docstring calls every returned codec "certified to play", but the map's own note says three returned entries are known not to play cleanly. That wording creates a playability guarantee at the helper boundary and conflicts with the allowlist contract above; describe the result as accepted for upload instead.
def _hw_decoded_codecs(device_key: str) -> frozenset[str]:
"""Video codecs the board named by ``device_key`` accepts.
src/anthias_server/processing.py:1815
- The final “Otherwise this board has not been profiled yet” clause is concatenated for every generic ARM64 device, including balena devices. That makes the message tell balena operators both that no subtype source exists and that they should open a profiling issue, even though the preceding text says every aarch64 balena device lands here by design. Make the profiling suggestion explicitly contingent on a compose install whose agent and Redis are healthy, and keep the balena case separate.
'this board, so it has no measured playback envelope for '
'it and cannot certify that any codec plays here.'
+ (
' On a docker-compose install, check that '
'anthias-host-agent and Redis are both running. balena '
src/anthias_server/processing.py:1653
- The normalisation docstring still describes the rejection boundary as codecs outside what the board is “known to play,” but this file now documents that the allowlist contains accepted entries with known playback failures. Keep this contract aligned with the map and call it the board's upload allowlist instead of implying a playability guarantee.
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
Two passages still asserted the guarantee this PR removes — the
module overview ("the viewer already plays every codec the upload
gate accepts") and _hw_decoded_codecs ("certified to play"). Both now
say what the map is: the accepted set, three of whose entries are
known not to play, pointing at the defect list rather than
contradicting it a few lines down.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🔵 Needs a closer look
A moderate issue remains because the board-identification branch checks the resolved key instead of the original DEVICE_TYPE, potentially suppressing the intended guidance.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
src/anthias_server/processing.py:1827
- This condition uses the resolved key rather than the original
DEVICE_TYPE. If Redis contains a non-empty subtype that is not yet present in the codec map (for example during a host-agent/server rollout),resolve_device_key()returns that subtype, so this falls into theDEVICE_TYPE is unset or unrecognisedmessage even though the deployment is the recognizedarm64catch-all. That hides the compose/balena diagnosis and the actionable profiling guidance; branch on the normalized environmentDEVICE_TYPE(or retain whether the ARM64 lookup was used) instead.
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
|
Heads up: this PR currently has merge conflicts with Flagged by an automated PR-hygiene sweep — no action needed beyond the rebase, and no reply expected. |
The unidentified-board message branched on resolve_device_key(), which returns the Redis subtype when there is one. A subtype the running server's codec map doesn't know yet — host_agent ahead of the server mid-rollout — therefore fell into the "DEVICE_TYPE is unset or unrecognised" arm, on a deployment that is exactly the arm64 catch-all the other arm is written for. The operator lost the host-agent and balena diagnosis and got a sentence that didn't apply. Branches on the normalised environment DEVICE_TYPE now, with a test pinning an unknown-subtype rollout to the arm64 text. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🔵 Needs a closer look
Three review comments remain unresolved regarding accepted-set wording and ARM64 board-identification messaging.
Review details
Suppressed comments (3)
src/anthias_server/processing.py:1662
- This sentence still defines rejection as being outside what the board is "known to play," but the map immediately above deliberately keeps x86 HEVC, Rock Pi 4 HEVC, and 4K Pi 4 H.264 cases in the accepted set even though they are documented as failing or dropping frames. Use the accepted-set wording here so the function contract does not contradict the new allowlist semantics.
and reject the asset if its codec is outside what this board is
known to play.
src/anthias_server/processing.py:1823
- This wording overstates the balena case: the message is reached for the generic
arm64key, but the balena fleets also deploy identified aarch64 images such aspi3-64,pi4-64, andpi5, which do not land in this branch. Scope the statement to balena's generic arm64 fleet (for example, Rock Pi 4) so operators are not told that every balena aarch64 board is permanently unidentified.
'anthias-host-agent and Redis are both running. balena '
'devices ship no host agent and have no other way to '
'identify the board, so aarch64 boards there always '
'land here. Otherwise this board has not been profiled '
src/anthias_server/processing.py:1824
- This sentence is outside the conditional expression, so an unset or unrecognised
DEVICE_TYPEalso gets told that the board has merely not been profiled and should prompt for an issue. In that path no board profile was selected at all, so this is misleading and contradicts the more precise suffix below; keep the sentence inside the ARM64 branch.
'land here. Otherwise this board has not been profiled '
'yet — please open an issue asking for it.'
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
Two Copilot findings on the rejection path's wording: * the summary line defined rejection as "outside what this board is known to play", which the map contradicts — x86 HEVC, Rock Pi 4 HEVC and 4K H.264 on pi4-64 stay accepted despite documented drops. Say "accepted set" and name the three exceptions. * the operator message claimed balena aarch64 boards "always land here". Only the generic arm64 fleet does; pi4-64 / pi5 images resolve their own key and never reach this branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🟡 Changes recommended
Three unresolved documentation comments remain in src/anthias_server/processing.py.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
src/anthias_server/processing.py:1674
- The parenthetical still says
HEVC only on Pi 5, but_HW_DECODE_VIDEO_CODECSalso accepts HEVC forpi4-64,rockpi4, andx86; because it follows “accepted codec set”, this is a false summary of the map. Please describe Pi 5's HEVC as its hardware path and H.264 as the software exception instead of implying HEVC is accepted only there.
on-device — most boards the viewer supports hardware-decode their
accepted codec set (H.264 + HEVC on most boards; HEVC only on
Pi 5; H.264 only on Pi 2 / Pi 3), while ``pi5``'s H.264 and
``rk3566`` are accepted on measured software throughput — and the
src/anthias_server/processing.py:1248
- This pipeline summary still says every board other than pi2/pi3 uses QtMultimedia/libavcodec, but pi3-64 is a documented exception: its preferred video path is the C++ GStreamer
v4l2h264dec→ vc4 overlay-plane pipeline, with CPU-raster fallback (src/anthias_viewer/__init__.py:445-448). Qualify the summary so a maintainer does not infer the wrong decoder path for pi3-64.
# with: pi2/pi3 through GStreamer's V4L2 elements
# (``GstFbdevMediaPlayer`` — bcm2835 codec, H.264 only), every other
# board through the viewer's in-process QtMultimedia + libavcodec
# pipeline (``MPVMediaPlayer`` — a legacy name; there is no mpv
# binary).
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
UnsupportedVideoCodecError's docstring still said it meant "can't be hardware-decoded", which the accepted-set contract has outgrown: pi5 and rk3566 accept H.264 on software throughput, and the same exception now carries the pixel-cap rejections. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🔵 Needs a closer look
A moderate scoping issue remains in the board diagnostic, with related codec documentation and wording updates also requested.
Review details
Suppressed comments (4)
src/anthias_server/processing.py:1798
- This says an empty set happens in only two ways, but the new regression test covers a third:
DEVICE_TYPE=arm64with a resolved subtype that is not yet in the map. That case is intentionally routed through this branch, so the explanation should include the unknown-subtype path instead of implying the arm64 path requires no resolved subtype.
# Empty ``supported`` means no allowlist was found for this
# key, which happens two ways: the catch-all ``arm64`` with
# DEVICE_TYPE set but no subtype resolved, and an unset or
# unrecognised DEVICE_TYPE, which ``resolve_device_key``
# passes through to a key the map has no entry for. The branch
src/anthias_server/processing.py:1825
- Use the standard single-word form
cannotin this operator-facing message; the newly added text currently sayscan not, while the intended meaning is simple inability and the rest of the message usescannot.
f'Video codec {display_codec!r} can not be verified for '
src/anthias_server/processing.py:1253
- This changes the map's contract to an accepted-codec allowlist, but the same module still has user/maintainer-facing helpers that describe the argument as a hardware-decode set:
_ffmpeg_reencode_recipesays an empty set means no HW decode (1497-1503),_handbrake_stepsrepeats that (1587-1589), andpreferred_download_vcodeccalls H.264 the primary hardware path for all unlisted boards even thoughrk3566is software-decoded. Please update those related descriptions in this PR so the corrected contract is not immediately contradicted elsewhere inprocessing.py.
# Read it as a per-board codec allowlist, not a playback certificate.
# The failure it exists to prevent is real — accept a codec the board
# cannot decode in real time and playback degrades silently at the
# viewer (drops / black screen) — but an entry certifies the *codec*.
src/anthias_server/processing.py:1833
- The compose/balena paragraph is concatenated before the
if ... else, so an unset or unrecognisedDEVICE_TYPEstill receives the balena and host-agent advice. This makes the new scoping test fail ('balena' in msg) and sends unrelated installs to irrelevant troubleshooting; put the deployment-specific paragraph entirely in the ARM64 branch and leave only theDEVICE_TYPEdiagnostic in the other branch.
' On a docker-compose install, check that '
'anthias-host-agent and Redis are both running. On '
'balena, the generic arm64 fleet (Rock Pi 4) ships no '
'host agent and has no other subtype source, so those '
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
Three follow-ups to the same wording change: * the empty-allowlist comment listed two ways to get there and missed the third the new test covers (arm64 with a subtype the map doesn't know yet) — which is also why the branch keys on DEVICE_TYPE. * _ffmpeg_reencode_recipe, _handbrake_steps and preferred_download_vcodec still described their argument as a hardware-decode set, contradicting the corrected contract. * "can not" -> "cannot" in the operator-facing message. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🔵 Needs a closer look
A moderate documentation inconsistency still describes rejected codecs as outside the hardware decode set.
Review details
Suppressed comments (1)
src/anthias_server/processing.py:1691
- The updated contract here is still contradicted by the rejection-path comment at line 1764, which says a rejected codec is outside the board's "HW decode set." That is false for Pi 5/RK3566 H.264, which this doc now explicitly treats as accepted software-decoded codecs; please update that remaining comment to say "accepted set" so this path does not reintroduce the old hardware-only assumption.
Uploading a codec outside the board's accepted set is rejected —
no playback path on this board has been shown to keep up with it,
so shipping it would mean drops or a black screen at the viewer
with nothing to warn the operator first. (Not "outside the
hardware set": ``pi5`` and ``rk3566`` accept H.264 on measured
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
|



Two review points raised on the RK3566 codec-envelope PR arrived after it was squash-merged, so the fixes had nowhere to land. This carries them onto the same base.
The board-identification message is wrong for balena
The catch-all branch told every operator to "Check that anthias-host-agent is running". balena devices have never shipped that service, and the in-container device-tree fallback reads nothing there either — Docker masks
/sys/firmwarein the unprivileged server container, the caveat corrected in the hardware skill earlier on this branch. That fleet has no subtype source at all, so every aarch64 board on it lands here permanently and the advice sends those operators after something their device has never had.The message also read a running agent as proof the board is unprofiled, when an unreachable Redis produces an identical symptom.
It now leads with "could not identify this board" rather than the internal word "subtype", names Redis alongside the agent for compose installs, states the balena situation plainly, and keeps "not profiled yet, open an issue" as the remaining case rather than the default conclusion.
The codec map is not a hardware guarantee
_HW_DECODE_VIDEO_CODECSand_hw_decoded_codecsboth claimed every codec they return is hardware-decoded. That stopped being true before the RK3566 work —pi5accepts H.264 on the Cortex-A76 in software — and RK3566 makes it routine. Left alone, the next person to add a board reads "hardware-decode set" and adds a codec assuming the silicon handles it.Both now describe the set as what the board accepts for playback, name
pi5andrk3566as the deliberately software-decoded entries, and point at_SW_DECODE_MAX_PIXELSfor the resolution ceiling those entries need and hardware-decoded ones don't.I did not rename the two symbols, which would be the root-cause fix. They reach into
docs/board-enablement.mdand two committed knowledge-base skills, and those references carry their own stale claims about this map (the viewer skill still documents'pi5': frozenset({'hevc'})). That deserves a deliberate pass rather than a drive-by rename. The names are flagged as historical in the comment so the misnomer is documented where someone would trip on it.Testing
ruff check,ruff format --check, and the full non-integration suite green locally — 1779 passed. The catch-all test had pinned the old message wording; its assertions are now written around the properties that matter, each with the reason it matters.🤖 Generated with Claude Code