Commit c8d8cc3
feat: SHM cross-process format consistency via per-slot AVPixelFormat
The deprecated Monitors.Colours column was driving the on-disk SHM
image_buffer slot format end-to-end: zmc allocated each slot in
camera->Colours()/SubpixelOrder() shape, zms attached and built its
own per-process Image objects assuming the same shape. Anything that
wrote a different format into a slot — i.e. anything that wasn't
already RGB32 on a Colours=4 monitor — left zmc's local Image with
the new format but zms reading the bytes as RGB32. The visible
artefacts varied with the format pair (4 small images per row for
YUV420P-into-RGB32, 3 tiles for the planar-as-RGB24 fallthrough,
fully garbled colours for image_pixelformats overlapping alarm_image,
etc.) but the underlying contract was just broken — the SHM had no
representation of the per-slot format.
Make the SHM transport any format Image supports without an upfront
convert step:
- Place image_pixelformats[] correctly. mem_size already reserved
image_buffer_count*sizeof(AVPixelFormat) at the end of the SHM
region, but the pointer was set to shared_images +
image_buffer_count*image_size — overlapping the alarm_image
region. zmc's writes scribbled into alarm_image; zms read alarm
pixel data back as enum values. Move it to
+2*image_buffer_count*image_size, after both image regions.
- Add Monitor::WriteShmFrame(index, capture_image): no conversion,
just Assign and record image_pixelformats[index] =
capture_image->AVPixFormat(). Used by both the normal Decode path
and the signal-loss path so they share the same cross-process
format-consistency contract.
- Add Monitor::ReadShmFrame(index): the read-side counterpart. Calls
image_buffer[index]->AVPixFormat(image_pixelformats[index]) before
returning so other-process Image objects interpret the SHM bytes
correctly per-frame. zm_monitorstream's image_buffer[index]
accesses go through this accessor.
- image_buffer[i] / alarm_image: initial format is now just a
placeholder (YUV420P), with allocation sized from
camera->ImageSize() as the upper bound. The actual format carried
in each slot is the one zmc wrote, recorded in image_pixelformats
and adopted on read.
This means the typical capture pipelines run with zero sws_scale
calls in the SHM hot path:
- H.264/H.265 sw decode -> YUV420P -> identity copy via
av_image_copy in Image::Assign(AVFrame*).
- LocalCamera/MJPEG -> RGB32 (DecodeJpeg target) -> SHM holds RGB32;
zms reads RGB32 directly.
- H.265 hwaccel -> NV12 -> falls through to YUV420P (NV12 isn't in
zm_pixformat) — one convert at decode time, then passthrough
through the rest of the pipeline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 45a4671 commit c8d8cc3
3 files changed
Lines changed: 82 additions & 22 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1120 | 1120 | | |
1121 | 1121 | | |
1122 | 1122 | | |
1123 | | - | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
1124 | 1131 | | |
1125 | 1132 | | |
1126 | | - | |
1127 | | - | |
1128 | | - | |
1129 | | - | |
1130 | | - | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
1131 | 1138 | | |
1132 | 1139 | | |
1133 | 1140 | | |
1134 | 1141 | | |
1135 | | - | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
1136 | 1150 | | |
1137 | 1151 | | |
1138 | 1152 | | |
| |||
1226 | 1240 | | |
1227 | 1241 | | |
1228 | 1242 | | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
1229 | 1248 | | |
1230 | 1249 | | |
1231 | 1250 | | |
| |||
2698 | 2717 | | |
2699 | 2718 | | |
2700 | 2719 | | |
2701 | | - | |
| 2720 | + | |
2702 | 2721 | | |
2703 | 2722 | | |
2704 | 2723 | | |
| |||
2836 | 2855 | | |
2837 | 2856 | | |
2838 | 2857 | | |
| 2858 | + | |
| 2859 | + | |
| 2860 | + | |
| 2861 | + | |
| 2862 | + | |
| 2863 | + | |
| 2864 | + | |
| 2865 | + | |
| 2866 | + | |
| 2867 | + | |
| 2868 | + | |
| 2869 | + | |
| 2870 | + | |
| 2871 | + | |
| 2872 | + | |
| 2873 | + | |
| 2874 | + | |
| 2875 | + | |
| 2876 | + | |
| 2877 | + | |
| 2878 | + | |
| 2879 | + | |
| 2880 | + | |
| 2881 | + | |
| 2882 | + | |
| 2883 | + | |
| 2884 | + | |
2839 | 2885 | | |
2840 | 2886 | | |
2841 | 2887 | | |
| |||
3070 | 3116 | | |
3071 | 3117 | | |
3072 | 3118 | | |
3073 | | - | |
3074 | | - | |
3075 | | - | |
3076 | | - | |
3077 | | - | |
3078 | | - | |
| 3119 | + | |
| 3120 | + | |
| 3121 | + | |
| 3122 | + | |
| 3123 | + | |
| 3124 | + | |
| 3125 | + | |
| 3126 | + | |
| 3127 | + | |
| 3128 | + | |
| 3129 | + | |
3079 | 3130 | | |
3080 | 3131 | | |
3081 | 3132 | | |
| |||
3158 | 3209 | | |
3159 | 3210 | | |
3160 | 3211 | | |
3161 | | - | |
| 3212 | + | |
3162 | 3213 | | |
3163 | 3214 | | |
3164 | | - | |
3165 | | - | |
| 3215 | + | |
3166 | 3216 | | |
3167 | 3217 | | |
3168 | 3218 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
985 | 985 | | |
986 | 986 | | |
987 | 987 | | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
988 | 998 | | |
989 | 999 | | |
990 | 1000 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
643 | 643 | | |
644 | 644 | | |
645 | 645 | | |
646 | | - | |
| 646 | + | |
647 | 647 | | |
648 | 648 | | |
649 | 649 | | |
| |||
756 | 756 | | |
757 | 757 | | |
758 | 758 | | |
759 | | - | |
| 759 | + | |
760 | 760 | | |
761 | 761 | | |
762 | 762 | | |
763 | 763 | | |
764 | | - | |
| 764 | + | |
765 | 765 | | |
766 | 766 | | |
767 | 767 | | |
| |||
829 | 829 | | |
830 | 830 | | |
831 | 831 | | |
832 | | - | |
| 832 | + | |
833 | 833 | | |
834 | 834 | | |
835 | 835 | | |
| |||
985 | 985 | | |
986 | 986 | | |
987 | 987 | | |
988 | | - | |
| 988 | + | |
989 | 989 | | |
990 | 990 | | |
991 | 991 | | |
| |||
0 commit comments