How to properly terminate a complex stream with tee and avimux

Tim Müller tim at centricular.com
Tue Aug 12 01:08:21 PDT 2014


On Mon, 2014-08-11 at 06:25 -0700, tnewman wrote:

Hi,

> I have been attempting to create a complex pipeline with some success except
> for how to close the video saving (avimux) portion of the stream.  Below one
> will find an illustration of the pipeline.
> 
> 
> 
> Here is the story:  I have an embedded device where I need to create a video
> stream to a fakesink; where the fakesink is used to hand framebuffers to a
> Qt application to be displayed in a widget.  This is the primary stream
> connected to the tee as seen above.  The second portion of the stream is the
> connected to the tee on request (a user pushes a Qt button) and begins
> recording an AVI file to disk.  The addition of this pipeline to the tee
> seems to be working (most of the time, sometimes the pipeline hangs; but
> that is for later).  The issue is when the user presses the Qt button again
> to stop the recording.  The first time through it works, the filesink sees a
> EOS event and the file terminates with an updated header.  The problem comes
> the second time around.  From the g_print statements one sees this:
> 
> 
> 
> And thereafter the pipeline fails.
> 
> Below one will find the source code for the project.  Any help would be
> greatly appreciated.
> 
> 
> 
> I have tried may variants with no success. So the real question is: how does
> one unlink a section of the pipeline from the tee, terminate the avimux and
> audio source elements to create a proper AVI file, remove the elements from
> the pipeline and then at a later time recreate these elements, link them,
> and do it all over again.

event_probe_cb() will be called from the streaming thread, the same
thread you want to shut down. This won't really work well like this.
What you should work better is something like this:

 - set g_object_set (pipeline, "message-forward", TRUE, NULL)
   so you get a message on the bus even if just filesink is EOS
   (but not the other sink)

 - wait for an GST_MESSAGE_ELEMENT on the bus like this:

    case GST_MESSAGE_ELEMENT:{
      const GstStructure *s = gst_message_get_structure (msg);

      if (gst_structure_has_name (s, "GstBinForwarded")) {
        GstMessage *forward_msg = NULL;

        gst_structure_get (s, "message", GST_TYPE_MESSAGE, &forward_msg,
NULL);
        if (GST_MESSAGE_TYPE (forward_msg) == GST_MESSAGE_EOS) {
           ... shut down / remove pipeline branch ... 
        }
      }
      break;
    }

 - This assumes you unlinked the tee branch and sent an EOS
   yourself on the queue's sink pad before jpegenc and
   to audiotestsrc via gst_element_send_event().

 Cheers
  -Tim

-- 
Tim Müller, Centricular Ltd - http://www.centricular.com



More information about the gstreamer-devel mailing list