mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-03 16:09:39 +00:00
324 lines
11 KiB
Text
324 lines
11 KiB
Text
There are a number of different ways of coding a GstSrc. I'll try to
|
|
outline them and how the function here:
|
|
|
|
1a) Simple push-function based with single output
|
|
|
|
|
|
*------* *------
|
|
! ! !
|
|
! src !--->--! plugin
|
|
! ! !
|
|
*------* *------
|
|
|
|
This is the style that all the existing sources use. There is a single
|
|
output pad, and a _push function that's global to the whole element. The
|
|
_push function simply constructs buffers and pushes them out the pad.
|
|
|
|
Chained (current implementation):
|
|
|
|
|
|
bin src pad1 pad2 plugin
|
|
! (= pad1->peer)
|
|
gst_bin_iterate
|
|
!
|
|
! (find entry)
|
|
!
|
|
! gst_src_push
|
|
!---------------->!
|
|
! (create buffer)
|
|
!
|
|
! gst_pad_push
|
|
!---------------->!
|
|
!
|
|
! pad1->chainfunc (pad1->peer)
|
|
!------------------------------->!
|
|
! !
|
|
: :
|
|
(more chaining)
|
|
: :
|
|
!<-------------------------------!
|
|
!<----------------!
|
|
!<-----------------!
|
|
!
|
|
iteration ends
|
|
!
|
|
---
|
|
-
|
|
|
|
Typically this will be the/an entry into the Bin. The Bin's iterate
|
|
function simply calls the Src's _push function. When the _push function
|
|
pushes a buffer out it's pad, the chain function of the peer pad is
|
|
called, presumably causing a push out the other side of that element, and
|
|
eventually data gets to the other end. The stack unrolls, and the
|
|
iteration ends for that Src.
|
|
|
|
|
|
|
|
Cothreaded:
|
|
|
|
Again, the source would generally be an entry into the Bin. A loopfunc
|
|
will be constructed around it, which will simply loop calling the Src's
|
|
_push function as in the non-cothreaded case. When the _push function
|
|
pushes a buffer, it finds a pushfunc attached to the pad, drops the buffer
|
|
in the pen, and calls the pushfunc provided by the Bin. This causes a
|
|
switch to the next element, then the next, to the end, at which point a
|
|
buffer pull will travel back down the chain. The _push function gets
|
|
context and finishes, at which point the loopfunc wrapper simply calls it
|
|
again in the next iteration.
|
|
|
|
(current implementation):
|
|
|
|
|
|
bin cothread1 src pad1 pad2 cothread2 plugin
|
|
! (src) (= pad2->peer) (plugin)
|
|
gst_bin_iterate
|
|
!
|
|
! (first entry)
|
|
!
|
|
! cothread_switch
|
|
!---------------->!
|
|
! gst_src_push
|
|
!---------------->!
|
|
! (create buffer)
|
|
!
|
|
! gst_pad_push (pad1)
|
|
!
|
|
!--------------------!
|
|
! (fill bufpen)
|
|
!
|
|
! cothread switch
|
|
----------------------->!
|
|
! gst_pad_pull (pad2)
|
|
!
|
|
!<----------!
|
|
!
|
|
! (get buffer from bufpen)
|
|
!
|
|
!---------->!
|
|
! pad2->chainfunc
|
|
!------------->!
|
|
!
|
|
:
|
|
|
|
:
|
|
!<-------------!
|
|
! gst_pad_pull (pad2)
|
|
!<----------!
|
|
!
|
|
! (bufpen empty)
|
|
!<----------!
|
|
!<-------------------------------------! cothread switch
|
|
!<----------------!
|
|
!
|
|
iteration ends
|
|
!
|
|
:
|
|
|
|
:
|
|
!
|
|
next iteration
|
|
!
|
|
! cothread_switch
|
|
!---------------->!
|
|
! gst_src_push
|
|
!---------------->!
|
|
! (create buffer)
|
|
!
|
|
! gst_pad_push (pad1)
|
|
!
|
|
!--------------------!
|
|
! (fill bufpen)
|
|
!
|
|
! cothread switch
|
|
!---------->!
|
|
! (get buffer from bufpen)
|
|
!
|
|
!---------->!
|
|
! pad2->chainfunc
|
|
!------------->!
|
|
!
|
|
:
|
|
|
|
:
|
|
!<-------------!
|
|
! gst_pad_pull (pad2)
|
|
!<----------!
|
|
!
|
|
! (bufpen empty)
|
|
!<----------!
|
|
!<-------------------------------------! cothread switch
|
|
!<----------------!
|
|
!
|
|
iteration ends
|
|
!
|
|
:
|
|
|
|
|
|
-----------------------------------------------------------------------------------------------
|
|
1b) Simple push-function based with multiple output
|
|
|
|
Chained:
|
|
|
|
Similar to the single output variant, except several chains are spawned
|
|
off, one per push, hanging off whichever pad the buffer is pushed off of.
|
|
The stack will grow and unwind as many times as buffers are pushed out.
|
|
|
|
(current implementation)
|
|
|
|
bin src pad1 pad2 plugin
|
|
! (= pad1->peer)
|
|
gst_bin_iterate
|
|
!
|
|
! (find entry)
|
|
!
|
|
! gst_src_push
|
|
!---------------->!
|
|
! (create buffer)
|
|
!
|
|
! gst_pad_push
|
|
!---------------->!
|
|
!
|
|
! pad1->chainfunc (pad1->peer)
|
|
!------------------------------->!
|
|
! !
|
|
: :
|
|
(more chaining)
|
|
: :
|
|
!<-------------------------------!
|
|
!<----------------!
|
|
! (create buffer)
|
|
!
|
|
! gst_pad_push
|
|
!---------------->!
|
|
!
|
|
! pad1->chainfunc (pad1->peer)
|
|
!------------------------------->!
|
|
! !
|
|
: :
|
|
(more chaining)
|
|
: :
|
|
!<-------------------------------!
|
|
!<----------------!
|
|
:
|
|
(more pushes)
|
|
:
|
|
!<-----------------!
|
|
!
|
|
iteration ends
|
|
!
|
|
---
|
|
-
|
|
|
|
|
|
Cothreaded:
|
|
|
|
Also similar to the single output variant. When the pull winds its way
|
|
back from the first push, execution returns to the Src's _push function,
|
|
which simply goes off and pushes out another buffer, causing another
|
|
series of context switches. Eventually the loopfunc wrapper starts over,
|
|
round and round we go.
|
|
|
|
|
|
|
|
-----------------------------------------------------------------------------------------------
|
|
2) Pull-function based with single output
|
|
|
|
Similar to a regular filter with a chain function associated with each
|
|
pad, this kind of source doesn't provide a src-wide push function, but
|
|
does provide pullfuncs for its pad. A pullfunc puts a buffer in the pen
|
|
and exits.
|
|
|
|
Chained:
|
|
|
|
bin src pad1 pad2 plugin
|
|
! (= pad1->peer)
|
|
gst_bin_iterate
|
|
!
|
|
! (find entry)
|
|
!
|
|
! (find src pad
|
|
! of entry element)
|
|
!
|
|
! gst_pad_pull
|
|
!------------------------------------------------>!
|
|
? !
|
|
!<------------------------------!
|
|
!
|
|
! (create buffer)
|
|
!
|
|
! gst_pad_push
|
|
!------------------------------>!
|
|
! (bufpen filled)
|
|
(return buffer) !
|
|
!<------------------------------------------------!
|
|
!
|
|
! gst_pad_chain
|
|
!------------------------------------------------------------------->!
|
|
!
|
|
:
|
|
(more chaining)
|
|
:
|
|
!<-------------------------------------------------------------------!
|
|
!
|
|
iteration ends
|
|
!
|
|
---
|
|
-
|
|
|
|
As usual, is likely to be an entry into a Bin. The Bin iterate code must
|
|
explicitly pull a buffer and pass it on to the peer.
|
|
|
|
Cothreaded:
|
|
|
|
|
|
bin cothread1 src pad1 pad2 cothread2 plugin
|
|
! (src) (= pad2->peer) (plugin)
|
|
gst_bin_iterate
|
|
!
|
|
! (first entry)
|
|
!
|
|
! cothread_switch
|
|
!---------------->! gst_pad_pull
|
|
!------------------------------------------------>!
|
|
? !
|
|
!<------------------------------!
|
|
!
|
|
! (create buffer)
|
|
!
|
|
! gst_pad_push
|
|
!------------------------------>!
|
|
! (bufpen filled)
|
|
(return buffer) !
|
|
!<------------------------------------------------!
|
|
!
|
|
! pad_chain
|
|
!--------------------------------------! cothread switch
|
|
|---------------------->!
|
|
! gst_pad_pull (pad2)
|
|
!
|
|
!<----------!
|
|
!
|
|
! (get buffer from bufpen)
|
|
!
|
|
!---------->!
|
|
! pad2->chainfunc
|
|
!------------->!
|
|
!
|
|
:
|
|
|
|
:
|
|
!<-------------!
|
|
! gst_pad_pull (pad2)
|
|
!<----------!
|
|
!
|
|
! (bufpen empty)
|
|
!<-----------!
|
|
! cothread switch
|
|
!-------------------!
|
|
!<----------------!
|
|
!<----------------!
|
|
!
|
|
iteration ends
|
|
!
|
|
:
|
|
|