diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-07-30 17:20:53 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-07-30 17:20:57 +0000 |
| commit | f372f217202c4966bd132123831184de4436cce6 (patch) | |
| tree | 117a73a5ce5779ea2ada1ac5f3afae1cfd0557e7 | |
| parent | accept format and format_options for ffmpeg sources (diff) | |
| download | glsl-view-f372f217202c4966bd132123831184de4436cce6.tar.gz glsl-view-f372f217202c4966bd132123831184de4436cce6.zip | |
add freeze and step controls to Source
| -rw-r--r-- | src/control.zig | 34 | ||||
| -rw-r--r-- | src/ffmpeg.zig | 8 | ||||
| -rw-r--r-- | src/gl.zig | 9 | ||||
| -rw-r--r-- | src/tsv.zig | 2 |
4 files changed, 48 insertions, 5 deletions
diff --git a/src/control.zig b/src/control.zig index 032a927..4f4d547 100644 --- a/src/control.zig +++ b/src/control.zig @@ -175,6 +175,9 @@ pub const ControlServer = struct { if (build_config.have_tsv) { _ = c.lo_server_add_method(self.server, "/texture/*/tsv", "ss", wrapCallback(handle_texture_tsv), @as(*anyopaque, @ptrCast(self))); } + _ = c.lo_server_add_method(self.server, "/texture/*/freeze", "T", wrapCallback(handle_texture_freeze), @as(*anyopaque, @ptrCast(self))); + _ = c.lo_server_add_method(self.server, "/texture/*/freeze", "F", wrapCallback(handle_texture_freeze), @as(*anyopaque, @ptrCast(self))); + _ = c.lo_server_add_method(self.server, "/texture/*/step", "", wrapCallback(handle_texture_step), @as(*anyopaque, @ptrCast(self))); _ = c.lo_server_add_method(self.server, "/texture/*/destroy", "", wrapCallback(handle_destroy_texture), @as(*anyopaque, @ptrCast(self))); return self; @@ -380,6 +383,35 @@ pub const ControlServer = struct { return true; } + fn handle_texture_freeze(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { + _ = argv; + + var parts = std.mem.tokenizeScalar(u8, path, '/'); + _ = parts.next(); + const name = parts.next() orelse unreachable; + + if (self.cache.textures.get(name)) |source| { + source.freeze = types[0] == 'T'; + } else return false; + + return true; + } + + fn handle_texture_step(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { + _ = argv; + _ = types; + + var parts = std.mem.tokenizeScalar(u8, path, '/'); + _ = parts.next(); + const name = parts.next() orelse unreachable; + + if (self.cache.textures.get(name)) |source| { + source.step.store(true, .monotonic); + } else return false; + + return true; + } + fn handle_destroy_texture(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { _ = types; _ = argv; @@ -394,6 +426,6 @@ pub const ControlServer = struct { self.cache.allocator.free(kv.key); } else return false; - return false; + return true; } }; diff --git a/src/ffmpeg.zig b/src/ffmpeg.zig index 67c3c2c..dda3f8c 100644 --- a/src/ffmpeg.zig +++ b/src/ffmpeg.zig @@ -286,7 +286,6 @@ pub const VideoSource = struct { self.* = .{ .source = .{ .texture = undefined, - .deinit_fn = deinit, }, .decoder = if (is_hap and build_config.have_hap) @@ -356,7 +355,6 @@ pub const StreamSource = struct { self.* = .{ .source = .{ .texture = texture, - .deinit_fn = deinit, }, @@ -389,7 +387,11 @@ pub const StreamSource = struct { if (self.packet.*.stream_index != self.stream) return; self.decoder.num_frames = 0; - _ = try self.decoder.process_packet_fn(self.decoder, self.packet, &self.source.texture); + _ = try self.decoder.process_packet_fn( + self.decoder, + self.packet, + if (self.source.shouldStep()) &self.source.texture else null, + ); } fn deinit(source: *gl.Source, allocator: std.mem.Allocator) void { @@ -941,11 +941,20 @@ pub const Source = struct { }; texture: Texture, + freeze: bool = false, + step: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + deinit_fn: *const fn (self: *Source, allocator: std.mem.Allocator) void, pub fn deinit(self: *Source, allocator: std.mem.Allocator) void { self.deinit_fn(self, allocator); } + + pub fn shouldStep(self: *Source) bool { + const step = !self.freeze or self.step.load(.acquire); + if (step) self.step.store(false, .release); + return step; + } }; pub const UniformCache = struct { diff --git a/src/tsv.zig b/src/tsv.zig index 687a2ed..a723a52 100644 --- a/src/tsv.zig +++ b/src/tsv.zig @@ -44,7 +44,6 @@ pub const TSVSource = struct { self.* = .{ .source = .{ .texture = gl.Texture.create(texture_type), - .deinit_fn = deinit, }, .name = try allocator.dupeZ(u8, std.mem.span(name)), @@ -86,6 +85,7 @@ pub const TSVSource = struct { } fn update(self: *TSVSource) void { + if (!self.source.shouldStep()) return; _ = c.gl_client_recv_image( get_or_init_client(), self.name.ptr, |
