GStreamer视频采集
task.json
"args": [ "-fdiagnostics-color=always", "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}", "-I", "/usr/include/glib-2.0", "-I", "/usr/lib/x86_64-linux-gnu/glib-2.0/include", "-I", "/usr/include/gstreamer-1.0", "-L", "/usr/lib/x86_64-linux-gnu", "-l", "gstreamer-1.0", "-l", "gobject-2.0", "-l", "glib-2.0" ]
#include <gst/gst.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_printerr("ERROR from element %s: %s\n", GST_OBJECT_NAME(msg->src), error->message); if (debug) g_printerr("Error details: %s\n", debug); g_free(debug); g_error_free(error); g_main_loop_quit(loop); break; } default: break; } return TRUE; } int main(int argc, char *argv[]) { GstElement *pipeline, *v4l2_src, *video_convert, *tee, *disp_queue, *xvimage_sink; GstElement *record_queue, *video_rate, *jpeg_enc, *avi_mux, *file_sink; GstPad *tee_disp_pad, *tee_record_pad; GstPad *queue_disp_pad, *queue_record_pad; // Initialize GStreamer gst_init(&argc, &argv); // Create the elements v4l2_src = gst_element_factory_make("v4l2src", "v4l2_src"); video_convert = gst_element_factory_make("videoconvert", "video_convert"); tee = gst_element_factory_make("tee", "tee"); disp_queue = gst_element_factory_make("queue", "disp_queue"); xvimage_sink = gst_element_factory_make("xvimagesink", "xvimage_sink"); record_queue = gst_element_factory_make("queue", "record_queue"); video_rate = gst_element_factory_make("videorate", "video_rate"); jpeg_enc = gst_element_factory_make("jpegenc", "jpeg_enc"); avi_mux = gst_element_factory_make("avimux", "avi_mux"); file_sink = gst_element_factory_make("filesink", "file_sink"); // Create the empty pipeline pipeline = gst_pipeline_new("test-pipeline"); if (!pipeline || !v4l2_src || !video_convert || !tee || !disp_queue || !xvimage_sink || !record_queue || !video_rate || !jpeg_enc || !avi_mux || !file_sink) { g_printerr("Not all elements could be created.\n"); return -1; } // Configure elements // Link all elements that can be automatically linked because they have "Always" pads gst_bin_add_many(GST_BIN(pipeline), v4l2_src, video_convert, tee, disp_queue, xvimage_sink, record_queue, video_rate, jpeg_enc, avi_mux, file_sink, NULL); if (gst_element_link_many(v4l2_src, video_convert, tee, NULL) != TRUE || gst_element_link_many(disp_queue, xvimage_sink, NULL) != TRUE || gst_element_link_many(record_queue, video_rate, jpeg_enc, avi_mux, file_sink, NULL) != TRUE) { g_printerr("Elements could not be linked.\n"); gst_object_unref(pipeline); return -1; } g_object_set(G_OBJECT(file_sink), "location", "video21.avi", NULL); // Manually link the Tee, which has "Request" pads tee_disp_pad = gst_element_get_request_pad(tee, "src_%u"); g_print("Obtained request pad %s for disp branch.\n", gst_pad_get_name(tee_disp_pad)); queue_disp_pad = gst_element_get_static_pad(disp_queue, "sink"); tee_record_pad = gst_element_get_request_pad(tee, "src_%u"); g_print("Obtained request pad %s for record branch.\n", gst_pad_get_name(tee_record_pad)); queue_record_pad = gst_element_get_static_pad(record_queue, "sink"); if (gst_pad_link(tee_disp_pad, queue_disp_pad) != GST_PAD_LINK_OK || gst_pad_link(tee_record_pad, queue_record_pad) != GST_PAD_LINK_OK) { g_printerr("Tee could not be linked.\n"); gst_object_unref(pipeline); return -1; } g_object_set(G_OBJECT(disp_queue), "max-size-buffers", 0, NULL); g_object_set(G_OBJECT(disp_queue), "max-size-time", 0, NULL); g_object_set(G_OBJECT(disp_queue), "max-size-bytes", 512000000, NULL); g_object_set(G_OBJECT(record_queue), "max-size-buffers", 0, NULL); g_object_set(G_OBJECT(record_queue), "max-size-time", 0, NULL); g_object_set(G_OBJECT(record_queue), "max-size-bytes", 512000000, NULL); gst_object_unref(queue_disp_pad); gst_object_unref(queue_record_pad); // Start playing the pipeline gst_element_set_state(pipeline, GST_STATE_PLAYING); GstBus *bus = NULL; GMainLoop *loop = NULL; guint bus_watch_id; loop = g_main_loop_new(NULL, FALSE); bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); bus_watch_id = gst_bus_add_watch(bus, bus_call, loop); gst_object_unref(bus); g_main_loop_run(loop); gst_element_release_request_pad(tee, tee_disp_pad); gst_element_release_request_pad(tee, tee_record_pad); gst_object_unref(tee_disp_pad); gst_object_unref(tee_record_pad); gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); return 0; }