Last active
May 6, 2025 15:26
-
-
Save fusetim/0b8ab6978a4601931d0ec6cf815ae02e to your computer and use it in GitHub Desktop.
v4l2src to file yuv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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