Add cmake target to generate API docs and write some basic API docs where needed.
[qtgstreamer:qtgstreamer.git] / README
1 1. About
2 --------
3
4 - What is QtGstreamer?
5
6 QtGstreamer aims to become a library providing C++ bindings for Gstreamer [1]
7 with a Qt-style API plus some helper classes for integrating Gstreamer better
8 in Qt [2] applications.
9
10 [1]. http://gstreamer.freedesktop.org/
11 [2]. http://qt.nokia.com/
12
13 - What is QtGstreamer’s development state at the moment?
14
15 QtGstreamer is still under development, but might be suitable for simple uses.
16 However, note that there is no source or binary compatibility guarantee yet,
17 so if you want to use QtGstreamer in your project, I would recommend to ship
18 it with your sources and build it as a static library.
19
20 - What are the differences between the C++ bindings of QtGstreamer and Gstreamermm?
21
22  * QtGstreamer provides bindings that completely hide the Gstreamer ABI,
23    so your application doesn’t need to link to Gstreamer itself.
24  * QtGstreamer uses QtCore helper classes (QString, QList, etc..) where it can,
25    to ease integration with Qt.
26  * QtGstreamer provides support for connecting arbitrary GObject signals to
27    slots, while in Gstreamermm every signal needs to be defined in the bindings,
28    or else you need to use the C API for connecting it. This is especially useful
29    for connecting signals from element plugins, where their interface is unknown
30    at compile time.
31
32
33 2. Building
34 -----------
35
36 2.1 Dependencies
37 ----------------
38
39 QtGstreamer requires the following software to be installed in order to build:
40  * CMake <http://www.cmake.org/>
41  * Gstreamer <http://gstreamer.freedesktop.org/>
42    With its dependencies:
43    - Glib / GObject <http://www.gtk.org/>
44    - libxml2 <http://xmlsoft.org/>
45  * Qt 4 <http://qt.nokia.com/>
46  * Automoc <svn://anonsvn.kde.org/home/kde/trunk/kdesupport/automoc/>
47  * Boost (static_assert, type_traits, function, bind, preprocessor) <http://www.boost.org/>
48  * Flex <http://flex.sourceforge.net/>
49  * Bison <http://www.gnu.org/software/bison/>
50
51 2.2 Compiler
52 ------------
53
54 A decent compiler with proper support for advanced templates, including features
55 such as partial template specialization, is required. QtGstreamer can also make
56 use of C++0x features (see below for details). A compiler supporting at least
57 some of them is recommended. Currently, only the GNU C++ compiler (g++) version
58 4.3 or later is known to support all the features that QtGstreamer uses. However,
59 other compilers can be used too, but with some limitations.
60
61 C++0x features in use:
62  * static_assert(). Used to show nice error messages when the programmer is trying
63    to use some template in the wrong way. If not present, the templates will still
64    fail to compile if used in the wrong way, but the error messages may be quite
65    weird to understand...
66  * Variadic templates together with rvalue references. Used to support connecting
67    and emitting GObject signals with any number of arguments. If not available, a
68    hack-ish implementation using boost's preprocessor library, boost::function and
69    boost::bind is used to provide support for up to 9 arguments.
70
71 2.3 Procedure
72 -------------
73
74 The build procedure is simple:
75
76 $ mkdir build && cd build
77 $ cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/installation/prefix
78 $ make
79 $ make install
80
81 The above commands will build and install QtGstreamer as a shared library.
82 If you prefer to build QtGstreamer as a static library, pass the
83 -DSTATIC_QTGSTREAMER=1 option to cmake, like that:
84
85 $ cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/installation/prefix -DSTATIC_QTGSTREAMER=1
86
87 2.4 Generating documentation
88 ----------------------------
89
90 QtGstreamer uses doxygen for documentation. To generate the documentation you need
91 to install doxygen and run "make doc" after you have run cmake. This will generate
92 the documentation in <builddir>/doc/html/.
93
94
95 3. Using QtGstreamer
96 --------------------
97
98 3.1. Build system integration
99 -----------------------------
100
101 If you are using cmake as your build system, using QtGstreamer is quite easy.
102 You can just do:
103
104     find_package(QtGstreamer)
105
106 which will find QtGstreamer and define the following variables:
107
108     QTGSTREAMER_FOUND - system has QtGstreamer
109     QTGSTREAMER_INCLUDE_DIR - the QtGstreamer include directory
110     QTGSTREAMER_INCLUDES - the include directories needed to use QtGstreamer
111     QTGSTREAMER_LIBRARY - the QtGstreamer library
112     QTGSTREAMER_LIBRARIES - the libraries needed to use QtGstreamer
113     QTGSTREAMER_DEFINITIONS - definitions recommended for using QtGstreamer
114     QTGSTREAMER_FLAGS - extra compiler switches recommended for using QtGstreamer
115
116 Take a look at the CMakeLists.txt of the QtGstreamer examples to see how to use them.
117
118 Alternatively, if you are using qmake, you can manually set the required variables,
119 as demonstrated in the example qmake project files that you can find together with
120 the QtGstreamer examples. Unfortunately qmake does not support dynamic detection
121 of installed libraries, so those variables have to be set manually, or you will have
122 to write some wrapper "configure" script that generates a qmake project file. This
123 is quite painful, compared to cmake, thus cmake is recommended.
124
125 3.2. Headers
126 ------------
127
128 The correct way to include a certain QtGstreamer header for a class is to use
129 the #include <namespace/class> syntax. For example: #include <QGst/Element>
130 All the other lowercase headers (which all end with .h) are considered private
131 and should not be used directly.
132
133
134 4. Developing QtGstreamer
135 -------------------------
136
137 4.1. Coding style
138 -----------------
139
140 QtGstreamer follows the kdelibs coding style:
141 http://techbase.kde.org/Policies/Kdelibs_Coding_Style
142
143
144 4.2. Naming policies
145 --------------------
146
147 4.2.1. The namespaces
148 ---------------------
149
150 The "G" namespace (GObject, GValue, etc...) is referred to as "QGlib".
151 The "Gst" namespace (GstObject, GstElement, etc...) is referred to as "QGst".
152 I didn't like them much when I chose them, better names could be discussed...
153
154 4.2.2. The class names
155 ----------------------
156
157 Class names should be the same as their G* equivalents, with the namespace
158 prefix removed. For example, "GstObject" becomes "QGst::Object", "GParamSpec"
159 becomes "QGlib::ParamSpec", etc...
160
161 4.2.3. The method names
162 -----------------------
163
164 In general the method names should be the same as the gstreamer ones,
165 with the g[st]_<class> prefix removed and converted to camel case.
166
167 For example,
168     gboolean gst_caps_is_empty(const GstCaps *caps);
169 becomes:
170     bool isEmpty() const;
171 (and member of the QGst::Caps class)
172
173 There are cases where this may not be followed:
174
175 1) Properties. Most property getters have a "get" prefix, for example,
176 gst_object_get_name(). In QtGstreamer the "get" prefix is omitted, so this
177 becomes just name().
178
179 2) Overloaded members. In C there is no possibility to have two methods with
180 the same name, so overloaded members usually have some extra suffix, like "_full".
181 For example, g_object_set_data and g_object_set_data_full. In C++ we just add
182 a method with the same name, or put optional parameters in the existing method.
183
184 3) Other cases where the glib/gstreamer method name doesn't make much sense...
185 For example, gst_element_is_locked_state(). That doesn't make sense in english,
186 as "state" is the subject and should go before the verb "is".
187 So, it becomes stateIsLocked().
188
189
190 4.3. Refcounted wrappers policy
191 -------------------------------
192
193 All reference counted classes must:
194 1) Inherit from QGlib::RefCountedObject and implement its virtual ref() and
195    unref() methods (and possibly makeWritable() too).
196 2) Include the QGLIB_WRAPPER (or QGST_WRAPPER) macro in their class declaration.
197    This is used like this: QGST_WRAPPER(ClassName).
198 3) Be used with QGlib::RefPointer<T> and provide a
199    typedef QGlib::RefPointer<ClassName> ClassNamePtr;
200
201 No constructor/destructor/copy constructor/assignment operator is allowed for
202 these classes and they are all defined as private in the QGLIB_WRAPPER/QGST_WRAPPER
203 macros.
204
205 RefPointer always creates a new instance of the wrapper class every time it is
206 copied, but it keeps the m_object protected variable of RefCountedObject pointing
207 to the same underlying glib/gstreamer object, using ref()/unref() to keep its
208 reference count correct.
209
210 For classes that implement the makeWritable() virtual method, this method is always
211 called before accessing a non-const member function. This is to implement semantics
212 similar to Qt's implicit sharing for gstreamer classes that use the concept of being
213 writable only when their reference count is 1, such as GstMiniObject and GstCaps.
214 The idea is that makeWritable() makes a copy of the object if its reference count is
215 higher than 1, so when one accesses a non-const method on an object that has more
216 than one references, it is automatically copied.
217
218
219 4.4. About codegen
220 ------------------
221
222 Codegen is a simple code generator that does two basic jobs:
223
224  1) It generates all the implementations of the QGlib::GetType<T> specializations.
225 GetType<T>() is used to get the GType of a type at runtime. Since we don't want
226 the target application to include any glib/gstreamer headers and/or link to
227 glib/gstreamer directly, this is the only way to be able to find the GType of
228 a class in a template class or method, such as RefPointer::dynamicCast(),
229 Value::init(), etc...
230
231 The header declaration of all these specializations is added on the header of each
232 class, with the QGLIB_REGISTER_TYPE() macro. This defines the declaration of the
233 specialization and also acts as a keyword for codegen, which then generates the
234 implementation.
235
236 The usage is simple. For example: QGLIB_REGISTER_TYPE(QGst::Element)
237 With this declaration, codegen will generate an implementation that returns
238 GST_TYPE_ELEMENT.
239
240 If a class name doesn't exactly reflect its GType getter macro, then one can
241 tell codegen which is the real GType macro with a special "codegen instruction"
242 comment after the QGLIB_REGISTER_TYPE keyword that goes like this:
243
244     //codegen: GType=GST_TYPE_FOO
245
246 For example, QGLIB_REGISTER_TYPE(QGlib::ParamSpec) would generate an implementation
247 that returns G_TYPE_PARAM_SPEC. However, that macro doesn't really exist, the
248 correct one is G_TYPE_PARAM. So, we define it like this:
249
250     QGLIB_REGISTER_TYPE(QGst::ParamSpec) //codegen: GType=G_TYPE_PARAM
251
252
253  2) It generates static assertions for all the enums to make sure that their
254 value is exactly the same as their glib/gstreamer equivalent. This is just used
255 as a safety test for developers and doesn't have any impact on the library.
256
257 Since, according to the coding style, all enums should be camel case, starting
258 with a capital and glib's coding style says all enums should be capitals with
259 underscores for separators, codegen does a style conversion to find out the
260 glib/gstreamer equivalent of the enum. An enum that is defined as: FooBar
261 in the namespace QGst will become GST_FOO_BAR. If an enum is defined in such a way
262 that the conversion is not accurate, then one can use a "codegen instruction"
263 after the opening brace of the enum definition that goes like this:
264
265     //codegen: EnumToBeConverted=ENUM_HOW_IT_SHOULD_BE_CONVERTED, SecondEnum=SECONDENUM , ...
266
267 This will assume that "EnumToBeConverted" is "GST_ENUM_HOW_IT_SHOULD_BE_CONVERTED"
268 (assuming that the namespace is QGst), and similar for "SecondEnum" -> GST_SECONDENUM
269
270 A real world example:
271
272 ---- snip ----
273 namespace QGst {
274     enum PadLinkReturn {
275         //codegen: PadLinkNoFormat=PAD_LINK_NOFORMAT, PadLinkNoSched=PAD_LINK_NOSCHED
276         PadLinkOk = 0,
277         PadLinkWrongHierarchy = -1,
278         PadLinkWasLinked = -2,
279         PadLinkWrongDirection = -3,
280         PadLinkNoFormat = -4,
281         PadLinkNoSched = -5,
282         PadLinkRefused = -6
283     };
284 }
285 QGLIB_REGISTER_TYPE(QGst::PadLinkReturn)
286 ---- endsnip ----
287
288 For this snippet, codegen will generate:
289
290 ---- snip ----
291 QGLIB_REGISTER_TYPE_IMPLEMENTATION(QGst::PadLinkReturn,GST_TYPE_PAD_LINK_RETURN)
292
293 namespace QGst {
294     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkOk) == static_cast<int>(GST_PAD_LINK_OK));
295     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongHierarchy) == static_cast<int>(GST_PAD_LINK_WRONG_HIERARCHY));
296     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWasLinked) == static_cast<int>(GST_PAD_LINK_WAS_LINKED));
297     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongDirection) == static_cast<int>(GST_PAD_LINK_WRONG_DIRECTION));
298     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoFormat) == static_cast<int>(GST_PAD_LINK_NOFORMAT));
299     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoSched) == static_cast<int>(GST_PAD_LINK_NOSCHED));
300     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkRefused) == static_cast<int>(GST_PAD_LINK_REFUSED));
301 }
302 ---- endsnip ----
303
304
305 4.5. How to contribute
306 ----------------------
307
308 Simply clone the repository on gitorious, develop the feature that you want there
309 and when it's ready, send me a merge request.
310
311
312 --
313 George Kiagiadakis <kiagiadakis.george@gmail.com>
314 Last updated: 11 July 2010