From 20d376703126f710051ce7ab38eaba214640d7c5 Mon Sep 17 00:00:00 2001 From: Nickiel12 Date: Sun, 20 Oct 2024 02:26:02 +0000 Subject: [PATCH] added header file tomfoolery --- build.zig | 19 ++-- flake.nix | 3 +- src/gstreamer-main.zig | 75 -------------- src/gstreamer_functions.zig | 65 ++++++++++++ src/hailo-main.zig | 197 ++++++++++++++++++++++++++++++++++++ src/main.zig | 178 ++++++-------------------------- 6 files changed, 305 insertions(+), 232 deletions(-) delete mode 100644 src/gstreamer-main.zig create mode 100644 src/gstreamer_functions.zig create mode 100644 src/hailo-main.zig diff --git a/build.zig b/build.zig index 7cfdcb7..f481935 100644 --- a/build.zig +++ b/build.zig @@ -25,7 +25,8 @@ pub fn build(b: *std.Build) void { // These environment vars are set with the `nix develop` command 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_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) { + 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", .{}); } @@ -48,18 +53,18 @@ pub fn build(b: *std.Build) void { 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", .{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}/lib/glib-2.0/include", .{glib_path.?}) }); - 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.linkSystemLibrary("hailort"); + // exe.addIncludePath(.{ .cwd_relative = "/usr/include/hailo" }); + // exe.addLibraryPath(.{ .cwd_relative = "/home/nixolas/Documents/hailort/build/hailort/libhailort/src"}); + // exe.linkSystemLibrary("hailort"); + exe.addLibraryPath(.{ .cwd_relative = b.fmt("{s}/lib", .{ gst_plugins_base_path.? }) }); exe.linkSystemLibrary("gstreamer-1.0"); - exe.linkSystemLibrary("gstreamer-app-1.0"); + exe.linkSystemLibrary("gstapp-1.0"); exe.linkSystemLibrary("glib-2.0"); exe.linkSystemLibrary("gobject-2.0"); diff --git a/flake.nix b/flake.nix index 5e6de5c..0415acd 100644 --- a/flake.nix +++ b/flake.nix @@ -31,7 +31,8 @@ ]; 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_PATH = pkgs.glib.out; diff --git a/src/gstreamer-main.zig b/src/gstreamer-main.zig deleted file mode 100644 index 1f562a3..0000000 --- a/src/gstreamer-main.zig +++ /dev/null @@ -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); -} diff --git a/src/gstreamer_functions.zig b/src/gstreamer_functions.zig new file mode 100644 index 0000000..7c7e0cb --- /dev/null +++ b/src/gstreamer_functions.zig @@ -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; +} diff --git a/src/hailo-main.zig b/src/hailo-main.zig new file mode 100644 index 0000000..090bff5 --- /dev/null +++ b/src/hailo-main.zig @@ -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); +} + diff --git a/src/main.zig b/src/main.zig index 8af635b..8129e6d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,101 +1,17 @@ - const std = @import("std"); -const hlo = @cImport({ - @cInclude("hailort.h"); -}); 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 + @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; -const assert = std.debug.assert; - -const hef_file = "yolov7.hef"; -const max_edge_layers = 32; - - -pub fn main() !void { +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 sink: ?*gst.GstElement = gst.gst_element_factory_make("autovideosink", "sink"); 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", .{}); } - // 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, - //); + 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; - - - 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; + 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); } - - 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); + gst.gst_object_unref(bus); + _ = gst.gst_element_set_state(pipeline, gst.GST_STATE_NULL); + gst.gst_object_unref(pipeline); } -