Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <gst/gst.h>
- #include <stdio.h>
- /* Structure to contain all our information, so we can pass it to callbacks */
- typedef struct _VideoCompositor {
- GstElement *pipeline;
- GstElement *background;
- GstElement *encoder;
- GstElement *muxer;
- GstElement *convert;
- GstElement *sink;
- } VideoCompositor;
- /* Handler for the pad-added signal */
- static void pad_added_handler (GstElement *src, GstPad *pad, VideoCompositor *data);
- int main(int argc, char *argv[]) {
- GstBus *bus;
- GstMessage *msg;
- GstStateChangeReturn ret;
- gboolean terminate = FALSE;
- VideoCompositor videoCompositor;
- /* Initialize GStreamer */
- gst_init (&argc, &argv);
- /* Compositor init */
- videoCompositor.background = gst_element_factory_make ("uridecodebin", "background");
- videoCompositor.encoder = gst_element_factory_make("x264enc", "x264enc");
- videoCompositor.muxer = gst_element_factory_make("mp4mux", "mp4mux");
- videoCompositor.sink = gst_element_factory_make("filesink", "finalsink");
- videoCompositor.pipeline = gst_pipeline_new ("compositor_pipeline");
- if (!videoCompositor.pipeline || !videoCompositor.background || !videoCompositor.sink) {
- g_printerr ("Not all elements could be created.\n");
- return -1;
- }
- gst_bin_add_many (GST_BIN (videoCompositor.pipeline), videoCompositor.background, videoCompositor.encoder, videoCompositor.muxer, videoCompositor.sink, NULL);
- if (!gst_element_link_many (videoCompositor.encoder, videoCompositor.muxer, videoCompositor.sink, NULL)) {
- g_printerr ("Elements could not be linked.\n");
- gst_object_unref (videoCompositor.pipeline);
- return -1;
- }
- g_object_set (videoCompositor.background, "uri", "file:///Users/vinayak/video-fuzzing/compositor/resources/cars/1.mp4", NULL);
- g_object_set (videoCompositor.sink, "location", "./file.mp4", NULL);
- /* Connect to the pad-added signal */
- g_signal_connect (videoCompositor.background, "pad-added", G_CALLBACK (pad_added_handler), &videoCompositor);
- ret = gst_element_set_state (videoCompositor.pipeline, GST_STATE_PLAYING);
- if (ret == GST_STATE_CHANGE_FAILURE) {
- g_printerr ("Unable to set the pipeline to the playing state.\n");
- gst_object_unref (videoCompositor.pipeline);
- return -1;
- }
- /* Listen to the bus */
- bus = gst_element_get_bus (videoCompositor.pipeline);
- do {
- msg = gst_bus_timed_pop_filtered (bus, 100000000 * GST_MSECOND,
- GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_DURATION);
- /* Parse message */
- if (msg != NULL) {
- GError *err;
- gchar *debug_info;
- switch (GST_MESSAGE_TYPE (msg)) {
- case GST_MESSAGE_DURATION:
- gst_element_set_state (videoCompositor.pipeline, GST_STATE_NULL);
- terminate = TRUE;
- break;
- case GST_MESSAGE_ERROR:
- gst_message_parse_error (msg, &err, &debug_info);
- g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
- g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
- g_clear_error (&err);
- g_free (debug_info);
- terminate = TRUE;
- break;
- case GST_MESSAGE_EOS:
- g_print ("End-Of-Stream reached.\n");
- gst_element_set_state (videoCompositor.pipeline, GST_STATE_NULL);
- terminate = TRUE;
- break;
- case GST_MESSAGE_STATE_CHANGED:
- /* We are only interested in state-changed messages from the pipeline */
- if (GST_MESSAGE_SRC (msg) == GST_OBJECT (videoCompositor.pipeline)) {
- GstState old_state, new_state, pending_state;
- gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
- g_print ("Pipeline state changed from %s to %s:\n",
- gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
- }
- break;
- default:
- /* We should not reach here */
- g_printerr ("Unexpected message received.\n");
- break;
- }
- gst_message_unref (msg);
- }
- } while (!terminate);
- g_print("ended exec");
- /* Free resources */
- gst_object_unref (bus);
- gst_element_set_state (videoCompositor.pipeline, GST_STATE_NULL);
- gst_object_unref (videoCompositor.pipeline);
- return 0;
- }
- /* This function will be called by the pad-added signal */
- static void pad_added_handler (GstElement *src, GstPad *new_pad, VideoCompositor *data) {
- GstPad *sink_pad = gst_element_get_request_pad (data->encoder, "sink");
- GstPadLinkReturn ret;
- GstCaps *new_pad_caps = NULL;
- GstStructure *new_pad_struct = NULL;
- const gchar *new_pad_type = NULL;
- g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));
- /* If our converter is already linked, we have nothing to do here */
- if (gst_pad_is_linked (sink_pad)) {
- g_print ("We are already linked. Ignoring.\n");
- goto exit;
- }
- /* Check the new pad's type */
- new_pad_caps = gst_pad_get_current_caps (new_pad);
- new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
- new_pad_type = gst_structure_get_name (new_pad_struct);
- if (!g_str_has_prefix (new_pad_type, "video/x-raw")) {
- g_print ("It has type '%s' which is not raw video. Ignoring.\n", new_pad_type);
- goto exit;
- }
- /* Attempt the link */
- ret = gst_pad_link (new_pad, sink_pad);
- if (GST_PAD_LINK_FAILED (ret)) {
- g_print ("Type is '%s' but link failed.\n", new_pad_type);
- } else {
- g_print ("Link succeeded (type '%s').\n", new_pad_type);
- }
- exit:
- /* Unreference the new pad's caps, if we got them */
- if (new_pad_caps != NULL)
- gst_caps_unref (new_pad_caps);
- /* Unreference the sink pad */
- gst_object_unref (sink_pad);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement