#include<gst/gst.h>
#include<stdio.h>
#include<time.h>
static GMainLoop *loop;
// static gboolean recording = False;
// static char *file_path;
typedef struct _PipelineData{
GstElement *pipeline ;
GstElement *src1 ;
GstElement *tee;
GstElement *live_queue ;
GstElement *record_queue;
GstElement *rec1;
GstElement *rec2;
GstElement *muxer;
GstElement *filesink;
GstElement *dec1;
GstElement *dec2 ;
GstElement *dec3 ;
GstElement *vidcon;
GstElement *overlay;
GstElement *autovideosink;
} PipelineData ;
const char* get_time(){
time_t t;
char date[4];
char mon[4];
char ye [16];
char curr [24];
int month ;
int year ;
t = time(NULL);
struct tm tm = *localtime(&t);
// printf("Current Date: %d-%d-%d", tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900);
sprintf(date,"%d",tm.tm_mday);
month = tm.tm_mon+1;
year = tm.tm_year+1900 - 2000;
sprintf(mon,"%d",month);
sprintf(ye,"%d",year);
sprintf(curr,"%s-%s-%s",date,mon,ye); // Store date in one string !!
char *retu = curr ;
return retu;
}
/**
* @brief Linking Pads of Source with Queue
*
* @param src It is rtsp Source feed
* @param new_pad
* @param pThis
*/
static void pad_added_handler(GstElement *src, GstPad *new_pad, PipelineData *pThis)
{
GstPad *sink_pad = gst_element_get_static_pad(pThis->autovideosink, "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));
/* Check the new pad's name */
if (!g_str_has_prefix(GST_PAD_NAME(new_pad), "recv_rtp_src_")) {
g_print(" It is not the right pad. Need recv_rtp_src_. Ignoring.\n");
goto exit;
}
/* If our converter is already linked, we have nothing to do here */
if (gst_pad_is_linked(sink_pad)) {
g_print(" Sink pad from %s already linked. Ignoring.\n", GST_ELEMENT_NAME(src));
goto exit;
}
/* Check the new pad's type */
new_pad_caps = gst_pad_query_caps(new_pad, NULL);
new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
new_pad_type = gst_structure_get_name(new_pad_struct);
/* 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);
}
/**
* @brief Watches for messages on the pipeline Bus.
*
*
* @param bus --- Gstreamer Busthat is being watached.
* @param message --- Message received on the bus.
* @param data --- User data passed to callback
* @return gboolean
*/
static gboolean my_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
{
g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR:{
GError *err;
gchar *debug;
gst_message_parse_error (message, &err, &debug);
g_print ("Error: %s\n", err->message);
g_error_free (err);
g_free (debug);
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_EOS:
/* end-of-stream */
g_main_loop_quit (loop);
break;
default:
/* unhandled message */
break;
}
return TRUE; /* we want to be notified each time message is received on the bus */
}
int main(int argc , char *argv[])
{
PipelineData data ;
GstBus *bus;
GstMessage *msg;
// guint bus_watch_id;
GstStateChangeReturn ret;
GstPad *tee_live_pad, *tee_record_pad ;
GstPad *queue_live_pad, *queue_record_pad ;
gst_init(&argc,&argv);
data.src1 = gst_element_factory_make("rtspsrc", "src1");
data.tee = gst_element_factory_make("tee","tee");
data.rec1 = gst_element_factory_make("rtph264depay",NULL);
data.rec2 = gst_element_factory_make("h264parse",NULL);
data.muxer = gst_element_factory_make("mp4mux",NULL);
data.filesink = gst_element_factory_make("filesink",NULL);
data.record_queue = gst_element_factory_make("queue","record_queue");
data.live_queue = gst_element_factory_make("queue", "live_queue");
data.dec1 = gst_element_factory_make("rtph264depay","dec1");
data.dec2 = gst_element_factory_make("h264parse","dec2");
data.dec3 = gst_element_factory_make("avdec_h264", "dec3");
data.vidcon = gst_element_factory_make("videoconvert","vidocn");
data.overlay = gst_element_factory_make("clockoverlay","clock");
data.autovideosink = gst_element_factory_make("autovideosink","autovideo");
/* Create Emplty Pipeline */
data.pipeline = gst_pipeline_new("Pipeline-1");
/* check for all Elements */
if ( !data.pipeline || !data.src1 || !data.tee || !data.rec1 || !data.rec2 || !data.muxer || !data.filesink || !data.record_queue || !data.live_queue || !data.dec1 || !data.dec2 || !data.dec3 || !data.vidcon || !data.overlay || !data.autovideosink ) {
g_printerr ("Not all elements could be created.\n");
return -1;
}
/* Configure Gstreamer Element Properties */
g_object_set(data.src1,"location","rtsp://10.223.240.1:8554/cam_1", NULL);
g_object_set(data.filesink, "location", argv[1], NULL);
g_object_set(data.overlay,"halignment",1,"valignment",1,"text",get_time(),NULL);
/* Add All Elements to the Pipeline */
gst_bin_add_many(GST_BIN(data.pipeline),data.src1,data.tee,data.dec1,data.dec2,data.dec3,data.live_queue,data.vidcon,data.overlay,data.autovideosink,data.record_queue,data.rec1,data.rec2,data.muxer,data.filesink,NULL);
// if(gst_element_link (data.src1,data.dec1) != TRUE) {
// g_printerr("src1 and dec1 cannot could not be linked");
// gst_object_unref (data.pipeline);
// return -1;
// }
if(gst_element_link (data.tee,data.live_queue) != TRUE) {
g_printerr("dec1 and dec2 cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.live_queue,data.dec1) != TRUE) {
g_printerr("enc1 and enc2 cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.dec1,data.dec2) != TRUE) {
g_printerr("dec3 and tee cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.dec2,data.dec3) != TRUE) {
g_printerr("dec3 and tee cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.dec3,data.vidcon) != TRUE) {
g_printerr("enc2 and sink cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.vidcon,data.overlay) != TRUE) {
g_printerr("enc2 and sink cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.overlay,data.autovideosink) != TRUE) {
g_printerr("enc2 and sink cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.record_queue,data.rec1) != TRUE) {
g_printerr("record_queue and encoder cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.rec1,data.rec2) != TRUE) {
g_printerr("record_queue and encoder cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.rec2,data.muxer) != TRUE) {
g_printerr("encoder and muxer cannot could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
if(gst_element_link (data.muxer,data.filesink) != TRUE) {
g_printerr("muxer and filesink could not be linked");
gst_object_unref (data.pipeline);
return -1;
}
tee_live_pad = gst_element_get_request_pad(data.tee, "src_%u");
g_print ("Obtained request pad %s for live branch.\n", gst_pad_get_name (tee_live_pad));
queue_live_pad = gst_element_get_static_pad(data.live_queue, "sink");
tee_record_pad = gst_element_get_request_pad(data.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(data.record_queue,"sink");
if (gst_pad_link (tee_live_pad, queue_live_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 (data.pipeline);
return -1;
}
gst_object_unref (queue_live_pad);
gst_object_unref (queue_record_pad);
g_signal_connect(data.src1,"pad-added",G_CALLBACK(pad_added_handler),&data);
printf("GST Initialization Done");
ret = gst_element_set_state(data.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 (data.pipeline);
return -1;
}
/* Set-Up Gstreamer Bus Handler for Messages */
bus = gst_pipeline_get_bus(GST_PIPELINE(data.pipeline));
gst_bus_add_signal_watch(bus);
g_signal_connect(G_OBJECT(bus),"message",G_CALLBACK(my_bus_callback),NULL);
gst_object_unref(bus);
loop = g_main_loop_new (NULL,FALSE);
g_main_loop_run(loop);
/* clean up */
gst_element_set_state (data.pipeline, GST_STATE_NULL);
gst_object_unref (data.pipeline);
g_main_loop_unref (loop);
return 0;
}
Hi,
We suggest verify the correctness of pipeline in gst-launch-1.0 command first. To have a working pipeline for reference This should bring further information about programming C sample.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.