mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
docs/design/part-gstghostpad.txt: Update ascii art in documentation.
Original commit message from CVS: * docs/design/part-gstghostpad.txt: Update ascii art in documentation. * gst/gstghostpad.c: (gst_proxy_pad_do_internal_link), (gst_proxy_pad_set_target_unlocked), (gst_proxy_pad_init), (gst_ghost_pad_parent_set), (gst_ghost_pad_parent_unset), (gst_ghost_pad_internal_do_activate_push), (gst_ghost_pad_internal_do_activate_pull), (gst_ghost_pad_do_activate_push), (gst_ghost_pad_do_activate_pull), (gst_ghost_pad_do_link), (gst_ghost_pad_do_unlink), (gst_ghost_pad_dispose), (gst_ghost_pad_new_full), (gst_ghost_pad_set_target): Small cleanups and leak fixes. Remove some checks now that the internal pad is never NULL. Fix the case where linking pads without a target would create nasty criticals. Fixes #341029. Don't assign a GstPadLinkReturn to a gboolean and mess up the return value of _set_target(). * tests/check/gst/gstghostpad.c: (GST_START_TEST), (gst_ghost_pad_suite): Some more tests for creating and linking untargeted ghostpads.
This commit is contained in:
parent
ce6e126d47
commit
47e5ba2f15
4 changed files with 398 additions and 274 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
||||||
|
2006-08-31 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* docs/design/part-gstghostpad.txt:
|
||||||
|
Update ascii art in documentation.
|
||||||
|
|
||||||
|
* gst/gstghostpad.c: (gst_proxy_pad_do_internal_link),
|
||||||
|
(gst_proxy_pad_set_target_unlocked), (gst_proxy_pad_init),
|
||||||
|
(gst_ghost_pad_parent_set), (gst_ghost_pad_parent_unset),
|
||||||
|
(gst_ghost_pad_internal_do_activate_push),
|
||||||
|
(gst_ghost_pad_internal_do_activate_pull),
|
||||||
|
(gst_ghost_pad_do_activate_push), (gst_ghost_pad_do_activate_pull),
|
||||||
|
(gst_ghost_pad_do_link), (gst_ghost_pad_do_unlink),
|
||||||
|
(gst_ghost_pad_dispose), (gst_ghost_pad_new_full),
|
||||||
|
(gst_ghost_pad_set_target):
|
||||||
|
Small cleanups and leak fixes.
|
||||||
|
Remove some checks now that the internal pad is never NULL.
|
||||||
|
Fix the case where linking pads without a target would create nasty
|
||||||
|
criticals. Fixes #341029.
|
||||||
|
Don't assign a GstPadLinkReturn to a gboolean and mess up the return
|
||||||
|
value of _set_target().
|
||||||
|
|
||||||
|
* tests/check/gst/gstghostpad.c: (GST_START_TEST),
|
||||||
|
(gst_ghost_pad_suite):
|
||||||
|
Some more tests for creating and linking untargeted ghostpads.
|
||||||
|
|
||||||
2006-08-31 Edward Hervey <edward@fluendo.com>
|
2006-08-31 Edward Hervey <edward@fluendo.com>
|
||||||
|
|
||||||
* docs/gst/gstreamer-sections.txt:
|
* docs/gst/gstreamer-sections.txt:
|
||||||
|
|
|
@ -9,9 +9,9 @@ Ghostpads
|
||||||
|
|
||||||
- Must look like a real GstPad on both sides.
|
- Must look like a real GstPad on both sides.
|
||||||
- target of Ghostpad must be changeable
|
- target of Ghostpad must be changeable
|
||||||
|
- target can be initially NULL
|
||||||
|
|
||||||
|
* a GhostPad is implemented using a private GstProxyPad class:
|
||||||
* a GhostPad is implemented using a smaller GstProxyPad class:
|
|
||||||
|
|
||||||
|
|
||||||
GstProxyPad
|
GstProxyPad
|
||||||
|
@ -20,17 +20,57 @@ Ghostpads
|
||||||
|------------------|
|
|------------------|
|
||||||
| GstPad *target |
|
| GstPad *target |
|
||||||
(------------------)
|
(------------------)
|
||||||
|
| GstPad *internal |
|
||||||
|
(------------------)
|
||||||
|
|
||||||
|
|
||||||
GstGhostPad
|
GstGhostPad
|
||||||
(------------------) -\
|
(------------------) -\
|
||||||
| GstPad | |
|
| GstPad | |
|
||||||
|------------------| > GstProxyPad
|
|------------------| |
|
||||||
| GstPad *target | |
|
| GstPad *target | > GstProxyPad
|
||||||
|
|------------------| |
|
||||||
|
| GstPad *internal | |
|
||||||
|------------------| -/
|
|------------------| -/
|
||||||
| GstPad *internal |
|
| <private data> |
|
||||||
(------------------)
|
(------------------)
|
||||||
|
|
||||||
|
A GstGhostPad (X) is _always_ created together with a GstProxyPad (Y).
|
||||||
|
The internal pad pointers are set to point to the eachother. The
|
||||||
|
GstProxyPad pairs have opposite directions, the GstGhostPad has the same
|
||||||
|
direction as the (future) ghosted pad (target).
|
||||||
|
|
||||||
|
|
||||||
|
(- X --------)
|
||||||
|
| |
|
||||||
|
| target * |
|
||||||
|
|------------|
|
||||||
|
| internal *----+
|
||||||
|
(------------) |
|
||||||
|
^ V
|
||||||
|
| (- Y --------)
|
||||||
|
| | |
|
||||||
|
| | target * |
|
||||||
|
| |------------|
|
||||||
|
+----* internal |
|
||||||
|
(------------)
|
||||||
|
|
||||||
|
Which we will abreviate to:
|
||||||
|
|
||||||
|
(- X --------)
|
||||||
|
| |
|
||||||
|
| target *--------->//
|
||||||
|
(------------)
|
||||||
|
|
|
||||||
|
(- Y --------)
|
||||||
|
| target *----->//
|
||||||
|
(------------)
|
||||||
|
|
||||||
|
The GstGhostPad (X) is also set as the parent of the GstProxyPad (Y).
|
||||||
|
|
||||||
|
The target is a pointer to the internal pads peer. It is an optimisation to
|
||||||
|
quickly get to the peer of a ghostpad without having to dereference the
|
||||||
|
internal->peer.
|
||||||
|
|
||||||
Some use case follow with a description of how the datastructure
|
Some use case follow with a description of how the datastructure
|
||||||
is modified.
|
is modified.
|
||||||
|
@ -40,11 +80,11 @@ Ghostpads
|
||||||
|
|
||||||
gst_ghost_pad_new (char *name, GstPad *target)
|
gst_ghost_pad_new (char *name, GstPad *target)
|
||||||
|
|
||||||
1) create new GstGhostPad X
|
1) create new GstGhostPad X + GstProxyPad Y
|
||||||
2) X name set to @name
|
2) X name set to @name
|
||||||
3) X direction is the same as the target
|
3) X direction is the same as the target, Y is opposite.
|
||||||
4) the target is set to @target
|
4) the target of X is set to @target
|
||||||
5) internal is NULL
|
5) Y is linked to @target
|
||||||
6) link/unlink and activate functions are set up
|
6) link/unlink and activate functions are set up
|
||||||
on GstGhostPad.
|
on GstGhostPad.
|
||||||
|
|
||||||
|
@ -53,10 +93,12 @@ Ghostpads
|
||||||
(- X --------) |
|
(- X --------) |
|
||||||
| | |------)
|
| | |------)
|
||||||
| target *------------------> | sink |
|
| target *------------------> | sink |
|
||||||
|------------| |------)
|
(------------) -------> |------)
|
||||||
| internal *---->// (--------------
|
| / (--------------
|
||||||
(------------)
|
(- Y --------) / (pad link)
|
||||||
|
//<-----* target |/
|
||||||
|
(------------)
|
||||||
|
|
||||||
- Automatically takes same direction as target.
|
- Automatically takes same direction as target.
|
||||||
- target is filled in automatically.
|
- target is filled in automatically.
|
||||||
|
|
||||||
|
@ -65,20 +107,20 @@ Ghostpads
|
||||||
|
|
||||||
gst_ghost_pad_new_no_target (char *name, GstPadDirection dir)
|
gst_ghost_pad_new_no_target (char *name, GstPadDirection dir)
|
||||||
|
|
||||||
1) create new GstGhostPad X
|
1) create new GstGhostPad X + GstProxyPad Y
|
||||||
2) X name set to @name
|
2) X name set to @name
|
||||||
3) X direction is @dir
|
3) X direction is @dir
|
||||||
4) internal is NULL
|
|
||||||
5) link/unlink and activate functions are set up
|
5) link/unlink and activate functions are set up
|
||||||
on GstGhostPad.
|
on GstGhostPad.
|
||||||
|
|
||||||
|
(- X --------)
|
||||||
(- X --------)
|
| |
|
||||||
| |
|
| target *--------->//
|
||||||
| target *------>//
|
(------------)
|
||||||
|------------|
|
|
|
||||||
| internal *---->//
|
(- Y --------)
|
||||||
(------------)
|
| target *----->//
|
||||||
|
(------------)
|
||||||
|
|
||||||
- allows for setting the target later
|
- allows for setting the target later
|
||||||
|
|
||||||
|
@ -87,59 +129,69 @@ Ghostpads
|
||||||
|
|
||||||
gst_ghost_pad_set_target (char *name, GstPad *newtarget)
|
gst_ghost_pad_set_target (char *name, GstPad *newtarget)
|
||||||
|
|
||||||
(- X --------)
|
(- X --------)
|
||||||
| |
|
| |
|
||||||
| target *------>//
|
| target *--------->//
|
||||||
|------------|
|
(------------)
|
||||||
| internal *---->//
|
|
|
||||||
(------------)
|
(- Y --------)
|
||||||
|
| target *----->//
|
||||||
|
(------------)
|
||||||
|
|
||||||
1) assert direction of newtarget == X direction
|
1) assert direction of newtarget == X direction
|
||||||
2) target is set to newtarget
|
2) target is set to newtarget
|
||||||
|
3) internal pad Y is linked to newtarget
|
||||||
|
|
||||||
(--------
|
(--------------
|
||||||
(- X --------) |
|
(- X --------) |
|
||||||
| | |------)
|
| | |------)
|
||||||
| target *------------->| sink |
|
| target *------------------> | sink |
|
||||||
|------------| |------)
|
(------------) -------> |------)
|
||||||
| internal *--->// (--------
|
| / (--------------
|
||||||
(------------)
|
(- Y --------) / (pad link)
|
||||||
|
//<-----* target |/
|
||||||
|
(------------)
|
||||||
|
|
||||||
|
* Setting target on a targetted unlinked ghostpad
|
||||||
* Setting target on an targetted unlinked ghostpad
|
|
||||||
|
|
||||||
gst_ghost_pad_set_target (char *name, GstPad *newtarget)
|
gst_ghost_pad_set_target (char *name, GstPad *newtarget)
|
||||||
|
|
||||||
(--------
|
(--------------
|
||||||
(- X --------) |
|
(- X --------) |
|
||||||
| | |------)
|
| | |-------)
|
||||||
| target *------------->| sink |
|
| target *------------------> | sink1 |
|
||||||
|------------| |------)
|
(------------) -------> |-------)
|
||||||
| internal *--->// (--------
|
| / (--------------
|
||||||
(------------)
|
(- Y --------) / (pad link)
|
||||||
|
//<-----* target |/
|
||||||
|
(------------)
|
||||||
|
|
||||||
1) assert direction of newtarget == X direction
|
1) assert direction of newtarget (sink2) == X direction
|
||||||
2) target is set to newtarget
|
2) unlink internal pad Y and oldtarget
|
||||||
|
3) target is set to newtarget (sink2)
|
||||||
(--------
|
4) internal pad Y is linked to newtarget
|
||||||
(- X --------) |
|
|
||||||
| | |------)
|
|
||||||
| target *------------->| sink |
|
|
||||||
|------------| |------)
|
|
||||||
| internal *--->// (--------
|
|
||||||
(------------)
|
|
||||||
|
|
||||||
|
(--------------
|
||||||
|
(- X --------) |
|
||||||
|
| | |-------)
|
||||||
|
| target *------------------> | sink2 |
|
||||||
|
(------------) -------> |-------)
|
||||||
|
| / (--------------
|
||||||
|
(- Y --------) / (pad link)
|
||||||
|
//<-----* target |/
|
||||||
|
(------------)
|
||||||
|
|
||||||
* Linking a pad to an untargetted ghostpad:
|
* Linking a pad to an untargetted ghostpad:
|
||||||
|
|
||||||
gst_pad_link (src, X)
|
gst_pad_link (src, X)
|
||||||
|
|
||||||
|
(- X --------)
|
||||||
(- X --------)
|
| |
|
||||||
| |
|
| target *--------->//
|
||||||
| target *------>//
|
(------------)
|
||||||
|------------|
|
|
|
||||||
| internal *---->//
|
(- Y --------)
|
||||||
|
| target *----->//
|
||||||
(------------)
|
(------------)
|
||||||
-------)
|
-------)
|
||||||
|
|
|
|
||||||
|
@ -148,28 +200,28 @@ Ghostpads
|
||||||
(-----|
|
(-----|
|
||||||
-------)
|
-------)
|
||||||
|
|
||||||
|
X is a sink GstGhostPad without a target. The internal GstProxyPad Y has
|
||||||
|
the same direction as the src pad (peer).
|
||||||
|
|
||||||
1) link function is called
|
1) link function is called
|
||||||
a) new GstProxyPad Y is created
|
a) Y direction is same as @src
|
||||||
b) Y direction is same as peer
|
b) Y target is set to @src
|
||||||
c) Y target is set to peer
|
c) Y is activated in the same mode as X
|
||||||
d) X internal pad is set to Y (X is parent of Y)
|
d) core makes link from @src to X
|
||||||
e) Y is activated in the same mode as X
|
|
||||||
f) core makes link from src to X
|
|
||||||
|
|
||||||
|
|
||||||
(- X --------)
|
(- X --------)
|
||||||
| |
|
| |
|
||||||
| target *----->//
|
| target *----->//
|
||||||
>|------------|
|
>(------------)
|
||||||
(real pad link) / | internal * |
|
(real pad link) / |
|
||||||
/ (----------|-)
|
/ (- Y ------)
|
||||||
/ |
|
/ -----* target |
|
||||||
-------) / V
|
-------) / / (----------)
|
||||||
| / (- Y ------)
|
| / /
|
||||||
(-----|/ | |
|
(-----|/ /
|
||||||
| src |<-------------* target |
|
| src |<----
|
||||||
(-----| (----------)
|
(-----|
|
||||||
-------)
|
-------)
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,39 +229,37 @@ Ghostpads
|
||||||
|
|
||||||
gst_pad_link (src, X)
|
gst_pad_link (src, X)
|
||||||
|
|
||||||
(--------
|
(--------
|
||||||
(- X --------) |
|
(- X --------) |
|
||||||
| | |------)
|
| | |------)
|
||||||
| target *------------->| sink |
|
| target *------------->| sink |
|
||||||
|------------| |------)
|
(------------) >|------)
|
||||||
| internal *--->// (--------
|
| / (--------
|
||||||
(------------)
|
| /
|
||||||
-------)
|
| /
|
||||||
|
|
-------) | / (real pad link)
|
||||||
(-----|
|
| (- Y ------) /
|
||||||
| src |
|
(-----| | |/
|
||||||
(-----|
|
| src | //<----* target |
|
||||||
-------)
|
(-----| (----------)
|
||||||
|
-------)
|
||||||
|
|
||||||
|
|
||||||
1) link function is called
|
1) link function is called
|
||||||
a) new GstProxyPad Y is created
|
a) Y direction is same as @src
|
||||||
b) Y direction is same as peer
|
b) Y target is set to @src
|
||||||
c) Y target is set to peer
|
c) Y is activated in the same mode as X
|
||||||
d) X internal pad is set to Y (X is parent of Y)
|
d) core makes link from @src to X
|
||||||
e) link is made from Y to X target (sink)
|
|
||||||
f) Y is activated in the same mode as X
|
|
||||||
g) core makes link from src to X
|
|
||||||
|
|
||||||
(--------
|
(--------
|
||||||
(- X --------) |
|
(- X --------) |
|
||||||
| | |------)
|
| | |------)
|
||||||
| target *------------->| sink |
|
| target *------------->| sink |
|
||||||
>|------------| >|------)
|
>(------------) >|------)
|
||||||
(real pad link) / | internal * | / (--------
|
(real pad link) / | / (--------
|
||||||
/ (----------|-) /
|
/ | /
|
||||||
/ | /
|
/ | /
|
||||||
-------) / V / (real pad link)
|
-------) / | / (real pad link)
|
||||||
| / (- Y ------) /
|
| / (- Y ------) /
|
||||||
(-----|/ | |/
|
(-----|/ | |/
|
||||||
| src |<-------------* target |
|
| src |<-------------* target |
|
||||||
|
@ -221,77 +271,73 @@ Ghostpads
|
||||||
|
|
||||||
gst_ghost_pad_set_target (char *name, GstPad *newtarget)
|
gst_ghost_pad_set_target (char *name, GstPad *newtarget)
|
||||||
|
|
||||||
|
|
||||||
(- X --------)
|
(- X --------)
|
||||||
| |
|
| |
|
||||||
| target *----->//
|
| target *------>//
|
||||||
>|------------|
|
>(------------)
|
||||||
(real pad link) / | internal * |
|
(real pad link) / |
|
||||||
/ (----------|-)
|
/ |
|
||||||
/ |
|
/ |
|
||||||
-------) / V
|
-------) / |
|
||||||
| / (- Y ------)
|
| / (- Y ------)
|
||||||
(-----|/ | |
|
(-----|/ | |
|
||||||
| src |<-------------* target |
|
| src |<-------------* target |
|
||||||
(-----| (----------)
|
(-----| (----------)
|
||||||
-------)
|
-------)
|
||||||
|
|
||||||
1) assert direction of newtarget == X direction
|
1) assert direction of @newtarget == X direction
|
||||||
2) X target is set to newtarget
|
2) X target is set to @newtarget
|
||||||
3) Y (X internal) is linked to newtarget
|
3) Y is linked to @newtarget
|
||||||
|
|
||||||
|
|
||||||
(--------
|
(--------
|
||||||
(- X --------) |
|
(- X --------) |
|
||||||
| | |------)
|
| | |------)
|
||||||
| target *------------->| sink |
|
| target *------------->| sink |
|
||||||
>|------------| >|------)
|
>(------------) >|------)
|
||||||
(real pad link) / | internal * | / (--------
|
(real pad link) / | / (--------
|
||||||
/ (----------|-) /
|
/ | /
|
||||||
/ | /
|
/ | /
|
||||||
-------) / V / (real pad link)
|
-------) / | / (real pad link)
|
||||||
| / (- Y ------) /
|
| / (- Y ------) /
|
||||||
(-----|/ | |/
|
(-----|/ | |/
|
||||||
| src |<-------------* target |
|
| src |<-------------* target |
|
||||||
(-----| (----------)
|
(-----| (----------)
|
||||||
-------)
|
-------)
|
||||||
|
|
||||||
|
|
||||||
* Setting target on targetted linked ghostpad:
|
* Setting target on targetted linked ghostpad:
|
||||||
|
|
||||||
gst_ghost_pad_set_target (char *name, GstPad *newtarget)
|
gst_ghost_pad_set_target (char *name, GstPad *newtarget)
|
||||||
|
|
||||||
|
|
||||||
(--------
|
(--------
|
||||||
(- X --------) |
|
(- X --------) |
|
||||||
| | |------)
|
| | |-------)
|
||||||
| target *------------->| sink |
|
| target *------------->| sink1 |
|
||||||
>|------------| >|------)
|
>(------------) >|-------)
|
||||||
(real pad link) / | internal * | / (--------
|
(real pad link) / | / (--------
|
||||||
/ (----------|-) /
|
/ | /
|
||||||
/ | /
|
/ | /
|
||||||
-------) / V / (real pad link)
|
-------) / | / (real pad link)
|
||||||
| / (- Y ------) /
|
| / (- Y ------) /
|
||||||
(-----|/ | |/
|
(-----|/ | |/
|
||||||
| src |<-------------* target |
|
| src |<-------------* target |
|
||||||
(-----| (----------)
|
(-----| (----------)
|
||||||
-------)
|
-------)
|
||||||
|
|
||||||
1) assert direction of newtarget == X direction
|
1) assert direction of @newtarget == X direction
|
||||||
2) Y and X target are unlinked
|
2) Y and X target are unlinked
|
||||||
2) X target is set to newtarget
|
2) X target is set to @newtarget
|
||||||
3) Y (X internal) is linked to newtarget
|
3) Y is linked to @newtarget
|
||||||
|
|
||||||
|
|
||||||
(--------
|
(--------
|
||||||
(- X --------) |
|
(- X --------) |
|
||||||
| | |------)
|
| | |-------)
|
||||||
| target *------------->| sink |
|
| target *------------->| sink2 |
|
||||||
>|------------| >|------)
|
>(------------) >|-------)
|
||||||
(real pad link) / | internal * | / (--------
|
(real pad link) / | / (--------
|
||||||
/ (----------|-) /
|
/ | /
|
||||||
/ | /
|
/ | /
|
||||||
-------) / V / (real pad link)
|
-------) / | / (real pad link)
|
||||||
| / (- Y ------) /
|
| / (- Y ------) /
|
||||||
(-----|/ | |/
|
(-----|/ | |/
|
||||||
| src |<-------------* target |
|
| src |<-------------* target |
|
||||||
|
|
|
@ -58,7 +58,6 @@
|
||||||
#define GST_PROXY_PAD_TARGET(pad) (GST_PROXY_PAD (pad)->target)
|
#define GST_PROXY_PAD_TARGET(pad) (GST_PROXY_PAD (pad)->target)
|
||||||
#define GST_PROXY_PAD_INTERNAL(pad) (GST_PROXY_PAD (pad)->internal)
|
#define GST_PROXY_PAD_INTERNAL(pad) (GST_PROXY_PAD (pad)->internal)
|
||||||
|
|
||||||
|
|
||||||
typedef struct _GstProxyPad GstProxyPad;
|
typedef struct _GstProxyPad GstProxyPad;
|
||||||
typedef struct _GstProxyPadClass GstProxyPadClass;
|
typedef struct _GstProxyPadClass GstProxyPadClass;
|
||||||
|
|
||||||
|
@ -136,8 +135,6 @@ gst_proxy_pad_do_event (GstPad * pad, GstEvent * event)
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
||||||
|
|
||||||
g_return_val_if_fail (internal != NULL, FALSE);
|
|
||||||
|
|
||||||
res = gst_pad_push_event (internal, event);
|
res = gst_pad_push_event (internal, event);
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
|
|
||||||
|
@ -161,8 +158,8 @@ gst_proxy_pad_do_query (GstPad * pad, GstQuery * query)
|
||||||
static GList *
|
static GList *
|
||||||
gst_proxy_pad_do_internal_link (GstPad * pad)
|
gst_proxy_pad_do_internal_link (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstPad *target = gst_proxy_pad_get_target (pad);
|
|
||||||
GList *res = NULL;
|
GList *res = NULL;
|
||||||
|
GstPad *target = gst_proxy_pad_get_target (pad);
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
res = gst_pad_get_internal_links (target);
|
res = gst_pad_get_internal_links (target);
|
||||||
|
@ -179,8 +176,6 @@ gst_proxy_pad_do_bufferalloc (GstPad * pad, guint64 offset, guint size,
|
||||||
GstFlowReturn result;
|
GstFlowReturn result;
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
||||||
|
|
||||||
g_return_val_if_fail (internal != NULL, GST_FLOW_NOT_LINKED);
|
|
||||||
|
|
||||||
result = gst_pad_alloc_buffer (internal, offset, size, caps, buf);
|
result = gst_pad_alloc_buffer (internal, offset, size, caps, buf);
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
|
|
||||||
|
@ -193,8 +188,6 @@ gst_proxy_pad_do_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
||||||
GstFlowReturn res;
|
GstFlowReturn res;
|
||||||
|
|
||||||
g_return_val_if_fail (internal != NULL, GST_FLOW_NOT_LINKED);
|
|
||||||
|
|
||||||
res = gst_pad_push (internal, buffer);
|
res = gst_pad_push (internal, buffer);
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
|
|
||||||
|
@ -208,8 +201,6 @@ gst_proxy_pad_do_getrange (GstPad * pad, guint64 offset, guint size,
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
||||||
GstFlowReturn res;
|
GstFlowReturn res;
|
||||||
|
|
||||||
g_return_val_if_fail (internal != NULL, GST_FLOW_NOT_LINKED);
|
|
||||||
|
|
||||||
res = gst_pad_pull_range (internal, offset, size, buffer);
|
res = gst_pad_pull_range (internal, offset, size, buffer);
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
|
|
||||||
|
@ -222,8 +213,6 @@ gst_proxy_pad_do_checkgetrange (GstPad * pad)
|
||||||
gboolean result;
|
gboolean result;
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
||||||
|
|
||||||
g_return_val_if_fail (internal != NULL, FALSE);
|
|
||||||
|
|
||||||
result = gst_pad_check_pull_range (internal);
|
result = gst_pad_check_pull_range (internal);
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
|
|
||||||
|
@ -332,6 +321,7 @@ gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
wrong_direction:
|
wrong_direction:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (pad,
|
GST_ERROR_OBJECT (pad,
|
||||||
|
@ -422,6 +412,7 @@ gst_proxy_pad_init (GstProxyPad * ppad)
|
||||||
gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_query));
|
gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_query));
|
||||||
gst_pad_set_internal_link_function (pad,
|
gst_pad_set_internal_link_function (pad,
|
||||||
GST_DEBUG_FUNCPTR (gst_proxy_pad_do_internal_link));
|
GST_DEBUG_FUNCPTR (gst_proxy_pad_do_internal_link));
|
||||||
|
|
||||||
gst_pad_set_getcaps_function (pad,
|
gst_pad_set_getcaps_function (pad,
|
||||||
GST_DEBUG_FUNCPTR (gst_proxy_pad_do_getcaps));
|
GST_DEBUG_FUNCPTR (gst_proxy_pad_do_getcaps));
|
||||||
gst_pad_set_acceptcaps_function (pad,
|
gst_pad_set_acceptcaps_function (pad,
|
||||||
|
@ -430,7 +421,6 @@ gst_proxy_pad_init (GstProxyPad * ppad)
|
||||||
GST_DEBUG_FUNCPTR (gst_proxy_pad_do_fixatecaps));
|
GST_DEBUG_FUNCPTR (gst_proxy_pad_do_fixatecaps));
|
||||||
gst_pad_set_setcaps_function (pad,
|
gst_pad_set_setcaps_function (pad,
|
||||||
GST_DEBUG_FUNCPTR (gst_proxy_pad_do_setcaps));
|
GST_DEBUG_FUNCPTR (gst_proxy_pad_do_setcaps));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GST_DISABLE_LOADSAVE
|
#ifndef GST_DISABLE_LOADSAVE
|
||||||
|
@ -510,33 +500,57 @@ gst_critical (const gchar * format, ...)
|
||||||
* _ the internal and target are unlinked as soon as the GhostPad is removed
|
* _ the internal and target are unlinked as soon as the GhostPad is removed
|
||||||
* from it's parent.
|
* from it's parent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ghost_pad_parent_set (GstObject * object, GstObject * parent)
|
gst_ghost_pad_parent_set (GstObject * object, GstObject * parent)
|
||||||
{
|
{
|
||||||
GstPad *gpad = GST_PAD (object);
|
GstPad *gpad;
|
||||||
GstPad *target = gst_proxy_pad_get_target (gpad);
|
GstPad *target;
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (gpad);
|
GstPad *internal;
|
||||||
|
GstPadLinkReturn ret;
|
||||||
|
|
||||||
|
gpad = GST_PAD (object);
|
||||||
|
|
||||||
|
/* internal is never NULL */
|
||||||
|
internal = gst_proxy_pad_get_internal (gpad);
|
||||||
|
target = gst_proxy_pad_get_target (gpad);
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
if (GST_PAD_IS_SRC (internal))
|
if (GST_PAD_IS_SRC (internal))
|
||||||
gst_pad_link (internal, target);
|
ret = gst_pad_link (internal, target);
|
||||||
else
|
else
|
||||||
gst_pad_link (target, internal);
|
ret = gst_pad_link (target, internal);
|
||||||
gst_object_unref (target);
|
gst_object_unref (target);
|
||||||
|
|
||||||
|
if (ret != GST_PAD_LINK_OK)
|
||||||
|
goto link_failed;
|
||||||
}
|
}
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
|
|
||||||
if (GST_OBJECT_CLASS (gst_ghost_pad_parent_class)->parent_set)
|
if (GST_OBJECT_CLASS (gst_ghost_pad_parent_class)->parent_set)
|
||||||
GST_OBJECT_CLASS (gst_ghost_pad_parent_class)->parent_set (object, parent);
|
GST_OBJECT_CLASS (gst_ghost_pad_parent_class)->parent_set (object, parent);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
link_failed:
|
||||||
|
{
|
||||||
|
/* a warning is all we can do */
|
||||||
|
gst_object_unref (internal);
|
||||||
|
g_warning ("could not link internal ghostpad");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ghost_pad_parent_unset (GstObject * object, GstObject * parent)
|
gst_ghost_pad_parent_unset (GstObject * object, GstObject * parent)
|
||||||
{
|
{
|
||||||
GstPad *gpad = GST_PAD (object);
|
GstPad *gpad;
|
||||||
GstPad *target = gst_proxy_pad_get_target (gpad);
|
GstPad *target;
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (gpad);
|
GstPad *internal;
|
||||||
|
|
||||||
|
gpad = GST_PAD (object);
|
||||||
|
internal = gst_proxy_pad_get_internal (gpad);
|
||||||
|
target = gst_proxy_pad_get_target (gpad);
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
if (GST_PAD_IS_SRC (internal))
|
if (GST_PAD_IS_SRC (internal))
|
||||||
|
@ -570,29 +584,18 @@ static gboolean
|
||||||
gst_ghost_pad_internal_do_activate_push (GstPad * pad, gboolean active)
|
gst_ghost_pad_internal_do_activate_push (GstPad * pad, gboolean active)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
GstPad *other;
|
||||||
|
|
||||||
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
|
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK)
|
||||||
GstPad *parent = gst_proxy_pad_get_internal (pad);
|
other = gst_proxy_pad_get_internal (pad);
|
||||||
|
else
|
||||||
|
other = gst_pad_get_peer (pad);
|
||||||
|
|
||||||
if (parent) {
|
if (G_LIKELY (other)) {
|
||||||
g_return_val_if_fail (GST_IS_GHOST_PAD (parent), FALSE);
|
ret = gst_pad_activate_push (other, active);
|
||||||
|
gst_object_unref (other);
|
||||||
ret = gst_pad_activate_push (parent, active);
|
} else
|
||||||
|
ret = FALSE;
|
||||||
gst_object_unref (parent);
|
|
||||||
} else {
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GstPad *peer = gst_pad_get_peer (pad);
|
|
||||||
|
|
||||||
if (peer) {
|
|
||||||
ret = gst_pad_activate_push (peer, active);
|
|
||||||
gst_object_unref (peer);
|
|
||||||
} else {
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -601,29 +604,18 @@ static gboolean
|
||||||
gst_ghost_pad_internal_do_activate_pull (GstPad * pad, gboolean active)
|
gst_ghost_pad_internal_do_activate_pull (GstPad * pad, gboolean active)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
GstPad *other;
|
||||||
|
|
||||||
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
|
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK)
|
||||||
GstPad *peer = gst_pad_get_peer (pad);
|
other = gst_pad_get_peer (pad);
|
||||||
|
else
|
||||||
|
other = gst_proxy_pad_get_internal (pad);
|
||||||
|
|
||||||
if (peer) {
|
if (G_LIKELY (other)) {
|
||||||
ret = gst_pad_activate_pull (peer, active);
|
ret = gst_pad_activate_pull (other, active);
|
||||||
gst_object_unref (peer);
|
gst_object_unref (other);
|
||||||
} else {
|
} else
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GstPad *parent = gst_proxy_pad_get_internal (pad);
|
|
||||||
|
|
||||||
if (parent) {
|
|
||||||
g_return_val_if_fail (GST_IS_GHOST_PAD (parent), FALSE);
|
|
||||||
|
|
||||||
ret = gst_pad_activate_pull (parent, active);
|
|
||||||
|
|
||||||
gst_object_unref (parent);
|
|
||||||
} else {
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -633,19 +625,16 @@ gst_ghost_pad_do_activate_push (GstPad * pad, gboolean active)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
|
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
||||||
|
|
||||||
if (internal) {
|
if (internal) {
|
||||||
ret = gst_pad_activate_push (internal, active);
|
ret = gst_pad_activate_push (internal, active);
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
} else {
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,26 +642,18 @@ static gboolean
|
||||||
gst_ghost_pad_do_activate_pull (GstPad * pad, gboolean active)
|
gst_ghost_pad_do_activate_pull (GstPad * pad, gboolean active)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
GstPad *other;
|
||||||
|
|
||||||
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
|
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK)
|
||||||
GstPad *peer = gst_pad_get_peer (pad);
|
other = gst_pad_get_peer (pad);
|
||||||
|
else
|
||||||
|
other = gst_proxy_pad_get_internal (pad);
|
||||||
|
|
||||||
if (peer) {
|
if (G_LIKELY (other)) {
|
||||||
ret = gst_pad_activate_pull (peer, active);
|
ret = gst_pad_activate_pull (other, active);
|
||||||
gst_object_unref (peer);
|
gst_object_unref (other);
|
||||||
} else {
|
} else
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
|
||||||
|
|
||||||
if (internal) {
|
|
||||||
ret = gst_pad_activate_pull (internal, active);
|
|
||||||
gst_object_unref (internal);
|
|
||||||
} else {
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -680,44 +661,55 @@ gst_ghost_pad_do_activate_pull (GstPad * pad, gboolean active)
|
||||||
static GstPadLinkReturn
|
static GstPadLinkReturn
|
||||||
gst_ghost_pad_do_link (GstPad * pad, GstPad * peer)
|
gst_ghost_pad_do_link (GstPad * pad, GstPad * peer)
|
||||||
{
|
{
|
||||||
GstPad *internal, *target;
|
GstPadLinkReturn ret;
|
||||||
GstPadLinkReturn ret = GST_PAD_LINK_OK;
|
GstPad *internal;
|
||||||
|
|
||||||
target = gst_proxy_pad_get_target (pad);
|
ret = GST_PAD_LINK_OK;
|
||||||
g_return_val_if_fail (target != NULL, GST_PAD_LINK_NOSCHED);
|
|
||||||
|
|
||||||
internal = gst_proxy_pad_get_internal (pad);
|
internal = gst_proxy_pad_get_internal (pad);
|
||||||
gst_proxy_pad_set_target (internal, peer);
|
if (!gst_proxy_pad_set_target (internal, peer))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* if we are a source pad, we should call the peer link function
|
/* if we are a source pad, we should call the peer link function
|
||||||
* if the peer has one */
|
* if the peer has one */
|
||||||
if (GST_PAD_IS_SRC (pad)) {
|
if (GST_PAD_IS_SRC (pad)) {
|
||||||
if (GST_PAD_LINKFUNC (peer) && ret == GST_PAD_LINK_OK)
|
if (GST_PAD_LINKFUNC (peer))
|
||||||
ret = GST_PAD_LINKFUNC (peer) (peer, pad);
|
ret = GST_PAD_LINKFUNC (peer) (peer, pad);
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
gst_object_unref (target);
|
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
failed:
|
||||||
|
{
|
||||||
|
ret = GST_PAD_LINK_REFUSED;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ghost_pad_do_unlink (GstPad * pad)
|
gst_ghost_pad_do_unlink (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstPad *target = gst_proxy_pad_get_target (pad);
|
GstPad *target;
|
||||||
GstPad *internal = gst_proxy_pad_get_internal (pad);
|
GstPad *internal;
|
||||||
|
|
||||||
|
target = gst_proxy_pad_get_target (pad);
|
||||||
|
internal = gst_proxy_pad_get_internal (pad);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pad, "unlinking ghostpad");
|
GST_DEBUG_OBJECT (pad, "unlinking ghostpad");
|
||||||
|
|
||||||
/* The target of the internal pad is no longer valid */
|
/* The target of the internal pad is no longer valid */
|
||||||
gst_proxy_pad_set_target (internal, NULL);
|
gst_proxy_pad_set_target (internal, NULL);
|
||||||
|
|
||||||
if (target && target->unlinkfunc)
|
if (target) {
|
||||||
target->unlinkfunc (target);
|
if (GST_PAD_UNLINKFUNC (target))
|
||||||
|
GST_PAD_UNLINKFUNC (target) (target);
|
||||||
|
|
||||||
if (target)
|
|
||||||
gst_object_unref (target);
|
gst_object_unref (target);
|
||||||
|
}
|
||||||
|
|
||||||
gst_object_unref (internal);
|
gst_object_unref (internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,9 +763,9 @@ gst_ghost_pad_dispose (GObject * object)
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_PROXY_PAD_INTERNAL (internal) = NULL;
|
GST_PROXY_PAD_INTERNAL (internal) = NULL;
|
||||||
/*
|
|
||||||
disposes of the internal pad, since the ghostpad is the only possible object
|
/* disposes of the internal pad, since the ghostpad is the only possible object
|
||||||
that has a refcount on the internal pad.
|
* that has a refcount on the internal pad.
|
||||||
*/
|
*/
|
||||||
gst_object_unparent (GST_OBJECT_CAST (internal));
|
gst_object_unparent (GST_OBJECT_CAST (internal));
|
||||||
|
|
||||||
|
@ -819,7 +811,6 @@ gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir,
|
||||||
|
|
||||||
|
|
||||||
/* INTERNAL PAD */
|
/* INTERNAL PAD */
|
||||||
|
|
||||||
internal =
|
internal =
|
||||||
g_object_new (GST_TYPE_PROXY_PAD, "name", NULL,
|
g_object_new (GST_TYPE_PROXY_PAD, "name", NULL,
|
||||||
"direction", (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC, NULL);
|
"direction", (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC, NULL);
|
||||||
|
@ -840,37 +831,45 @@ gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir,
|
||||||
GST_PROXY_LOCK (ret);
|
GST_PROXY_LOCK (ret);
|
||||||
|
|
||||||
if (!gst_object_set_parent (GST_OBJECT_CAST (internal),
|
if (!gst_object_set_parent (GST_OBJECT_CAST (internal),
|
||||||
GST_OBJECT_CAST (ret))) {
|
GST_OBJECT_CAST (ret)))
|
||||||
gst_critical ("Could not set internal pad%" GST_PTR_FORMAT, internal);
|
goto parent_failed;
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/* The ghostpad is the parent of the internal pad and is the only object that
|
||||||
The ghostpad is the parent of the internal pad and is the only object that
|
* can have a refcount on the internal pad.
|
||||||
can have a refcount on the internal pad.
|
* At this point, the GstGhostPad has a refcount of 1, and the internal pad has
|
||||||
At this point, the GstGhostPad has a refcount of 1, and the internal pad has
|
* a refcount of 1.
|
||||||
a refcount of 1.
|
* When the refcount of the GstGhostPad drops to 0, the ghostpad will dispose
|
||||||
When the refcount of the GstGhostPad drops to 0, the ghostpad will dispose
|
* it's refcount on the internal pad in the dispose method by un-parenting it.
|
||||||
it's refcount on the internal pad in the dispose method by un-parenting it.
|
* This is why we don't take extra refcounts in the assignments below
|
||||||
This is why we don't take extra refcounts in the assignments below
|
|
||||||
*/
|
*/
|
||||||
GST_PROXY_PAD_INTERNAL (ret) = internal;
|
GST_PROXY_PAD_INTERNAL (ret) = internal;
|
||||||
GST_PROXY_PAD_INTERNAL (internal) = GST_PAD (ret);
|
GST_PROXY_PAD_INTERNAL (internal) = ret;
|
||||||
|
|
||||||
/* could be more general here, iterating over all writable properties...
|
/* could be more general here, iterating over all writable properties...
|
||||||
* taking the short road for now tho */
|
* taking the short road for now tho */
|
||||||
GST_GHOST_PAD (ret)->notify_id = g_signal_connect (internal, "notify::caps",
|
GST_GHOST_PAD_CAST (ret)->notify_id =
|
||||||
G_CALLBACK (on_int_notify), ret);
|
g_signal_connect (internal, "notify::caps", G_CALLBACK (on_int_notify),
|
||||||
on_int_notify (internal, NULL, GST_GHOST_PAD (ret));
|
ret);
|
||||||
|
/* call function to init values */
|
||||||
|
on_int_notify (internal, NULL, GST_GHOST_PAD_CAST (ret));
|
||||||
|
|
||||||
gst_pad_set_activatepull_function (GST_PAD (internal),
|
gst_pad_set_activatepull_function (GST_PAD (internal),
|
||||||
GST_DEBUG_FUNCPTR (gst_ghost_pad_internal_do_activate_pull));
|
GST_DEBUG_FUNCPTR (gst_ghost_pad_internal_do_activate_pull));
|
||||||
gst_pad_set_activatepush_function (GST_PAD (internal),
|
gst_pad_set_activatepush_function (GST_PAD (internal),
|
||||||
GST_DEBUG_FUNCPTR (gst_ghost_pad_internal_do_activate_push));
|
GST_DEBUG_FUNCPTR (gst_ghost_pad_internal_do_activate_push));
|
||||||
|
|
||||||
beach:
|
|
||||||
GST_PROXY_UNLOCK (ret);
|
GST_PROXY_UNLOCK (ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
parent_failed:
|
||||||
|
{
|
||||||
|
gst_critical ("Could not set internal pad %" GST_PTR_FORMAT, internal);
|
||||||
|
GST_PROXY_UNLOCK (ret);
|
||||||
|
gst_object_unref (ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -979,13 +978,12 @@ set_target_failed:
|
||||||
* @templ: the #GstPadTemplate to create the ghostpad from.
|
* @templ: the #GstPadTemplate to create the ghostpad from.
|
||||||
*
|
*
|
||||||
* Create a new ghostpad based on @templ, without setting a target. The
|
* Create a new ghostpad based on @templ, without setting a target. The
|
||||||
* direction will be taken from @templ.
|
* direction will be taken from the @templ.
|
||||||
*
|
*
|
||||||
* Returns: a new #GstPad, or NULL in case of an error.
|
* Returns: a new #GstPad, or NULL in case of an error.
|
||||||
*
|
*
|
||||||
* Since: 0.10.10
|
* Since: 0.10.10
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GstPad *
|
GstPad *
|
||||||
gst_ghost_pad_new_no_target_from_template (const gchar * name,
|
gst_ghost_pad_new_no_target_from_template (const gchar * name,
|
||||||
GstPadTemplate * templ)
|
GstPadTemplate * templ)
|
||||||
|
@ -1034,11 +1032,12 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
|
||||||
GstPad *oldtarget;
|
GstPad *oldtarget;
|
||||||
GstObject *parent;
|
GstObject *parent;
|
||||||
gboolean result;
|
gboolean result;
|
||||||
|
GstPadLinkReturn lret;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
|
g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
|
||||||
|
|
||||||
GST_PROXY_LOCK (gpad);
|
GST_PROXY_LOCK (gpad);
|
||||||
internal = GST_PROXY_PAD_INTERNAL (GST_PAD (gpad));
|
internal = GST_PROXY_PAD_INTERNAL (GST_PAD_CAST (gpad));
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));
|
GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));
|
||||||
|
|
||||||
|
@ -1059,9 +1058,13 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
|
||||||
/* and link to internal pad if we are not unparent-ed */
|
/* and link to internal pad if we are not unparent-ed */
|
||||||
if ((parent = gst_object_get_parent (GST_OBJECT (gpad)))) {
|
if ((parent = gst_object_get_parent (GST_OBJECT (gpad)))) {
|
||||||
if (GST_PAD_IS_SRC (internal))
|
if (GST_PAD_IS_SRC (internal))
|
||||||
result = gst_pad_link (internal, newtarget);
|
lret = gst_pad_link (internal, newtarget);
|
||||||
else
|
else
|
||||||
result = gst_pad_link (newtarget, internal);
|
lret = gst_pad_link (newtarget, internal);
|
||||||
|
|
||||||
|
/* FIXME, do something with lret, possibly checking the return value and
|
||||||
|
* undoing the set_target operation if it failed */
|
||||||
|
|
||||||
gst_object_unref (parent);
|
gst_object_unref (parent);
|
||||||
} else {
|
} else {
|
||||||
/* we need to connect the internal pad once we have a parent */
|
/* we need to connect the internal pad once we have a parent */
|
||||||
|
|
|
@ -148,17 +148,26 @@ GST_START_TEST (test_remove2)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
#if 0
|
/* test if a ghost pad without a target can be linked and
|
||||||
/* test if a ghost pad without a target can be linked
|
* unlinked. An untargeted ghostpad has a default ANY caps unless there
|
||||||
* It can't because it has incompatible caps...
|
* is a padtemplate that says something else.
|
||||||
*/
|
*/
|
||||||
GST_START_TEST (test_ghost_pad_notarget)
|
GST_START_TEST (test_ghost_pads_notarget)
|
||||||
{
|
{
|
||||||
GstElement *b1, *b2, *sink;
|
GstElement *b1, *b2, *sink;
|
||||||
GstPad *srcpad, *sinkpad;
|
GstPad *srcpad, *sinkpad, *peer;
|
||||||
GstPadLinkReturn ret;
|
GstPadLinkReturn ret;
|
||||||
|
gboolean bret;
|
||||||
|
GstBus *bus;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
b1 = gst_element_factory_make ("pipeline", NULL);
|
b1 = gst_element_factory_make ("pipeline", NULL);
|
||||||
|
|
||||||
|
/* make sure all messages are discarded */
|
||||||
|
bus = gst_pipeline_get_bus (GST_PIPELINE (b1));
|
||||||
|
gst_bus_set_flushing (bus, TRUE);
|
||||||
|
gst_object_unref (bus);
|
||||||
|
|
||||||
b2 = gst_element_factory_make ("bin", NULL);
|
b2 = gst_element_factory_make ("bin", NULL);
|
||||||
sink = gst_element_factory_make ("fakesink", NULL);
|
sink = gst_element_factory_make ("fakesink", NULL);
|
||||||
|
|
||||||
|
@ -172,10 +181,33 @@ GST_START_TEST (test_ghost_pad_notarget)
|
||||||
|
|
||||||
ret = gst_pad_link (srcpad, sinkpad);
|
ret = gst_pad_link (srcpad, sinkpad);
|
||||||
fail_unless (ret == GST_PAD_LINK_OK);
|
fail_unless (ret == GST_PAD_LINK_OK);
|
||||||
|
|
||||||
|
/* check if the peers are ok */
|
||||||
|
peer = gst_pad_get_peer (srcpad);
|
||||||
|
fail_unless (peer == sinkpad);
|
||||||
|
gst_object_unref (peer);
|
||||||
|
|
||||||
|
peer = gst_pad_get_peer (sinkpad);
|
||||||
|
fail_unless (peer == srcpad);
|
||||||
|
gst_object_unref (peer);
|
||||||
|
|
||||||
|
/* check caps, untargetted pad should return ANY or the padtemplate caps
|
||||||
|
* when it was created from a template */
|
||||||
|
caps = gst_pad_get_caps (srcpad);
|
||||||
|
fail_unless (gst_caps_is_any (caps));
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
/* unlink */
|
||||||
|
bret = gst_pad_unlink (srcpad, sinkpad);
|
||||||
|
fail_unless (bret == TRUE);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
gst_object_unref (srcpad);
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
gst_object_unref (b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* test if linking fails over different bins using a pipeline
|
/* test if linking fails over different bins using a pipeline
|
||||||
* like this:
|
* like this:
|
||||||
|
@ -225,6 +257,10 @@ GST_START_TEST (test_link)
|
||||||
gst_element_set_state (b1, GST_STATE_READY);
|
gst_element_set_state (b1, GST_STATE_READY);
|
||||||
gst_element_set_state (b1, GST_STATE_NULL);
|
gst_element_set_state (b1, GST_STATE_NULL);
|
||||||
ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
|
ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
|
||||||
|
|
||||||
|
gst_object_unref (srcpad);
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
gst_object_unref (b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -345,8 +381,8 @@ GST_START_TEST (test_ghost_pads_bin)
|
||||||
GstBin *sinkbin;
|
GstBin *sinkbin;
|
||||||
GstElement *src;
|
GstElement *src;
|
||||||
GstElement *sink;
|
GstElement *sink;
|
||||||
GstPad *srcghost;
|
GstPad *srcpad, *srcghost, *target;
|
||||||
GstPad *sinkghost;
|
GstPad *sinkpad, *sinkghost;
|
||||||
|
|
||||||
pipeline = GST_BIN (gst_pipeline_new ("pipe"));
|
pipeline = GST_BIN (gst_pipeline_new ("pipe"));
|
||||||
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
|
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
|
||||||
|
@ -361,27 +397,35 @@ GST_START_TEST (test_ghost_pads_bin)
|
||||||
|
|
||||||
src = gst_element_factory_make ("fakesrc", "src");
|
src = gst_element_factory_make ("fakesrc", "src");
|
||||||
gst_bin_add (srcbin, src);
|
gst_bin_add (srcbin, src);
|
||||||
srcghost = gst_ghost_pad_new ("src", gst_element_get_pad (src, "src"));
|
srcpad = gst_element_get_pad (src, "src");
|
||||||
|
srcghost = gst_ghost_pad_new ("src", srcpad);
|
||||||
|
gst_object_unref (srcpad);
|
||||||
gst_element_add_pad (GST_ELEMENT (srcbin), srcghost);
|
gst_element_add_pad (GST_ELEMENT (srcbin), srcghost);
|
||||||
|
|
||||||
sink = gst_element_factory_make ("fakesink", "sink");
|
sink = gst_element_factory_make ("fakesink", "sink");
|
||||||
gst_bin_add (sinkbin, sink);
|
gst_bin_add (sinkbin, sink);
|
||||||
sinkghost = gst_ghost_pad_new ("sink", gst_element_get_pad (sink, "sink"));
|
sinkpad = gst_element_get_pad (sink, "sink");
|
||||||
|
sinkghost = gst_ghost_pad_new ("sink", sinkpad);
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
gst_element_add_pad (GST_ELEMENT (sinkbin), sinkghost);
|
gst_element_add_pad (GST_ELEMENT (sinkbin), sinkghost);
|
||||||
|
|
||||||
gst_element_link (GST_ELEMENT (srcbin), GST_ELEMENT (sinkbin));
|
gst_element_link (GST_ELEMENT (srcbin), GST_ELEMENT (sinkbin));
|
||||||
|
|
||||||
fail_unless (GST_PAD_PEER (srcghost) != NULL);
|
fail_unless (GST_PAD_PEER (srcghost) != NULL);
|
||||||
fail_unless (GST_PAD_PEER (sinkghost) != NULL);
|
fail_unless (GST_PAD_PEER (sinkghost) != NULL);
|
||||||
fail_unless (GST_PAD_PEER (gst_ghost_pad_get_target (GST_GHOST_PAD
|
target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcghost));
|
||||||
(srcghost))) != NULL);
|
fail_unless (GST_PAD_PEER (target) != NULL);
|
||||||
fail_unless (GST_PAD_PEER (gst_ghost_pad_get_target (GST_GHOST_PAD
|
gst_object_unref (target);
|
||||||
(sinkghost))) != NULL);
|
target = gst_ghost_pad_get_target (GST_GHOST_PAD (sinkghost));
|
||||||
|
fail_unless (GST_PAD_PEER (target) != NULL);
|
||||||
|
gst_object_unref (target);
|
||||||
|
|
||||||
/* flush the message, dropping the b1 refcount to 1 */
|
/* flush the message, dropping the b1 refcount to 1 */
|
||||||
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
|
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
|
||||||
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
|
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
|
||||||
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
|
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
|
||||||
|
|
||||||
|
gst_object_unref (pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -437,6 +481,9 @@ GST_START_TEST (test_ghost_pads_block)
|
||||||
|
|
||||||
g_mutex_free (block_data.mutex);
|
g_mutex_free (block_data.mutex);
|
||||||
g_cond_free (block_data.cond);
|
g_cond_free (block_data.cond);
|
||||||
|
|
||||||
|
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
|
||||||
|
gst_object_unref (pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -475,6 +522,9 @@ GST_START_TEST (test_ghost_pads_probes)
|
||||||
|
|
||||||
g_mutex_free (block_data.mutex);
|
g_mutex_free (block_data.mutex);
|
||||||
g_cond_free (block_data.cond);
|
g_cond_free (block_data.cond);
|
||||||
|
|
||||||
|
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
|
||||||
|
gst_object_unref (pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -569,7 +619,7 @@ gst_ghost_pad_suite (void)
|
||||||
tcase_add_test (tc_chain, test_link);
|
tcase_add_test (tc_chain, test_link);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads);
|
tcase_add_test (tc_chain, test_ghost_pads);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_bin);
|
tcase_add_test (tc_chain, test_ghost_pads_bin);
|
||||||
/* tcase_add_test (tc_chain, test_ghost_pad_notarget); */
|
tcase_add_test (tc_chain, test_ghost_pads_notarget);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_block);
|
tcase_add_test (tc_chain, test_ghost_pads_block);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_probes);
|
tcase_add_test (tc_chain, test_ghost_pads_probes);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_new_from_template);
|
tcase_add_test (tc_chain, test_ghost_pads_new_from_template);
|
||||||
|
|
Loading…
Reference in a new issue