diff --git a/build.zig b/build.zig index a42f85d..b9a6e09 100644 --- a/build.zig +++ b/build.zig @@ -38,8 +38,8 @@ pub fn build(b: *std.Build) void { exe.root_module.addImport("glib", gobject.module("glib2")); exe.root_module.addImport("gobject", gobject.module("gobject2")); - // exe.root_module.addImport("gst", gobject.module("gst1")); - // exe.root_module.addImport("gstapp", gobject.module("gstapp1")); + exe.root_module.addImport("gst", gobject.module("gst1")); + exe.root_module.addImport("gstapp", gobject.module("gstapp1")); // exe.addLibraryPath( .{ .cwd_relative = "/lib/aarch64-linux-gnu" }); // glib // exe.addLibraryPath( .{ .cwd_relative = "/lib/aarch64-linux-gnu/gstreamer-1.0" }); // gstreamer diff --git a/src/main.zig b/src/main.zig index 416ed14..2232e3b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -20,15 +20,108 @@ const assert = std.debug.assert; const hef_file = "yolov7.hef"; const max_edge_layers = 32; +var exit_loop: bool = false; + pub fn main() !void { + + std.posix.sigaction(std.posix.SIG.INT, &std.posix.Sigaction { + .handler = .{ + .handler = struct { + pub fn handler(_: c_int) callconv(.C) void { + std.debug.print("Control C caught!\n", .{}); + exit_loop = true; + } + }.handler + }, + .mask = std.posix.empty_sigset, + .flags = 0, + }, null); + + std.debug.print("ctrl+c handler registered\n", .{}); + + std.debug.print("Program started\n", .{}); // This allows me to utilize the same command line args and gstreamer 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", .{}); + + std.debug.print("Gstreamer Initialized\n", .{}); - const source: *gst.Element = gst.ElementFactory.make("videotestsrc", "source") orelse unreachable; + const source: *gst.Element = gst.ElementFactory.make("v4l2src", "source") orelse unreachable; std.debug.print("test source created\n", .{}); const scale: *gst.Element = gst.ElementFactory.make("videoscale", "scale") orelse unreachable; std.debug.print("video scale created\n", .{}); @@ -67,7 +160,7 @@ pub fn main() !void { pipeline.unref(); std.debug.panic("Elements could not be linked\n", .{}); } - std.debug.print("Elements linked", .{}); + std.debug.print("Elements linked\n", .{}); // g_int is just i32. You can // source.set("pattern", @as(i16, 0)); @@ -79,48 +172,82 @@ pub fn main() !void { std.debug.panic("Could not start pipeline", .{}); } - const bus: *gst.Bus = pipeline.getBus(); + const bus: *gst.Bus = pipeline.getBus(); + + + 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 }); + + + 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); + const input_data: [:0]u8 = try alloc.allocSentinel(u8, frame_count, 0); - const sample = sink.pullSample() orelse unreachable; - const buffer: *gst.Buffer = sample.getBuffer() orelse unreachable; - std.debug.print("Got the buffer! {any}\n", .{ buffer }); - std.debug.print("My buffer was '{d}' big!\n", .{ buffer.getSize() }); + 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 msg: *gst.Message = bus.popFiltered( gst.MessageType.flags_eos + gst.MessageType.flags_warning ); - const message_type: gst.MessageType = .{ .eos = true, .warning = true }; - const ret_msg: ?*gst.Message = bus.timedPopFiltered(std.math.maxInt(u64), message_type); + const output_frame_count = output_frame_size / @sizeOf(f32); + const output_data: [:0]f32 = try alloc.allocSentinel(f32, output_frame_count, 0); - std.debug.print("reg_msg returned!\n", .{}); - if (ret_msg) |msg| { - if (msg.f_type.eos == true) { - std.debug.print("EOS recieved\n", .{}); - } else if (msg.f_type.warning == true) { - std.debug.print("Warning message received\n", .{}); - const err: ?**glib.Error = null; - const debug_info: ?*[*:0]u8 = null; + var run_count: u8 = 0; - msg.parseError(err, debug_info); - if (err) |e| { - std.debug.print("Error received from element {s}: {s}", .{ msg.f_src, e.*.*.message }); + while (!exit_loop) { + const sample = sink.pullSample() orelse unreachable; + const buffer: *gst.Buffer = sample.getBuffer() orelse unreachable; + + _ = buffer.extract(0, @ptrCast(input_data), input_frame_size); + + status = hlo.hailo_vstream_write_raw_buffer(input_vstreams[0], input_data.ptr, input_frame_size); + assert(status == hlo.HAILO_SUCCESS); + + status = hlo.hailo_flush_input_vstream(input_vstreams[0]); + assert(status == hlo.HAILO_SUCCESS); + + status = hlo.hailo_vstream_read_raw_buffer(output_vstreams[0], output_data.ptr, output_frame_size); + if (status == hlo.HAILO_SUCCESS) { + for (0..50) |x| { + std.debug.print(" {d} ", .{output_data[x]}); } - 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.?}); + std.debug.print("\n", .{}); + + run_count += 1; + if (run_count > 20) { + break; } - glib.clearError(@ptrCast(err)); - glib.free(@ptrCast(debug_info)); } else { - std.debug.print("Unknown type received {any}\n", .{ msg }); + std.debug.print("Read failed!\n", .{}); + continue; } - // msg.unref(); - } else { - std.debug.print("ret message not handled type: {any}\n", .{ ret_msg }); } + std.debug.print("Staring shutdown\n", .{ }); + + bus.unref(); _ = pipeline.as(gst.Element).setState(gst.State.null); pipeline.unref(); + // const bus: *gst.Bus = pipeline.getBus(); + + + _ = 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); std.debug.print("run complete\n", .{}); }