Files
gst-plugin-linescan/gst/linescan/rollover_example.c
yair a7a776fb58 feat: adapt linescan scripts to use uv and proper rollover-based file saving
- Updated launch_with_signal.py with PEP 723 metadata for uv compatibility
- Added day/night mode presets with command-line arguments
- Implemented proper rollover-only file saving via Python/PIL callbacks
- Removed multifilesink from pipeline (was saving every frame incorrectly)
- Added funny auto-generated output directory names (e.g., fuzzy-photon)
- Updated rollover_example.py to follow same pattern with uv support
- Updated rollover_example.c to demonstrate signal detection without file saving
- Updated launch_with_capture.ps1 to remove incorrect multifilesink usage
- All scripts now save files ONLY on rollover events, not every frame
- Pipeline simplified: camera -> linescan -> display (files saved in callback)
2025-11-18 19:39:51 +02:00

149 lines
4.7 KiB
C

/* Simple Rollover Example - Linescan Buffer Capture Demo (C)
*
* This is a minimal C example showing rollover signal detection.
*
* NOTE: This example demonstrates signal connection but doesn't save files.
* For actual file saving, use the Python examples (rollover_example.py or
* launch_with_signal.py) which use PIL/numpy to properly save images.
*
* In C, you would need to:
* 1. Map the buffer (gst_buffer_map)
* 2. Parse the caps to get width/height/format
* 3. Use a library like libpng or libjpeg to encode and save
*
* Compile with:
* gcc rollover_example.c -o rollover_example `pkg-config --cflags --libs gstreamer-1.0 gstreamer-video-1.0`
*
* Usage:
* ./rollover_example
*
* Pipeline:
* videotestsrc -> linescan -> videoconvert -> autovideosink
* ↓
* (rollover signal)
* ↓
* C callback prints message
*/
#include <gst/gst.h>
#include <gst/video/video.h>
#include <stdio.h>
static gint frame_counter = 0;
/* Callback function when rollover signal is emitted */
static void
on_rollover (GstElement *linescan, GstBuffer *buffer, gpointer user_data)
{
GstCaps *caps;
GstStructure *structure;
gint width, height;
const gchar *format_str;
frame_counter++;
/* Get buffer information */
GstPad *srcpad = gst_element_get_static_pad (linescan, "src");
caps = gst_pad_get_current_caps (srcpad);
structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "height", &height);
format_str = gst_structure_get_string (structure, "format");
g_print ("[ROLLOVER] Frame %d - %dx%d %s (size: %lu bytes)\n",
frame_counter,
width, height,
format_str,
(unsigned long) gst_buffer_get_size (buffer));
/* NOTE: To actually save the buffer to a file, you would:
* 1. Map the buffer: gst_buffer_map(buffer, &map_info, GST_MAP_READ)
* 2. Encode using libpng/libjpeg based on the data in map_info.data
* 3. Write to file with the frame_counter in the filename
* 4. Unmap: gst_buffer_unmap(buffer, &map_info)
*
* For a complete example with file saving, see the Python version.
*/
gst_caps_unref (caps);
gst_object_unref (srcpad);
}
int
main (int argc, char *argv[])
{
GstElement *pipeline, *source, *linescan;
GstElement *videoconvert, *videosink;
GstBus *bus;
GstMessage *msg;
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Create elements - simplified pipeline without file branch */
pipeline = gst_pipeline_new ("rollover-pipeline");
source = gst_element_factory_make ("videotestsrc", "source");
linescan = gst_element_factory_make ("linescan", "linescan");
videoconvert = gst_element_factory_make ("videoconvert", "convert");
videosink = gst_element_factory_make ("autovideosink", "videosink");
if (!pipeline || !source || !linescan || !videoconvert || !videosink) {
g_printerr ("Not all elements could be created.\n");
g_printerr ("Make sure linescan plugin is built and in GST_PLUGIN_PATH.\n");
return -1;
}
/* Configure elements */
g_object_set (source, "pattern", 18, NULL); /* ball pattern */
g_object_set (linescan,
"direction", 0, /* horizontal */
"line-index", 100,
"output-size", 400,
NULL);
/* Connect to rollover signal */
g_signal_connect (linescan, "rollover", G_CALLBACK (on_rollover), NULL);
/* Build the pipeline - simple chain */
gst_bin_add_many (GST_BIN (pipeline), source, linescan,
videoconvert, videosink, NULL);
if (!gst_element_link_many (source, linescan, videoconvert, videosink, NULL)) {
g_printerr ("Elements could not be linked.\n");
gst_object_unref (pipeline);
return -1;
}
/* Start playing */
g_print ("Pipeline running. Rollover events will be printed.\n");
g_print ("Press Ctrl+C to stop.\n\n");
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Handle any errors */
if (msg != NULL) {
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
GError *err;
gchar *debug_info;
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("\nError: %s\n", err->message);
g_error_free (err);
g_free (debug_info);
}
gst_message_unref (msg);
}
/* Free resources */
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
g_print ("\nDetected %d rollover events\n", frame_counter);
return 0;
}