added header file tomfoolery
This commit is contained in:
parent
b94d7c6e99
commit
20d3767031
6 changed files with 305 additions and 232 deletions
19
build.zig
19
build.zig
|
@ -25,7 +25,8 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
// These environment vars are set with the `nix develop` command
|
// These environment vars are set with the `nix develop` command
|
||||||
const gst_dev_path = b.graph.env_map.get("GST_DEV_PATH");
|
const gst_dev_path = b.graph.env_map.get("GST_DEV_PATH");
|
||||||
const gst_plugins_base_path = b.graph.env_map.get("GST_PLUGINS_BASE_PATH");
|
const gst_plugins_base_path = b.graph.env_map.get("GST_PLUGINS_BASE_PATH"); // system libraries
|
||||||
|
const gst_plugins_base_dev_path = b.graph.env_map.get("GST_PLUGINS_BASE_DEV_PATH"); // header files
|
||||||
const glib_dev_path = b.graph.env_map.get("GLIB_DEV_PATH");
|
const glib_dev_path = b.graph.env_map.get("GLIB_DEV_PATH");
|
||||||
const glib_path = b.graph.env_map.get("GLIB_PATH");
|
const glib_path = b.graph.env_map.get("GLIB_PATH");
|
||||||
|
|
||||||
|
@ -34,6 +35,10 @@ pub fn build(b: *std.Build) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gst_plugins_base_path == null) {
|
if (gst_plugins_base_path == null) {
|
||||||
|
std.debug.panic("GST_PLUGINS_PATH environment variable was not set. Has the nix flake been updated? This should point at the gst_all_1.gst-plugins-base folder", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_plugins_base_dev_path == null) {
|
||||||
std.debug.panic("GST_PLUGINS_DEV_PATH environment variable was not set. Has the nix flake been updated? This should point at the gst_all_1.gst-plugins-base.dev folder", .{});
|
std.debug.panic("GST_PLUGINS_DEV_PATH environment variable was not set. Has the nix flake been updated? This should point at the gst_all_1.gst-plugins-base.dev folder", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,18 +53,18 @@ pub fn build(b: *std.Build) void {
|
||||||
exe.linkSystemLibrary("c");
|
exe.linkSystemLibrary("c");
|
||||||
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include/gstreamer-1.0", .{gst_dev_path.?}) }); // not sure why both are needed, but
|
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include/gstreamer-1.0", .{gst_dev_path.?}) }); // not sure why both are needed, but
|
||||||
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include/gstreamer-1.0/gst", .{gst_dev_path.?}) }); // it won't compile without them
|
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include/gstreamer-1.0/gst", .{gst_dev_path.?}) }); // it won't compile without them
|
||||||
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include/gstreamer-1.0/gst/app", .{gst_plugins_base_path.?}) }); // gstreamer-appsink
|
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include/gstreamer-1.0", .{gst_plugins_base_dev_path.?}) }); // needed for header resolution of below dep
|
||||||
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include/glib-2.0", .{glib_dev_path.?}) });
|
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include/glib-2.0", .{glib_dev_path.?}) });
|
||||||
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/lib/glib-2.0/include", .{glib_path.?}) });
|
exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/lib/glib-2.0/include", .{glib_path.?}) });
|
||||||
|
|
||||||
exe.addIncludePath(.{ .cwd_relative = "/usr/include/hailo" });
|
// exe.addIncludePath(.{ .cwd_relative = "/usr/include/hailo" });
|
||||||
// exe.addLibraryPath(.{ .cwd_relative = "/usr/lib"});
|
// exe.addLibraryPath(.{ .cwd_relative = "/home/nixolas/Documents/hailort/build/hailort/libhailort/src"});
|
||||||
exe.addLibraryPath(.{ .cwd_relative = "/home/nixolas/Documents/hailort/build/hailort/libhailort/src"});
|
// exe.linkSystemLibrary("hailort");
|
||||||
exe.linkSystemLibrary("hailort");
|
|
||||||
|
|
||||||
|
|
||||||
|
exe.addLibraryPath(.{ .cwd_relative = b.fmt("{s}/lib", .{ gst_plugins_base_path.? }) });
|
||||||
exe.linkSystemLibrary("gstreamer-1.0");
|
exe.linkSystemLibrary("gstreamer-1.0");
|
||||||
exe.linkSystemLibrary("gstreamer-app-1.0");
|
exe.linkSystemLibrary("gstapp-1.0");
|
||||||
exe.linkSystemLibrary("glib-2.0");
|
exe.linkSystemLibrary("glib-2.0");
|
||||||
exe.linkSystemLibrary("gobject-2.0");
|
exe.linkSystemLibrary("gobject-2.0");
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
GST_DEV_PATH = pkgs.gst_all_1.gstreamer.dev;
|
GST_DEV_PATH = pkgs.gst_all_1.gstreamer.dev;
|
||||||
GST_PLUGINS_BASE_PATH = pkgs.gst_all_1.gst-plugins-base.dev;
|
GST_PLUGINS_BASE_PATH = pkgs.gst_all_1.gst-plugins-base;
|
||||||
|
GST_PLUGINS_BASE_DEV_PATH = pkgs.gst_all_1.gst-plugins-base.dev;
|
||||||
GLIB_DEV_PATH = pkgs.glib.dev;
|
GLIB_DEV_PATH = pkgs.glib.dev;
|
||||||
GLIB_PATH = pkgs.glib.out;
|
GLIB_PATH = pkgs.glib.out;
|
||||||
|
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
const gst = @cImport({ // glib-object for g_object_* functions
|
|
||||||
@cInclude("glib-object.h");
|
|
||||||
@cInclude("gst.h");
|
|
||||||
@cInclude("glib.h"); // and glib for other g_* functions
|
|
||||||
});
|
|
||||||
|
|
||||||
pub fn main() void {
|
|
||||||
// This allows me to utilize the same command line args and gstreamer
|
|
||||||
gst.gst_init(@ptrCast(&std.os.argv.len), @ptrCast(&std.os.argv.ptr));
|
|
||||||
|
|
||||||
const source: ?*gst.GstElement = gst.gst_element_factory_make("videotestsrc", "source");
|
|
||||||
const sink: ?*gst.GstElement = gst.gst_element_factory_make("autovideosink", "sink");
|
|
||||||
|
|
||||||
const pipeline: ?*gst.GstElement = gst.gst_pipeline_new("test-pipeline");
|
|
||||||
|
|
||||||
if (source == null or sink == null or pipeline == null) {
|
|
||||||
std.debug.panic("Not all elements could be created!", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
// When you look into the GST_BIN macro that zig can't compile,
|
|
||||||
// it really is just this pointer cast with extra steps of verification
|
|
||||||
const bin: *gst.GstBin = @ptrCast(pipeline);
|
|
||||||
|
|
||||||
|
|
||||||
// Gstreamer gives a critical warning when using gst.gst_bin_add_many, but doesn't
|
|
||||||
// when calling each individually
|
|
||||||
_ = gst.gst_bin_add(bin, source);
|
|
||||||
_ = gst.gst_bin_add(bin, sink);
|
|
||||||
|
|
||||||
// the failure return code is -1 I believe
|
|
||||||
if (gst.gst_element_link(source, sink) < 0) {
|
|
||||||
gst.gst_object_unref(pipeline);
|
|
||||||
std.debug.panic("Elements could not be linked\n", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
// g_int is just i32. You can
|
|
||||||
gst.g_object_set(source, "pattern", @as(i16, 0));
|
|
||||||
|
|
||||||
const ret = gst.gst_element_set_state(pipeline, gst.GST_STATE_PLAYING);
|
|
||||||
if (ret == gst.GST_STATE_CHANGE_FAILURE) {
|
|
||||||
gst.gst_object_unref(pipeline);
|
|
||||||
std.debug.panic("Could not start pipeline", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
const bus: *gst.GstBus = gst.gst_element_get_bus(pipeline);
|
|
||||||
const msg: *gst.GstMessage = gst.gst_bus_timed_pop_filtered( // This call holds until there is a valid message
|
|
||||||
bus,
|
|
||||||
gst.GST_CLOCK_TIME_NONE,
|
|
||||||
gst.GST_MESSAGE_ERROR | gst.GST_MESSAGE_EOS,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (gst.GST_MESSAGE_TYPE(msg) == gst.GST_MESSAGE_ERROR) {
|
|
||||||
const err: [*c][*c]gst.GError = null;
|
|
||||||
var debug_info: ?*gst.gchar = null;
|
|
||||||
|
|
||||||
switch (gst.GST_MESSAGE_TYPE(msg)) {
|
|
||||||
gst.GST_MESSAGE_ERROR => {
|
|
||||||
gst.gst_message_parse_error(msg, err, &debug_info);
|
|
||||||
std.debug.print("Error received from element {s}: {s}", .{ gst.GST_OBJECT_NAME(msg.src), err.*.*.message });
|
|
||||||
if (debug_info != null) { // I couldn't figure out how to do a orelse statement for this unwrap.
|
|
||||||
std.debug.print("Debugging information: {s}", .{debug_info.?});
|
|
||||||
}
|
|
||||||
gst.g_clear_error(err);
|
|
||||||
gst.g_free(debug_info);
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
gst.gst_message_unref(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst.gst_object_unref(bus);
|
|
||||||
_ = gst.gst_element_set_state(pipeline, gst.GST_STATE_NULL);
|
|
||||||
gst.gst_object_unref(pipeline);
|
|
||||||
}
|
|
65
src/gstreamer_functions.zig
Normal file
65
src/gstreamer_functions.zig
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const gst = @cImport({ // glib-object for g_object_* functions
|
||||||
|
@cInclude("glib-object.h");
|
||||||
|
@cInclude("gst.h");
|
||||||
|
@cInclude("gstappsrc.h");
|
||||||
|
@cInclude("glib.h"); // and glib for other g_* functions
|
||||||
|
});
|
||||||
|
|
||||||
|
pub const GstError = error {
|
||||||
|
EmptySample,
|
||||||
|
EmptyBuffer,
|
||||||
|
EmptyBufferMap,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_buffer(app_sink: gst.GstElement) !*gst.GstBuffer {
|
||||||
|
const sample: *gst.GstSample = undefined;
|
||||||
|
var buffer: ?*gst.GetBuffer = undefined;
|
||||||
|
|
||||||
|
std.debug.print("pulling sample\n", .{});
|
||||||
|
sample = gst.gst_app_sink_pull_sample(@ptrCast(app_sink));
|
||||||
|
std.debug.print("Pulled appsink sample\n", .{});
|
||||||
|
|
||||||
|
const sample_info = gst.gst_sample_get_info(sample);
|
||||||
|
if (sample_info != null) {
|
||||||
|
const si_string = gst.gst_structure_to_string(sample_info);
|
||||||
|
std.debug.print("Sample info retrieved {s}\n", .{ si_string });
|
||||||
|
gst.g_free(si_string);
|
||||||
|
} else {
|
||||||
|
std.debug.print("Got sample with no info!\n", .{});
|
||||||
|
return GstError.EmptySample;
|
||||||
|
}
|
||||||
|
defer gst.gst_sample_unref(sample);
|
||||||
|
|
||||||
|
const s_caps: ?*gst.GstCaps = gst.gst_sample_get_caps(sample);
|
||||||
|
if (s_caps != null) {
|
||||||
|
const cap_str = gst.gst_caps_to_string(s_caps);
|
||||||
|
std.debug.print("Got sample with caps {s}\n", .{ cap_str });
|
||||||
|
gst.g_free(cap_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = gst.gst_sample_get_buffer(sample);
|
||||||
|
std.debug.print("Got buffer from sample!\n", .{});
|
||||||
|
|
||||||
|
var map: *gst.GstMapInfo = undefined;
|
||||||
|
|
||||||
|
defer gst.gst_buffer_unmap(buffer, &map);
|
||||||
|
|
||||||
|
if (buffer == null || !gst.gst_buffer_map(buffer, &map, gst.GST_MAP_READ)) {
|
||||||
|
std.debug.print("Failed to get buffer or buffer map!\n", .{});
|
||||||
|
if (buffer == null) {
|
||||||
|
return GstError.EmptyBuffer;
|
||||||
|
} else {
|
||||||
|
return GstError.EmptyBufferMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const len = map.size;
|
||||||
|
std.debug.print("map size is: {d}\n", .{ len });
|
||||||
|
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
197
src/hailo-main.zig
Normal file
197
src/hailo-main.zig
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const gst_funcs = @import("src/gstreamer_functions.zig");
|
||||||
|
const hlo = @cImport({
|
||||||
|
@cInclude("hailort.h");
|
||||||
|
});
|
||||||
|
const gst = @cImport({ // glib-object for g_object_* functions
|
||||||
|
@cInclude("glib-object.h");
|
||||||
|
@cInclude("gst.h");
|
||||||
|
@cInclude("gst/app/gstappsrc.h"); // because I don't want two include paths for header file name resolution
|
||||||
|
@cInclude("glib.h"); // and glib for other g_* functions
|
||||||
|
});
|
||||||
|
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
const hef_file = "yolov7.hef";
|
||||||
|
const max_edge_layers = 32;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
// This allows me to utilize the same command line args and gstreamer
|
||||||
|
gst.gst_init(@ptrCast(&std.os.argv.len), @ptrCast(&std.os.argv.ptr));
|
||||||
|
|
||||||
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
|
std.fs.cwd().access(hef_file, .{ }) catch |e| {
|
||||||
|
std.debug.panic("Could not open hef file! '{any}'", .{ e });
|
||||||
|
};
|
||||||
|
|
||||||
|
var status: hlo.hailo_status = undefined;
|
||||||
|
var vdevice : hlo.hailo_vdevice = undefined;
|
||||||
|
var hef : hlo.hailo_hef = undefined;
|
||||||
|
var config_params: hlo.hailo_configure_params_t = undefined; // std.mem.zeroInit(hlo.hailo_vdevice_params_t, .{});
|
||||||
|
var network_group: hlo.hailo_configured_network_group = undefined;
|
||||||
|
var network_group_size : usize = 1;
|
||||||
|
var input_vstream_params : [max_edge_layers]hlo.hailo_input_vstream_params_by_name_t = undefined;
|
||||||
|
var output_vstream_params : [max_edge_layers]hlo.hailo_output_vstream_params_by_name_t = undefined;
|
||||||
|
var output_vstreams : [max_edge_layers]hlo.hailo_output_vstream = undefined;
|
||||||
|
var input_vstreams : [max_edge_layers]hlo.hailo_input_vstream = undefined;
|
||||||
|
var input_vstream_size : usize = max_edge_layers;
|
||||||
|
var output_vstream_size : usize = max_edge_layers;
|
||||||
|
|
||||||
|
|
||||||
|
status = hlo.hailo_create_vdevice(null, &vdevice);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
status = hlo.hailo_create_hef_file(&hef, hef_file);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
std.debug.print("vdevice inited, hef file created!\n", .{});
|
||||||
|
|
||||||
|
status = hlo.hailo_init_configure_params_by_vdevice(hef, vdevice, &config_params);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
std.debug.print("Init configure params complete\n", .{});
|
||||||
|
|
||||||
|
assert(vdevice != null);
|
||||||
|
assert(hef != null);
|
||||||
|
assert(network_group_size != 0);
|
||||||
|
|
||||||
|
status = hlo.hailo_configure_vdevice(vdevice, hef, &config_params, &network_group, &network_group_size);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
std.debug.print("Configure vdevice complete!\n", .{});
|
||||||
|
|
||||||
|
status = hlo.hailo_make_input_vstream_params(network_group, false, hlo.HAILO_FORMAT_TYPE_AUTO,
|
||||||
|
&input_vstream_params, &input_vstream_size);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
std.debug.print("Input vstream params initialized\n", .{});
|
||||||
|
|
||||||
|
status = hlo.hailo_make_output_vstream_params(network_group, true, hlo.HAILO_FORMAT_TYPE_AUTO,
|
||||||
|
&output_vstream_params, &output_vstream_size);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
std.debug.print("Output vstream params initialized\n", .{});
|
||||||
|
|
||||||
|
assert(input_vstream_size <= max_edge_layers);
|
||||||
|
|
||||||
|
status = hlo.hailo_create_input_vstreams(network_group, &input_vstream_params, input_vstream_size, &input_vstreams);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
std.debug.print("Input vstreams initialized\n", .{});
|
||||||
|
|
||||||
|
status = hlo.hailo_create_output_vstreams(network_group, &output_vstream_params, output_vstream_size, &output_vstreams);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
std.debug.print("Output vstreams initialized\n", .{});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std.debug.print("HailoRT init completed\nGstreamer Init starting", .{});
|
||||||
|
|
||||||
|
const source: ?*gst.GstElement = gst.gst_element_factory_make("videotestsrc", "source");
|
||||||
|
const sink: ?*gst.GstElement = gst.gst_element_factory_make("appsink", "sink");
|
||||||
|
|
||||||
|
const pipeline: ?*gst.GstElement = gst.gst_pipeline_new("test-pipeline");
|
||||||
|
|
||||||
|
if (source == null or sink == null or pipeline == null) {
|
||||||
|
std.debug.panic("Not all elements could be created!", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
// When you look into the GST_BIN macro that zig can't compile,
|
||||||
|
// it really is just this pointer cast with extra steps of verification
|
||||||
|
const bin: *gst.GstBin = @ptrCast(pipeline);
|
||||||
|
|
||||||
|
|
||||||
|
// Gstreamer gives a critical warning when using gst.gst_bin_add_many, but doesn't
|
||||||
|
// when calling each individually
|
||||||
|
_ = gst.gst_bin_add(bin, source);
|
||||||
|
_ = gst.gst_bin_add(bin, sink);
|
||||||
|
|
||||||
|
// the failure return code is -1 I believe
|
||||||
|
if (gst.gst_element_link(source, sink) < 0) {
|
||||||
|
gst.gst_object_unref(pipeline);
|
||||||
|
std.debug.panic("Elements could not be linked\n", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
// g_int is just i32. You can
|
||||||
|
gst.g_object_set(source, "pattern", @as(i16, 0));
|
||||||
|
|
||||||
|
const ret = gst.gst_element_set_state(pipeline, gst.GST_STATE_PLAYING);
|
||||||
|
if (ret == gst.GST_STATE_CHANGE_FAILURE) {
|
||||||
|
gst.gst_object_unref(pipeline);
|
||||||
|
std.debug.panic("Could not start pipeline", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
// const bus: *gst.GstBus = gst.gst_element_get_bus(pipeline);
|
||||||
|
// const msg: *gst.GstMessage = gst.gst_bus_timed_pop_filtered( // This call holds until there is a valid message
|
||||||
|
// bus,
|
||||||
|
// gst.GST_CLOCK_TIME_NONE,
|
||||||
|
// gst.GST_MESSAGE_ERROR | gst.GST_MESSAGE_EOS,
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var input_frame_size: usize = 0;
|
||||||
|
|
||||||
|
status = hlo.hailo_get_input_vstream_frame_size(input_vstreams[0], &input_frame_size);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
const frame_count = input_frame_size / @sizeOf(u8);
|
||||||
|
var input_data: [:0]u8 = try alloc.allocSentinel(u8, frame_count, 0);
|
||||||
|
|
||||||
|
|
||||||
|
for (0..(frame_count + 1)) |i| {
|
||||||
|
input_data[i] = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std.debug.print("Getting vstream info\n", .{});
|
||||||
|
var stream_info: hlo.hailo_vstream_info_t = undefined;
|
||||||
|
status = hlo.hailo_get_input_vstream_info(input_vstreams[0], &stream_info);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
|
||||||
|
var output_info: hlo.hailo_vstream_info_t = undefined;
|
||||||
|
status = hlo.hailo_get_output_vstream_info(output_vstreams[0], &output_info);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
std.debug.print("\nOutput info: {any}\n\n", .{ output_info });
|
||||||
|
|
||||||
|
std.debug.print("Writing vstream data\n", .{});
|
||||||
|
status = hlo.hailo_vstream_write_raw_buffer(input_vstreams[0], input_data.ptr, input_frame_size);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
std.debug.print("Input written\n", .{});
|
||||||
|
|
||||||
|
status = hlo.hailo_flush_input_vstream(input_vstreams[0]);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
std.debug.print("input flushed!\n", .{});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var output_frame_size: usize = 0;
|
||||||
|
status = hlo.hailo_get_output_vstream_frame_size(output_vstreams[0], &output_frame_size);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
std.debug.print("output frame size is: {d}\n", .{ output_frame_size });
|
||||||
|
|
||||||
|
const output_frame_count = output_frame_size / @sizeOf(u8);
|
||||||
|
const output_data: [:0]u8 = try alloc.allocSentinel(u8, output_frame_count, 0);
|
||||||
|
|
||||||
|
status = hlo.hailo_vstream_read_raw_buffer(output_vstreams[0], output_data.ptr, output_frame_size);
|
||||||
|
assert(status == hlo.HAILO_SUCCESS);
|
||||||
|
std.debug.print("Output finished reading! Cleanup time\n", .{});
|
||||||
|
|
||||||
|
std.debug.print("good luck\n\n{x}", .{ output_data });
|
||||||
|
|
||||||
|
|
||||||
|
_ = hlo.hailo_release_output_vstreams(&output_vstreams, output_vstream_size);
|
||||||
|
_ = hlo.hailo_release_input_vstreams(&input_vstreams, input_vstream_size);
|
||||||
|
_ = hlo.hailo_release_hef(hef);
|
||||||
|
_ = hlo.hailo_release_vdevice(vdevice);
|
||||||
|
}
|
||||||
|
|
178
src/main.zig
178
src/main.zig
|
@ -1,101 +1,17 @@
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const hlo = @cImport({
|
|
||||||
@cInclude("hailort.h");
|
|
||||||
});
|
|
||||||
const gst = @cImport({ // glib-object for g_object_* functions
|
const gst = @cImport({ // glib-object for g_object_* functions
|
||||||
@cInclude("glib-object.h");
|
@cInclude("glib-object.h");
|
||||||
@cInclude("gst.h");
|
|
||||||
@cInclude("gstappsrc.h");
|
|
||||||
@cInclude("glib.h"); // and glib for other g_* functions
|
@cInclude("glib.h"); // and glib for other g_* functions
|
||||||
|
@cInclude("gst.h");
|
||||||
|
@cInclude("gst/app/gstappsrc.h"); // because I don't want two include paths for header file name resolution
|
||||||
});
|
});
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
pub fn main() void {
|
||||||
const assert = std.debug.assert;
|
|
||||||
|
|
||||||
const hef_file = "yolov7.hef";
|
|
||||||
const max_edge_layers = 32;
|
|
||||||
|
|
||||||
|
|
||||||
pub fn main() !void {
|
|
||||||
// This allows me to utilize the same command line args and gstreamer
|
// This allows me to utilize the same command line args and gstreamer
|
||||||
gst.gst_init(@ptrCast(&std.os.argv.len), @ptrCast(&std.os.argv.ptr));
|
gst.gst_init(@ptrCast(&std.os.argv.len), @ptrCast(&std.os.argv.ptr));
|
||||||
|
|
||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
||||||
defer arena.deinit();
|
|
||||||
|
|
||||||
const alloc = arena.allocator();
|
|
||||||
|
|
||||||
std.fs.cwd().access(hef_file, .{ }) catch |e| {
|
|
||||||
std.debug.panic("Could not open hef file! '{any}'", .{ e });
|
|
||||||
};
|
|
||||||
|
|
||||||
var status: hlo.hailo_status = undefined;
|
|
||||||
var vdevice : hlo.hailo_vdevice = undefined;
|
|
||||||
var hef : hlo.hailo_hef = undefined;
|
|
||||||
var config_params: hlo.hailo_configure_params_t = undefined; // std.mem.zeroInit(hlo.hailo_vdevice_params_t, .{});
|
|
||||||
var network_group: hlo.hailo_configured_network_group = undefined;
|
|
||||||
var network_group_size : usize = 1;
|
|
||||||
var input_vstream_params : [max_edge_layers]hlo.hailo_input_vstream_params_by_name_t = undefined;
|
|
||||||
var output_vstream_params : [max_edge_layers]hlo.hailo_output_vstream_params_by_name_t = undefined;
|
|
||||||
var output_vstreams : [max_edge_layers]hlo.hailo_output_vstream = undefined;
|
|
||||||
var input_vstreams : [max_edge_layers]hlo.hailo_input_vstream = undefined;
|
|
||||||
var input_vstream_size : usize = max_edge_layers;
|
|
||||||
var output_vstream_size : usize = max_edge_layers;
|
|
||||||
|
|
||||||
|
|
||||||
status = hlo.hailo_create_vdevice(null, &vdevice);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
status = hlo.hailo_create_hef_file(&hef, hef_file);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
std.debug.print("vdevice inited, hef file created!\n", .{});
|
|
||||||
|
|
||||||
status = hlo.hailo_init_configure_params_by_vdevice(hef, vdevice, &config_params);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
std.debug.print("Init configure params complete\n", .{});
|
|
||||||
|
|
||||||
assert(vdevice != null);
|
|
||||||
assert(hef != null);
|
|
||||||
assert(network_group_size != 0);
|
|
||||||
|
|
||||||
status = hlo.hailo_configure_vdevice(vdevice, hef, &config_params, &network_group, &network_group_size);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
std.debug.print("Configure vdevice complete!\n", .{});
|
|
||||||
|
|
||||||
status = hlo.hailo_make_input_vstream_params(network_group, false, hlo.HAILO_FORMAT_TYPE_AUTO,
|
|
||||||
&input_vstream_params, &input_vstream_size);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
std.debug.print("Input vstream params initialized\n", .{});
|
|
||||||
|
|
||||||
status = hlo.hailo_make_output_vstream_params(network_group, true, hlo.HAILO_FORMAT_TYPE_AUTO,
|
|
||||||
&output_vstream_params, &output_vstream_size);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
std.debug.print("Output vstream params initialized\n", .{});
|
|
||||||
|
|
||||||
assert(input_vstream_size <= max_edge_layers);
|
|
||||||
|
|
||||||
status = hlo.hailo_create_input_vstreams(network_group, &input_vstream_params, input_vstream_size, &input_vstreams);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
std.debug.print("Input vstreams initialized\n", .{});
|
|
||||||
|
|
||||||
status = hlo.hailo_create_output_vstreams(network_group, &output_vstream_params, output_vstream_size, &output_vstreams);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
std.debug.print("Output vstreams initialized\n", .{});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std.debug.print("HailoRT init completed\nGstreamer Init starting", .{});
|
|
||||||
|
|
||||||
const source: ?*gst.GstElement = gst.gst_element_factory_make("videotestsrc", "source");
|
const source: ?*gst.GstElement = gst.gst_element_factory_make("videotestsrc", "source");
|
||||||
const sink: ?*gst.GstElement = gst.gst_element_factory_make("appsink", "sink");
|
const sink: ?*gst.GstElement = gst.gst_element_factory_make("autovideosink", "sink");
|
||||||
|
|
||||||
const pipeline: ?*gst.GstElement = gst.gst_pipeline_new("test-pipeline");
|
const pipeline: ?*gst.GstElement = gst.gst_pipeline_new("test-pipeline");
|
||||||
|
|
||||||
|
@ -128,69 +44,33 @@ pub fn main() !void {
|
||||||
std.debug.panic("Could not start pipeline", .{});
|
std.debug.panic("Could not start pipeline", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
// const bus: *gst.GstBus = gst.gst_element_get_bus(pipeline);
|
const bus: *gst.GstBus = gst.gst_element_get_bus(pipeline);
|
||||||
// const msg: *gst.GstMessage = gst.gst_bus_timed_pop_filtered( // This call holds until there is a valid message
|
const msg: *gst.GstMessage = gst.gst_bus_timed_pop_filtered( // This call holds until there is a valid message
|
||||||
// bus,
|
bus,
|
||||||
// gst.GST_CLOCK_TIME_NONE,
|
gst.GST_CLOCK_TIME_NONE,
|
||||||
// gst.GST_MESSAGE_ERROR | gst.GST_MESSAGE_EOS,
|
gst.GST_MESSAGE_ERROR | gst.GST_MESSAGE_EOS,
|
||||||
//);
|
);
|
||||||
|
|
||||||
|
if (gst.GST_MESSAGE_TYPE(msg) == gst.GST_MESSAGE_ERROR) {
|
||||||
|
const err: [*c][*c]gst.GError = null;
|
||||||
|
var debug_info: ?*gst.gchar = null;
|
||||||
|
|
||||||
|
switch (gst.GST_MESSAGE_TYPE(msg)) {
|
||||||
|
gst.GST_MESSAGE_ERROR => {
|
||||||
var input_frame_size: usize = 0;
|
gst.gst_message_parse_error(msg, err, &debug_info);
|
||||||
|
std.debug.print("Error received from element {s}: {s}", .{ gst.GST_OBJECT_NAME(msg.src), err.*.*.message });
|
||||||
status = hlo.hailo_get_input_vstream_frame_size(input_vstreams[0], &input_frame_size);
|
if (debug_info != null) { // I couldn't figure out how to do a orelse statement for this unwrap.
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
std.debug.print("Debugging information: {s}", .{debug_info.?});
|
||||||
|
}
|
||||||
const frame_count = input_frame_size / @sizeOf(u8);
|
gst.g_clear_error(err);
|
||||||
var input_data: [:0]u8 = try alloc.allocSentinel(u8, frame_count, 0);
|
gst.g_free(debug_info);
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
for (0..(frame_count + 1)) |i| {
|
}
|
||||||
input_data[i] = 5;
|
gst.gst_message_unref(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst.gst_object_unref(bus);
|
||||||
std.debug.print("Getting vstream info\n", .{});
|
_ = gst.gst_element_set_state(pipeline, gst.GST_STATE_NULL);
|
||||||
var stream_info: hlo.hailo_vstream_info_t = undefined;
|
gst.gst_object_unref(pipeline);
|
||||||
status = hlo.hailo_get_input_vstream_info(input_vstreams[0], &stream_info);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
|
|
||||||
var output_info: hlo.hailo_vstream_info_t = undefined;
|
|
||||||
status = hlo.hailo_get_output_vstream_info(output_vstreams[0], &output_info);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
std.debug.print("\nOutput info: {any}\n\n", .{ output_info });
|
|
||||||
|
|
||||||
std.debug.print("Writing vstream data\n", .{});
|
|
||||||
status = hlo.hailo_vstream_write_raw_buffer(input_vstreams[0], input_data.ptr, input_frame_size);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
std.debug.print("Input written\n", .{});
|
|
||||||
|
|
||||||
status = hlo.hailo_flush_input_vstream(input_vstreams[0]);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
std.debug.print("input flushed!\n", .{});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var output_frame_size: usize = 0;
|
|
||||||
status = hlo.hailo_get_output_vstream_frame_size(output_vstreams[0], &output_frame_size);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
std.debug.print("output frame size is: {d}\n", .{ output_frame_size });
|
|
||||||
|
|
||||||
const output_frame_count = output_frame_size / @sizeOf(u8);
|
|
||||||
const output_data: [:0]u8 = try alloc.allocSentinel(u8, output_frame_count, 0);
|
|
||||||
|
|
||||||
status = hlo.hailo_vstream_read_raw_buffer(output_vstreams[0], output_data.ptr, output_frame_size);
|
|
||||||
assert(status == hlo.HAILO_SUCCESS);
|
|
||||||
std.debug.print("Output finished reading! Cleanup time\n", .{});
|
|
||||||
|
|
||||||
std.debug.print("good luck\n\n{x}", .{ output_data });
|
|
||||||
|
|
||||||
|
|
||||||
_ = hlo.hailo_release_output_vstreams(&output_vstreams, output_vstream_size);
|
|
||||||
_ = hlo.hailo_release_input_vstreams(&input_vstreams, input_vstream_size);
|
|
||||||
_ = hlo.hailo_release_hef(hef);
|
|
||||||
_ = hlo.hailo_release_vdevice(vdevice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue