Eight Copilot comments from the second review pass:
1. monitor.php (#3): "Deprecated - will be auto-detected..." note next
to TargetColorspace bypassed translate(). Added DeprecatedColoursSetting
key to en_gb and routed the deprecation note through translate() so it
localises with the rest of the form.
2. tests/zm_pixformat.cpp (#4): zm_colours_from_pixformat / round-trip
tests didn't cover the new YUV422P/YUVJ422P entries (added by
02e6be6b4). Added explicit assertions in both test cases — bumps
pixformat coverage from 105 to 115 assertions.
3. zm_image.cpp WriteBuffer (#5): linesize and size were derived from
p_width * p_colours, which undercounts planar YUV* (where p_colours=1
via the GRAY8 alias collision but actual buffer needs ~1.5x/2x for
chroma). Use av_image_get_buffer_size and av_image_get_linesize for
the AVPixelFormat instead, with bail-out on either failing.
4. zm_image.cpp AssignDirect (#6, #7): av_image_get_buffer_size returns
int and can be negative; assigning that into unsigned size/allocation
wrapped to a huge value. Check the return first, treat negative as the
same "unsupported format" failure as zm_colours_from_pixformat
returning false, and reset size/allocation/linesize/pixels to 0
(alongside imagePixFormat=NONE/colours=0/subpixelorder=0) so the
Image is left in a single coherent invalid state instead of partially
stale.
5. zm_image.cpp Assign (#8): av_get_pix_fmt_name(format) can return
nullptr (e.g. AV_PIX_FMT_NONE / unknown); passing that into
Debug(..., "%s", ...) would segfault. Capture once with a fallback
string before logging.
6. zm_monitor.cpp Capture path (#9): same nullptr issue with two Debug
calls — capture native_fmt_name once with fallback.
7. zm_monitor.cpp can_passthrough comment (#10): comment claimed
YUVJ422P would be converted to YUV420P because Image drops chroma,
but can_passthrough now allows YUV422P/YUVJ422P passthrough since
02e6be6b4 added 4:2:2 support. Updated the comment to describe the
current behavior (full 4:2:0 + 4:2:2 planar passthrough plus GRAY8
and RGB24/32) so the code and the rationale agree.
Tests: 76 cases, 788 assertions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ZM_COLOUR_GRAY8, ZM_COLOUR_YUV420P, and ZM_COLOUR_YUVJ420P were all
defined to 1, making format identification via colours ambiguous.
LocalCamera misidentified YUV420P as GRAY8, causing V4L2 MJPEG cameras
to decode to grayscale via expensive sws_scale conversion.
Replace the legacy ZM_COLOUR_*/ZM_SUBPIX_ORDER_* integer pair with
AVPixelFormat as the single source of truth for pixel format dispatch:
- Add src/zm_pixformat.h with central format helpers:
zm_pixformat_from_colours, zm_colours_from_pixformat,
zm_bytes_per_pixel, zm_db_colours_to_pixformat, zm_is_rgb32,
zm_is_rgb24, zm_is_yuv420
- Add AVPixelFormat pixelFormat member + PixelFormat() accessor to Camera
- Add PixFormat() accessor to Image, delegate AVPixFormat methods
to shared helpers
- Migrate all ~100 format dispatch comparisons in zm_image.cpp,
zm_local_camera.cpp, zm_ffmpeg_camera.cpp, zm_remote_camera_rtsp.cpp,
zm_libvlc_camera.cpp, zm_libvnc_camera.cpp, zm_monitor.cpp,
zm_mpeg.cpp from colours/subpixelorder checks to imagePixFormat/
AVPixelFormat checks
- Deprecate GetFFMPEGPixelFormat, delegate to zm_pixformat_from_colours
- Fix DeColourise bug: imagePixFormat was not updated to GRAY8
- Deprecate ZM_COLOUR_* and ZM_SUBPIX_ORDER_* constants in zm_rgb.h
- Add deprecation notice on Monitor.Colours web UI dropdown
- Add 13 Catch2 test cases (105 assertions) for format mapping helpers
refs #4735
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>