// g++ -Wall gstreamer_nvidia_appsrcLoopEx.cpp -o gstNvidiaApparcLoop `pkg-config --cflags --libs gstreamer-1.0` -lgstapp-1.0 // gst-launch-1.0 udpsrc port=5000 ! application/x-rtp,encoding-name=H264, payload = 96 ! rtph264depay ! h264parse ! queue ! avdec_h264 ! xvimagesink sync=false async=false -e #include #include #include #include #include #include #include #include //#define CLIENT_IP "130.134.235.179" #define CLIENT_IP "192.168.70.203" #define TARGET_BITRATE 15000000 #define WIDTH 640 #define HEIGHT 640 //GSTREAMER COMPONENTS static GMainLoop *loop; GstElement *pipeline, *appsrc, *Nvidia_vid_conv, *encoder, *YUV_filter, *Ethernet_filter, *parser, *rtp264, *sink; GstCaps *appsrc_caps, *YUV_filter_caps, *Ethernet_filter_caps; GstBus *bus; GstStateChangeReturn ret; guint bus_watch_id; //APPSRC BUFFER FUNCTIONS //int want = 1; //uint16_t b_white[385*288]; //uint16_t b_black[385*288]; /* static void prepare_buffer(GstAppSrc* appsrc) { static gboolean white = FALSE; static GstClockTime timestamp = 0; GstBuffer *buffer; guint size; GstFlowReturn ret; //if (!want) return; //want = 0; size = 385 * 288 * 2; buffer = gst_buffer_new_wrapped_full( GST_MEMORY_FLAG_READONLY, (gpointer)(white?b_white:b_black), size, 0, size, NULL, NULL ); white = !white; GST_BUFFER_PTS (buffer) = timestamp; GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int (1, GST_SECOND, 4); timestamp += GST_BUFFER_DURATION (buffer); ret = gst_app_src_push_buffer(appsrc, buffer); if (ret != GST_FLOW_OK) { // something wrong, stop pushing g_main_loop_quit (loop); } } */ /* static void cb_need_data (GstElement *appsrc, guint unused_size, gpointer user_data) { prepare_buffer((GstAppSrc*)appsrc); //want = 1; } */ static void cb_need_data (GstElement *appsrc, guint unused_size, gpointer user_data) { g_printerr ("xxxx\n"); static gboolean white = FALSE; static GstClockTime timestamp = 0; GstBuffer *buffer; guint size; GstFlowReturn ret; //size = 385 * 288 * 3; size = WIDTH * HEIGHT * 3; buffer = gst_buffer_new_allocate (NULL, size, NULL); /* this makes the image black/white */ gst_buffer_memset (buffer, 0, white ? 0xff : 0x0, size); white = !white; g_printerr ("aaaaa\n"); GST_BUFFER_PTS (buffer) = timestamp; GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int (1, GST_SECOND, 2); timestamp += GST_BUFFER_DURATION (buffer); g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret); gst_buffer_unref (buffer); g_printerr ("bbbbb\n"); if (ret != GST_FLOW_OK) { /* something wrong, stop pushing */ g_printerr ("11111\n"); g_main_loop_quit (loop); } } //EVENT HANDLERS static void sigint_restore (void) { struct sigaction action; memset (&action, 0, sizeof (action)); action.sa_handler = SIG_DFL; sigaction (SIGINT, &action, NULL); } /* Signal handler for ctrl+c */ void intHandler(int dummy) { //! Emit the EOS signal which tells all the elements to shut down properly: printf("Sending EOS signal to shutdown pipeline cleanly\n"); gst_element_send_event(pipeline, gst_event_new_eos()); sigint_restore(); return; } 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; } int watcher_make() { /* 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); return 0; } int main(int argc, char *argv[]) { signal(SIGINT, intHandler); /* Initialize GStreamer */ gst_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE); //Initialize black and white buffers //for (int i = 0; i < 385*288; i++) { b_black[i] = 0; b_white[i] = 0xFFFF; } /* Create the elements */ pipeline = gst_pipeline_new ("pipeline"); appsrc = gst_element_factory_make ("appsrc", "source"); Nvidia_vid_conv = gst_element_factory_make ("nvvidconv", "Nvidia_vid_conv"); //Nvidia_vid_conv = gst_element_factory_make ("videoconvert", "Nvidia_vid_conv"); YUV_filter = gst_element_factory_make ("capsfilter", "YUV_filter"); encoder = gst_element_factory_make ("omxh264enc", "encoder"); Ethernet_filter = gst_element_factory_make ("capsfilter", "Ethernet_filter"); parser = gst_element_factory_make ("h264parse", "parser"); rtp264 = gst_element_factory_make ("rtph264pay", "rtp264"); sink = gst_element_factory_make ("udpsink", "sink"); if (!pipeline) { g_printerr ("Pipeline not created.\n"); return -1; } if (!appsrc) { g_printerr ("Appsrc not created\n"); return -1; } if (!YUV_filter) { g_printerr ("YUV filter not created\n"); return -1; } if (!Ethernet_filter || !parser || !rtp264 || !sink) { g_printerr("Stream Elements not created\n"); return -1; } if (!encoder) { g_printerr("Encoder not created\n"); return -1; } if (!Nvidia_vid_conv) { g_printerr ("Nvvidconv not created\n"); return -1; } /* Modify the caps properties */ appsrc_caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "BGRx", "width", G_TYPE_INT, WIDTH, "height", G_TYPE_INT, HEIGHT, "framerate", GST_TYPE_FRACTION, 30, 1, NULL); YUV_filter_caps = gst_caps_from_string("video/x-raw(memory:NVMM),format=I420"); Ethernet_filter_caps = gst_caps_new_simple ("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", NULL); g_object_set (G_OBJECT (appsrc), "caps", appsrc_caps, NULL); g_object_set (G_OBJECT (YUV_filter), "caps", YUV_filter_caps, NULL); g_object_set (G_OBJECT (Ethernet_filter), "caps", Ethernet_filter_caps, NULL); g_object_set (G_OBJECT (encoder), "bitrate", TARGET_BITRATE, "control-rate", 2, NULL); g_object_set( G_OBJECT(rtp264), "pt", 96, "config-interval",1,NULL); g_object_set( G_OBJECT(sink), "host", CLIENT_IP, "port", 5000, "sync",FALSE, "async", FALSE, NULL); /* setup appsrc g_object_set (G_OBJECT (appsrc), "stream-type", 0, //GST_APP_STREAM_TYPE_STREAM , "format", GST_FORMAT_TIME, //NULL); "is-live", TRUE, NULL); */ g_signal_connect (appsrc, "need-data", G_CALLBACK (cb_need_data), NULL); g_printerr ("ccccc\n"); /* Add function to watch bus */ if(watcher_make() != 0) { g_printerr("Failed to make watcher\n"); return -1; } /* Build the pipeline */ gst_bin_add_many (GST_BIN (pipeline), appsrc, Nvidia_vid_conv, YUV_filter, encoder, Ethernet_filter, parser, rtp264, sink, NULL); /* Link the elements together */ gst_element_link_many (appsrc, Nvidia_vid_conv, YUV_filter, encoder, Ethernet_filter, parser, rtp264, sink, NULL); g_printerr ("ddddd\n"); /* play */ ret = gst_element_set_state (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 (pipeline); return -1; } g_main_loop_run(loop); /* clean up */ gst_caps_unref (appsrc_caps); gst_caps_unref (YUV_filter_caps); gst_caps_unref (Ethernet_filter_caps); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (pipeline)); g_main_loop_unref (loop); return 0; }