[gst-devel] event system

Thomas Vander Stichele thomas at urgent.rug.ac.be
Thu Jun 14 23:04:55 CEST 2001


Hi,

> what's the  difference between flush and clear? none IMHO, I would think
> that a flush event would suffice.

Hmmm... I thought I had a good example to indicate the difference (a queue
would throw away all of the data it hasn't sent yet, while an mp3 encoder
would create fake data to finish off the frame it's working on) but
they're complementary anyway and can be handled by the same event.

> I feel speed and qos are the same. changing the speed would require to 
> change the global clockspeed of the pipeline.

Hmmm... I'd rather combine speed and seek; with speed I didn't mean "send
buffers faster", but I meant "send the same amount of data but
time-compress it".  So it would work as a speed-based seek.  Also, if you
would set speed to -1, you'd just reverse the data.

> > 3) These events shouldn't be user-definable IMO; if there is need for new
> > types of events, they should be tied to the gstreamer core as to ensure a
> > well-defined set of events.
> not sure about that... 

hmmm... what I mean in this regard is that it would be better to agree on
events than, for example, in the case of plugins, have a plugin with has a
"silent" argument and another which has a "mute" argument.

> > 4) IMO, for downstream events, a plugin should either only send an event
> > *or* a data buffer, but not both at the same time, as to make it easier on
> > plugin writers.  I'm not sure this really should be a requirement, but it
> > seems like a good rule of thumb unless there are counterexamples.  In any
> > case, I would let a plugin send only one event at a time.
> 
> events and buffers have nothing in common. It must be perfectly possible
> to send a seek event followed by a buffer push.

Well, since this point was leading up to the combining of data and events,
and since you could still send out a seek event first and in the next
iteration a buffer push, this seemed like a good idea.  But it could work
either way of course.

> > 5) As to how events should be passed on :
> > * for downstream events : I would tie a new variable to the src pad, which
> > would be a struct with an enum for the type of data that's passed through
> > in it's iteration.
> > The enum would be { DATA, EVENT_NODATA, EVENT_EOS, EVENT_FLUSH, ... }
> > The enum would be checked by the next plugin; if it's DATA, then it works
> > as it is now, but the buffer pointer would be in the event struct.
> > if it's another, and it also has a parameter, that parameter would be in
> > the struct as well, probably in the same way as gtk arguments are handled
> > now.  
> > 
> I don't agree with events sending out data. Sending data is a separate
> functionality that involves a scheduler and such. People could abuse the
> event system to pass data, which is not good IMO.

The data would just be the same as it is now, a buffer which is passed on.
I just lumped data and events together since it made sense to me.  But
they could be split up as well.

> > 6) plugins should proxy all of these events by default automatically.
> > Only plugins that specifically know the event has a meaning for them
> > should install event handlers.
> 
> proxying the events would be a core feature similar to how the eos/qos
> events are proxied now.

yes.

> <snip>
> 
> A little example of a possible API to send events:
> 
>   GstEvent *ev = gst_event_new (GST_EVENT_SEEK);
>   GST_EVENT_SEEK_TYPE (ev) = GST_EVENT_SEEK_OFFSET; 
>   GST_EVENT_SEEK_POSITION (ev) = 1000; 
> 
>   gint res = gst_pad_send_event (sinkpad, ev);
>   gst_event_unref (ev);
>   if (res) {
>    // event succeeded
>    buf = gst_pad_pull (sinkpad);
>    // we now have a buffer with the requested offset...
>   }
>   
> A possible event_handler in disksrc:
> 
> gint
> gst_disksrc_handle_event (GstPad *pad, GstEvent *ev)
> {
>   if (GST_EVENT_TYPE (ev) == GST_EVENT_SEEK) {
>     disksrc->offset = GST_EVENT_POSITION (ev);
>     return true; // we handled the event
>   }
>   return false; // we did not handle the event.
> }
> 

Hmm, so in this case, the plugin sending the event would block until one
of the plugins downstream responds to it.  But of course if you want
acknowledgement of your event you have to wait for that.  I was thinking
at first of sending out events and not waiting for the reply.

Anyway, in the case of multidisksrc ! mad ! afsink, when the multidisksrc
sends a flush, mad is the first to catch it, and it decides to clear out
it's buffers (using multiple iterations, probably), and after that sends
out a flush of it's own, which afsink catches.  Afsink closes the file and
reopens another, possibly, and responds yes to the flush.  Mad gets the
yes and responds yes to it's flush event too.  multidisksrc catches the
yes and does what it needed to do.  So that would seem to work then ;).

Hmmm, only problem in this case might be the blocking of the plugins then;
suppose osssrc records and some plugin down the stream sends out an event,
which blocks the upper plugins (osssrc included).  What would be a good
solution in this case ? Make events non-blocking ? Ask app-writers to
protect their real-time plugin needs with queues ?

The above code seems to look good IMO as a starting point.  If people need
help in implementing it, and don't mind taking me along for the ride,
please do ;)

thomas

<-*-                      -*->
Now, if it were called the Orgasmator, 
I'd be the first to try your basic 
button-press approach ...
<-*- thomas at apestaart.org -*->
URGent, the best radio on the Internet - 24/7 ! - http://urgent.rug.ac.be/





More information about the gstreamer-devel mailing list