This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[ GStreamer MUX ] Dm816x hangs when asked to change state from PLAYING to NULL

Hi All  ,

Could Team members please provide some pointer for below mentioned problem in Gstreamer-0.10 ( TI SDK )


1) With Gstreamer-0.10 the MUX element hangs when asked to change the state to NULL
   ( from PLAYING state to NULL state )
   i.e
   gst_element_set_state (mux, GST_STATE_NULL) , instruction hangs.


2) Same logic we tested on Gstreamer-1.0 on UBUNTU-14.04 logic where we are able to get
   multiple files being created as the AVI MUX changes the state to NULL using the
   same instruction ( this was done as proof of concept )


3) Attached is the stripped down sample to demonstrate the problem.
   #define MACRO of VERSION can be used to compile same code effectively to
   Gstreamer-0.10 ( VERSION = 0 ) & Gstreamer-1.0 ( VERSION = 1 )


Since we have the logic working on Gstreamer-1.0 , if group could please help us
to solve the above mentioned problem of " MUX getting hanged when asked to do an change of state"
we feel we could build up our solution quickly.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <gst/gst.h>

#define TIMER_DURATION 10 
#define VERSION 0

GstElement 		*pipeline,
			*src, 
			*timeoverlay,
			*clockoverlay,
			*q1, 
			*q2, 
			*filesink,
			*mux,
			*audiosrc,
			*capsfilter,
			*tempfilesink;

GstCaps 		*acaps;

GMainLoop 		*loop,
			*mainloop;

GstPad 			*muxvideosinkpad,
			*muxaudiosinkpad,
			*muxsrcpad,
			*filesinkpad,
			*q1sinkpad,
			*q2sinkpad;

static gulong 		probe_id; // probe ID

GstBus 			*bus;

GError 			*err = NULL;



gchar  			*sinkname;
char 			buffer[128];
volatile unsigned int 	attempt=0;
unsigned int 		timer_count=0;
unsigned int 		dynamic_filesink= 1;  
gboolean		return_bool = FALSE,
			chunk = TRUE;
unsigned long		return_gulong =0;

typedef enum {
	  NO_NEW_FILE,	        // Keep current file destination
	  NEW_FILE,		// Switch file destination
} NewFileStatus;

static NewFileStatus newfile = NO_NEW_FILE; // Switch File Flag

#if ( VERSION == 1) 
static GstPadProbeReturn eos_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  g_print("\t [ APP-BLOCK ]: EOS_PROBE [ START ] ===================\n");
  if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) != GST_EVENT_EOS)
    return GST_PAD_PROBE_DROP;

   gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));

#else
static gboolean eos_cb (GstPad * pad, GstEvent * event, gpointer user_data)
{
  g_print("\t [ APP-BLOCK ]: EOS_PROBE [ START ] ===================\n");
  if (GST_EVENT_TYPE (event) != GST_EVENT_EOS){
    return TRUE;
  }

  //Remove the probe first
  gst_pad_remove_event_probe (pad, probe_id);
#endif


  gst_element_release_request_pad(mux, muxvideosinkpad);
  g_print("\t [ APP-BLOCK ]: About to set ELEMENTS as NULL \n");
  gst_element_set_state (mux, GST_STATE_NULL);  // Gst-0.10 hangs at this instruction 
  gst_element_set_state (filesink, GST_STATE_NULL);        
  
  // Remove unlinks automatically
  gst_bin_remove (GST_BIN (pipeline), mux);
  gst_bin_remove (GST_BIN (pipeline), filesink);
  
  GstElement *mux0   = gst_element_factory_make  ("avimux",NULL);
  GstElement *fsink0 = gst_element_factory_make("filesink", NULL);
  mux 		= mux0;
  filesink 	= fsink0;
  if(!mux0 || !fsink0) {
	g_print("[ERROR]: Missing elements\n");
  }
 
  gst_bin_add (GST_BIN (pipeline), mux);
  gst_bin_add (GST_BIN (pipeline), filesink);

#if (VERSION == 1)   
  sprintf( buffer, "test_%u.avi" , attempt);
#else
  sprintf( buffer, "test_%d.avi" , attempt);
#endif 

  g_object_set(G_OBJECT (filesink),"location", buffer, NULL);

  muxsrcpad   = gst_element_get_static_pad (mux,"src");
#if (VERSION == 1)
  muxvideosinkpad = gst_element_get_request_pad (mux, "video_%u");
#else
  muxvideosinkpad = gst_element_get_request_pad (mux, "video_%d");
#endif

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

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

  g_print ("Moving to PLAYING\n");
  gst_element_set_state (mux, GST_STATE_PLAYING);
  gst_element_set_state (filesink, GST_STATE_PLAYING);

  newfile = NO_NEW_FILE;
  chunk = TRUE;

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

#if ( VERSION == 1) 
 return GST_PAD_PROBE_OK;
#else
  return TRUE;
#endif


} 



#if ( VERSION == 1 ) 
static GstPadProbeReturn pad_probe_cb (GstPad * pad, GstPadProbeInfo * info,gpointer user_data)
#else 
static gboolean pad_probe_cb (GstPad * pad, GstBuffer * buffer, gpointer user_data)
#endif
{
  unsigned int sleep_count =0;

  g_print("\t [ APP-BLOCK ]: VIDEO_PAD_BROBE [ START ] ===================\n");
#if ( VERSION == 1) 
    gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
#else
   gst_pad_remove_buffer_probe (pad, probe_id);
#endif 

   g_object_set (G_OBJECT(src), "pattern",attempt, NULL);

#if ( VERSION == 1 )    
    gst_pad_add_probe  (filesinkpad,GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, eos_cb, user_data, NULL);
#else
   probe_id = gst_pad_add_event_probe (filesinkpad, G_CALLBACK(eos_cb), user_data);
#endif 
   gst_pad_send_event (muxvideosinkpad, gst_event_new_eos ());


  // Wait til the EOS have been processed  
  while(newfile != NO_NEW_FILE){
	g_print("In sleep %d \n",sleep_count);
	sleep_count=sleep_count+1;
	sleep(1);
  }

   g_print("\t [ APP-BLOCK ]: VIDEO_PAD_BROBE [ STOP  ] ===================\n");
#if ( VERSION == 1) 
 return GST_PAD_PROBE_OK;
#else
  return TRUE;
#endif

} // End brace of video_pad_probe_cb


static gboolean timeout_cb (gpointer user_data)
{

  attempt = attempt+1;
  timer_count=timer_count+1;

  if ( chunk == TRUE ) {
	chunk = FALSE;
	g_print("\t [ APP-TIMER ]: IN-TIMER %d [ BEFORE-BLOCKING ] =========\n",timer_count);
	newfile = NEW_FILE;

	#if ( VERSION == 1 )
	gst_pad_add_probe (q1sinkpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,pad_probe_cb, user_data, NULL);
	#else 
 	probe_id = gst_pad_add_buffer_probe (q1sinkpad, pad_probe_cb, user_data);
	#endif
  }

  g_print("\t [ APP-TIMER ]: IN-TIMER %d =========\n",timer_count);
  if ( timer_count == 12 ){
 	return FALSE;
  }

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






static gboolean bus_cb (GstBus * bus, GstMessage * msg, gpointer 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(mainloop);
    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;
    }

    case GST_MESSAGE_WARNING:{
	GError *err = NULL;
        gchar *name, *debug = NULL;
        name = gst_object_get_path_string (msg->src);
        gst_message_parse_warning (msg, &err, &debug);
        g_print ("\n[ APP - MESSAGE ]: ERROR: from element %s: %s\n", name, 
								err->message);
        if (debug != NULL)
           g_print ("%s \n\n",debug);
  
        g_error_free (err);
        g_free (debug);
        g_free (name);
    break;
    }

    case GST_MESSAGE_EOS:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_EOS\n");
    break;
    }

    case GST_MESSAGE_INFO:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_INFO\n");
    break;
    }

    case GST_MESSAGE_TAG:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_TAG\n");
    break;
    }
  
    case GST_MESSAGE_BUFFERING:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_BUFFERING\n");
    break;
    }
 
    case GST_MESSAGE_STEP_DONE:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_STEP_DONE\n");
    break;
    }
 
    case GST_MESSAGE_CLOCK_PROVIDE:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_CLOCK_PROVIDE\n");
    break;
    }
 
    case GST_MESSAGE_CLOCK_LOST:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_CLOCK_LOST\n");
    break;
    }
 
    case GST_MESSAGE_NEW_CLOCK:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_NEW_CLOCK\n");
    break;
    }
 
    case GST_MESSAGE_APPLICATION:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_APPLICATION\n");
    break;
    }
 
   case GST_MESSAGE_ELEMENT:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_ELEMENT\n");
   break;
   }
 
   case GST_MESSAGE_SEGMENT_START:{
 	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_SEGMENT_START\n");
   break;
   }
 
   case GST_MESSAGE_SEGMENT_DONE:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_SEGMENT_DONE\n");
   break;
   }
 
    case GST_MESSAGE_LATENCY:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_LATENCY\n");
    break;
    }
 
    case GST_MESSAGE_ASYNC_START:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_ASYNC_START\n");
    break;
    }
 
    case GST_MESSAGE_ASYNC_DONE:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_ASYNC_DONE\n");
    break;
    }
 
    case GST_MESSAGE_REQUEST_STATE:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_REQUEST_STATE\n");
    break;
    }
 
    case GST_MESSAGE_STEP_START:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_STEP_START\n");
    break;
    }
 
    case GST_MESSAGE_QOS:{
	g_print ("[ APP - MESSAGE ]: GST_MESSAGE_QOS\n");
    break;
    }
  
 
    default:
      break;
  }

  return TRUE;

}//End brace of SWITCH condition


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


  gst_init (&argc, &argv);
 
  // 0 - Creating the PIPELINE
  pipeline = gst_pipeline_new ("pipeline");
  
  // 1 - Creating the SRC & TIMEOVERLAY
  src = gst_element_factory_make ("videotestsrc", NULL);
  g_object_set (G_OBJECT(src), "pattern",attempt, NULL);
  g_object_set (G_OBJECT(src), "do-timestamp",attempt, NULL);
  g_object_set (G_OBJECT(src), "is-live", TRUE, NULL);  

  clockoverlay = gst_element_factory_make ("clockoverlay", NULL ) ;
  g_object_set (G_OBJECT (clockoverlay), "time-format","%d-%b-%Y / %H:%M:%S",NULL);
 
  timeoverlay = gst_element_factory_make ("timeoverlay", 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);
  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),mux,filesink, NULL);  
  gst_bin_add_many (GST_BIN (pipeline), src, clockoverlay ,timeoverlay, q1,NULL);  


  // 8 - Linking all static pad
   if (!gst_element_link_many (src, clockoverlay,timeoverlay , q1, NULL )) {
	    g_print ("[APP]: Failed to link src, clockoverlay,timeoverlay \n");
	    return -3;
  } 
  
  if (!gst_element_link_many (mux,filesink, NULL)) {
	    g_print ("[APP]: Failed to link mux,filesink ");
	    return -3;
  } 


  // 9 - Linking DYNAMIC PAD
#if ( VERSION == 1 )
  muxvideosinkpad = gst_element_get_request_pad (mux, "video_%u");
#else
  muxvideosinkpad = gst_element_get_request_pad (mux, "video_%d");
#endif

  sinkname = gst_pad_get_name (muxvideosinkpad);
  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 q1, mux");
	    return -3;
  }
  g_free (sinkname);


  // 10 - Getting the blocking PAD 
  muxsrcpad   = gst_element_get_static_pad (mux,"src");
  filesinkpad = gst_element_get_static_pad (filesink,"sink");
  q1sinkpad   = gst_element_get_static_pad (q1,"sink");
  if (q1sinkpad == NULL){
	g_print("Q1SINK pad is NULL \n"); 
        return -4;
  }

  // 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 -6;
  }

  mainloop = g_main_loop_new (NULL, FALSE);
  gst_bus_add_watch (GST_ELEMENT_BUS (pipeline), bus_cb, mainloop);
  g_timeout_add_seconds (TIMER_DURATION, 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;
}


  • Hello,

    Are you trying to move only one element in NULL state(mux in your case)?
    Could you provide more details about what you are tying to archive, please?

    Between 0.10 and 1.0 gstreamer there are differences.

    They are two completely different libraries which just happen to have a similar name.
    They are using different plugins versions etc.
    API/ABI are not compatible GStreamer-0.10 or GStreamer-1.0.
    Some functions present in 1.0 missing in 0.10 etc.
    You could search for the differences between them.

    gstreamer.freedesktop.org/.../chapter-getting.html

    When you are building your application I would recommend you to follow the guides about the gst's version that you are using.

    BR
    Margarita
  • Dear Margarita ,
    Thanks for prompt input ,please find the details below :-

    1) The sample plugin is VIDEOTESTSRC ---> CLOCKOVERLAY ---> TIMEOVERLAY ---> QUEUE _1 --- > AVIMUX ---> FILESINK

    2) I have a timeout function registered in main function , which gets triggered after say 10sec.
    In TIMEOUT function i am calling an gst_pad_add_buffer_probe on "QUEUE_SINKPAD " ......This works

    In PAD_Probe function registered , i had an EOS function binded to "FILE_SINKPAD "
    & i am calling generating an EOS event on "MUX_VIDEOSINKPAD " ........ This works

    In EOS handler , i want to remove the older instance of FILESINK & MUX.
    To do this i have to make their state as NULL.

    It is here when i call gst_set_state ( MUX , NULL ) , the function gets hanged .
    It is not returning from this call , hence i am unable to track the return value of this function

    3) I have exact identical logic for Gstreamer-1.0 which works .
    its only in Gstreamer-0.10 where the MUX is not responding to state change , due to this my entire logic gets hanged !!!

    Hope this provides some clarity on implementation , can you please provide any inputs .
  • Hello,

    So you want to null->unlink->relink->play only the filesink and the mux element right and the videotestsrc and other elements to be in playing state when the unlinking happens? In other words dynamic link/unlink elements?

    BR
    Margarita
  • Hello,

    The dynamic link/unlink elements is different between 0.10 and 1.0.

    For 0.10 you could try:

    Block the queue, unlink pads, send EOS, move to NULL, remove the element from the pipeline, create the new element, get and link the pads, move it to play, unblock.



    BR
    Margarita
  • Dear Margarita ,

    Thanks a lot for the inputs , i would re-modify the pipeline stage as directed by you.

    Just to ensure that i had clearly understood , below is flow which i have could visualize as per your valuable input
    ( --> QUEUE ---> AVIMUX ---> FILESINK )
    1. Block the queue_sinkpad,
    2. Unlink Filesink-MUX and Queue-MUX
    3. Send EOS to MUX
    4. Move MUX , FILESINK to NULL
    5. Remove the MUX, FILESINK element from the pipeline
    6. Create the MUX , FILESINK new element
    7. Get and link the pads( Queue - MUX & MUX-Filesink ),
    8. Move it to play
    9. Unblock the queue_Sinkpad.
  • Hello,

    Do you want an example code?

    BR
    Margarita
  • Dear Margarita ,
    It would be helpful if you can share sample code for same.
  • Hello,

    Here is example for unlink/link "multisink" element(in this case is ....queue->filesink element).

    /* create_filesink_tail function to create a new multisink element
     * end link it to the pipeline
     * */
    static void create_filesink_tail()
    {
        GstPad *srcpad;
        GstPad *sinkpad;
        
       //Create the new multisink element
       multisink = NULL;
       multisink = gst_element_factory_make ("filesink", NULL);
    
        if(!multisink)
        {
            g_print("failed to create new sink element! \n");
            return;
        }
    
        //add it to the bin
        gst_bin_add(GST_BIN (pipeline), multisink);
        
            //switch the filename
        sprintf(name_buf, "image%05d.jpg", counter++);
        g_print ("File Switching %s\n", name_buf);
        g_object_set( G_OBJECT( multisink ), "location", name_buf, NULL );
        
        //get and link the pads
        gst_element_link(multi_queue, multisink);
        srcpad = gst_element_get_static_pad( multi_queue, "src" );
        sinkpad = gst_element_get_static_pad( multisink, "sink" );
        
        gst_element_link_pads (multi_queue, "src", multisink, "sink");
        
        
        gst_element_set_state (multisink, GST_STATE_PLAYING);
    }
    
    /*
     *  destroy_bin_cb function to remove the multisink element from the pipeline
     *  */
    static gboolean destroy_bin_cb (gpointer user_data)
    {
        //oldbin is multisink element easy way to destroy it by using pipeline remove
        GstElement *oldbin = (GstElement *) user_data;
    
        g_print("Destroying old bin.\n");
        if (pipeline)
        {
            //move it to the NULL state and remove it from the pipeline
            gst_element_set_state (oldbin, GST_STATE_NULL);
            gst_bin_remove (GST_BIN(pipeline), oldbin);
        }
        return FALSE;
    }
    
    
    /* replace_filesink_blocked_cb  Callback function to block the block, unlink pads
     * */
    
    static void replace_filesink_blocked_cb (GstPad *pad, gboolean blocked, gpointer user_data)
    {
        int ret;
        
        if (blocked)
        {
            GstElement *oldbin;
            GstPad *sinkpad;
    
           
            g_print("Blocked filesink queue.\n");
            g_static_rec_mutex_lock(&mutex);
            g_print("Locked.\n");
            oldbin = multisink;
            sinkpad = gst_element_get_static_pad(multisink, "sink");
            if (!sinkpad)
            {
                g_print("replace_filesink_blocked_cb: oldbin doesn't have sink pad.\n");
                goto fail;
            }
            
            //Unlink pads
            gst_pad_unlink(multi_queue_srcpad, sinkpad);
            g_print("Unlinked.\n");
    
            //send EOS to the multisink sinkpad
            gst_pad_send_event(sinkpad, gst_event_new_eos());
            g_print("Sent event.\n");
    
            g_print("Checked sinks.\n");
            
       
        
            g_print("Destroying old bin.\n");
            if (pipeline)
            {
            //move it to the NULL state and remove it from the pipeline
            gst_element_set_state (oldbin, GST_STATE_NULL);
            gst_bin_remove (GST_BIN(pipeline), oldbin);
            }
                 
        
           
           
            //call the tail to create the new multisink element
            create_filesink_tail();
            
            
            
            g_print("Created filesink.\n");
            g_static_rec_mutex_unlock(&mutex);
            g_print("Unlocked mutex.\n");
    
            /* And unblock again. */
            ret = gst_pad_set_blocked_async(multi_queue_srcpad, gboolean (FALSE), replace_filesink_blocked_cb, NULL);
            g_print("gst_pad_set_unblocked_async ret : %d \n", ret );
    
            g_print("Done replacing filesink.\n");
        }
        else
        {
            g_print("Unblocked filesink queue.\n");
        }
        return;
    
    fail:
        g_print("FAIL!!!\n");
    }
    
    /*replace_filesink function to replace the multisink element
     * */
    static void replace_filesink()
    {
        int ret;
        
        if (multi_queue_srcpad == NULL)
            g_print("replace_filesink while no multi_queue_srcpad yet, waiting for it to appear.\n");
        else
        {
           ret =  gst_pad_set_blocked_async(multi_queue_srcpad, TRUE, replace_filesink_blocked_cb, NULL);
           g_print("gst_pad_set_blocked_async ret : %d \n", ret );
        }
    }
    
    

    BR

    Margarita

  • Dear Margarita ,
    I modified the code according to the suggested flow .
    It still hangs at the same instruction of gst_set_state ( MUX , NULL ) ;

    So the problem is MUX plugin getting hang when gst_set_state ( MUX , NULL ) .

    Hence , could you please suggest probable cause of MUX pluging getting hang when asked to change the state .

    Or if there is any other debugging which i can check.
  • Hello,

    The example which I share is working on my side but it is unlinking the last filesink element only.
    Could you try to gst_object_unref (mux); .
    The multiplexers and the tee element are using requested pads.
    You could check in the 0.10 guide about requested pads.

    BR
    Margarita

  • Dear Margarita ,

    I tried playing around with filesink , it gets to NULL state .

    Problem was only with "MUX" , MUX which is AVIMUX / MATROSKAMUX doesn't go to NULL state .

    Could you please provide some pointers as to what might be the probable cause of MUX not changing the state to NULL state.

    or if you can provide any other inputs. 

    I am falling short of debugging pointers ...

     

  • Hello,

    I would recommend you to check the requested pads.
    If you are changing avimux and matroskamux you could try to archive this by using output-selector. I think I already provided you an example code for output - selector element.

    BR
    Margarita
  • Hello,

    When you connect mp4mux or some other are you observe the same problem?

    BR
    Margarita

  • Dear Margarita , 

    Yes the problem seems to be at behavior of mux plugin as same instructions work properly on Filesink. 

    Initially i was using AVIMUX in pipeline but  later on changed it to MATROSKA mux , the state state HANGS for MUX , ir-respective of which mux i have used . 

    Is it possible to share any sample code where MUX + FILESINK  are changed ?

  • Hello Ashish,

    No I do not have sample code for mux+filesink.


    The mux element has audio and video sink pads(inputs) and one output.
    Are you unlink both audio and video sink pads?

    BR
    Margarita