moved gstreamer example into hailo main

This commit is contained in:
Nickiel12 2024-10-26 01:48:13 +00:00
parent b475ba9782
commit cac4fe8ad2
3 changed files with 235 additions and 256 deletions

104
src/gst-zobject-main.zig Normal file
View file

@ -0,0 +1,104 @@
const std = @import("std");
const hlo = @cImport({
@cInclude("hailort.h");
});
// remove "sources/" and "X.zig"
// const gst = @import("sources/gst1.zig");
// const gstapp = @import ("sources/gstapp1.zig");
// const glib = @import("sources/glib2.zig");
// const gobject = @import("sources/gobject2.zig");
const gst = @import("gst");
const gstapp = @import ("gstapp");
const glib = @import("glib");
const gobject = @import("gobject");
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.init(@ptrCast(&std.os.argv.len), @ptrCast(&std.os.argv.ptr));
const source: *gst.Element = gst.ElementFactory.make("videotestsrc", "source") orelse unreachable;
const scale: *gst.Element = gst.ElementFactory.make("videoscale", "scale") orelse unreachable;
const format: *gst.Element = gst.ElementFactory.make("videoconvert", "format") orelse unreachable;
const sink_el: *gst.Element = gst.ElementFactory.make("appsink", "sink") orelse unreachable;
const sink: *gstapp.AppSink = gobject.ext.cast(gstapp.AppSink, sink_el) orelse unreachable;
const sink_caps = gst.Caps.fromString("video/x-raw,format=RGB,width=640,height=640") orelse unreachable;
sink.setCaps(sink_caps);
const pipeline: *gst.Pipeline = gst.Pipeline.new("test-pipeline");
const bin: *gst.Bin = &pipeline.f_bin;
_ = gst.Bin.addMany(bin, source, scale, format, sink_el);
// the failure return code is -1 I believe
if (gst.Element.linkMany(source, scale, format, sink_el) < 0) {
pipeline.unref();
std.debug.panic("Elements could not be linked\n", .{});
}
// g_int is just i32. You can
// source.set("pattern", @as(i16, 0));
// gobject.Object.set(source.as(gobject.Object), "pattern", @as(i16, 0));
const ret = pipeline.as(gst.Element).setState(gst.State.playing);
if (ret == gst.StateChangeReturn.failure) {
pipeline.unref();
std.debug.panic("Could not start pipeline", .{});
}
const bus: *gst.Bus = pipeline.getBus();
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() });
// 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);
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;
msg.parseError(err, debug_info);
if (err) |e| {
std.debug.print("Error received from element {s}: {s}", .{ msg.f_src, e.*.*.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.?});
}
glib.clearError(@ptrCast(err));
glib.free(@ptrCast(debug_info));
} else {
std.debug.print("Unknown type received {any}\n", .{ msg });
}
// msg.unref();
} else {
std.debug.print("ret message not handled type: {any}\n", .{ ret_msg });
}
bus.unref();
_ = pipeline.as(gst.Element).setState(gst.State.null);
pipeline.unref();
std.debug.print("run complete\n", .{});
}

View file

@ -1,197 +0,0 @@
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);
}

View file

@ -1,19 +1,14 @@
const std = @import("std"); const std = @import("std");
const hlo = @cImport({ const hlo = @cImport({
@cInclude("hailort.h"); @cInclude("hailort.h");
}); });
// remove "sources/" and "X.zig"
// const gst = @import("sources/gst1.zig");
// const gstapp = @import ("sources/gstapp1.zig");
// const glib = @import("sources/glib2.zig");
// const gobject = @import("sources/gobject2.zig");
const gst = @import("gst"); const gst = @import("gst");
const gstapp = @import ("gstapp"); const gstapp = @import ("gstapp");
const glib = @import("glib"); const glib = @import("glib");
const gobject = @import("gobject"); const gobject = @import("gobject");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const assert = std.debug.assert; const assert = std.debug.assert;
@ -25,81 +20,158 @@ 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.init(@ptrCast(&std.os.argv.len), @ptrCast(&std.os.argv.ptr)); 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", .{});
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);
std.debug.print("HailoRT init completed\nGstreamer Init starting", .{});
const source: *gst.Element = gst.ElementFactory.make("videotestsrc", "source") orelse unreachable; const source: *gst.Element = gst.ElementFactory.make("videotestsrc", "source") orelse unreachable;
const scale: *gst.Element = gst.ElementFactory.make("videoscale", "scale") orelse unreachable;
const format: *gst.Element = gst.ElementFactory.make("videoconvert", "format") orelse unreachable;
const sink_el: *gst.Element = gst.ElementFactory.make("appsink", "sink") orelse unreachable; const sink_el: *gst.Element = gst.ElementFactory.make("appsink", "sink") orelse unreachable;
const sink: *gstapp.AppSink = gobject.ext.cast(gstapp.AppSink, sink_el) orelse unreachable; const sink: *gstapp.AppSink = gobject.ext.cast(gstapp.AppSink, sink_el) orelse unreachable;
const sink_caps = gst.Caps.fromString("video/x-raw,format=RGB,width=640,height=640") orelse unreachable;
sink.setCaps(sink_caps);
const pipeline: *gst.Pipeline = gst.Pipeline.new("test-pipeline"); const pipeline: *gst.Pipeline = gst.Pipeline.new("test-pipeline");
// 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.Bin = &pipeline.f_bin; const bin: *gst.Bin = &pipeline.f_bin;
_ = gst.Bin.addMany(bin, source, scale, format, sink_el);
// Gstreamer gives a critical warning when using gst.gst_bin_add_many, but doesn't if (gst.Element.linkMany(source, scale, format, sink_el) < 0) {
// when calling each individually
_ = gst.Bin.add(bin, source);
_ = gst.Bin.add(bin, sink_el);
// the failure return code is -1 I believe
if (gst.Element.link(source, sink_el) < 0) {
pipeline.unref(); pipeline.unref();
std.debug.panic("Elements could not be linked\n", .{}); std.debug.panic("Elements could not be linked\n", .{});
} }
// g_int is just i32. You can
// source.set("pattern", @as(i16, 0));
// gobject.Object.set(source.as(gobject.Object), "pattern", @as(i16, 0));
const ret = pipeline.as(gst.Element).setState(gst.State.playing); const ret = pipeline.as(gst.Element).setState(gst.State.playing);
std.debug.print("pipeline state change returned: {any}\n", .{ ret });
if (ret == gst.StateChangeReturn.failure) { if (ret == gst.StateChangeReturn.failure) {
pipeline.unref(); pipeline.unref();
std.debug.panic("Could not start pipeline", .{}); std.debug.panic("Could not start pipeline", .{});
} }
const bus: *gst.Bus = pipeline.getBus(); // const bus: *gst.Bus = pipeline.getBus();
const sample = sink.pullSample() orelse unreachable; const sample = sink.pullSample() orelse unreachable;
const buffer: *gst.Buffer = sample.getBuffer() 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() });
// const msg: *gst.Message = bus.popFiltered( gst.MessageType.flags_eos + gst.MessageType.flags_warning ); buffer.extract(0, input_data, input_frame_size);
const message_type: gst.MessageType = .{ .eos = true, .warning = true };
const ret_msg: ?*gst.Message = bus.timedPopFiltered(std.math.maxInt(u64), message_type);
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;
msg.parseError(err, debug_info); std.debug.print("Getting vstream info\n", .{});
if (err) |e| { var stream_info: hlo.hailo_vstream_info_t = undefined;
std.debug.print("Error received from element {s}: {s}", .{ msg.f_src, e.*.*.message }); status = hlo.hailo_get_input_vstream_info(input_vstreams[0], &stream_info);
} assert(status == hlo.HAILO_SUCCESS);
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.?});
}
glib.clearError(@ptrCast(err));
glib.free(@ptrCast(debug_info));
} else {
std.debug.print("Unknown type received {any}\n", .{ msg });
}
// msg.unref();
} else {
std.debug.print("ret message not handled type: {any}\n", .{ ret_msg });
}
bus.unref(); var output_info: hlo.hailo_vstream_info_t = undefined;
_ = pipeline.as(gst.Element).setState(gst.State.null); status = hlo.hailo_get_output_vstream_info(output_vstreams[0], &output_info);
pipeline.unref(); assert(status == hlo.HAILO_SUCCESS);
std.debug.print("\nOutput info: {any}\n\n", .{ output_info });
std.debug.print("run complete\n", .{}); 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);
} }