Improve the CMakeLists.txt files.
[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
82 3. Coding style
83 ---------------
84
85 QtGstreamer follows the kdelibs coding style:
86 http://techbase.kde.org/Policies/Kdelibs_Coding_Style
87
88
89 4. Naming policies
90 ------------------
91
92 4.1 The namespaces
93 ------------------
94
95 The "G" namespace (GObject, GValue, etc...) is referred to as "QGlib".
96 The "Gst" namespace (GstObject, GstElement, etc...) is referred to as "QGst".
97 I didn't like them much when I chose them, better names could be discussed...
98
99 4.2 The class names
100 -------------------
101
102 Class names should be the same as their G* equivalents, with the namespace
103 prefix removed. For example, "GstObject" becomes "QGst::Object", "GParamSpec"
104 becomes "QGlib::ParamSpec", etc...
105
106 4.3 The method names
107 --------------------
108
109 In general the method names should be the same as the gstreamer ones,
110 with the g[st]_<class> prefix removed and converted to camel case.
111
112 For example,
113     gboolean gst_caps_is_empty(const GstCaps *caps);
114 becomes:
115     bool isEmpty() const;
116 (and member of the QGst::Caps class)
117
118 There are cases where this may not be followed:
119
120 1) Properties. Most property getters have a "get" prefix, for example,
121 gst_object_get_name(). In QtGstreamer the "get" prefix is omitted, so this
122 becomes just name().
123
124 2) Overloaded members. In C there is no possibility to have two methods with
125 the same name, so overloaded members usually have some extra suffix, like "_full".
126 For example, g_object_set_data and g_object_set_data_full. In C++ we just add
127 a method with the same name, or put optional parameters in the existing method.
128
129 3) Other cases where the glib/gstreamer method name doesn't make much sense...
130 For example, gst_element_is_locked_state(). That doesn't make sense in english,
131 as "state" is the subject and should go before the verb "is".
132 So, it becomes stateIsLocked().
133
134
135 5. Refcounted wrappers policy
136 -----------------------------
137
138 All reference counted classes must:
139 1) Inherit from QGlib::RefCountedObject and implement its virtual ref() and
140    unref() methods (and possibly makeWritable() too).
141 2) Include the QGLIB_WRAPPER (or QGST_WRAPPER) macro in their class declaration.
142    This is used like this: QGST_WRAPPER(ClassName).
143 3) Be used with QGlib::RefPointer<T> and provide a
144    typedef QGlib::RefPointer<ClassName> ClassNamePtr;
145
146 No constructor/destructor/copy constructor/assignment operator is allowed for
147 these classes and they are all defined as private in the QGLIB_WRAPPER/QGST_WRAPPER
148 macros.
149
150 RefPointer always creates a new instance of the wrapper class every time it is
151 copied, but it keeps the m_object protected variable of RefCountedObject pointing
152 to the same underlying glib/gstreamer object, using ref()/unref() to keep its
153 reference count correct.
154
155 For classes that implement the makeWritable() virtual method, this method is always
156 called before accessing a non-const member function. This is to implement semantics
157 similar to Qt's implicit sharing for gstreamer classes that use the concept of being
158 writable only when their reference count is 1, such as GstMiniObject and GstCaps.
159 The idea is that makeWritable() makes a copy of the object if its reference count is
160 higher than 1, so when one accesses a non-const method on an object that has more
161 than one references, it is automatically copied.
162
163
164 6. About codegen
165 ----------------
166
167 Codegen is a simple code generator that does two basic jobs:
168
169  1) It generates all the implementations of the QGlib::GetType<T> specializations.
170 GetType<T>() is used to get the GType of a type at runtime. Since we don't want
171 the target application to include any glib/gstreamer headers and/or link to
172 glib/gstreamer directly, this is the only way to be able to find the GType of
173 a class in a template class or method, such as RefPointer::dynamicCast(),
174 Value::init(), etc...
175
176 The header declaration of all these specializations is added on the header of each
177 class, with the QGLIB_REGISTER_TYPE() macro. This defines the declaration of the
178 specialization and also acts as a keyword for codegen, which then generates the
179 implementation.
180
181 The usage is simple. For example: QGLIB_REGISTER_TYPE(QGst::Element)
182 With this declaration, codegen will generate an implementation that returns
183 GST_TYPE_ELEMENT.
184
185 If a class name doesn't exactly reflect its GType getter macro, then one can
186 tell codegen which is the real GType macro with a special "codegen instruction"
187 comment after the QGLIB_REGISTER_TYPE keyword that goes like this:
188
189     //codegen: GType=GST_TYPE_FOO
190
191 For example, QGLIB_REGISTER_TYPE(QGlib::ParamSpec) would generate an implementation
192 that returns G_TYPE_PARAM_SPEC. However, that macro doesn't really exist, the
193 correct one is G_TYPE_PARAM. So, we define it like this:
194
195     QGLIB_REGISTER_TYPE(QGst::ParamSpec) //codegen: GType=G_TYPE_PARAM
196
197
198  2) It generates static assertions for all the enums to make sure that their
199 value is exactly the same as their glib/gstreamer equivalent. This is just used
200 as a safety test for developers and doesn't have any impact on the library.
201
202 Since, according to the coding style, all enums should be camel case, starting
203 with a capital and glib's coding style says all enums should be capitals with
204 underscores for separators, codegen does a style conversion to find out the
205 glib/gstreamer equivalent of the enum. An enum that is defined as: FooBar
206 in the namespace QGst will become GST_FOO_BAR. If an enum is defined in such a way
207 that the conversion is not accurate, then one can use a "codegen instruction"
208 after the opening brace of the enum definition that goes like this:
209
210     //codegen: EnumToBeConverted=ENUM_HOW_IT_SHOULD_BE_CONVERTED, SecondEnum=SECONDENUM , ...
211
212 This will assume that "EnumToBeConverted" is "GST_ENUM_HOW_IT_SHOULD_BE_CONVERTED"
213 (assuming that the namespace is QGst), and similar for "SecondEnum" -> GST_SECONDENUM
214
215 A real world example:
216
217 ---- snip ----
218 namespace QGst {
219     enum PadLinkReturn {
220         //codegen: PadLinkNoFormat=PAD_LINK_NOFORMAT, PadLinkNoSched=PAD_LINK_NOSCHED
221         PadLinkOk = 0,
222         PadLinkWrongHierarchy = -1,
223         PadLinkWasLinked = -2,
224         PadLinkWrongDirection = -3,
225         PadLinkNoFormat = -4,
226         PadLinkNoSched = -5,
227         PadLinkRefused = -6
228     };
229 }
230 QGLIB_REGISTER_TYPE(QGst::PadLinkReturn)
231 ---- endsnip ----
232
233 For this snippet, codegen will generate:
234
235 ---- snip ----
236 QGLIB_REGISTER_TYPE_IMPLEMENTATION(QGst::PadLinkReturn,GST_TYPE_PAD_LINK_RETURN)
237
238 namespace QGst {
239     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkOk) == static_cast<int>(GST_PAD_LINK_OK));
240     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongHierarchy) == static_cast<int>(GST_PAD_LINK_WRONG_HIERARCHY));
241     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWasLinked) == static_cast<int>(GST_PAD_LINK_WAS_LINKED));
242     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongDirection) == static_cast<int>(GST_PAD_LINK_WRONG_DIRECTION));
243     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoFormat) == static_cast<int>(GST_PAD_LINK_NOFORMAT));
244     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoSched) == static_cast<int>(GST_PAD_LINK_NOSCHED));
245     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkRefused) == static_cast<int>(GST_PAD_LINK_REFUSED));
246 }
247 ---- endsnip ----
248
249
250 7. How to contribute
251 --------------------
252
253 Simply clone the repository on gitorious, develop the feature that you want there
254 and when it's ready, send me a merge request.
255
256
257 --
258 George Kiagiadakis <kiagiadakis.george@gmail.com>
259 Last updated: 8 July 2010