Skip to content

Instantly share code, notes, and snippets.

@fusetim
Last active May 6, 2025 15:26
Show Gist options
  • Save fusetim/0b8ab6978a4601931d0ec6cf815ae02e to your computer and use it in GitHub Desktop.
Save fusetim/0b8ab6978a4601931d0ec6cf815ae02e to your computer and use it in GitHub Desktop.
v4l2src to file yuv
#include <gst/gst.h>
#include <glib.h>
#include <gst/video/video.h>
#include <gst/app/app.h>
#include <gst/app/gstappsink.h>
#include <gst/app/app-prelude.h>
#include <gst/app/app-enumtypes.h>
static gboolean
bus_call(GstBus *bus,
GstMessage *msg,
gpointer data)
{
GMainLoop *loop = (GMainLoop *)data;
switch (GST_MESSAGE_TYPE(msg))
{
case GST_MESSAGE_EOS:
g_print("End of stream\n");
g_main_loop_quit(loop);
break;
case GST_MESSAGE_ERROR:
{
gchar *debug;
GError *error;
gst_message_parse_error(msg, &error, &debug);
g_free(debug);
g_printerr("Error: %s\n", error->message);
g_error_free(error);
g_main_loop_quit(loop);
break;
}
default:
break;
}
return TRUE;
}
static GstFlowReturn on_new_sample(GstAppSink *appsink, gpointer user_data) {
GstSample *sample = gst_app_sink_pull_sample(appsink);
if (!sample) return GST_FLOW_ERROR;
GstBuffer *buffer = gst_sample_get_buffer(sample);
GstMapInfo map;
if (gst_buffer_map(buffer, &map, GST_MAP_READ)) {
g_print("Received frame of size %zu bytes\n", map.size);
gst_buffer_unmap(buffer, &map);
}
gst_sample_unref(sample);
return GST_FLOW_OK;
}
int main(int argc,
char *argv[])
{
GMainLoop *loop;
GstElement *pipeline, *source, /**parser,*/ *convert, *capsfilter, *sink;
GstBus *bus;
GstCaps *caps;
guint bus_watch_id;
/* Initialisation */
gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE);
/* Check input arguments */
if (argc != 2)
{
g_printerr("Usage: %s <input-device>\n", argv[0]);
return -1;
}
/* Create gstreamer elements */
pipeline = gst_pipeline_new("yuv-storing");
source = gst_element_factory_make("v4l2src", "camera-source");
//parser = gst_element_factory_make("rawvideoparse", "parser");
convert = gst_element_factory_make("videoconvert", "converter");
capsfilter = gst_element_factory_make("capsfilter", "capsfilter");
sink = gst_element_factory_make("appsink", "output");
if (!pipeline || /*!parser ||*/ !source || !convert || !capsfilter || !sink)
{
g_printerr("One element could not be created. Exiting.\n");
return -1;
}
/* Set up the pipeline */
// Setup the Appsink element
gst_app_sink_set_emit_signals((GstAppSink *)sink, TRUE);
gst_app_sink_set_drop((GstAppSink *)sink, TRUE);
gst_app_sink_set_max_buffers((GstAppSink *)sink, 1);
GstAppSinkCallbacks callbacks = {NULL, NULL, on_new_sample};
gst_app_sink_set_callbacks(GST_APP_SINK(sink), &callbacks, NULL, NULL);
/* we set the input device to the source element */
g_object_set(G_OBJECT(source), "device", argv[1], NULL);
g_object_set(G_OBJECT(source), "width", 640, NULL);
g_object_set(G_OBJECT(source), "height", 480, NULL);
g_object_set(G_OBJECT(source), "framerate", 30, NULL);
g_object_set(G_OBJECT(source), "format", GST_VIDEO_FORMAT_YUY2, NULL);
/* we set the input format to the parser element */
//g_object_set(G_OBJECT(parser), "width", 640, NULL);
//g_object_set(G_OBJECT(parser), "height", 480, NULL);
//g_object_set(G_OBJECT(parser), "framerate", 30, NULL);
//g_object_set(G_OBJECT(parser), "format", GST_VIDEO_FORMAT_YUY2, NULL);
/* we add a message handler */
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);
// Set caps to force YUV format (YUY2 is the format used by the camera)
caps = gst_caps_from_string("video/x-raw,format=YUY2,width=640,height=480,framerate=30/1");
g_object_set(capsfilter, "caps", caps, NULL);
gst_caps_unref(caps);
/* we add all elements into the pipeline */
/* file-source | image/x-raw,width=640,height=480,framerate=30/1 | filesink */
gst_bin_add_many(GST_BIN(pipeline),
source, /*parser,*/ convert, capsfilter, sink, NULL);
/* we link the elements together */
gst_element_link_many(source, /*parser,*/ convert, capsfilter, sink, NULL);
/* Set the pipeline to "playing" state*/
g_print("Recording: %s\n", argv[1]);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
/* Iterate */
g_print("Running...\n");
g_main_loop_run(loop);
/* Out of the main loop, clean up nicely */
g_print("Returned, stopping playback\n");
gst_element_set_state(pipeline, GST_STATE_NULL);
g_print("Deleting pipeline\n");
gst_object_unref(GST_OBJECT(pipeline));
g_source_remove(bus_watch_id);
g_main_loop_unref(loop);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment