Index: docs/design/part-gstghostpad.txt
===================================================================
RCS file: /cvs/gstreamer/gstreamer/docs/design/part-gstghostpad.txt,v
retrieving revision 1.5
diff -u -r1.5 part-gstghostpad.txt
--- docs/design/part-gstghostpad.txt	22 Nov 2005 11:48:57 -0000	1.5
+++ docs/design/part-gstghostpad.txt	18 Jul 2006 14:59:16 -0000
@@ -11,23 +11,25 @@
   - target of Ghostpad must be changeable
 
 
-* a GhostPad is implemented using a smaller GstProxyPad class:
+* a GhostPad is implemented using a private GstProxyPad class:
 
 
    GstProxyPad
    (------------------)
    | GstPad           |
    |------------------|
-   | GstPad *target   |
+   | GstPad *target   |   /* the pad being proxyed */
+   |------------------|
+   | GstPad *internal |   /* The neighbour GstProxyPad of opposite direction */
    (------------------)
 
 
    GstGhostPad
-   (------------------)   -\
-   | GstPad           |    |
-   |------------------|     > GstProxyPad
-   | GstPad *target   |    |
-   |------------------|   -/
+   (------------------)
+   | GstPad           |
+   |------------------|
+   | GstPad *target   |
+   |------------------|
    | GstPad *internal |
    (------------------)
 
@@ -36,30 +38,6 @@
   is modified.
 
 
-* Creating a ghostpad with a target:
-
-   gst_ghost_pad_new (char *name, GstPad *target)
-
-   1) create new GstGhostPad X
-   2) X name set to @name
-   3) X direction is the same as the target
-   4) the target is set to @target
-   5) internal is NULL
-   6) link/unlink and activate functions are set up
-      on GstGhostPad.
-
-
-                                      (--------------
-	(- X --------)                |
-	|            |                |------)
-	| target *------------------> | sink |
-	|------------|                |------)
-        | internal *---->//           (--------------
-	(------------)
-
-   - Automatically takes same direction as target.
-   - target is filled in automatically.
-
 
 * Creating a ghostpad without a target
 
@@ -68,235 +46,73 @@
    1) create new GstGhostPad X
    2) X name set to @name
    3) X direction is @dir
-   4) internal is NULL
-   5) link/unlink and activate functions are set up
-      on GstGhostPad.
-
-
-	(- X --------)
-	|            |
-	| target *------>//
-	|------------|
-        | internal *---->//
-	(------------)
+   4) a new GstProxyPad pad (Y) is created without a target
+   5) the internal of X is set to Y (X becomes parent of Y)
+   6) the internal of Y is set to X
+   7) link/unlink and activate functions are set up
+      on GstGhostPad and internal pad.
 
+   - these are the minimum steps when creating a ghostpad.
    - allows for setting the target later
 
 
-* Setting target on an untargetted unlinked ghostpad
-
-   gst_ghost_pad_set_target (char *name, GstPad *newtarget)
-
-	(- X --------)
-	|            |
-	| target *------>//
-	|------------|
-        | internal *---->//
-	(------------)
 
-   1) assert direction of newtarget == X direction
-   2) target is set to newtarget
 
-                                (--------
-        (- X --------)          |
-        |            |          |------)
-        | target *------------->| sink |
-        |------------|          |------)
-        | internal *--->//      (--------
-        (------------)
 
+* Creating a ghostpad with a target:
 
-* Setting target on an targetted unlinked ghostpad
-
-   gst_ghost_pad_set_target (char *name, GstPad *newtarget)
-
-                                (--------
-        (- X --------)          |
-        |            |          |------)
-        | target *------------->| sink |
-        |------------|          |------)
-        | internal *--->//      (--------
-        (------------)
-
-   1) assert direction of newtarget == X direction
-   2) target is set to newtarget
+   gst_ghost_pad_new (char *name, GstPad *target)
 
-                                (--------
-        (- X --------)          |
-        |            |          |------)
-        | target *------------->| sink |
-        |------------|          |------)
-        | internal *--->//      (--------
-        (------------)
+   1) create new GstGhostPad X
+   2) X name set to @name
+   3) X direction is the same as the target
+   4) a new GstProxyPad pad (Y) is created without a target and with
+      a direction opposite to the direction of the target.
+   5) the internal of X is set to Y (X becomes parent of Y)
+   6) the internal of Y is set to X
+   7) link/unlink and activate functions are set up
+      on GstGhostPad and the internal pad.
+   8) the target of X is set to @target
+   9) Y is linked to @target
+ 
+   - Automatically takes same direction as target.
+   - target is filled in automatically.
 
 
-* Linking a pad to an untargetted ghostpad:
 
-  gst_pad_link (src, X)
 
 
-	          (- X --------)
-	          |            |
-	          | target *------>//
-	          |------------|
-                  | internal *---->//
-	          (------------)
-     -------)
-            |
-      (-----|
-      | src |
-      (-----|
-     -------)
+* Setting target on an untargetted ghostpad
 
+   gst_ghost_pad_set_target (char *name, GstPad *newtarget)
 
-    1) link function is called
-      a) new GstProxyPad Y is created
-      b) Y direction is same as peer
-      c) Y target is set to peer
-      d) X internal pad is set to Y (X is parent of Y)
-      e) Y is activated in the same mode as X
-      f) core makes link from src to X
-
-
-                         (- X --------)
-                         |            |
-                         | target *----->//
-                        >|------------|
-       (real pad link) / | internal * |
-                      /  (----------|-)
-                     /              |
-          -------)  /               V
-                 | /          (- Y ------)
-           (-----|/           |          |
-           | src |<-------------* target |
-           (-----|            (----------)
-          -------)
-
-
-* Linking a pad to a targetted ghostpad:
-
-    gst_pad_link (src, X)
-
-                                              (--------
-                      (- X --------)          |
-                      |            |          |------)
-                      | target *------------->| sink |
-                      |------------|          |------)
-                      | internal *--->//      (--------
-                      (------------)
-     -------)
-            |
-      (-----|
-      | src |
-      (-----|
-     -------)
+   1) assert direction of newtarget == X direction
+   2) target of X is set to newtarget
+   3) internal pad Y is linked to newtarget
 
 
-    1) link function is called
-      a) new GstProxyPad Y is created
-      b) Y direction is same as peer
-      c) Y target is set to peer
-      d) X internal pad is set to Y (X is parent of Y)
-      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 --------)          |
-                         |            |          |------)
-                         | target *------------->| sink |
-                        >|------------|         >|------)
-       (real pad link) / | internal * |        / (--------
-                      /  (----------|-)       /
-                     /              |        /
-          -------)  /               V       / (real pad link)
-		 | /          (- Y ------) /
-           (-----|/           |          |/
-           | src |<-------------* target |
-           (-----|            (----------)
-          -------)
 
 
-* Setting target on untargetted linked ghostpad:
+* Setting target on an targetted ghostpad
 
    gst_ghost_pad_set_target (char *name, GstPad *newtarget)
 
-
-                         (- X --------)
-                         |            |
-                         | target *----->//
-                        >|------------|
-       (real pad link) / | internal * |
-                      /  (----------|-)
-                     /              |
-          -------)  /               V
-		 | /          (- Y ------)
-           (-----|/           |          |
-           | src |<-------------* target |
-           (-----|            (----------)
-          -------)
-
    1) assert direction of newtarget == X direction
-   2) X target is set to newtarget
-   3) Y (X internal) is linked to newtarget
+   2) unlink internal pad Y and oldtarget
+   3) target is set to newtarget
+   4) internal pad Y is linked to newtarget
 
 
-                                                 (--------
-                         (- X --------)          |
-                         |            |          |------)
-                         | target *------------->| sink |
-                        >|------------|         >|------)
-       (real pad link) / | internal * |        / (--------
-                      /  (----------|-)       /
-                     /              |        /
-          -------)  /               V       / (real pad link)
-		 | /          (- Y ------) /
-           (-----|/           |          |/
-           | src |<-------------* target |
-           (-----|            (----------)
-          -------)
 
 
-* Setting target on targetted linked ghostpad:
+* Linking a pad to a ghostpad:
 
-   gst_ghost_pad_set_target (char *name, GstPad *newtarget)
+  gst_pad_link (src, X)
 
 
-                                                 (--------
-                         (- X --------)          |
-                         |            |          |------)
-                         | target *------------->| sink |
-                        >|------------|         >|------)
-       (real pad link) / | internal * |        / (--------
-                      /  (----------|-)       /
-                     /              |        /
-          -------)  /               V       / (real pad link)
-		 | /          (- Y ------) /
-           (-----|/           |          |/
-           | src |<-------------* target |
-           (-----|            (----------)
-          -------)
+    1) link function is called
+      a) target of internal pad Y is set to src
 
-   1) assert direction of newtarget == X direction
-   2) Y and X target are unlinked
-   2) X target is set to newtarget
-   3) Y (X internal) is linked to newtarget
-
-
-                                                 (--------
-                         (- X --------)          |
-                         |            |          |------)
-                         | target *------------->| sink |
-                        >|------------|         >|------)
-       (real pad link) / | internal * |        / (--------
-                      /  (----------|-)       /
-                     /              |        /
-          -------)  /               V       / (real pad link)
-		 | /          (- Y ------) /
-           (-----|/           |          |/
-           | src |<-------------* target |
-           (-----|            (----------)
-          -------)
 
 
 Activation
@@ -329,27 +145,23 @@
 does not have a live source, all of the pads will end up activated at
 the end. There are 4 possible activation modes:
 
-1) AD and ab in PUSH, cd and CD in PUSH
-2) AD and ab in PUSH, cd and CD in PULL
-3) AD and ab in PULL, cd and CD in PUSH
-4) AD and ab in PULL, cd and CD in PULL
+1) AB and ab in PUSH, cd and CD in PUSH
+2) AB and ab in PUSH, cd and CD in PULL
+3) AB and ab in PULL, cd and CD in PUSH
+4) AB and ab in PULL, cd and CD in PULL
+
 
 When activating (1), the state change algorithm will first visit the
 parent of D and activate D in push mode. Then it visits the bin. The bin
-will first change the state of its child before activating its pads.
-That means c will be activated in push mode. [*] At this point, d and C
-should also be active in push mode, because it could be that activating
-c in push mode starts a thread, which starts pushing to pads which
-aren't ready yet. Then b is activated in push mode. Then, the bin
-activates C in push mode, which should already be in push mode, so
-nothing is done. It then activates B in push mode, which activates b in
-push mode, but it's already there, then activates a in push mode as
-well. The order of activating a and b does not matter in this case.
+will first activate it's srcpads before changing the state of it's child,
+and then activate it's sinkpads. This means C will be activated in push mode.
+Then the child's scrpad (c) and sinkpad (b) are
+activated in that order. Finally the bin activates it's sinkpads, which in
+this case is the ghostpad B which will also activate it's internal pad (a).
+The order of activating a and b does not matter in this case.
 Then, finally, the state change algorithm moves to the parent of A,
 activates A in push mode, and dataflow begins.
 
-[*] Not yet implemented.
-
 Activation mode (2) is implausible, so we can ignore it for now. That
 leaves us with the rest.
 
