aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-07-29 09:18:23 +0000
committers-ol <s+removethis@s-ol.nu>2025-07-29 09:18:23 +0000
commita392d7b43740b58f5ad1dd0e1d4a78f9c4f8a406 (patch)
tree2113d4db5dcbdc1e6f939eb9a27e7e83ae6fc302
parentadd libav StreamSource, run Sources in threads (diff)
downloadglsl-view-a392d7b43740b58f5ad1dd0e1d4a78f9c4f8a406.tar.gz
glsl-view-a392d7b43740b58f5ad1dd0e1d4a78f9c4f8a406.zip
accept format and format_options for ffmpeg sources
-rw-r--r--src/control.zig18
-rw-r--r--src/ffmpeg.zig35
-rw-r--r--src/tsv.zig2
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);