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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
Orc Integration
===============
Sections
--------
- About Orc
- Fast memcpy()
- Normal Usage
- Build Process
- Testing
- Orc Limitations
About Orc
---------
Orc code can be in one of two forms: in .orc files that is converted
by orcc to C code that calls liborc functions, or C code that calls
liborc to create complex operations at runtime. The former is mostly
for functions with predetermined functionality. The latter is for
functionality that is determined at runtime, where writing .orc
functions for all combinations would be prohibitive. Orc also has
a fast memcpy and memset which are useful independently.
Fast memcpy()
-------------
*** This part is not integrated yet. ***
Orc has built-in functions orc_memcpy() and orc_memset() that work
like memcpy() and memset(). These are meant for large copies only.
A reasonable cutoff for using orc_memcpy() instead of memcpy() is
if the number of bytes is generally greater than 100. DO NOT use
orc_memcpy() if the typical is size is less than 20 bytes, especially
if the size is known at compile time, as these cases are inlined by
the compiler.
(Example: sys/ximage/ximagesink.c)
Add $(ORC_CFLAGS) to libgstximagesink_la_CFLAGS and $(ORC_LIBS) to
libgstximagesink_la_LIBADD. Then, in the source file, add:
#ifdef HAVE_ORC
#include <orc/orc.h>
#else
#define orc_memcpy(a,b,c) memcpy(a,b,c)
#endif
Then switch relevant uses of memcpy() to orc_memcpy().
The above example works whether or not Orc is enabled at compile
time.
Normal Usage
------------
The following lines are added near the top of Makefile.am for plugins
that use Orc code in .orc files (this is for the volume plugin):
ORC_BASE=volume
include $(top_srcdir)/common/orc.mk
Also add the generated source file to the plugin build:
nodist_libgstvolume_la_SOURCES = $(ORC_SOURCES)
And of course, add $(ORC_CFLAGS) to libgstvolume_la_CFLAGS, and
$(ORC_LIBS) to libgstvolume_la_LIBADD.
The value assigned to ORC_BASE does not need to be related to
the name of the plugin.
Advanced Usage
--------------
The Holy Grail of Orc usage is to programmatically generate Orc code
at runtime, have liborc compile it into binary code at runtime, and
then execute this code. Currently, the best example of this is in
Schroedinger. An example of how this would be used is audioconvert:
given an input format, channel position manipulation, dithering and
quantizing configuration, and output format, a Orc code generator
would create an OrcProgram, add the appropriate instructions to do
each step based on the configuration, and then compile the program.
Successfully compiling the program would return a function pointer
that can be called to perform the operation.
This sort of advanced usage requires structural changes to current
plugins (e.g., audioconvert) and will probably be developed
incrementally. Moreover, if such code is intended to be used without
Orc as strict build/runtime requirement, two codepaths would need to
be developed and tested. For this reason, until GStreamer requires
Orc, I think it's a good idea to restrict such advanced usage to the
cog plugin in -bad, which requires Orc.
Build Process
-------------
The goal of the build process is to make Orc non-essential for most
developers and users. This is not to say you shouldn't have Orc
installed -- without it, you will get slow backup C code, just that
people compiling GStreamer are not forced to switch from Liboil to
Orc immediately.
With Orc installed, the build process will use the Orc Compiler (orcc)
to convert each .orc file into a temporary C source (tmp-orc.c) and a
temporary header file (${name}orc.h if constructed from ${base}.orc).
The C source file is compiled and linked to the plugin, and the header
file is included by other source files in the plugin.
If 'make orc-update' is run in the source directory, the files
tmp-orc.c and ${base}orc.h are copied to ${base}orc-dist.c and
${base}orc-dist.h respectively. The -dist.[ch] files are automatically
disted via orc.mk. The -dist.[ch] files should be checked in to
git whenever the .orc source is changed and checked in. Example
workflow:
edit .orc file
... make, test, etc.
make orc-update
git add volume.orc volumeorc-dist.c volumeorc-dist.h
git commit
At 'make dist' time, all of the .orc files are compiled, and then
copied to their -dist.[ch] counterparts, and then the -dist.[ch]
files are added to the dist directory.
Without Orc installed (or --disable-orc given to configure), the
-dist.[ch] files are copied to tmp-orc.c and ${name}orc.h. When
compiled Orc disabled, DISABLE_ORC is defined in config.h, and
the C backup code is compiled. This backup code is pure C, and
does not include orc headers or require linking against liborc.
The common/orc.mk build method is limited by the inflexibility of
automake. The file tmp-orc.c must be a fixed filename, using ORC_NAME
to generate the filename does not work because it conflicts with
automake's dependency generation. Building multiple .orc files
is not possible due to this restriction.
Testing
-------
If you create another .orc file, please add it to
tests/orc/Makefile.am. This causes automatic test code to be
generated and run during 'make check'. Each function in the .orc
file is tested by comparing the results of executing the run-time
compiled code and the C backup function.
Orc Limitations
---------------
audioconvert
Orc doesn't have a mechanism for generating random numbers, which
prevents its use as-is for dithering. One way around this is to
generate suitable dithering values in one pass, then use those
values in a second Orc-based pass.
Orc doesn't handle 64-bit float, for no good reason.
Irrespective of Orc handling 64-bit float, it would be useful to
have a direct 32-bit float to 16-bit integer conversion.
audioconvert is a good candidate for programmatically generated
Orc code.
audioconvert enumerates functions in terms of big-endian vs.
little-endian. Orc's functions are "native" and "swapped".
Programmatically generating code removes the need to worry about
this.
Orc doesn't handle 24-bit samples. Fixing this is not a priority
(for ds).
videoscale
Orc doesn't handle horizontal resampling yet. The plan is to add
special sampling opcodes, for nearest, bilinear, and cubic
interpolation.
videotestsrc
Lots of code in videotestsrc needs to be rewritten to be SIMD
(and Orc) friendly, e.g., stuff that uses oil_splat_u8().
A fast low-quality random number generator in Orc would be useful
here.
volume
Many of the comments on audioconvert apply here as well.
There are a bunch of FIXMEs in here that are due to misapplied
patches.
|