aboutsummaryrefslogtreecommitdiff
path: root/doc/misc/devdoc.html
blob: 0f79eb77728d6854c2e81241516c216e552149bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>PDP Developer Documentation</title>
  </head>

  <body>
	<p> FIXME: This is probably a bit out of date.


    <h1>PDP Developer Documentation</h1>

    <h2>Introduction</h2>

    <p>There is not yet much developer information, partly because pdp is not that big and since the goals are
      not completely clear yet, a lot will probably change on the inside in the future. I believe it is
      not too hard to figure out how it works, once you get started somewhere. This document is a minimalistic 
      attempt to provide that starting point.  For full prototypes see the header files. I suggest you have a look at the pdp_base base class, and some simple
      modules: pdp_add, pdp_noise and pdp_gain for examples.

    <h2> PDP architecture </h2>
    <p> Architecture is a big word, but pdp is organized as modules. A packet pool module (a reuse pool memory manager), 
    a packet class, a processing queue module, a high level type conversion module, an image packet class, and some
    low level modules for image type conversion, image resampling and all sorts of other image processing. Besides that
    there are 2 extension libraries: pdp_scaf, a cellular automata extension and pdp_opengl, a 3d rendering extension.
    These are separate because of portability issues. The different pdp_* externs in the main pdp library use the 
    core modules' functionality to minimize code duplication. I'm relatively happy with how it fits together,
    but some things need to change for future plans. Most objects are written in the object oriented c style of pd.
    To prevent namespace conflicts, (almost) all routines start with the pdp_ prefix. The second name is the name of the
    object or module they belong to. The first argument is always a pointer to an object or an integer (for packets).

    
    <h2> PD ties </h2>
    <p> PDP is written as an extension for PD. One of the goals of pdp is to evolve to a separate library that can
      be reused in other software. The architecture will be split into two parts. A pd-independent part (the packet classes,
      the packet pool, the type conversion system and the forth system) and a part with pd specific stuff (the process queue and interfaces to the
      pd system like the base classes and the pd communication protocol). In order to do this the packet class will probably
      evolve to a proper object model, supporting run time attribute binding (inspired by the python object model).

    <p>There are some things that put a stamp on the current pdp design. Most importantly pd's processor object model and
      communication protocol. (i.e. the fact that pd only supports unidirectional messaging creates the awkward concept
      of a "passing packet" to eliminate excessive data copying.)

    <p> In pd, the pdp messaging protocol is implemented as pd messages. The protocol is however 3 phase. 
      With a read only register phase, a read/write register phase and a process phase. This functionality
      is part of the base class or the forth processor object. The dpd protocol is entirely different, 
      and is used in the opengl library. It is
      not based on parallel dataflow but serial context passing.

      <h2> Packets </h2>
    <p> PDP introduces a new atom: the data packet. This can contain all kinds of data. Images (16bit/8bit), cellular
      automata (1bit), matrices (real/complex float/double), opengl textures and 3d rendering contexts. Packets
      are stored in a pool to ensure fast reuse, and to enable sharing. The paradigm is centered around a
      combination of an object oriented approach and a dataflow approach. 
    <p>The methods operating on packets 
      (pdp_packet_*) are mainly for administrative purposes: memory management (construction, registering, copying)
      and getting or setting info. 
    <p>All processing is done in the pd modules. Processors can be defined using
      the forth scripting language, but this is still experimental. The forth system can be accessed
      from the guile library.
    <p> There is a central mechanism for packet type conversion. This is to facilitate the combination of different
      media types. Whenever a packet class is constructed (i.e. in an extension library), a number of conversion
      routines should be defined to convert the added type to one or some of the main pdp types.
      
      



    
    <h2>PDP API Overview</h2>

    The pdp public api contains only a single class: the packet. (The internal api has more classes, that can be used
    too if necessary, but i won't document them.) A packet is a class in pdp. The table below lists the supported methods. 
    The first argument of a call is a packet id. 

    <TABLE border = "1">
	<TR><TH colspan = "2">pdp_packet_*
	<TR><TD>new                <TD>construct a raw packet (depreciated)
	<TR><TD>new_*              <TD>construct packet of specific type/subtype/...
	<TR><TD>mark_unused        <TD>release
	<TR><TD>mark_passing       <TD>conditional release (release on first copy ro/rw)
	<TR><TD>copy_ro            <TD>readonly (shared) copy
	<TR><TD>copy_rw            <TD>private copy
	<TR><TD>clone_rw           <TD>private copy (copies only meta data, not the content)
	<TR><TD>header             <TD>get the raw header (t_pdp *)
	<TR><TD>data               <TD>get the raw data (void *)
	<TR><TD>pass_if_valid      <TD>send a packet to pd outlet, if it is valid, and mark unused
	<TR><TD>replace_if_valid   <TD>delete packet and replace with new one, if new is valid
	<TR><TD>copy_ro_or_drop    <TD>copy readonly, or don't copy if dest slot is full + send drop notify
	<TR><TD>copy_rw_or_drop    <TD>same, but private copy
	<TR><TD>get_description    <TD>retrieve type info
	<TR><TD>convert_ro         <TD>same as copy_ro, but with an automatic conversion matching a type template
	<TR><TD>convert_rw         <TD>same as convert_ro, but producing a private copy
    </TABLE>


    <p>The pool object methods. All the packets are stored in a central packet pool.

    <TABLE border = "1">
	<TR><TH colspan = "2">pdp_pool_*
	<TR><TD>collect_garbage    <TD>manually free all unused resources in packet pool
    </TABLE>

    <p>The process queue object methods. PDP supports a separate processing thread.

    <TABLE border = "1">
	<TR><TH colspan = "2"> pdp_queue_*
	<TR><TD>add                <TD>add a process method + callback
	<TR><TD>finish             <TD>wait until a specific task is done
	<TR><TD>wait               <TD>wait until processing queue is done
    </TABLE>

    <p>The control methods. General pdp control messages.

    <TABLE border = "1">
	<TR><TH colspan = "2"> pdp_control_*
	<TR><TD>notify_drop        <TD>notify that a packet has been dropped
    </TABLE>

    <p> The type mediator methods.
    <TABLE border = "1">
      <TR><TH colspan = "2"> pdp_type_* 
	<TR><TD>description_match   <TD>check if two type templates match
	<TR><TD>register_conversion <TD>register a type conversion program


</TABLE>


   <p>NOTE: it is advised to derive your module from the pdp base class defined in pdp_base.h
         instead of communicating directly with the pdp core



    <h2>pdp_base class</h2>
    If you want to write a pdp extern, you can derive it from the pdp_base class, instead of t_object.
    This class abstracts a lot of the hassle of writing ordinary (inplace) packet processors. The base
    allows you to register process callbacks. There are 3 kinds of callbacks: preproc, process and postproc.
    The preproc method is called inside the pd thread. This can be used to setup some things that can only
    be done inside the pd thread. The process method should do most of the work, and is called from the
    pdp processing thread if it is enabled, after the preproc method is finished. You can't use most
    of pd's calls in this method. The postproc method is called
    from the pd thread after the process method is finished, and can be used to send data to pd outlets. Simple
    packet processors only need the process method (packet input/output is handled by the pdp_base class).

    <h2>pdp_imageproc_* modules</h2>
    Most of the image processing code is organized as planar 16 bit signed processors. 
    This is crude and oversimplified, but it helps to keep the code size small and fast
    at the same time (platform dependent assembly code is reduced to a bare minimum). These
    routines can be used to build higher level image processing objects that are more (cache)
    efficient than an abstraction using separate pdp modules. If you plan to write your own image
    processing routines, you can use the pdp_imageproc_dispatch_ routine to support all 16bit image
    types at once (greyscale, subsampled YCrCb, multichannel planar). This requires you write the
    image processing routine as a planar (greyscale) processor using the pdp_imageproc_
    interface. (see pdp_imageproc.h)

    <h2>pdp_llconv call</h2>
    Low level image conversion routines. (operating on raw data buffers). You probably won't need this,
    since the high level type conversion (pdp_packet_convert_ro/rw) covers most of its functionality.



    <hr>
    <address><a href="mailto:tom@zwizwa.be">Tom Schouten</a></address>
<!-- Created: Mon Apr 28 15:35:12 CEST 2003 -->
<!-- hhmts start -->
Last modified: Fri Sep 19 04:52:12 CEST 2003
<!-- hhmts end -->
  </body>
</html>