Change File Locations for Container Formats that Have Headers

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

Change File Locations for Container Formats that Have Headers

Wes Miller
Administrator

Here is what i have gathered is supposed to happen to accomplish changing filesink output file locations in a running pipeline.

The pipeline ends with "...!  queue2 name="q1"  ! matroksamux  name-mux ! filesink name="fsink" "    
                                           I build mine using gst_parse_launch()

Status:
  -  The pipeline is in GST_STATE_PLAYING.  
  -  The g_main_loop is running.
  -  The first location output file is being filled with data.
  -  There is a callback for bus messages.


When it comes time to swap output files:   (for me this is in a timer callbak)
  -  block the src pad of q1                      

           q1_srcpad =   gst_element_get_static_pad( q1, "src" );
           rc = gst_pad_set_blocked_async( q1_srcpad, true, Q1Blocked, NULL );


in the callback Q1Blocked()  
  -  send an EOS to mux      
  -  This should pass down to fsink and cause t he mux to write its headers/trailers
         
          rc = gst_element_send_event( mux, gst_event_new_eos() );


in the bus messages callback handler, bus_call():
  -  detect we got the EOS
  -  set mux and fsink to GST_STATE_NULL
  -  change the location
  -  unblock the q1 src pad

          case GST_MESSAGE_EOS:
             rc = gst_element_set_state( mux,  GST_STATE_NULL );
             rc = gst_element_set_state( sink, GST_STATE_NULL );
             g_object_set( G_OBJECT( sink ), "location", newOutFileName, NULL );
             gst_pad_set_blocked_async( that->q1src, false, Q1UnBlocked, NULL );

in Q1UnBlocked() callback handler:
  -  return mux and fsink to GST_SATE_PLAYING

         rc = gst_element_set_state( mux,   GST_STATE_PLAYING );
         rc = gst_element_set_state( fsink,  GST_STATE_PLAYING );


And that's where I run into a brick wall.  The rc from setting fsink to GST_STATE_PLAYING is 2,  GST_STATE_CHANGE_ASYNC.  

Why does filesink not return to playing?  Does setting it to STATE_NULL mean that it disconnects from the mux?  The mux src pad is an always pad and so is the filesink sink pad.  Is the mux unlinked from the queue?

Many thanks,

Wes


------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Change File Locations for Container Formats that Have Headers

Wes Miller
Administrator
A few notes:

Tried relinking the mux to the queue.  Still not sure I have the right pads connected.
Then relinked mux to filesink.

And about 50 combinations of ordering the gst_element_set_state() for the filesink and mux, and also putting those before and after the relinking steps.

Also used gst_element_get_state( sink, , oldstate, newstate, 10 * GST_SECOND ) just tomake sure I wasn't waint enough time.

Filesink still stays in asynch wait.  WHAT THE HECK is it waiting on?


Thanks,

Wes
Reply | Threaded
Open this post in threaded view
|

Re: Change File Locations for Container Formats that Have Headers

Edward Hervey
Administrator
On Fri, 2010-07-09 at 13:36 -0700, Wes Miller wrote:

> A few notes:
>
> Tried relinking the mux to the queue.  Still not sure I have the right pads
> connected.
> Then relinked mux to filesink.
>
> And about 50 combinations of ordering the gst_element_set_state() for the
> filesink and mux, and also putting those before and after the relinking
> steps.
>
> Also used gst_element_get_state( sink, , oldstate, newstate, 10 * GST_SECOND
> ) just tomake sure I wasn't waint enough time.
>
> Filesink still stays in asynch wait.  WHAT THE HECK is it waiting on?

  Filesink (and any other non-live sinks) will be async when they
haven't received a buffer yet.
  So, based on that, start analyzing from that point upward (by which I
mean, read debug logs).
  * Are the mux and sink still linked ?
  * Is the muxer trying to push data ?
  * Is the muxer receiving data ?
  * Is the muxer waiting for data on pads that aren't used anymore ?

  GST_DEBUG=2,*sink:5,*mux:5 would be a good start to look at what's
going on.

    Edward

>
>
> Thanks,
>
> Wes



------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Change File Locations for Container Formats that Have Headers

Wes Miller
Administrator
[WorkingAnswer]

I really am not quite sure why my code started working.  I made one significant change, I constructed the pipeline the "hard" way rather than using gst_parse_launch().  This necessitated a pad-added callback and a link_to_mux() routine, both more or less straight outof the book.  The logic is pretty much what s seen above.

Good luck to whoever implements this next.

Wes
Reply | Threaded
Open this post in threaded view
|

Re: Change File Locations for Container Formats that Have Headers

Edward Hervey
Administrator
On Mon, 2010-07-12 at 14:59 -0700, Wes Miller wrote:
> [WorkingAnswer]
>
> I really am not quite sure why my code started working.  I made one
> significant change, I constructed the pipeline the "hard" way rather than
> using gst_parse_launch().

  I'm pretty sure everybody who replied to your questions assumed you
were doing that in the first place.

  People : Do not use gst_parse_launch() for anything more complicated
that "setup this pipeline and change its state". The moment you want to
start playing around with individual elements/pads, build the pipeline
yourself. It's not rocket science (as Wes mentions just below).

>   This necessitated a pad-added callback and a
> link_to_mux() routine, both more or less straight outof the book.  The logic
> is pretty much what s seen above.
>
> Good luck to whoever implements this next.
>
> Wes



------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

RE: Change File Locations for Container Formats that Have Headers

Wes Miller
Administrator

 

 

Thanks a million Edward.  I still don’t really understand the debug output, but a little of it went a long way.  And in particular, thanks for telling me how to get it to work with a pipeline in a program. 

 

HINT IF YOU MISSED IT:  Put the GST_DEBUG settings in an environment variable. 

     export GST_DEBUG=whatever 

     unset GST_DEBUG                            # to turn debug off

 

Just adding two more cents worth:  I got to using gst_parse_launh() because I never could get request pads to work.  The example in the book is good, but it skipped two important points.  So for future warriors: 

 

1.    Put the code (inline or call) that links the request pad right in line with the pipeline building process, before changing the state to “PLAYING”. 

I never could quite figure out whether it had to come before or after the pipeline was moved to GST_STATE_PLAYING and whether or not the request pads were present before some signal was issued.

2.    You’re going to want to use the same caps over and over.  Go ahead and codify a GstCaps and pass it around.  Fill in as many of the fields as you can so there is no question of incompleteness.

 

And in this particular case, the filesink goes to ASYNC until new data arrives.  Don’t gst_element_get_state( fildsink, NULL, NULL, -1 ). 

 

Finally, a thought.  I code in mangled C++ using mostly C syntax for “G” functions in the methods and using friend functions for the callbacks.  The nature of the friend function beast is that the friend needs a pointer to its class.  For that reason, I keep most of my element, caps, etc vars as class members, public if possible, so that I pass “this” to the friend functions as the third gpointer arg.  (FWIW, I always call the pointer in the functions “that” just so it’s obvious what’s up).  This way there are no global variables that can interfere with other code and I still get great access.

 

Wes