ReviewOS

also looking at this

home-lang/home

feat(video): add native AVC/HEVC and synchronized AAC MP4 streaming

#913
Merged chris wants to merge feat/avc-hevc-mp4 into main
14 files +1119 -0
packages/video/src/codecs/video/rgb_i420.zigadded+37-0
Changes to packages/video/src/codecs/video/rgb_i420.zig
@@ -0,0 +1,37 @@
1//! Home RGB -> limited-range BT.601 I420. Adapted from perf/simd.zig, with
2//! checked strides and actual 2x2 chroma averaging rather than corner sampling.
3const std = ;
4pub fn convert(rgb: []const u8, width: u32, height: u32, stride: u32, out: []u8) !void {
5 if (width == 0 or height == 0 or (width | height) & 1 != 0 or stride < @as(u64, width) * 3) return error.InvalidGeometry;
6 const pixels = std.math.mul(usize, width, height) catch return error.InvalidGeometry;
7 if (rgb.len < @as(u64, stride) * (height - 1) + @as(u64, width) * 3 or out.len < pixels + pixels / 2) return error.InvalidGeometry;
8 for (0..height / 2) |cy| {
9 for (0..width / 2) |cx| {
10 var r: i32 = 0;
11 var g: i32 = 0;
12 var b: i32 = 0;
13 for (0..2) |dy| {
14 for (0..2) |dx| {
15 const x = cx * 2 + dx;
16 const y = cy * 2 + dy;
17 const p = rgb[y * stride + x * 3 ..][0..3];
18 out[y * width + x] = @intCast(((66 * @as(i32, p[0]) + 129 * @as(i32, p[1]) + 25 * @as(i32, p[2]) + 128) >> 8) + 16);
19 r += p[0];
20 g += p[1];
21 b += p[2];
22 }
23 }
24 const uv = cy * (width / 2) + cx;
25 out[pixels + uv] = @intCast(((-38 * r - 74 * g + 112 * b + 512) >> 10) + 128);
26 out[pixels + pixels / 4 + uv] = @intCast(((112 * r - 94 * g - 18 * b + 512) >> 10) + 128);
27 }
28 }
29}
30test "strided RGB conversion averages chroma and rejects truncation" {
31 var out: [6]u8 = undefined;
32 const rgb = [_]u8{ 255, 0, 0, 0, 255, 0, 99, 99, 0, 0, 255, 255, 255, 255 };
33 try convert(&rgb, 2, 2, 8, &out);
34 try std.testing.expectEqualSlices(u8, &.{ 82, 144, 41, 235, 128, 128 }, &out);
35 try std.testing.expectError(error.InvalidGeometry, convert(rgb[0..13], 2, 2, 8, &out));
36 try std.testing.expectError(error.InvalidGeometry, convert(&rgb, 1, 2, 8, &out));
37}