Credit Andrea - correct HDR references
[goodguy/cin-manual-latex.git] / parts / Developer.tex
1 \chapter{Developer's Section}%
2 \label{cha:developer's_section}
3
4 \section{How Builds Really Work and Even More Options}
5 \label{sec:builds_really_work_more_options}
6 \index{build!more options}
7
8 This section describes how builds really work if you want to know more about making changes or understanding the process; probably only for a developer or system administrator.
9
10 Builds occur in 4 basic steps:
11
12 \begin{enumerate}[nosep]
13         \item unpack/patch source code
14         \item configure build
15         \item make build targets
16         \item installation
17 \end{enumerate}
18
19 So, an example of what happens in 4 steps for a single-user build would be as follows:
20
21 \begin{enumerate}[nosep]
22         \item unpack/patch source code: \\
23         \texttt{git clone -{}-depth 1 ``git:/{\dots}/target'' cinelerra5} \\
24         \texttt{./autogen.sh}
25         \item configure build:\\
26         \texttt{./configure --with-single-user}
27         \item make build targets:\\
28         \texttt{make 2 > \&1 | tee log}
29         \item installation:\\
30         \texttt{make install}
31 \end{enumerate}
32
33 A lot of things can be tweaked to change the results. Mostly these changes are parameters to the configure step, which can change important build related items, like the application name, or where and what the target system directories should be. This makes it possible to have several versions at the same time on the same computer if needed. To see what it is that the makefiles use to build \CGG{}, look at the resulting top-level global\_config file which is created by the ./configure step.
34
35 Building \CGG{} requires many thirdparty libraries, and it is recommended that you use the static build version included in the git repo. Some of them are patched, and fix significant bugs. It is important to note that because system installation historically has been with as many shared objects as possible, the defaults are that any system library detected during configuration setup will be used, when the package is built \textit{-{}-without-single-user}, which is the default build. To build with static thirdparty libraries for system install to the system /usr area, use:
36
37 \hspace{2em}\texttt{.configure -{}-enable-static-build --prefix=/usr}
38
39 Sometimes, additional package parameters and variables are needed during thirdparty builds. These optional values occur before and after the \textit{configure} and \textit{make} commands during a build. A presentation of the format of the package qualified variable names and how they appear in the build procedure are:
40
41 \hspace{2em}
42 \begin{tabular}{@{}ll}
43         pkg.cfg\_vars & prepended to configure\\
44         pkg.cfg\_params & appended to configure\\
45         pkg.mak\_vars & prepended to make\\
46         pkg.mak\_params & appended to make\\
47     pkg.cflags & added as CFLAGS+=\$(cflags) to pkg.vars\\
48         pkg.cppflags & added as CPPFLAGS+=\$(cppflags) to pkg.vars\\
49 \end{tabular}
50
51 These steps are done for EACH of the packages in the thirdparty build:
52
53 \hspace{2em}\texttt{<pkg.cfg\_vars> ./configure <pkg.cfg\_params>}
54
55 \hspace{2em}\texttt{<pkg.mak\_vars> make <pkg.mak\_params>}
56
57 The thirdparty Makefile has a set of default vars and params used to build each of the needed thirdparty packages, but you can specify new or overriding values for these Makefile substitutions. These thirdparty build config changes are specified in the top-level file: \textit{cin\_config}. By using this file, you can save the configuration changes made for the current build to use the next time you do a new build. For example, to add an include file path to the giflib build, add this line to \textit{cin\_config}:
58
59 \hspace{2em}\texttt{giflib.cflags := -I/usr/local/include/giflib5}
60
61 To have a param/var change apply to all thirdparty builds, use:
62
63 \hspace{2em}\texttt{CFG\_VARS, CFG\_PARAMS, MAK\_VARS, MAK\_PARAMS}
64
65 CFLAGS, CXXFLAGS and LDFLAGS are forwarded to the thirdparty build environment via:
66
67 \hspace{2em}\texttt{CFLAGS=-ggdb ./configure -{}-with-single-user}
68
69 However, there is no guarantee that the thirdparty build will honor the environmental flags.
70
71 Finally, there are build controls, which enable/disable and set build features.
72
73 A few of the more useful ./configure -{}-parameters are:
74
75 \begin{tabular}{ll}
76         -{}-with-jobs=n & where n=number of build jobs; defaults to 1.5*cpus+2\\
77         -{}-enable-static-build & build all 3rd party libs; defaults to yes if single-user, else no\\
78         -{}-with-single-user& build installs to <build\_path>/bin; no system installation\\
79 \end{tabular}
80
81
82 The ./configure command builds \textit{global\_config}. The global\_config is read by the thirdparty/Makefile to create the recipes and definitions used by the thirdparty build.
83
84 There are a lot of different options.  Thirdparty library build control is available in the configure step of the build.  Thirdparty libraries are built on a demand basis.  So if you use:
85
86 \begin{tabular}{l p{11cm}}
87   -{}-enable-libname=auto & the static-build enable, or the lack of a system library causes a build\\
88   -{}-enable-libname=yes  &  this forces the thirdparty build\\
89   -{}-enable-libname=no   &  this forces no thirdparty build\\
90 \end{tabular}
91
92 FFmpeg is a \textit{strongly connected} component in the build linkage and widely influences the \CGG{} library demands.  It is possible to make small additions to the ffmpeg configuration step using the environment variable \texttt{FFMPEG\_EXTRA\_CFG}.  For example, to eliminate the use of libvdpau (an nvidia support library) in the ffmpeg configuration step after you have determined that it is causing an error, use:
93
94 \begin{itemize}[label={},nosep]
95         \item \texttt{make clean}
96         \item \texttt{autogen.sh}
97         \item \texttt{export FFMPEG\_EXTRA\_CFG=" -{}-disable-vdpau"} 
98         \item \texttt{./configure} {\dots}
99 \end{itemize}
100
101 \section{Experimental Builds}
102 \label{sec:experimental_builds}
103 \index{build!experimental}
104
105 The main compilation we have seen leads to building \CGG{} with its own internal ffmpeg, which includes its stability and feature patches. Normally ffmpeg is updated to version x.1 of each release. The reasons why it is best to use thirdparty with their static versions of the libraries and ffmpeg are explained in detail in \nameref{sec:latest_libraries} and in \nameref{sub:unbundled_builds}.
106
107 You can still compile \CGG{} with ffmpeg-git to enjoy the latest version. This build may lead to feature variation and less stability, but in most cases will work perfectly fine.
108 You have to supply the actual URL location of the ffmpeg git as you can see in this example \texttt{bld.sh} script:
109
110 \begin{lstlisting}[numbers=none]
111         #!/bin/bash
112         ./autogen.sh
113         ./configure --with-single-user --with-booby --with-git-ffmpeg=https://git.ffmpeg.org/ffmpeg.git
114         make && make install ) 2>1 | tee log
115         mv Makefile Makefile.cfg
116         cp Makefile.devel Makefile
117 \end{lstlisting}
118
119 Since the procedure for obtaining the latest ffmpeg version is not always kept up-to-date and the line numbers will always change, you may have to create some patch first. Generally those line numbers are only updated by a developer when a new stable version with worthwhile features is actually included in the \CGG{} build. FFmpeg is constantly changing and many times the git version is not as stable as desired.
120
121 Finally, it is possible to compile \CGG{} so that it uses ffmpeg which is already installed on the system. This build takes less time to compile and may increase performance in both rendering and timeline manipulation. Again, there may be variations in functionality and less stability.
122 Getting a build to work in a system environment is not easy. If you have already installed libraries which are normally in the thirdparty build, getting them to be recognized means you have to install the devel version
123 so the header files which match the library interfaces exist. If you want to build using only the thirdparty libraries installed in your system, just include \texttt{-–without-thirdparty} to your configure script. For example:
124
125 \begin{lstlisting}[numbers=none]
126 ./confgure --with-single-user --disable-static-build --without-thirdparty --without-libdpx
127 \end{lstlisting}
128
129 The library, libdpx, is just such an example of lost functionality: this build of \CGG{} will not be able to use the DPX format.
130
131 \section{Configuration Features}
132 \label{sec:configuration_features}
133 \index{build!configuration}
134
135 A listing of the current configuration features as of January 11, 2020:
136
137 \begingroup
138     \fontsize{10pt}{12pt}\selectfont
139 \begin{verbatim}
140
141 `configure' configures \CGG{} to adapt to many kinds of systems.
142
143 Usage: ./configure [OPTION]... [VAR=VALUE]...
144
145 To assign environment variables (e.g., CC, CFLAGS...), specify them as
146 VAR=VALUE.  See below for descriptions of some of the useful variables.
147
148 Defaults for the options are specified in brackets.
149
150 Configuration:
151   -h, --help              display this help and exit
152       --help=short        display options specific to this package
153       --help=recursive    display the short help of all the included packages
154   -V, --version           display version information and exit
155   -q, --quiet, --silent   do not print `checking ...' messages
156       --cache-file=FILE   cache test results in FILE [disabled]
157   -C, --config-cache      alias for `--cache-file=config.cache'
158   -n, --no-create         do not create output files
159       --srcdir=DIR        find the sources in DIR [configure dir or `..']
160
161 Installation directories:
162   --prefix=PREFIX         install architecture-independent files in PREFIX
163                           [/usr/local]
164   --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
165                           [PREFIX]
166
167 By default, `make install' will install all the files in
168 `/usr/local/bin', `/usr/local/lib' etc.  You can specify
169 an installation prefix other than `/usr/local' using `--prefix',
170 for instance `--prefix=$HOME'.
171
172 For better control, use the options below.
173
174 Fine tuning of the installation directories:
175   --bindir=DIR            user executables [EPREFIX/bin]
176   --sbindir=DIR           system admin executables [EPREFIX/sbin]
177   --libexecdir=DIR        program executables [EPREFIX/libexec]
178   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
179   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
180   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
181   --libdir=DIR            object code libraries [EPREFIX/lib]
182   --includedir=DIR        C header files [PREFIX/include]
183   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
184   --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
185   --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
186   --infodir=DIR           info documentation [DATAROOTDIR/info]
187   --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
188   --mandir=DIR            man documentation [DATAROOTDIR/man]
189   --docdir=DIR            documentation root [DATAROOTDIR/doc/cinelerra]
190   --htmldir=DIR           html documentation [DOCDIR]
191   --dvidir=DIR            dvi documentation [DOCDIR]
192   --pdfdir=DIR            pdf documentation [DOCDIR]
193   --psdir=DIR             ps documentation [DOCDIR]
194
195 Program names:
196   --program-prefix=PREFIX            prepend PREFIX to installed program names
197   --program-suffix=SUFFIX            append SUFFIX to installed program names
198   --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
199
200 Optional Features:
201   --disable-option-checking  ignore unrecognized --enable/--with options
202   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
203   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
204   --enable-silent-rules   less verbose build output (undo: "make V=1")
205   --disable-silent-rules  verbose build output (undo: "make V=0")
206   --enable-dependency-tracking
207                           do not reject slow dependency extractors
208   --disable-dependency-tracking
209                           speeds up one-time build
210   --enable-a52dec         build a52dec (yes)
211   --enable-djbfft         build djbfft (yes)
212   --enable-audiofile      build audiofile (no)
213   --enable-encore         build encore (no)
214   --enable-esound         build esound (no)
215   --enable-ffmpeg         build ffmpeg (yes)
216   --enable-fftw           build fftw (auto)
217   --enable-flac           build flac (auto)
218   --enable-giflib         build giflib (yes)
219   --enable-ilmbase        build ilmbase (auto)
220   --enable-lame           build lame (auto)
221   --enable-libavc1394     build libavc1394 (auto)
222   --enable-libraw1394     build libraw1394 (auto)
223   --enable-libiec61883    build libiec61883 (auto)
224   --enable-libdv          build libdv (auto)
225   --enable-libjpeg        build libjpeg (auto)
226   --enable-opus           build opus (auto)
227   --enable-openjpeg       build openjpeg (auto)
228   --enable-libogg         build libogg (auto)
229   --enable-libsndfile     build libsndfile (auto)
230   --enable-libsvtav1      build libsvtav1 (no)
231   --enable-libtheora      build libtheora (auto)
232   --enable-libuuid        build libuuid (yes)
233   --enable-libvorbis      build libvorbis (auto)
234   --enable-mjpegtools     build mjpegtools (yes)
235   --enable-openexr        build openexr (auto)
236   --enable-tiff           build tiff (auto)
237   --enable-twolame        build twolame (auto)
238   --enable-x264           build x264 (auto)
239   --enable-x265           build x265 (auto)
240   --enable-libvpx         build libvpx (auto)
241   --enable-lv2            build lv2 (auto)
242   --enable-sratom         build sratom (auto)
243   --enable-serd           build serd (auto)
244   --enable-sord           build sord (auto)
245   --enable-lilv           build lilv (auto)
246   --enable-suil           build suil (auto)
247   --enable-libaom         build libaom (auto)
248   --enable-dav1d          build dav1d (auto)
249   --enable-libwebp        build libwebp (auto)
250   --enable-ffnvcodec      build ffnvcodec (auto)
251   --enable-static-build   build static ([auto])
252   --enable-x264_hidepth   build x264 10bit ([no])
253   --enable-x265_hidepth   build x265 10bit ([no])
254
255 Optional Packages:
256   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
257   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
258   --with-jobs             parallel build jobs (auto)
259   --with-exec-name        binary executable name (cin)
260   --with-single-user      to install cin in bin (no)
261   --with-ladspa-build     build ladspa library (yes)
262   --with-lv2              lv2 library support (yes)
263   --with-cinlib           cinelerra library path (auto)
264   --with-cindat           cinelerra share path (auto)
265   --with-plugin-dir       plugin install dir (auto)
266   --with-ladspa-dir       ladspa install dir (auto)
267   --with-config-dir       .bcast config dir ($$HOME/.bcast5)
268   --with-nested-dir       nested proxy dir ($$HOME/Videos)
269   --with-browser          cin_browser path (firefox)
270   --with-git-ffmpeg       git ffmpeg using url (no)
271   --with-noelision        use noelision/libpthread (auto)
272   --with-booby            window lock trace booby trap (no)
273   --with-libzmpeg         build libzmpeg (yes)
274   --with-commercial       enable commercial capture (yes)
275   --with-thirdparty       use thirdparty build (yes)
276   --with-shuttle          shuttle device (yes)
277   --with-wintv            usb 2040:826d wintv device (yes)
278   --with-x10tv            usb 0bc7:0004 X10 remote device (yes)
279   --with-vaapi            video acceleration api (yes)
280   --with-vdpau            video decode+presentation api for unix (yes)
281   --with-nv               nvenc/nvdec ffnvcodec api (yes)
282   --with-cuda             nv cuda plugins (auto)
283   --with-clang            use clang instead of gcc/g++ (no)
284   --with-gl               use opengl (auto)
285   --with-oss              use OSS audio (auto)
286   --with-xft              use libXft (auto)
287   --with-alsa             use libasound/alsa (auto)
288   --with-firewire         use firewire (auto)
289   --with-dv               use dv (auto)
290   --with-dvb              use dvb (auto)
291   --with-video4linux2     use v4l2 (auto)
292   --with-xxf86vm          use xf86vmode (auto)
293   --with-esound           use esd (auto)
294   --with-shuttle          shuttle dev support (auto)
295   --with-shuttle_usb      use libusb-1.0 (auto)
296   --with-lv2              use lv2 (auto)
297   --with-cuda             build cuda plugins (auto)
298   --with-dl               system has libdl (auto)
299   --with-opencv           opencv=sys/sta/dyn,git/tar=url (auto)
300   --with-numa             system has libnuma (auto)
301   --with-openexr          use openexr (auto)
302   --with-onevpl           use Intel hardware oneAPI Video Processing Library (no)
303
304 Some influential environment variables:
305   CC          C compiler command
306   CFLAGS      C compiler flags
307   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
308               nonstandard directory <lib dir>
309   LIBS        libraries to pass to the linker, e.g. -l<library>
310   CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
311               you have headers in a nonstandard directory <include dir>
312   CCAS        assembler compiler command (defaults to CC)
313   CCASFLAGS   assembler compiler flags (defaults to CFLAGS)
314   CXX         C++ compiler command
315   CXXFLAGS    C++ compiler flags
316
317 Use these variables to override the choices made by `configure' or to help
318 it to find libraries and programs with nonstandard names/locations.
319
320 Report bugs to <mail@lists.cinelerra-gg.org>.
321
322 \end{verbatim}
323 \endgroup
324
325 \section{Thirdparty Parallel Build}
326 \label{sec:thirdparty_parallel_build}
327 \index{build!thirdparty}
328
329 The Makefile in the thirdparty build directory employs a set of macros used to create a build rule set of thirdparty library build dependencies.  The standard build sequence of [source, config, build] is used to prepare thirdparty products as static libraries.  Build package dependency can be specified in the Makefile std-build macro call.  These Makefile macro calls define the rules used for each thirdparty build.  The expanded rule definitions may be viewed by using:
330
331 \hspace{2em}\texttt{make -C thirdparty rules}
332
333 Individual package libraries can be rebuilt, via:
334
335 \hspace{2em}\texttt{make -C thirdparty <pkg>-clean;  make -C thirdparty <pkg>}
336
337 The rule targets create the set of thirdparty packages which are built from local source archive copies of thirdparty source code and patches, if needed.  The build rule set of dependencies allows for compiling multiple thirdparty programs simultaneously using maximum computer resources.  This parallel build speeds up the process considerably.  For example, these are full static build timings on the production build machine (full build includes building all thirdparty programs as well as all of \CGG{}):
338
339 \begin{center}
340         \begin{tabular}{@{}lcr}
341                 1 cpu & = & 61 mins\\
342                 12 cpus & = & 7.5 mins\\
343                 24 cpus & = & 2 mins\\
344         \end{tabular}
345 \end{center}
346
347 \section{Using the very latest Libraries}
348 \label{sec:latest_libraries}
349 \index{build!use latest library}
350
351 Using the most current libraries can be a challenge for some of the Operating System distros that use
352 stable compilers, assemblers, and their own libraries.  Because they are stable, they frequently do
353 not keep up with the very latest of thirdparty libraries.  Consequently, some program constructs may
354 not yet be implemented.  \CGG{} tries to maintain stability since it is better to have less features
355 and no crashes.  The goal is to make \CGG{} widely available on many platforms rather than
356 dependent on advanced tools that are not supported on some distros.
357
358 \CGG{} attempts to upgrade to the latest releases of many thirdparty libraries about every 3-4
359 months. But it is often difficult to keep some of these thirdparty libraries up to date as their
360 developers switch from tried and true standard tools to newer, less standard tools. As a result 
361 in order to build \CGG{} on 2-3 versions of any distro rather than only the most current version,
362 some thirdparty libraries can not be kept up to date and may even be to the point of no further
363 updates.  In a lot of cases, the updated releases provide little new capabilities but rather
364 are bug fixes that may not even be relevant to \CGG{}'s use.
365
366 So as a computer savvy user or a developer, if you would like to build \CGG{} with the latest
367 thirdparty releases for some of the packages here are a few suggestions based on other 
368 developer's feedback and experimentation.
369
370 \textbf{dav1d} 
371 \begin{description}[noitemsep]
372      \item Status - currently \CGG{} is staying at 0.5.1.  This is disappointing because there
373 may be speed gains in later versions that would be beneficial. However, it is usable for decoding
374 whereas libaom is a lot slower.  Unfortunately, it has no effective encoder.
375      \item Problem - 0.6 dav1d requires NASM 2.14 (and later versions of dav1d use even later versions of NASM) and uses instructions like vgf2p8affineqb,
376 not exactly an "add" instruction. It also uses meson which is not widely available on all
377 distros.  The more recent NASM requirement apparently provides for using AVX-512 
378 instructions (like vgf2p8affineqb, which is more like a whole routine than a simple instruction).
379      \item Workaround already in use by \CGG{} - a Makefile was generated to replace Meson usage
380 but has to be continuously updated for new releases. Dav1d 0.5.1 requires NASM 2.13 so at this level
381 the newer distros will work.  The availability of meson and nasm are a significant problem on
382 many systems which are still in wide use.
383      \item Your workaround - Because a request to dav1d developers to consider changes to
384 ensure their library is more widely usable does not appear to be in their future, since it works
385 for them, you can upgrade NASM to 2.14 to stay up to date.  Even then, you will have to build using meson and incorporate it into \CGG{}.
386 \end{description}
387
388 \textbf{OpenExr} 
389 \begin{description}[noitemsep]
390      \item Status - stable at 2.4.1 from February 2020.
391      \item Problem - the OpenExr tarball is not a single package but is 2 packages instead.
392      \item Workaround already in use by \CGG{} - reworked the packages so that it looks like
393 one package with 2 stubs.
394      \item Your workaround - perhaps use the same workaround.
395 \end{description}
396
397 \textbf{OpenCV}
398 \begin{description}[noitemsep]
399      \item Status - 2 different versions specific for O/S but none for Ubuntu 14, 32 or 64 bit.
400      \item Problem - There are really 2 problems here.  The first is OpenCV is not really
401 "Open" in that Surf is patented/non-free and there is no actual source available for certain
402 capabilities. The second is that cmake 3.5.1 is required for OpenCV 4.2.
403      \item Workaround already in use by \CGG{} - using 3.4.1 for older distros and 4.2 for newer.
404      \item Your workaround - upgrade cmake to 3.5.1 for upgrade to 4.2; add non-free to the
405 compile; and use binaries that you do not know what they contain since no source code to compile.
406 Look into opencv4/opencv2/core/types.hpp:711;27.
407 \end{description}
408
409 \textbf{libaom}
410 \begin{description}[noitemsep]
411      \item Status - currently at version 3.6.0 for older O/S and 3.8.0 for newer O/S.
412      \item Problem - requires cmake 3.5 at v3.6.0 and 3.7.2 for v3.8.0.
413      \item Workaround already in use by \CGG{} - modify configure.ac to switch from 3.8.0 to 3.6.0 for Ubuntu 16 and delete thirdparty/src/libaom-v3.8.0*.*.
414      \item Your workaround - upgrade on some systems to cmake 3.7.2, switch to using 3.6.0 as in last sentence, or add --libaom-enable=no to configure line when building.
415 \end{description}
416
417 \textbf{x10tv}
418 \begin{description}[noitemsep]
419      \item Status - this is the x10 TV remote control.
420      \item Problem - INPUT\_PROP\_POINTING\_STICK not defined error on older distros.
421      \item Workaround already in use by \CGG{} - leaving out of Ubuntu14, Ubuntu, Centos7.
422      \item Your workaround - look into /usr/include/linux/input-event-codes.h.
423 \end{description}
424
425 \textbf{lv2 plugins, consisting of 6 routines}
426 \begin{description}[noitemsep]
427      \item Status - currently at version 1.18.0 for lv2 and different for other 5.
428      \item Problem - the current versions use cmake but the updated versions now all use meson and \CGG{} is not set up to handle that.
429      \item Workaround already in use by \CGG{} - not upgrading at this time.
430      \item Your workaround - if you are familiar with meson, you can independently upgrade the 6 routines.
431 \end{description}
432
433 \section{Find Lock Problems with Booby Trap}
434 \label{sec:find_lock_problems_booby_trap}
435 \index{build!booby trap}
436
437 A Booby Trap is used in \CGG{} for setting a trap to catch lock problems that might have been missed. It will trap boobies only if compile by adding \textit{-{}-with-booby} on the configuration command line. This is the default if you compile using \texttt{./bld.sh} from the GIT repository. It should not interfere with normal execution.
438
439 If you have the time and inclination, enable \textit{-{}-with-booby} and send any trap output that you find. Maybe you will catch some boobies and if you do, send a snapshot of any boobies you find.
440
441 There are 2 potential traps:
442
443 \begin{itemize}[nosep]
444         \item If you try to unlock a lock when it is not locked
445         \item If you execute a drawing operation without holding the window lock
446 \end{itemize}
447
448 The trap prints the following in the controlling terminal window:
449
450 \hspace{2em} \textit{BOOBY! \qquad <backtrace>}
451
452 An example backtrace is below along with a hint below on how to analyze:
453
454 \begin{lstlisting}[numbers=none]
455 /home/cin5/bin/./cin(_Z5boobyv+0x3f) [0x557069fa9b2f] /home/cin5/bin/./cin(_ZN13BC_WindowBase9draw_lineEiiiiP9BC_Pixmap+0x3b)0x557069fb9a9b]
456 /home/cin5/bin/./cin(\_ZN10BC_ListBox11draw_borderEi+0x73)[0x557069f7dc73]
457 /home/cin5/bin/./cin(+0x9707fb) [0x557069f7e7fb]
458 /home/cin5/bin/./cin(\ZN10BC\ListBox16center\selectionEv+0x4e)[0x557069f7f2ae]
459 /home/cin5/bin/plugins/video/sketcher.plugin(_ZN17SketcherCurveList6updateEi+0x1a0)[0x7f1b8002a4c0]
460 /home/cin5/bin/plugins/video/sketcher.plugin(_ZN18SketcherCurveColor17handle_done_eventEi+0x76)[0x7f1b8002a5f6]
461 /home/cin5/bin/./cin(_ZN15BC_DialogThread3runEv+0xd8)[0x557069f6fb78]
462 /home/cin5/bin/./cin(_ZN6Thread10entrypointEPv+0x45)[0x557069fc5995]
463 /usr/lib/libpthread.so.0(+0x7a9d) [0x7f1b91b4ea9d]
464 /usr/lib/libc.so.6(clone+0x43) [0x7f1b90accb23]
465 \end{lstlisting}
466
467 To see which routine is reporting the booby key in:
468
469 \hspace{2em} \texttt{c++filt}
470
471 And then the $2^{nd}$ line in the backtrace above:
472
473 \hspace{2em}\texttt{\_ZN13BC\_WindowBase9draw\_lineEiiiiP9BC\_Pixmap}
474
475 It comes back with the routine as:
476
477 \hspace{2em}\texttt{BC\_WindowBase::draw\_line(int, int, int, int, BC\_Pixmap*)}
478
479 \section{Valgrind Support Level}
480 \label{sec:valgrind_support_level}
481 \index{build!valgrind}
482
483 Valgrind is a memory mis-management detector.  It shows you memory leaks, deallocation errors, mismanaged threads, rogue reads/writes, etc.  \CGG{} memory management is designed to work with Valgrind detection methods.  This assists in developing reliable code.  Use of Valgrind points out problems so that they can be fixed.  For example, when this version of \CGG{} shuts down, it deallocates memory instead of just stopping, thus making memory leak detection possible.  An alternative to Valgrind is
484 \textit{heaptrack} which has good documentation and for large programs can run
485 faster.  You can find the source and information about it at {\small\url{https://github.com/KDE/heaptrack}}.
486 \index{valgrind!heaptrack}
487
488 The best way to compile and run valgrind is to run the developer static build. This takes 2 steps and you must already have gdb and valgrind installed:
489
490 \begin{enumerate}[nosep]
491         \item The standard static build:\\
492                 \texttt{cd /path/cinelerra-5.1}\\
493                 \texttt{make clean}\\
494                 \texttt{./bld.sh}
495         \item run the incremental rebuild for debug objs:\\
496                 \texttt{CFLAGS=-ggdb make -j8 rebuild\_all}
497 \end{enumerate}
498
499 If you frequently make mods and changes in \CGG{} or the thirdparty libraries, do not depend on those
500 compiled versions to have the headers updated; so be sure to fully rebuild as shown in the previous 2
501 steps before running valgrind or you will get false errors.
502
503 Now your \CGG{} obj has all of the debug stuff. Next run valgrind as root for the most useful results:
504
505 \hspace{2em}\texttt{cd /path/cinelerra-5.1/cinelerra}
506
507 \hspace{2em}\texttt{valgrind -{}-log-file=/tmp/log -{}-leak-check=full\\
508         -{}-num-callers=32 ./ci}
509
510 This runs \CGG{} under the control of valgrind, and produces a log file in /tmp which will list information about any leaks, usually clearly identifiable. Be sure to Quit out of \CGG{} normally instead of Ctrl-C or a SEGV otherwise the program does not have a chance to cleanup and there will be some false alarms. But it runs very slowly, and is basically single threaded, which means that race conditions may be impossible to catch$\dots$ like one thread deletes memory that another thread is currently using. But overall it is a big help and if you test any new features, please email the log output. A lot of effort when writing the code was put into trying to be sure that all of the object constructors have matching destructors so that the leaks can be identified. There are already several libraries that create predictable memory leaks and valgrind does a good job for most of these.
511
512 It is impossible to test everything with valgrind because some things are just too big and slow for a practical test. Occasionally you can find a leak or an illegal memory access. There are several false alarms that are difficult to avoid \textit{Conditional jump} messages, and \textit{unhandled DW\_OP\_}, but anything with the word \textit{illegal} in the message is important. Memory leaks that originate in \CGG{} are good to find and fix, but are usually not
513 deadly. The listing of the memory leaks can be quite voluminous so locating the \textit{LEAK SUMMARY} section
514 towards the end of the report is most useful.
515
516 Another very useful valgrind run to locate unitialized variables while executing is:
517
518 \hspace{2em}\texttt{valgrind -{}-log-file=/tmp/log -{}-tool=memcheck\\
519         -{}-num-callers=32 ./ci}
520
521 \section{CFLAGS has -Wall}
522 \label{sec:cflags_has_-wall}
523 When compiling \CGG{} Infinity a CFLAGS option used is \textit{Wall} where the "W" represents warnings and "all" means all.  This causes the compile to check for simple mistakes that can be detected automatically and issue warnings when the code is questionable.  It can also detect situations where the compiler will generate incorrect code, like type-punned pointer.  By turning on this flag, when new code is vetted for predictable mistakes, the code can be corrected before becoming manifested in the application.
524
525 \section{Prof2 -- A Profiler}
526 \label{sec:prof2_profiler}
527 \index{build!prof2}
528
529 Frequently there is a problem with a program running slow and you do not know why. You need a thumbnail analysis of where the program is spending most of its time without all of the overwhelming details. This is when a Profiler comes in handy.
530
531 There are many different profilers available -- this particular one does not do anything special and is fairly ordinary in that it just characterizes frequency of execution of various regions in the program. However, it has some pretty good strengths as listed next.
532
533 \begin{enumerate}[nosep]
534         \item It takes very little or no preconditioning, i.e. setup
535         \item The effect it has on the running program is minimal
536         \item It runs almost at full speed, which is really nice
537         \item It is not particularly thread aware
538         \item Reports where it is executing at intervals of 100 times a second
539 \end{enumerate}
540
541 \subsection{Setup}
542 \label{sub:setup}
543
544 This profiler works on x86\_64 systems and you must be root to compile and run it. Also, you must install your operating system's \textit{iberty} -- for example, which would be binutils-devel for Fedora or libiberty-dev for Ubuntu 18.
545
546 Go to the top level \CGG{} directory.
547
548 Key in: \qquad \texttt{prof2}
549
550 Key in: \qquad \texttt{make clean all install}
551
552 Because \textit{smap} may have to be found in the system if \textit{How to use} below does not work, you will have to do the following:
553 \newline
554 \newline
555 Key in: \qquad \texttt{cp -a smap /usr/local/bin}
556
557
558 Later, if you want to remove this from the system,
559
560 Key in: \qquad \texttt{make uninstall}
561
562 \subsection{How to use}
563 \label{sub:how_to_use}
564
565 The program you are profiling should be compiled debuggable with stack frame and symbols enabled.
566
567 To see help, key in: \qquad \texttt{prof -h}
568
569 usage: -h [-o path] [-d] [-e] [-p libpath] [-012] [-u \#] cmd args...
570
571 \hspace{2em}
572 \begin{tabular}{@{}ll}
573         -o & profile output pathname, -=stdout, -{}-=stderr\\
574         -d & debug otitleutput enabled\\
575         -e & child debug output enabled\\
576         -p & specify path for libprofile.so\\
577         -0 & usr+sys cpu timer intervals (sigprof)\\
578         -1 & usr only cpu timer intervals (sigvtalrm)\\
579         -2 & real time timer intervals (sigalrm)\\
580         -u & profile timer interval in usecs\\
581 \end{tabular}
582
583 To execute the profiler, key in:
584
585 \hspace{2em}\texttt{prof -o /tmp/prof\_list.txt ./cin}
586
587 where \texttt{/tmp/prof\_list.txt} is the output file and in this case \texttt{cin} is the \CGG{} binary file. The pid of this command will be displayed on the startup window. This comes in handy in the use case where there is a lot of initial load and possible configuration setup inside of \CGG{} and you want to profile plugins and not necessarily all of the setup steps. Then you can use the following command in another window to continue running \CGG{} and obtain the more useful information:
588
589 \hspace{2em}\texttt{kill -USR1 pid}
590
591 Running this command refreshes the memory maps used for profiling. When you are profiling a plugin, you want to run this AFTER the plugin loads.
592
593 \subsection{Results}
594 \label{sub:results}
595
596 There are 3 sections in the resulting output file of this stochastic quick analysis.
597
598 \begin{enumerate}[nosep]
599         \item The first section is a histogram of the timer intervals of that sample set. Each function occupies a region of addresses. One hundred times a second, the profiler samples the program address in the region of execution.
600         \item In the second section, there is another histogram of the cumulative frequency of all things in the call stack and this should point out who is the culprit. For example, a codec calls a bunch of subroutines, the cost of the subroutines is accumulated to the codec parent caller. This makes the actual cpu user much more apparent.
601         \item The last section is for the library spaces. Each library occupies a region and the profiler adds up the time spent in each of the libraries by frequency.
602 \end{enumerate}
603
604 On the very bottom is a 1 line summary which shows you if there is a bad guy and who it is.
605
606 \subsection{Sample output}
607 \label{sub:sample_output}
608
609 \textit{--- profile start ---}
610
611 \textbf{1020 ticks 43 modules 81412 syms}\\
612 \begin{tabular}{@{}rrp{\linewidth-6em}}
613  0.010s & 0.1\% & Autos::copy(long, long, FileXML*, int, int) /mnt0/build5/cinelerra-5.1/bin/cin\\
614  0.010s & 0.1\% & BinFolders::copy\_from(BinFolders*) /mnt0/build5/cinelerra-5.1/bin/cin\\
615  0.010s & 0.1\% & cstrdup(char const*)     /mnt0/build5/cinelerra-5.1/bin/cin\\
616  0.010s & 0.1\% & XMLBuffer::encode\_data(char*, char const*, int) /mnt0/build5/cinelerra-5.1/bin/cin\\
617  0.010s & 0.1\% & XMLBuffer::encoded\_length(char const*, int) /mnt0/build5/cinelerra-5.1/bin/cin\\
618  0.010s & 0.1\% & PluginClient::send\_configure\_change() /mnt0/build5/cinelerra-5.1/bin/cin\\
619  0.010s & 0.1\% & UndoVersion::scan\_lines(UndoHashTable*, char*, char*) /mnt0/.../cin\\
620  0.010s & 0.1\% & UndoStackItem::set\_data(char*) /mnt0/build5/cinelerra-5.1/bin/cin\\
621  0.010s & 0.1\% & UndoStack::load(\_IO\_FILE*) /mnt0/build5/cinelerra-5.1/bin/cin\\
622  0.010s & 0.1\% & BC\_Bitmap::cur\_bfr()     /mnt0/build5/cinelerra-5.1/bin/cin\\
623  0.010s & 0.1\% & YUV::init\_tables(int, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*) /mnt0/build5/cinelerra-5.1/bin/cin\\
624 \end{tabular}\\
625 $\dots$\\
626 $\dots$\\
627 \textit{--- profile calls ---}
628
629 \begin{tabular}{@{}rrl}
630  0.010s & 0.1\% & AutoConf::save\_xml(FileXML*)   1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
631  0.010s & 0.1\% & Automation::copy(long, long, FileXML*, int, int)   1.0 /mnt0/.../cin\\
632  0.010s & 0.1\% & AWindow::run()             1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
633  0.010s & 0.1\% & Canvas::stop\_single()      1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
634  0.010s & 0.1\% & ColorPicker::new\_gui()     1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
635  0.010s & 0.1\% & ColorWindow::create\_objects()   1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
636  0.010s & 0.1\% & PaletteWheel::draw(float, float)   1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
637  0.010s & 0.1\% & PaletteHex::update()       1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
638  0.010s & 0.1\% & CWindowGUI::draw\_status(int)   1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
639  0.010s & \textbf{0.1\%} & CWindowCanvas::status\_event()   1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
640 \end{tabular}\\
641 $\dots$\\
642 $\dots$\\
643 \begin{tabular}{@{}rrl}
644  0.990s & \textbf{9.7\%} & BC\_Xfer::xfer\_slices(int)   1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
645  1.880s & \textbf{18.4\%} & DirectUnit::process\_package(LoadPackage*)   1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
646  1.880s & \textbf{18.4\%} & DirectUnit::rgba8888()     1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
647  3.910s & \textbf{38.3\%} & \_\_init\_array\_end           1.1 /mnt0/build5/cinelerra-5.1/bin/cin\\
648  5.450s & \textbf{53.4\%} & LoadClient::run()          1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
649  7.890s & \textbf{77.4\%} & Thread::entrypoint(void*)   1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
650  7.890s & \textbf{77.4\%} & start\_thread               1.0 /lib64/libpthread-2.28.so\\
651 \end{tabular}\\
652 ---\\
653 ---\\
654 \begin{tabular}{@{}rrl}
655  0.010s & 0.1\%/  0.0\% & /lib64/libm-2.28.so\\
656  0.010s & 0.1\%/  0.0\% & /lib64/libexpat.so.1.6.8\\
657  0.020s & 0.2\%/  0.1\% & /lib64/libXext.so.6.4.0\\
658  0.020s & 0.2\%/  0.1\% & /lib64/libXft.so.2.3.2\\
659  0.020s & 0.2\%/  0.1\% & /lib64/libxcb.so.1.1.0\\
660  0.040s & 0.4\%/  0.2\% & /lib64/ld-2.28.so\\
661  0.050s & 0.5\%/  0.2\% & /lib64/libpng16.so.16.34.0\\
662  0.130s & 1.3\%/  0.6\% & /lib64/libX11.so.6.3.0\\
663  0.180s & 1.8\%/  0.8\% & /lib64/libz.so.1.2.11\\
664  0.200s & 2.0\%/  0.9\% & /lib64/libfontconfig.so.1.12.0\\
665  0.380s & 3.7\%/  1.8\% & /lib64/libpthread-2.28.so\\
666  1.660s & 16.3\%/ 7.7\% & /lib64/libc-2.28.so\\
667  7.480s & 73.3\%/34.7\% & /mnt0/build5/cinelerra-5.1/bin/cin\\
668 \end{tabular}
669
670 \textbf{10.200t 0.001u+0.000s 21.566r  47.3\%}\\
671 \textit{--- profile end ---}
672
673 The summary line above in Bold represents the User time, System time, Real time and the percentage is how much Timer time elapsed over Real time so in this case the measurement covers 47.3\% of time.
674
675 So why use a Profiler? Because it is the ``ls'' for executable functions!!
676
677 \section{Working on AppImage}
678 \label{sec:working_on_appimage}
679
680 You can work on the appimage file to make changes and fix errors, or you can create a new appimage from scratch containing customizations. For example, you can add new rendering presets, update the Context-Help, change libraries that are no longer supported by the current distro, or make other modifications.
681
682 \subsection{Managing AppImage}
683 \label{sub:managing_appimage}
684 \index{appimage!management}
685
686 A limitation of using AppImage instead of installing the binary or compiling from git, is that there is only a single file without the ability to browse the directory structure or to look for files to edit or check. So if using \CGG{} leads to some errors, it is not possible to investigate and fix the problem. Which means if you want to add the most up-to-date Context-Help or want to introduce some custom presets, that can not be done.
687
688 Because the appimage file is nothing more than a compressed file containing the same structure as the installed program plus other libraries that allow the program to run independently from the system, the content can be extracted so that you can work on it as you would have on the normally installed program.  To do this you will need the appimage management program.
689 Many Linux distros come with this managment program by default, but others may not. For instance in the case of Arch Linux the \texttt{appimagetool-bin} package from AUR needs to be installed. 
690
691 To work on the appimage, first unpack it using the command\protect\footnote{Example provided by Glitterball3} (note that you do not have to be root to do any of the following):
692
693 \begin{lstlisting}[numbers=none]
694         /{path to appimage}/CinGG-yyyymmdd.AppImage --appimage-extract
695 \end{lstlisting}
696
697 You will now have a \texttt{squashfs-root} folder in your current directory containing \texttt{/usr/bin/} as well as other files and directories such as \texttt{/usr/lib} and \texttt{/usr/share}. \texttt{Bin} is the folder similar to the one installed with \CGG{} and contains the files that you can work on. Now it is possible to make changes like adding a custom preset in \texttt{/ffmpeg/video} or replacing a library that no longer works with a more recent version by working in \texttt{/squashfs-root/usr/lib}.
698
699 To start the unpacked program from the bin folder use the command:
700
701 \begin{lstlisting}[numbers=none]
702         /{path to appimage}/squashfs-root/usr/bin/./cin
703 \end{lstlisting}
704
705 After making your changes, to get back to having an appimage file instead of having to run the program from the bin folder, you can take the extra step of recompressing the squashfs-root folder.
706 To do so use linuxdeploy's appimage, a program that can also be useful for creating appimages from scratch (\url{https://github.com/linuxdeploy/linuxdeploy/releases/continuous}).
707
708 The steps to recreate the appimage are:
709
710 \begin{enumerate}
711         \item Copy the linuxdeploy appimage to \texttt{/\{path to appimage\}} and make sure it is executable.
712         \item Then use the command:
713         \begin{lstlisting}[numbers=none]
714                 ./linuxdeploy-x86_64.AppImage --appdir squashfs-root --output appimage
715         \end{lstlisting}
716 \end{enumerate}
717
718 A new appimage will be created like the original but containing the changes.
719
720 Alternatively, download the \texttt{appimagetool} version from \url{https://github.com/AppImage/AppImageKit/releases} if available for your distro and use the command:
721
722 \begin{lstlisting}[numbers=none]
723         ./appimagetool --comp /{path to appimage}/squashfs-root /tmpCinGG-yyyymmdd.AppImage
724 \end{lstlisting}
725
726 Now there will be an appimage called \textit{CinGG-yyyymmdd.AppImage} with the changes that were made.
727
728 NOTE: for the \textbf{bdwrite} program which is used to create the udfs image to burn Blu-ray
729 media (or any other standalone program), you will find it in the squashfs-root/usr/bin
730 subdirectory. You only need to do the initial unpacking extract step and then just copy
731 bdwrite and the entire squashfs-root/usr/lib directory to a convenient permanent place for
732 usage.  Then when running bdwrite, you will have to first export the libary path by typing
733 this command in the window first:
734 \begin{lstlisting}[numbers=none]
735 export LD_LIBRARY_PATH=/{put your copied usr/lib path here}:$LD_LIBRARY_PATH
736 \end{lstlisting}
737
738 \subsection{Build the CinGG.AppImage from scratch}
739 \label{sub:built_appimage_scratch}
740 \index{appimage!creating}
741
742 If a developer wants to create an appimage from git, follow these next few steps. An existing automated script is available, \texttt{bld\_appimage.sh}, in the directory \texttt{/\{path to cinelerra-5.1\}}.
743
744 This follows four steps:
745
746 \begin{itemize}
747         \item Build static version of \CGG{}.
748         \item If desired and needed, build the HTML manual for context-sensitive help.
749         \item Organize code and if present, the manual, in a AppImage specific format \textit{AppDir}. Do this with tool makeappimage, which is built if needed.
750         \item Call an external tool to make the AppDir into an AppImage
751 \end{itemize}
752
753 Start by downloading the \CGG{} source from Cinelerra's git. The last parameter is a directory name of your choice, the directory must not exist. As example, the name \textit{cinelerra5} is used.
754
755 \begin{lstlisting}[numbers=none]
756         git clone --depth 1 git://git.cinelerra-gg.org/goodguy/cinelerra.git cinelerra5
757 \end{lstlisting}
758
759 The source will be in a subdirectory \texttt{cinelerra-5.1} of the directory created by the \textit{git clone} operation.
760
761 If context-sensitive help is needed, download the manual sources too, with a different destination directory.
762
763 \begin{lstlisting}[numbers=none]
764         git clone --depth 1 git://git.cinelerra-gg.org/goodguy/cin-manual-latex.git cin-manual-latex
765 \end{lstlisting}
766
767 Then move to the \texttt{/\{path to cinelerra-5.1}/\} directory.
768
769
770 There are two preliminaries to do before running the script:
771
772 1- If context sensitive help in the appimage version is required, the source of the manual and the tools (packages) to build it must be on the system. In the bld\_appimage.sh script, set the variable \texttt{MANUAL\_DIRECTORY=\$(pwd)/../../ cin-manual-latex} to the path of the source of the manual. If the variable is empty, or the specified directory does not exist, \CGG{} will be built without built-in help. The path to the manual source can be an absolute or relative one. An easier method to include the help from the manual rather than having to install a bunch of latex building software, is to simply download the latest tgz version from {\small\url{https://cinelerra-gg.org/download/images/HTML_Manual-202xxxxx.tgz}}.
773 Then extract the files using "tar xvf" into the cinelerra AppDir/usr/bin/doc directory.
774 This alternative method may not contain the most recent changes to the Manual but rather will contain what had been checked into Git by the date of the tgz file.
775
776 2- The script bld\_appimage.sh uses a platform specific version of appimagetool so that it can create appimages for \textit{x86\_64}, \textit{i686}, \textit{aarch64}, or \textit{armv7l} architecture. We need to add appimagetool-(platform).AppImage to the \texttt{/\{path to cinelerra- 5.1\}/tools} directory, or somewhere in your path. You can download the tool for your system (e.g. appimagetool-x86\_64.AppImage) from git: {\small\url{https://github.com/AppImage/AppImageKit/releases}}. Be aware of the possibility that an older appimagetool from 2020 might work better on some systems compared to the latest release.
777
778 Always remember to make it executable. The four supported platforms are:
779
780 \begin{itemize}
781         \item appimagetool-aarch64.AppImage
782         \item appimagetool-armhf.AppImage
783         \item appimagetool-i686.AppImage
784         \item appimagetool-x86\_64.AppImage
785 \end{itemize}
786
787 With the preparations done, let's go back to the bld\_appimage.sh script.
788
789 Make the script executable if it isn't already:
790
791 \begin{lstlisting}[numbers=none]
792 chmod x+u bld_appimage.sh
793 \end{lstlisting}
794
795 Start the script with:
796
797 \begin{lstlisting}[numbers=none]
798 ./bld_appimage.sh
799 \end{lstlisting}
800
801 The first part of the script customizes \texttt{configure}, depending on the architecture of our system. The next step compiles and installs \CGG{} in the \texttt{bin} subdirectory. The third part creates the manual in HTML; It will be the basis for the context help (see \nameref{sec:help_context_help}). The fourth part creates the directory \texttt{/AppDir/usr}, which is the basic structure of an appimage, and then populates it with the contents of \texttt{/\{path to cinelerra-5.1\}/bin}. Finally, the fifth step starts a script, called \texttt{makeappimage}, which points to \textit{bld.sh} contained in \texttt{/tools/makeappimagetool/}.
802
803 The script specifies all executables that are part of \CGG{}, so makeappimage can pick up dependencies. Any executable code in other places is not picked up. makeappimage will populate the AppDir directory, and then call the platform dependent appimagetool found in \texttt{/\{path to cinelerra-5.1\}/tools}.
804
805 At the end of the compilation there will be an appimage in the \texttt{cinelerra-5.1} directory, which we can move and use.
806
807 \section{How to Create a new Theme}
808 \label{sec:how_create_theme}
809 \index{theme!create new theme}
810
811 A \textit{Theme} is a base class object that is created and customized as \textit{ThemeName}.
812 It is constructed during program initialization in a theme plugin
813 \texttt{PluginTClient},
814 defined in \texttt{plugins/theme\_name} source directory.
815
816 \texttt{theme\_name.C} and \texttt{theme\_name.h} are derived \textit{Theme} class object constructors.
817
818 A \textit{Theme} is constructed during initialization in \texttt{init\_theme} (\texttt{mwindow.C}). The theme plugin is accessed using the \textit{name} from preferences and then the theme plugin is loaded which contains the code to construct the theme.  A \textit{Theme} object has functions and data that \CGG{} uses to do a variety of customizations, such as \texttt{default\_window\_positions}, and it can modify GUI defaults like \\
819 \texttt{default\_text\_color} when it is initialized.
820
821 The theme plugin contains a \textit{new\_theme} function that allocates and constructs a
822 \textit{ThemeName} object with base classes of \textit{BC\_Theme} (gui setup), \textit{Theme} (\CGG{} defaults), and \textit{ThemeName}, with definitions and overrides that create the custom theme. To create a new theme, a new plugin is needed:
823
824 \begin{lstlisting}[numbers=none]
825         #include "header files.h"
826         PluginClient* new_plugin(PluginServer *server)
827         {
828                 return new NameMain(server);
829         }
830         
831         NameMain::NameMain(PluginServer *server)
832         : PluginTClient(server)
833         {
834         }
835         
836         NameMain::~NameMain()
837         {
838         }
839         const char* NameMain::plugin_title() { return N_("Name"); }
840         
841         Theme* NameMain::new_theme()
842         {
843                 theme = new ThemeName;
844                 extern unsigned char _binary_theme_name_data_start[];
845                 theme->set_data(_binary_theme_name_data_start);
846                 return theme;
847         }
848         
849         Name::Name()
850         : Theme()
851         {
852         }
853         
854         Name::~Name()
855         {
856                 delete stuff;
857         }
858 \end{lstlisting}
859
860 When a theme is constructed by \texttt{NameMain::new\_theme()}, it sets a pointer to a
861 block of data created in the plugin build that contains all of the png data
862 files in the \texttt{plugins/theme\_name/data} directory.  These images may define or override the appearance of gui images, such as \textit{ok.png} (the ok button).  There are usually a large number of images that need to be defined.  The theme plugin adds them to the theme image data in the \texttt{theme $\rightarrow$ initialize()} function.  The best list of theme image setup is probably in SUV (\texttt{plugins/theme\_suv/suv}).
863
864 The easy way to create a new theme is to copy an existing theme and change
865 its name to \textit{ThemeName}, change \texttt{plugin\_title()} to the new name, and then tweak the definitions until you are happy with the results.   The file
866 names and Makefile also need to be updated to the new theme name.  The source
867 can by manually rebuilt by invoking \textit{make} in the \texttt{plugins/theme\_name}
868 directory.
869
870 Once the new theme is built into the plugin library, it will automatically be discovered by the plugin probe
871 and it will become an available theme in \textit{Preferences}.
872
873 If you are ready to add it to the main build, then \textit{theme\_name} should be
874 included in the DIRS targets of the \texttt{plugins/Makefile}, and \texttt{plugin\_defs} needs \textit{theme\_name} in the themes list.
875
876 Themes usually require considerable time to create from scratch.  For
877 example, the SUV theme has over 800 lines in the initialize function, and has over
878 500 png images in the data directory.  Most of these images and data values are
879 required to be initialized by the custom theme constructor; very tedious and
880 time consuming work.  Creating a new theme is usually a lot of work.
881
882 \section{How Context Help works in the Program Code}
883 \label{sec:context_help_coding}
884 \index{context help}
885
886 All class methods related to context help start with the common pattern \texttt{context \_help} in their names. It is easy to get all occurences in the code with the following command (example):
887
888 \begin{lstlisting}[style=sh]
889         grep -F context_help `find . -name '*.[Ch]' -print`
890 \end{lstlisting}
891
892 The base functionality is defined in several \textit{BC\_WindowBase} class methods in \\ \texttt{guicast/bcwindowbase.C} (search on \texttt{context\_help}). All BC\_Window's and BC\_SubWindow's inherit these methods.
893
894 For the simplest case of context help definition, it is sufficient to add the call to \texttt{context\_help\_set\_keyword()} in the most inclusive widget constructor. If \texttt{Alt/h} is pressed with the mouse over this widget's window, its \texttt{keypress\_event()} method (inherited from BC\_WindowBase) will catch this hotkey, fetch the keyphrase defined by \texttt{context\_help\_set\_keyword()} and call the \texttt{doc/ContextManual.pl} script with this keyphrase. Then ContextManual.pl script does the whole processing of the keyphrase given and calls web browser to display the found HTML manual page. The browser is called in the background to prevent from blocking the calling \CGG{} thread.
895
896 An example from \textit{cinelerra/zoombar.C}:
897
898 \begin{lstlisting}[style=sh]
899         ZoomBar::ZoomBar(MWindow *mwindow, MWindowGUI *gui)
900         : BC_SubWindow(...)
901         {
902                 this->gui = gui;
903                 this->mwindow = mwindow;
904                 context_help_set_keyword("Zoom Panel");
905         }                                                        
906 \end{lstlisting}
907
908 If \texttt{Alt/h} is pressed with the mouse over some subwindow (arbitrary depth) of the \texttt{context\_help\_set\_keyword()} caller, the \texttt{keypress\_event()} method of that subwindow catches the hotkey. Its own context help keyword, probably, will be empty. In this case the whole widget hierarchy is traced up to \textit{top\_level} widget, their context help keywords are checked, and the first nonempty keyword is used for context help.
909
910 This approach allows us to define the help keyword common to the whole dialog window with a bunch of diverse buttons with a single call to \texttt{context\_help\_set \_keyword()}, without placing such a call into each button constructor. And at the same time, this approach allows to assign different help keywords to GUI elements belonging to the same window but documented in different manual pages.
911
912 \subsubsection{An example with several different help keywords from cinelerra/mwindowgui.C:}%
913 \label{ssub:exemple_different_help_keywords}
914
915 \begin{lstlisting}[style=sh]
916         MWindowGUI::MWindowGUI(MWindow *mwindow)
917         : BC_Window(_(PROGRAM_NAME ": Program"), ...)
918         {
919                 this->mwindow = mwindow;
920                 ...
921                 context_help_set_keyword("Program Window");
922         }
923         ...
924         FFMpegToggle::FFMpegToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
925         : BC_Toggle(...)
926         {
927                 this->mwindow = mwindow;
928                 this->mbuttons = mbuttons;
929                 set_tooltip(get_value() ? FFMPEG_EARLY_TIP : FFMPEG_LATE_TIP);
930                 context_help_set_keyword("FFmpeg Early Probe Explanation");
931         }
932         ...
933         StackButton::StackButton(MWindow *mwindow, int x, int y)
934         : BC_GenericButton(x, y, mwindow->theme->stack_button_w, "0")
935         {
936                 this->mwindow = mwindow;
937                 set_tooltip(_("Close EDL"));
938                 context_help_set_keyword("OpenEDL");
939         }
940         ...
941         ProxyToggle::ProxyToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
942         : BC_Toggle(...)
943         {
944                 this->mwindow = mwindow;
945                 this->mbuttons = mbuttons;
946                 ...
947                 context_help_set_keyword("Proxy");
948         }
949         \end{lstlisting}
950 If the widget we wish to add context help to, overloads keypress\_event() of the base class with its own method, then it is necessary to introduce a small addition to its keypress\_event() handler: the call to \texttt{context\_help\_check\_and\_show()} has to be added in a suitable place in the handler.
951
952 An example with \texttt{context\_help\_check\_and\_show()} from \textit{cinelerra/mbuttons.C}:
953 \begin{lstlisting}[style=sh]
954         int MButtons::keypress_event()
955         {
956             int result = 0;
957             if(!result) {
958                 result = transport->keypress_event();
959             }
960             if(!result) {
961                 result = context_help_check_and_show();
962             }
963             return result;
964         }
965 \end{lstlisting}
966
967 All the keypress handlers are not equal, therefore we provide different variants of the methods context\_help\_check\_and\_show() and context\_help\_show() (the latter for explicit checking on hotkey).
968
969 An example with context\_help\_show() from cinelerra/editpanel.C:
970 \begin{lstlisting}[style=sh]
971         int EditPanelTcInt::keypress_event()
972         {
973                 if( get_keypress() == 'h' && alt_down() ) {
974                         context_help_show("Align Timecodes");
975                         return 1;
976                 }
977                 ...further processing...
978                 return 1;
979         }
980 \end{lstlisting}
981
982 A single example of much more sophisticated keypress\_event() handler can be found in \texttt{cinelerra/trackcanvas.C} (search on context\_help). The problem here was to track the particular object drawn on the canvas to figure out whose context help is to be requested. Another rare example of difficulty may appear when context help is desired for some GUI object which is not subclassed from BC\_WindowBase.
983
984 \textit{ContextManual.pl} looks for occurence of keyphrases in the following order:
985
986 \begin{enumerate}
987         \item In \textit{Contents.html}
988         \item In \textit{Index.html}
989         \item In all the \textit{CinelerraGG\_Manual/*.html} files via grep
990 \end{enumerate}
991
992 Keyphrase matching is tried first exact and case sensitive, then partially and case insensitive. The special keyword \texttt{TOC} shows Contents, \texttt{IDX} shows Index. If the keyword starts with \texttt{FILE:}, the filename after \textit{FILE:} is extracted and that file is shown. You can look in the ContextManual.pl script text.
993
994 For debugging purposes the script can be called from command line. For this to work, the environment variable \texttt{\$CIN\_DAT} has to be set to the parent directory of doc.
995
996
997 \subsubsection{Providing context help for plugins}%
998 \label{ssub:providing_context_help_plugins}
999
1000 In the simplest case, nothing has to be done at all. The plugin context help functionality introduced in \texttt{cinelerra/pluginclient.C} automatically assigns context help keyword from the plugin's title for all plugins subclassed from \textit{PluginClient}. For this to work, the manual page documenting the plugin must be entitled identically to the programmatic title of the plugin. A special treatment can be necessary in the following cases:
1001
1002 \begin{enumerate}
1003         \item \textit{Rendered effects} are not subclasses of PluginClient and require an explicit context help definition via \texttt{context\_help\_set\_keyword().}
1004         \item Only the main plugin dialog inherits context help functionality from the parent class. If a plugin opens additional dialog windows, they probably require explicit context help definitions.
1005         \item If the plugin title differs from its subsection title in the documentation, either its help keyword or the corresponding title in the manual should be renamed. Another possibility can be an addition to the \textit{\%rewrite table} in \texttt{doc/ContextManual.pl}.
1006         \item If the plugin title contains some characters special for HTML and/or Perl regular expression syntax, the special characters have to be escaped. For example, the keyphrase corresponding to the title \textit{Crop \& Position (X/Y)} should be converted to:
1007
1008         \begin{lstlisting}[style=sh]
1009                 Crop & Position \\(X\\/Y\\)
1010         \end{lstlisting}
1011
1012         Such a rewriting can be done either in the C++ code or in ContextManual.pl.
1013 \end{enumerate}
1014
1015 One additional explanation about previous user information when plugin tooltips are off. Help for the \textit {selected plugin} is shown because in this case it would be difficult to figure out, without a visual feedback, which particular item is currently under the mouse.
1016
1017 \subsection{Manual Maintenance is now Tightly Coupled with the Program Code}
1018 \label{sub:manmaintain}
1019
1020 If some section of the \CGG{} manual gets renamed and is used for Context Help, the corresponding help keywords should be adjusted too. All the keywords used can be listed via the following example command:
1021
1022 \begin{lstlisting}[style=sh]
1023         grep -F context_help `find . -name '*.C' -print` | grep -F '"'
1024 \end{lstlisting}
1025 ----------------
1026
1027 Note that the keyword does not have to exactly match the section title; it can also be a case insensitive substring of the section title.
1028
1029 If some new \CGG{} window or dialog is created and documented, the inclusion of context\_help\_set\_keyword() calls and/or adaptation of keypress\_event() handler (if any) should be included in the program code.
1030
1031 If some new \CGG{} plugin is created, it is best to document it in the section entitled exactly equal to that plugin's title. Then probably its context help will work out of the box. Otherwise, some adaptation to its keypress\_event() (if any) or to the %rewrite table in ContextManual.pl may be necessary.
1032
1033 Why the local copy of \CGG{} manual should be used?
1034
1035 \begin{enumerate}
1036         \item For context help keyphrases matching, the local copy of \textit{Contents.html} and \textit{Index.html} is necessary anyway.
1037         \item Grepping \textit{CinelerraGG\_Manual/*.html} files of the remote manual from the website cannot work per definition.
1038         \item The local copy usage ensures exact matching of the version of the manual to the version of \CGG{}. Otherwise, if one uses for some reason an older version of \CGG{} with the help fetched from the newer version of the website manual, various incompatibilities can be expected.
1039         \item Packing the manual into AppImage, the current method of \CGG{} packaging, should be much easier than merging two different git branches when building from source packages, as was done earlier.
1040 \end{enumerate}
1041
1042 What about Localization?
1043
1044 For now, \CGG{} context help is not localized at all. There is no complete \CGG{} manual in any language except English. But even should the manual be translated to other languages, the context help keywords must remain unlocalized literal string constants. First, because the set of languages known to \CGG{} itself is not the same as the set of languages the manual will be translated to. If some "translated keyword" is fed to the help system, while the manual in this language does not exist, keyword matching cannot succeed. Second, such a help localization with the translation of all keywords can be done and then maintained much easier and much more reliably inside the ContextManual.pl script rather than in the \CGG{} binary.
1045
1046 More about ContextManual.pl file?
1047
1048 The bin/doc/ContextManual.pl script can be configured further. Look in the script text. You can define your preferable web browser, or redefine it to 'echo' for debug purposes. There are also some predefined HTML pages for Contents and Index, and several explicitly rewritten keyphrases. 
1049
1050 After the first invocation of context help the system-wide script, bin/doc/ContextManual.pl, copies itself into
1051 the user's config directory, \$HOME/.bcast5. If the user needs to modify ContextManual.pl, it should be done
1052 on that copy from .bcast5 rather than the system-wide one. On all subsequent context help requests this
1053 (possibly modified) .bcast5 version of the script will be called.  If later the \CGG{} package gets
1054 upgraded containing a newer, not 100\% compatible version of ContextManual.pl script, and/or not compatible
1055 structure of the HTML manual itself, the new system-wide version of the script will be copied into .bcast5
1056 again to ensure context help functionality. The older version of the script will be backed up (with the .bak
1057 suffix) as a reference of the modifications done by the user.
1058
1059 \section{Unique Blend plugins workflow}
1060 \label{sec:ba_bp_workflow}
1061
1062 The uniqueness of the Blend Algebra/Blend Program plugins, different then most of the other plugins, provides a universal tool for creating new effects and may be handy in unexpected cases.
1063 These 2 plugins provide the advanced feature of combining and modifying color pixels and transparencies of several tracks according to a mathematic algorithm written entirely by the user in the form of compact and simple piece of code. Such user defined algorithms (blend functions) are compiled, dynamically linked and immediately executed inside \CGG{} on the fly without the need to restart the application, reload the project, reattach plugins, and so on.
1064 Because of this uniqueness, the Blend Algebra and Blend Program plugins workflow is documented here to explain how they work. Additional helpful information for developers can be found in the section on the Blend Algebra/Blend Program plugins themselves at \nameref{sub:blend_algebra}. You will most likely need to read parts to get a better understanding.
1065
1066 \subsection{Preparation phase}%
1067 \label{preparatio_phase}
1068
1069 As in any realtime plugin, the \texttt{process\_buffer()} method in Blend Algebra/Blend Program gets a set of frames from the tracks the plugin is attached to. Then the following events take place. It is checked if the configuration (the parameters) got changed. There is one parameter which requires special treatment, the \textit{user function name}.
1070
1071 In order to prevent resource consuming recompilation of the functions on each new frame, the plugin maintains the successfully compiled and attached functions in cache. If at some keyframe the function name gets changed, the plugin searches if this function is already known and cached. In addition to important function related objects such as entry points, there is a timestamp representing  when this function was last checked to be up to date.
1072
1073 If the current function name is empty, it means a function is not used. Nothing else has to be done; all tracks are fetched and passed along in the processing pipeline unchanged. If the function is not empty and seen for the first time, or its timestamp is older than the global timestamp, it is checked as follows.
1074
1075 \begin{enumerate}
1076 \item File lock is placed on the function source file to prevent concurrent modification of object files in case of several simultaneous compilations.
1077 \item Compilation script \texttt{BlendAlgebraCompile.pl}/\texttt{BlendProgramCompile.pl} is started. The script checks if the resulting shared object file exists and is newer than the source and recompiles it if not.
1078 \item The plugin checks if the shared object timestamp became newer than the timestamp of this function in cache (if any). If the cached version of the function in memory is up to date, it stays there. If not, the outdated function is detached from the plugin, the updated one is reattached, and its entry points are fetched and put into cache. The function's timestamp in cache is set to the current time since the function has just been checked.
1079 \end{enumerate}
1080
1081 While recompiling or dynamic linking, various things may go wrong.
1082 \begin{enumerate}
1083 \item If in the unlikely scenario where the given function file does not exist, the program does nothing, same as for an empty function. No error message is shown in this case in order to prevent a possible deadlock. 
1084 \item If recompilation was unsuccessful because of a syntax error, the error message is shown. More detailed diagnostics from the compiler can be seen in the terminal window in which \CGG{} was started. 
1085 \item If compilation succeeded, but dynamic linking did not, the error message is shown. In case of any error, the failed function is marked with the current timestamp in cache so that the error messages appear only once before the global timestamp gets updated.
1086 \end{enumerate}
1087
1088 Updating global timestamp forces all cached functions to be checked for recompilation when first accessed. The global timestamp is updated when the following events occur: changing function name, pressing \texttt{Edit...} or \texttt{Refresh} button, or exiting the \texttt{Attach...} dialog with the \texttt{OK} button.
1089
1090 If the current active function is up to date and attached, the plugin fetches video frames from all of the affected tracks with the important parameters like frame width and height. Then the \texttt{INIT} phase of the function is executed (once for each frame). Several important parameters are requested as defined by the function. They are:
1091
1092 \begin{itemize}
1093         \item Working color space needed inside the function. If it is not the same as the color space of the project, then color space conversions have to be done.
1094         \item The required number of tracks the function works on. If less than the required number of tracks is available, an error message is shown and the function is not executed.
1095         \item Whether the function supports parallelizing or not. If the function does not claim parallelizing support, it will be executed sequentially even if the \textit{PARALLE\_REQUEST} checkbox is ON in the plugin GUI.
1096 \end{itemize}
1097
1098 \subsection{Processing phase}%
1099 \label{processing_phase}
1100
1101 After the preparation phase, the processing itself takes place. If running sequentially instead of parallel, the following is done for each frame pixel individually.
1102
1103 For each input track, the corresponding pixel is split into color components according to the actual color space of the project. All color components are converted to float (type of the C language) in the ranges $[0.0 .. 1.0]$ for R, G, B, A, Y or $[-0.5 .. +0.5]$ for U, V. If the project color space has no alpha channel, the alpha component is set to A=1.0.
1104
1105 If the function uses a different color space than the project uses, the required conversions are performed. The key color components (selected in the plugin GUI) are also converted to the function color space in the same manner.
1106
1107 For Blend Algebra, the values for output are preinitialized from the track which the output is to go to. All the other tracks are cleared if the corresponding checkbox in the plugin GUI is checked. For Blend Program, this step is not needed.
1108
1109 \subsection{User function phase}%
1110 \label{user_function_phase}
1111
1112 The user function is called with the parameters: actual \textit{number of tracks}, \textit{4 arrays for the 4 color components} (dimensions are equal to the number of tracks), \textit{4 key color components}, \textit{current pixel coordinates} (x, y: upper left frame corner is (0,0), lower right is (width-1,height-1)), and \textit{width and height}. In addition for Blend Algebra, there ae \textit{placeholders} for the result.
1113
1114 The user function returns. First of all, the color components of the relevant pixels are clipped to range if the corresponding checkbox in the plugin GUI is on. Relevant for Blend Program are pixels of all the tracks (all tracks can be modified); for Blend Algebra the result only.
1115
1116 After optional clipping, the color components are checked for not being NaNs.
1117 If so, the pixel is replaced with the substitution color, then backconversion to the project color space is performed.
1118
1119 If the project has no alpha channel, but the function returned something not equal to 1.0, alpha channel is simulated as if an opaque black background were used.
1120
1121 If the project color space is not FLOAT, unconditional clipping followed by 8-bit transformation takes place.
1122
1123 For Blend Algebra, the result is placed in the right output track. For Blend Program, this step is unnecessary since all tracks are modified in place.
1124
1125 Then the loop is repeated for the next pixel in a row, next row in a frame, next frame in the whole sequence, and so on.
1126
1127 If the function is to be run parallelized, the necessary number of threads is created (as defined in \texttt{Settings $\rightarrow$ Preferences $\rightarrow$ Performance; Project SMP cpus}). Running parallel on 1 cpu is not exactly the same as running sequential because an extra processing thread is created, while sequential execution takes place inside the main plugin thread. This could induce some subtle differences if the function uses static variables inside or something else which is thread unsafe.
1128