Dynamic-Pipeline ( Vidoetestsrc element works but Filesink element fails )

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Dynamic-Pipeline ( Vidoetestsrc element works but Filesink element fails )

Ashish Kumar Mishra
Hi All ,

Test_Pipeline :- Videtestsrc -> Q1 -> AVIMUX -> Q2 -> FILESINK.

1) When i change the properties of VIDEOTEST src element in dynamic pipeline
    [ dynamic_filesink = 0] i am able to get proper file
    i.e i can verify that the test pattern of created file changes .
   
2) When i change the properties of FILESINK ( i.e location  ) element in dynamic pipeline
    [ dynamic_filesink = 1 ] i am able to get NEW_FILES with some data on it.
    But only the first file is in playable state other files fails to play and gives
    message
 "......COULD NOT DETERMINE TYPE OF STREAM ....... "  

Could group members please provide inputs as to what is causing this problem .


#include <gst/gst.h>

GstElement *pipeline,
  *src,
                         *q1,
                         *q2,
                         *filesink,
                         *mux;

GMainLoop *loop,
                  *mainloop;

GstPad *temppad,
  *muxsrcpad;

GstBus *bus;

GError *err = NULL;

gchar   *sinkname;
char buffer[128];
unsigned int attempt=0;
unsigned int timer_count=0;
unsigned int dynamic_filesink= 0; // 0 for videotestsrc , 1 for filesink

 

static GstPadProbeReturn pad_probe_cb (GstPad * pad, GstPadProbeInfo * info,
                                                        gpointer user_data)
{

  g_print("\t [ APP-BLOCK ]: PAD_BROBE [ START ] ===================\n");

       
  // Remove the probe first
  gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));


  if ( dynamic_filesink == 0 ) {
        // Changing the TEST-SRC PATTERN
        timer_count = timer_count +1;
        g_object_set (G_OBJECT(src), "pattern",timer_count, NULL);
  }else {
        // Changing the FILESINK  
        gst_element_set_state (filesink, GST_STATE_NULL);
        attempt = attempt+1;
        sprintf( buffer, "test_%d.avi" , attempt);
        g_object_set(G_OBJECT (filesink),"location", buffer, NULL);
        gst_element_set_state (filesink , GST_STATE_PLAYING);
 }

  g_print("\t [ APP-BLOCK ]: PAD_BROBE [ STOP  ] ===================\n");

 return GST_PAD_PROBE_OK;

} // End brace of pad_probe_cb

 
 
static gboolean timeout_cb (gpointer user_data)
{
  g_print("\t [ APP-TIMER ]: IN-TIMER  [ BEFORE-BLOCKING ] =========\n");
  timer_count=timer_count+1;
  gst_pad_add_probe (muxsrcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
                                        pad_probe_cb, user_data, NULL);
  if ( timer_count == 10 ){
        return FALSE;
  }

  return TRUE;
} // End brace of "timeout_cb"


static gboolean bus_cb (GstBus * bus, GstMessage * msg, gpointer user_data)
{
  GMainLoop *loop = user_data;

  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_ERROR:{
      GError *err = NULL;
      gchar *dbg;

      gst_message_parse_error (msg, &err, &dbg);
      gst_object_default_error (msg->src, err, dbg);
      g_error_free (err);
      g_free (dbg);
      g_main_loop_quit (loop);
      break;
    }

    case GST_MESSAGE_STATE_CHANGED: {
      GstState old_state, new_state;
      gst_message_parse_state_changed (msg, &old_state, &new_state, NULL);
      g_print ("[ APP - MESSAGE ]: Element %s changed state from %s to %s.\n",
              GST_OBJECT_NAME (msg->src),    
                                        gst_element_state_get_name (old_state),
                                gst_element_state_get_name (new_state));
    break;
    }

    default:
      break;
  }

  return TRUE;

}//End brace of SWITCH condition




int main (int argc, char **argv)
{


  gst_init (&argc, &argv);

  if ( dynamic_filesink  == 0 ) {
     g_print("\n\t [APP-DEBUG ]: ------- DYNAMIC VIDEO-PATTERN ---------- \n");
  }else{
     g_print("\n\t [APP-DEBUG ]: ------- DYNAMIC FILE-SINK file's ------- \n");
  }
         
  // 0 - Creating the PIPELINE
  pipeline = gst_pipeline_new ("pipeline");
 
  // 1 - Creating the SRC
  src = gst_element_factory_make ("videotestsrc", NULL);
  g_object_set (G_OBJECT(src), "is-live", TRUE, NULL);
  g_object_set (G_OBJECT(src), "pattern",18, NULL);

  // 2 - Creating the QUEUE
  q1 = gst_element_factory_make ("queue", NULL);
  q2 = gst_element_factory_make ("queue", NULL);


  // 3 - Creating the MUX
  mux = gst_element_factory_make("avimux",NULL);

  // 4 - Creating the FILESINK
  filesink = gst_element_factory_make ("filesink", NULL);
  attempt = attempt+1;
  sprintf( buffer, "test_%d.avi" , attempt);
  g_print("\n\t [APP]: Created new file of %s \n",buffer);
  g_object_set(G_OBJECT(filesink),"location", buffer, NULL);


  // 7 - Adding all the elements in to BIN
  gst_bin_add_many (GST_BIN (pipeline), src, q1,mux, q2,filesink, NULL);

 
  // 8 - Linking all static pad
  if (!gst_element_link_many (src, q1, NULL )) {
            g_print ("[APP]: Failed to link STATIC_1 Pad's of elements");
            return -3;
  }
 

  if (!gst_element_link_many (mux,q2,filesink, NULL)) {
            g_print ("[APP]: Failed to link STATIC_2 Pad's of elements");
            return -3;
  }

  // 9 - Linking DYNAMIC PAD
  temppad = gst_element_get_request_pad (mux, "video_%u");
  sinkname = gst_pad_get_name (temppad);
  g_print ("\t [APP]: A new pad %s was created\n\n", sinkname);

  if (!gst_element_link_many (q1, mux,NULL )) {
            g_print ("[APP]: Failed to link DYNAMIC Pad's of elements");
            return -3;
  }

  g_free (sinkname);
  gst_object_unref (GST_OBJECT (temppad));

  // 10 - Getting the blocking PAD
  muxsrcpad = gst_element_get_static_pad (mux,"src");

  // 11 - Starting the PIPELINE
  if (gst_element_set_state (pipeline,GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
            g_error ("[APP]: Failed to go into PLAYING state");
            return -4;
  }

  mainloop = g_main_loop_new (NULL, FALSE);
  gst_bus_add_watch (GST_ELEMENT_BUS (pipeline), bus_cb, mainloop);
  g_timeout_add_seconds (7, timeout_cb, mainloop);
  g_main_loop_run (mainloop);  
 
  // 10 - Stopping the PIPELINE
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
    return 0;
}




Reply | Threaded
Open this post in threaded view
|

Re: Dynamic-Pipeline ( Vidoetestsrc element works but Filesink element fails )

Thiago Santos-3
On 11/25/2015 07:04 AM, Ashish Kumar Mishra wrote:

> Hi All ,
>
> *Test_Pipeline :- Videtestsrc -> Q1 -> AVIMUX -> Q2 -> FILESINK. *
>
> 1) When i change the properties of VIDEOTEST src element in dynamic pipeline
>      [ dynamic_filesink = 0] i am able to get proper file
>      i.e i can verify that the test pattern of created file changes .
>    
> 2) /When i change the properties of FILESINK ( i.e location  ) element in
> dynamic pipeline
>      [ dynamic_filesink = 1 ] i am able to get NEW_FILES with some data on
> it.
>      But only the first file is in playable state other files fails to play
> and gives
>      message/* "......COULD NOT DETERMINE TYPE OF STREAM ....... " *
>
> *Could group members please provide inputs as to what is causing this
> problem . *
You can't just change the location of filesink without letting the file
be properly finished. Some parts of the file header can only be
determined when the file is fully finished and the muxer gets EOS.
Switching location abruptly will leave the file unfinished and
unplayable. To do this you need to properly instruct avimux to finish
the current file before switching and starting a new one at the new file.

You can use splitmuxsink that does this job for you.

Regards,

>
>
> #include <gst/gst.h>
>
> GstElement *pipeline,
>     *src,
> *q1,
> *q2,
> *filesink,
> *mux;
>
> GMainLoop *loop,
> *mainloop;
>
> GstPad *temppad,
>   *muxsrcpad;
>
> GstBus *bus;
>
> GError *err = NULL;
>
> gchar   *sinkname;
> char buffer[128];
> unsigned int attempt=0;
> unsigned int timer_count=0;
> *unsigned int dynamic_filesink= 0; // 0 for videotestsrc , 1 for filesink*
>
>  
>
> static GstPadProbeReturn pad_probe_cb (GstPad * pad, GstPadProbeInfo * info,
> gpointer user_data)
> {
>
>    g_print("\t [ APP-BLOCK ]: PAD_BROBE [ START ] ===================\n");
>
>
>    // Remove the probe first
>    gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
>
>
>    if ( dynamic_filesink == 0 ) {
> // Changing the TEST-SRC PATTERN
> timer_count = timer_count +1;
> g_object_set (G_OBJECT(src), "pattern",timer_count, NULL);
>    }else {
> // Changing the FILESINK
> gst_element_set_state (filesink, GST_STATE_NULL);
> attempt = attempt+1;
> sprintf( buffer, "test_%d.avi" , attempt);
> g_object_set(G_OBJECT (filesink),"location", buffer, NULL);
> gst_element_set_state (filesink , GST_STATE_PLAYING);
>   }
>
>    g_print("\t [ APP-BLOCK ]: PAD_BROBE [ STOP  ] ===================\n");
>
>   return GST_PAD_PROBE_OK;
>
> } // End brace of pad_probe_cb
>
>    
>  
> static gboolean timeout_cb (gpointer user_data)
> {
>    g_print("\t [ APP-TIMER ]: IN-TIMER  [ BEFORE-BLOCKING ] =========\n");
>    timer_count=timer_count+1;
>    gst_pad_add_probe (muxsrcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
> pad_probe_cb, user_data, NULL);
>    if ( timer_count == 10 ){
> return FALSE;
>    }
>
>    return TRUE;
> } // End brace of "timeout_cb"
>
>
> static gboolean bus_cb (GstBus * bus, GstMessage * msg, gpointer user_data)
> {
>    GMainLoop *loop = user_data;
>
>    switch (GST_MESSAGE_TYPE (msg)) {
>      case GST_MESSAGE_ERROR:{
>        GError *err = NULL;
>        gchar *dbg;
>
>        gst_message_parse_error (msg, &err, &dbg);
>        gst_object_default_error (msg->src, err, dbg);
>        g_error_free (err);
>        g_free (dbg);
>        g_main_loop_quit (loop);
>        break;
>      }
>
>      case GST_MESSAGE_STATE_CHANGED: {
>        GstState old_state, new_state;
>        gst_message_parse_state_changed (msg, &old_state, &new_state, NULL);
>        g_print ("[ APP - MESSAGE ]: Element %s changed state from %s to
> %s.\n",
>       GST_OBJECT_NAME (msg->src),
> gst_element_state_get_name (old_state),
>       gst_element_state_get_name (new_state));
>      break;
>      }
>
>      default:
>        break;
>    }
>
>    return TRUE;
>
> }//End brace of SWITCH condition
>
>
>
>
> int main (int argc, char **argv)
> {
>
>
>    gst_init (&argc, &argv);
>
>    if ( dynamic_filesink  == 0 ) {
>       g_print("\n\t [APP-DEBUG ]: ------- DYNAMIC VIDEO-PATTERN ----------
> \n");
>    }else{
>       g_print("\n\t [APP-DEBUG ]: ------- DYNAMIC FILE-SINK file's -------
> \n");
>    }
>
>    // 0 - Creating the PIPELINE
>    pipeline = gst_pipeline_new ("pipeline");
>    
>    // 1 - Creating the SRC
>    src = gst_element_factory_make ("videotestsrc", NULL);
>    g_object_set (G_OBJECT(src), "is-live", TRUE, NULL);
>    g_object_set (G_OBJECT(src), "pattern",18, NULL);
>
>    // 2 - Creating the QUEUE
>    q1 = gst_element_factory_make ("queue", NULL);
>    q2 = gst_element_factory_make ("queue", NULL);
>
>
>    // 3 - Creating the MUX
>    mux = gst_element_factory_make("avimux",NULL);
>
>    // 4 - Creating the FILESINK
>    filesink = gst_element_factory_make ("filesink", NULL);
>    attempt = attempt+1;
>    sprintf( buffer, "test_%d.avi" , attempt);
>    g_print("\n\t [APP]: Created new file of %s \n",buffer);
>    g_object_set(G_OBJECT(filesink),"location", buffer, NULL);
>
>
>    // 7 - Adding all the elements in to BIN
>    gst_bin_add_many (GST_BIN (pipeline), src, q1,mux, q2,filesink, NULL);
>
>    
>    // 8 - Linking all static pad
>    if (!gst_element_link_many (src, q1, NULL )) {
>    g_print ("[APP]: Failed to link STATIC_1 Pad's of elements");
>    return -3;
>    }
>  
>
>    if (!gst_element_link_many (mux,q2,filesink, NULL)) {
>    g_print ("[APP]: Failed to link STATIC_2 Pad's of elements");
>    return -3;
>    }
>
>    // 9 - Linking DYNAMIC PAD
>    temppad = gst_element_get_request_pad (mux, "video_%u");
>    sinkname = gst_pad_get_name (temppad);
>    g_print ("\t [APP]: A new pad %s was created\n\n", sinkname);
>
>    if (!gst_element_link_many (q1, mux,NULL )) {
>    g_print ("[APP]: Failed to link DYNAMIC Pad's of elements");
>    return -3;
>    }
>
>    g_free (sinkname);
>    gst_object_unref (GST_OBJECT (temppad));
>
>    // 10 - Getting the blocking PAD
>    muxsrcpad = gst_element_get_static_pad (mux,"src");
>
>    // 11 - Starting the PIPELINE
>    if (gst_element_set_state (pipeline,GST_STATE_PLAYING) ==
> GST_STATE_CHANGE_FAILURE) {
>    g_error ("[APP]: Failed to go into PLAYING state");
>    return -4;
>    }
>
>    mainloop = g_main_loop_new (NULL, FALSE);
>    gst_bus_add_watch (GST_ELEMENT_BUS (pipeline), bus_cb, mainloop);
>    g_timeout_add_seconds (7, timeout_cb, mainloop);
>    g_main_loop_run (mainloop);
>    
>    // 10 - Stopping the PIPELINE
>    gst_element_set_state (pipeline, GST_STATE_NULL);
>    gst_object_unref (pipeline);
>      return 0;
> }
>
>
>
>
>
>
>
>
> --
> View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Dynamic-Pipeline-Vidoetestsrc-element-works-but-Filesink-element-fails-tp4674638.html
> Sent from the GStreamer-devel mailing list archive at Nabble.com.
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


--
Thiago Sousa Santos
Senior Multimedia Engineer, Open Source Group
Samsung Research America - Silicon Valley

_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic-Pipeline ( Vidoetestsrc element works but Filesink element fails )

Ashish Kumar Mishra
Hi Thiago Sousa Santos ,

Sorry for delay in follow up of thread , would resume working on it back from today.

1) "...To do this you need to properly instruct avimux to finish
        the current file before switching and starting a new one at the new file...."
    I would use this as an pointer and would share the outcome shortly.


2) "...You can use splitmuxsink that does this job for you..."
    Correct , i had tested the same with Gstreamer 1.6.1
    But my problem is that i have to build an logic for Gstreamer 0.10 version. On Gstreamer 0.10
    version i could not find splitmuxsink element .
    Hence idea is to first understand the logic for Gstreamer1.6.1 and then map it to Gstreamer0.10.

Please do let me know if i am wrong or i am missing any other aspect.

Thanks ,
Ashish  
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic-Pipeline ( Vidoetestsrc element works but Filesink element fails )

Ashish Kumar Mishra
This post was updated on .
Hi All ,

As per input , i am trying to send EOS event to the MUX followed by updating the location property of filesink element. But the problem still exist


static GstPadProbeReturn eos_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));

  gst_element_set_state (filesink, GST_STATE_NULL);
 
  attempt = attempt+1;
  sprintf( buffer, "test_%d.avi" , attempt);
  g_object_set(G_OBJECT (filesink),"location", buffer, NULL);

  gst_element_set_state (filesink , GST_STATE_PLAYING);

  return GST_PAD_PROBE_PASS;
}


static GstPadProbeReturn pad_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
  gst_pad_add_probe  (muxsrcpad,GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, eos_cb, user_data, NULL);  
  gst_pad_send_event (muxsinkpad, gst_event_new_eos ());

 return GST_PAD_PROBE_OK;
} // End brace of pad_probe_cb


static gboolean timeout_cb (gpointer user_data)
{

  timer_count=timer_count+1;
  gst_pad_add_probe (q1sinkpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,pad_probe_cb, user_data, NULL);
 
  return TRUE;
} // End brace of "timeout_cb"


Could group member let me know wht is wrong in this logic
or
Share a code snip of changing MUX + FILESINK at run time .

Thanks ,
Ashish
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic-Pipeline ( Vidoetestsrc element works but Filesink element fails )

Ashish Kumar Mishra
Hi all ,

The problem is addressed and i am able to create multiple files using filesink element dynamically.

The problem was that along with filesinbk even instance of MUX needs to be handled i.e create an new
instance of mux + filesink.


Thanks ,
Ashish Kumar Mishra
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic-Pipeline ( Vidoetestsrc element works but Filesink element fails )

Luis de Bethencourt-4
In reply to this post by Ashish Kumar Mishra

Ashish Kumar Mishra writes:

> Hi All ,
>
> static GstPadProbeReturn eos_cb (GstPad * pad, GstPadProbeInfo *
> info,gpointer user_data)
> {
>   gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
>
>  gst_element_set_state (mux, GST_STATE_NULL);
>   gst_element_set_state (filesink, GST_STATE_NULL);
>
>   gst_bin_remove (GST_BIN (pipeline), filesink);
>   gst_bin_remove (GST_BIN (pipeline), mux);
>
>   gst_object_unref (filesink);
>   gst_object_unref (mux);
>
>   mux = gst_element_factory_make("avimux",NULL);
>
>   filesink = gst_element_factory_make ("filesink", NULL);
>   attempt = attempt+1;
>   sprintf( buffer, "test_%d.avi" , attempt);
>   g_object_set(G_OBJECT (filesink),"location", buffer, NULL);
>
>   gst_bin_add_many (GST_BIN (pipeline),mux,filesink, NULL);
>
>   if (!gst_element_link_many (mux,filesink, NULL)) {
>    g_print ("[APP]: Failed to link STATIC_2 Pad's of elements");
>    return -3;
>   }
>
>   muxsinkpad = gst_element_get_request_pad (mux, "video_%u");
>
>   if (!gst_element_link_many (q1, mux,NULL )) {
>    g_print ("[APP]: Failed to link DYNAMIC Pad's of elements");
>    return -3;
>   }
>
>   muxsrcpad   = gst_element_get_static_pad (mux,"src");
>   filesinkpad = gst_element_get_static_pad (filesink,"sink");
>   q1sinkpad   = gst_element_get_static_pad (filesink,"sink");
>
>   gst_element_set_state (filesink , GST_STATE_PLAYING);
>   gst_element_set_state (mux     , GST_STATE_PLAYING);
>
>   newfile = NO_NEW_FILE;
>
>   return GST_PAD_PROBE_DROP;
>
> }
>
>
> static GstPadProbeReturn pad_probe_cb (GstPad * pad, GstPadProbeInfo * info,
> gpointer user_data)
> {
>
>   gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
>   gst_pad_add_probe  (muxsrcpad,GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, eos_cb,
> user_data, NULL);
>   gst_pad_send_event (muxsinkpad, gst_event_new_eos ());
>
>   // Wait til the EOS have been processed
>   while(newfile != NO_NEW_FILE)
> sleep(1);
>
>  return GST_PAD_PROBE_OK;
>
> } // End brace of pad_probe_cb
>
>
> static gboolean timeout_cb (gpointer user_data)
> {
>
>   timer_count=timer_count+1;
>   newfile = NEW_FILE;
> gst_pad_add_probe (q1sinkpad,
> GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,pad_probe_cb, user_data, NULL);
>
>   if ( timer_count == 10 ){
>   return FALSE;
>   }
>
>   return TRUE;
> } // End brace of "timeout_cb"
>
>
>
> ** (dynamic-filter:3227): CRITICAL **: gst_collect_pads_pop: assertion
> 'GST_IS_COLLECT_PADS (pads)' failed
>
> (dynamic-filter:3227): GStreamer-CRITICAL **: gst_object_unref: assertion
> '((GObject *) object)->ref_count > 0' failed
>
>
> Could group member let me know cause of the problem
> or
> Share a code snip of changing MUX + FILESINK at run time .
>
> Thanks ,
> Ashish


Something is calling gst_collect_pads_pop() and failing defined in:
gstreamer/libs/gst/base/gstcollectpads.c

It would be easier if you generated a full GST_DEBUG log.

Enjoy,
Luis
_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic-Pipeline ( Vidoetestsrc element works but Filesink element fails )

Ashish Kumar Mishra
Hi  Luis de Bethencourt-4 ,

I resolved that issue . It was due to below mentioned part of code in eos_cb function :-
    gst_object_unref (filesink);
    gst_object_unref (mux);

Thanks for your valuable inputs.


~ Ashish Kumar Mishra.