Gstreamer record and receive pipeline does not work

#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.