diff --git a/build.zig b/build.zig index 1a8273a..5d7e6e0 100644 --- a/build.zig +++ b/build.zig @@ -45,11 +45,13 @@ pub fn build(b: *std.Build) void { 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/glib-2.0", .{glib_dev_path.?}) }); exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/lib/glib-2.0/include", .{glib_path.?}) }); + exe.addIncludePath(.{ .cwd_relative = "lib/hailo" }); exe.linkSystemLibrary("gstreamer-1.0"); exe.linkSystemLibrary("glib-2.0"); exe.linkSystemLibrary("gobject-2.0"); + exe.linkSystemLibrary("hailo"); // This declares intent for the executable to be installed into the // standard location when the user invokes the "install" step (the default diff --git a/src/main.zig b/src/main.zig index 1f562a3..fc76f39 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,75 +1,85 @@ + 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 +const hlo = @cImport({ + @cInclude("hlort.h"); }); +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; + +const hef_file = "yolov5s.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)); - const source: ?*gst.GstElement = gst.gst_element_factory_make("videotestsrc", "source"); - const sink: ?*gst.GstElement = gst.gst_element_factory_make("autovideosink", "sink"); + // var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + // defer arena.deinit(); - const pipeline: ?*gst.GstElement = gst.gst_pipeline_new("test-pipeline"); + // const alloc = arena.allocator(); - if (source == null or sink == null or pipeline == null) { - std.debug.panic("Not all elements could be created!", .{}); + var status: hlo.hailo_status = undefined; + var vdevice : hlo.hailo_vdevice = undefined; + var hef : hlo.hailo_hef = undefined; + var device_params: hlo.hailo_vdevice_params_t = undefined; + var network_group: hlo.hailo_configured_network_group = undefined; + const input_vstream_params : [max_edge_layers]hlo.hailo_input_vstream_params_by_name_t = undefined; + const output_vstream_params: [max_edge_layers]hlo.hailo_output_vstream_params_by_name_t = undefined; + const output_vstreams : [max_edge_layers]hlo.hailo_output_vstream = undefined; + const input_vstreams : [max_edge_layers]hlo.hailo_input_vstream = undefined; + var input_vstream_size = max_edge_layers; + var output_vstream_size = max_edge_layers; + var activated_network_group: hlo.hailo_activated_network_group = undefined; + var output_vstreams_info : [max_edge_layers]hlo.hailo_vstreams_info = undefined; + + + 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); + + status = hlo.hailo_init_configure_params(hef, hlo.HAILO_STREAM_INTERFACE_PCIE, &device_params); + assert(status == hlo.HAILO_SUCCESS); + + status = hlo.hailo_configure_vdevice(vdevice, hef, &device_params, &network_group, 1); + assert(status == hlo.HAILO_SUCCESS); + + status = hlo.hailo_make_input_vstream_params(network_group, true, hlo.HAILO_FORMAT_TYPE_AUTO, + input_vstream_params, &input_vstream_size); + assert(status == hlo.HAILO_SUCCESS); + + 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); + + status = hlo.hailo_create_input_vstreams(network_group, input_vstream_params, input_vstream_size, input_vstreams); + assert(status == hlo.HAILO_SUCCESS); + + status = hlo.hailo_create_output_vstreams(network_group, output_vstream_params, output_vstream_size, output_vstreams); + assert(status == hlo.HAILO_SUCCESS); + + status = hlo.activate_network_group(network_group, null, &activated_network_group); + assert(status == hlo.HAILO_SUCCESS); + + for (0..output_vstream_size) |i| { + hlo.hailo_get_output_vstream_info(output_vstreams[i], &output_vstreams_info[i]); } - // 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); + // write_to_hlo(_, alloc); + +} + +fn write_to_hlo(input_stream: hlo.hailo_input_vstream, alloc: Allocator) bool { + + var device_status: hlo.hailo_status = undefined; + var input_frame_size: usize = 0; + var src_data: *[]u8 = undefined; + + device_status = hlo.hailo_get_input_vstream_frame_size(input_stream, &input_frame_size); + + src_data = alloc.alloc(u8, input_frame_size); + - - // 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); }