diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-07-29 09:18:23 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-07-29 09:18:23 +0000 |
| commit | a392d7b43740b58f5ad1dd0e1d4a78f9c4f8a406 (patch) | |
| tree | 2113d4db5dcbdc1e6f939eb9a27e7e83ae6fc302 | |
| parent | add libav StreamSource, run Sources in threads (diff) | |
| download | glsl-view-a392d7b43740b58f5ad1dd0e1d4a78f9c4f8a406.tar.gz glsl-view-a392d7b43740b58f5ad1dd0e1d4a78f9c4f8a406.zip | |
accept format and format_options for ffmpeg sources
| -rw-r--r-- | src/control.zig | 18 | ||||
| -rw-r--r-- | src/ffmpeg.zig | 35 | ||||
| -rw-r--r-- | src/tsv.zig | 2 |
3 files changed, 39 insertions, 16 deletions
diff --git a/src/control.zig b/src/control.zig index 48aabc3..032a927 100644 --- a/src/control.zig +++ b/src/control.zig @@ -169,8 +169,8 @@ pub const ControlServer = struct { _ = c.lo_server_add_method(self.server, "/uniform/*", null, wrapCallback(handle_uniform), @as(*anyopaque, @ptrCast(self))); if (build_config.have_ffmpeg) { - _ = c.lo_server_add_method(self.server, "/texture/*/video", "ss", wrapCallback(handle_texture_video), @as(*anyopaque, @ptrCast(self))); - _ = c.lo_server_add_method(self.server, "/texture/*/stream", "ss", wrapCallback(handle_texture_stream), @as(*anyopaque, @ptrCast(self))); + _ = c.lo_server_add_method(self.server, "/texture/*/video", null, wrapCallback(handle_texture_video), @as(*anyopaque, @ptrCast(self))); + _ = c.lo_server_add_method(self.server, "/texture/*/stream", null, wrapCallback(handle_texture_stream), @as(*anyopaque, @ptrCast(self))); } if (build_config.have_tsv) { _ = c.lo_server_add_method(self.server, "/texture/*/tsv", "ss", wrapCallback(handle_texture_tsv), @as(*anyopaque, @ptrCast(self))); @@ -310,7 +310,7 @@ pub const ControlServer = struct { } fn handle_texture_video(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { - _ = types; + try verify_args('s', types); var parts = std.mem.tokenizeScalar(u8, path, '/'); _ = parts.next(); @@ -320,9 +320,11 @@ pub const ControlServer = struct { const texture_typeZ: [*:0]const u8 = @ptrCast(&argv[0].*.s); const texture_type = std.meta.stringToEnum(gl.Texture.Type, std.mem.span(texture_typeZ)) orelse return error.invalidType; const filenameZ: [*:0]const u8 = @ptrCast(&argv[1].*.s); + const formatZ: ?[*:0]const u8 = if (argv.len > 2) @ptrCast(&argv[2].*.s) else null; + const args = if (argv.len > 3) argv[3..] else &.{}; const ffmpeg = @import("ffmpeg.zig"); - const source = try ffmpeg.VideoSource.init(self.cache.allocator, self.progress, filenameZ, texture_type); + const source = try ffmpeg.VideoSource.init(self.cache.allocator, self.progress, texture_type, filenameZ, formatZ, args); const key = try self.cache.allocator.dupe(u8, name); errdefer self.cache.allocator.free(key); @@ -332,7 +334,7 @@ pub const ControlServer = struct { } fn handle_texture_stream(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { - _ = types; + try verify_args('s', types); var parts = std.mem.tokenizeScalar(u8, path, '/'); _ = parts.next(); @@ -341,11 +343,13 @@ pub const ControlServer = struct { const texture_typeZ: [*:0]const u8 = @ptrCast(&argv[0].*.s); const filenameZ: [*:0]const u8 = @ptrCast(&argv[1].*.s); + const formatZ: ?[*:0]const u8 = if (argv.len > 2) @ptrCast(&argv[2].*.s) else null; + const args = if (argv.len > 3) argv[3..] else &.{}; if (!std.mem.eql(u8, std.mem.span(texture_typeZ), "TEXTURE_2D")) return error.textureTypeInvalid; const ffmpeg = @import("ffmpeg.zig"); - const source = try ffmpeg.StreamSource.init(self.cache.allocator, self.constants, filenameZ); + const source = try ffmpeg.StreamSource.init(self.cache.allocator, self.constants, filenameZ, formatZ, args); const key = try self.cache.allocator.dupe(u8, name); errdefer self.cache.allocator.free(key); @@ -367,7 +371,7 @@ pub const ControlServer = struct { const tsv_nameZ: [*:0]const u8 = @ptrCast(&argv[1].*.s); const tsv = @import("tsv.zig"); - const source = try tsv.TSVSource.init(self.cache.allocator, self.constants, tsv_nameZ, texture_type); + const source = try tsv.TSVSource.init(self.cache.allocator, self.constants, texture_type, tsv_nameZ); const key = try self.cache.allocator.dupe(u8, name); errdefer self.cache.allocator.free(key); diff --git a/src/ffmpeg.zig b/src/ffmpeg.zig index be7b6bf..67c3c2c 100644 --- a/src/ffmpeg.zig +++ b/src/ffmpeg.zig @@ -23,17 +23,32 @@ pub fn check(err: c_int) Errors!void { return error.AVGenericError; } -fn get_format_context(filename: [*:0]const u8, format_name: ?[*:0]const u8) !*c.AVFormatContext { - var format_ctx: ?*c.AVFormatContext = null; - var format: ?*const c.AVInputFormat = null; - var options: ?*c.AVDictionary = null; - +fn get_format_context( + filename: [*:0]const u8, + format_name: ?[*:0]const u8, + format_options: []const [*c]c.lo_arg, +) !*c.AVFormatContext { c.avdevice_register_all(); + var format: ?*const c.AVInputFormat = null; if (format_name) |name| { format = c.av_find_input_format(name); } + var options: ?*c.AVDictionary = null; + var i: usize = 0; + std.debug.assert(format_options.len % 2 == 0); + std.debug.print("len {}\n", .{format_options.len}); + while (i < format_options.len) : (i += 2) { + try check(c.av_dict_set( + &options, + &format_options[i].*.s, + &format_options[i + 1].*.s, + 0, + )); + } + + var format_ctx: ?*c.AVFormatContext = null; try check(c.avformat_open_input(&format_ctx, filename, format, &options)); errdefer c.avformat_close_input(&format_ctx); @@ -239,8 +254,10 @@ pub const VideoSource = struct { pub fn init( allocator: std.mem.Allocator, progress_root: std.Progress.Node, - filename: [*:0]const u8, texture_type: gl.Texture.Type, + filename: [*:0]const u8, + format_name: ?[*:0]const u8, + format_options: []const [*c]c.lo_arg, ) !*gl.Source { const self = try allocator.create(VideoSource); errdefer allocator.destroy(self); @@ -248,7 +265,7 @@ pub const VideoSource = struct { const progress = progress_root.start("loading texture", 2); defer progress.end(); - var format = try get_format_context(filename, null); + var format = try get_format_context(filename, format_name, format_options); defer c.avformat_close_input(@ptrCast(&format)); try check(c.avformat_find_stream_info(format, null)); @@ -304,11 +321,13 @@ pub const StreamSource = struct { allocator: std.mem.Allocator, constants: *const gl.Constants, filename: [*:0]const u8, + format_name: ?[*:0]const u8, + format_options: []const [*c]c.lo_arg, ) !*gl.Source { const self = try allocator.create(StreamSource); errdefer allocator.destroy(self); - var format = try get_format_context(filename, null); + var format = try get_format_context(filename, format_name, format_options); errdefer c.avformat_close_input(@ptrCast(&format)); format.flags |= c.AVFMT_FLAG_NONBLOCK; diff --git a/src/tsv.zig b/src/tsv.zig index 77c45ae..687a2ed 100644 --- a/src/tsv.zig +++ b/src/tsv.zig @@ -35,8 +35,8 @@ pub const TSVSource = struct { pub fn init( allocator: std.mem.Allocator, constants: *const gl.Constants, - name: [*:0]const u8, texture_type: gl.Texture.Type, + name: [*:0]const u8, ) !*gl.Source { const self = try allocator.create(TSVSource); errdefer allocator.destroy(self); |
