Port the 'echo' example to the new bindings to make it work again.
[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 in early development state and is not suitable for use.
16
17 - What are the differences between the C++ bindings of QtGstreamer and Gstreamermm?
18
19  * QtGstreamer provides bindings that completely hide the Gstreamer ABI,
20    so your application doesn’t need to link to Gstreamer itself.
21  * QtGstreamer uses QtCore helper classes (QString, QList, etc..) where it can,
22    to ease integration with Qt.
23  * QtGstreamer provides support for connecting arbitrary GObject signals to
24    slots, while in Gstreamermm every signal needs to be defined in the bindings,
25    or else you need to use the C API for connecting it. This is especially useful
26    for connecting signals from element plugins, where their interface is unknown
27    at compile time.
28
29
30 2. Building
31 -----------
32
33 QtGstreamer requires the following software to be installed in order to build:
34  * CMake <http://www.cmake.org/>
35  * Gstreamer <http://gstreamer.freedesktop.org/>
36    With its dependencies:
37    - Glib / GObject <http://www.gtk.org/>
38    - libxml2 <http://xmlsoft.org/>
39  * Qt 4 <http://qt.nokia.com/>
40  * Automoc <svn://anonsvn.kde.org/home/kde/trunk/kdesupport/automoc/>
41  * Boost (static_assert, type_traits, function, bind) <http://www.boost.org/>
42  * Flex <http://flex.sourceforge.net/>
43  * Bison <http://www.gnu.org/software/bison/>
44
45 Also, for the moment, the GNU C++ compiler (g++) version 4.4 or later is required
46 in order to build the GObject signals wrapper, which is based on C++0x variadic
47 templates. In the future I plan to provide a non-variadic template version too,
48 with some limitation on the number of signal arguments.
49
50 To build, the procedure is simple:
51
52 $ mkdir build && cd build
53 $ cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/installation/prefix
54 $ make
55 $ make install
56
57
58 3. Coding style
59 ---------------
60
61 QtGstreamer follows the kdelibs coding style:
62 http://techbase.kde.org/Policies/Kdelibs_Coding_Style
63
64
65 4. Naming policies
66 ------------------
67
68 4.1 The namespaces
69 ------------------
70
71 The "G" namespace (GObject, GValue, etc...) is referred to as "QGlib".
72 The "Gst" namespace (GstObject, GstElement, etc...) is referred to as "QGst".
73 I didn't like them much when I chose them, better names could be discussed...
74
75 4.2 The class names
76 -------------------
77
78 Class names should be the same as their G* equivalents, with the namespace
79 prefix removed. For example, "GstObject" becomes "QGst::Object", "GParamSpec"
80 becomes "QGlib::ParamSpec", etc...
81
82 4.3 The method names
83 --------------------
84
85 In general the method names should be the same as the gstreamer ones,
86 with the g[st]_<class> prefix removed and converted to camel case.
87
88 For example,
89     gboolean gst_caps_is_empty(const GstCaps *caps);
90 becomes:
91     bool isEmpty() const;
92 (and member of the QGst::Caps class)
93
94 There are cases where this may not be followed:
95
96 1) Properties. Most property getters have a "get" prefix, for example,
97 gst_object_get_name(). In QtGstreamer the "get" prefix is omitted, so this
98 becomes just name().
99
100 2) Overloaded members. In C there is no possibility to have two methods with
101 the same name, so overloaded members usually have some extra suffix, like "_full".
102 For example, g_object_set_data and g_object_set_data_full. In C++ we just add
103 a method with the same name, or put optional parameters in the existing method.
104
105 3) Other cases where the glib/gstreamer method name doesn't make much sense...
106 For example, gst_element_is_locked_state(). That doesn't make sense in english,
107 as "state" is the subject and should go before the verb "is".
108 So, it becomes stateIsLocked().
109
110
111 5. Refcounted wrappers policy
112 -----------------------------
113
114 All reference counted classes must:
115 1) Inherit from QGlib::RefCountedObject and implement its virtual ref() and
116    unref() methods.
117 2) Include the QGLIB_WRAPPER (or QGST_WRAPPER) macro in their class declaration.
118    This is used like this: QGST_WRAPPER(ClassName).
119 3) Be used with QGlib::RefPointer<T> and provide a
120    typedef QGlib::RefPointer<ClassName> ClassNamePtr;
121
122 No constructor/destructor/copy constructor/assignment operator is allowed for
123 these classes and they are all defined as private in the QGLIB_WRAPPER/QGST_WRAPPER
124 macros.
125
126 RefPointer always creates a new instance of the wrapper class every time it is
127 copied, but it keeps the m_object protected variable of RefCountedObject pointing
128 to the same underlying glib/gstreamer object, using ref()/unref() to keep its
129 reference count correct.
130
131
132 6. About codegen
133 ----------------
134
135 Codegen is a simple code generator that does two basic jobs:
136
137  1) It generates all the implementations of the QGlib::GetType<T> specializations.
138 GetType<T>() is used to get the GType of a type at runtime. Since we don't want
139 the target application to include any glib/gstreamer headers and/or link to
140 glib/gstreamer directly, this is the only way to be able to find the GType of
141 a class in a template class or method, such as RefPointer::dynamicCast(),
142 Value::init(), etc...
143
144 The header declaration of all these specializations is added on the header of each
145 class, with the QGLIB_REGISTER_TYPE() macro. This defines the declaration of the
146 specialization and also acts as a keyword for codegen, which then generates the
147 implementation.
148
149 The usage is simple. For example: QGLIB_REGISTER_TYPE(QGst::Element)
150 With this declaration, codegen will generate an implementation that returns
151 GST_TYPE_ELEMENT.
152
153 If a class name doesn't exactly reflect its GType getter macro, then one can
154 tell codegen which is the real GType macro with a special "codegen instruction"
155 comment after the QGLIB_REGISTER_TYPE keyword that goes like this:
156
157     //codegen: GType=GST_TYPE_FOO
158
159 For example, QGLIB_REGISTER_TYPE(QGlib::ParamSpec) would generate an implementation
160 that returns G_TYPE_PARAM_SPEC. However, that macro doesn't really exist, the
161 correct one is G_TYPE_PARAM. So, we define it like this:
162
163     QGLIB_REGISTER_TYPE(QGst::ParamSpec) //codegen: GType=G_TYPE_PARAM
164
165
166  2) It generates static assertions for all the enums to make sure that their
167 value is exactly the same as their glib/gstreamer equivalent. This is just used
168 as a safety test for developers and doesn't have any impact on the library.
169
170 Since, according to the coding style, all enums should be camel case, starting
171 with a capital and glib's coding style says all enums should be capitals with
172 underscores for separators, codegen does a style conversion to find out the
173 glib/gstreamer equivalent of the enum. An enum that is defined as: FooBar
174 in the namespace QGst will become GST_FOO_BAR. If an enum is defined in such a way
175 that the conversion is not accurate, then one can use a "codegen instruction"
176 after the opening brace of the enum definition that goes like this:
177
178     //codegen: EnumToBeConverted=ENUM_HOW_IT_SHOULD_BE_CONVERTED, SecondEnum=SECONDENUM , ...
179
180 This will assume that "EnumToBeConverted" is "GST_ENUM_HOW_IT_SHOULD_BE_CONVERTED"
181 (assuming that the namespace is QGst), and similar for "SecondEnum" -> GST_SECONDENUM
182
183 A real world example:
184
185 ---- snip ----
186 namespace QGst {
187     enum PadLinkReturn {
188         //codegen: PadLinkNoFormat=PAD_LINK_NOFORMAT, PadLinkNoSched=PAD_LINK_NOSCHED
189         PadLinkOk = 0,
190         PadLinkWrongHierarchy = -1,
191         PadLinkWasLinked = -2,
192         PadLinkWrongDirection = -3,
193         PadLinkNoFormat = -4,
194         PadLinkNoSched = -5,
195         PadLinkRefused = -6
196     };
197 }
198 QGLIB_REGISTER_TYPE(QGst::PadLinkReturn)
199 ---- endsnip ----
200
201 For this snippet, codegen will generate:
202
203 ---- snip ----
204 QGLIB_REGISTER_TYPE_IMPLEMENTATION(QGst::PadLinkReturn,GST_TYPE_PAD_LINK_RETURN)
205
206 namespace QGst {
207     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkOk) == static_cast<int>(GST_PAD_LINK_OK));
208     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongHierarchy) == static_cast<int>(GST_PAD_LINK_WRONG_HIERARCHY));
209     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWasLinked) == static_cast<int>(GST_PAD_LINK_WAS_LINKED));
210     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongDirection) == static_cast<int>(GST_PAD_LINK_WRONG_DIRECTION));
211     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoFormat) == static_cast<int>(GST_PAD_LINK_NOFORMAT));
212     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoSched) == static_cast<int>(GST_PAD_LINK_NOSCHED));
213     BOOST_STATIC_ASSERT(static_cast<int>(PadLinkRefused) == static_cast<int>(GST_PAD_LINK_REFUSED));
214 }
215 ---- endsnip ----
216
217
218 7. How to contribute
219 --------------------
220
221 Simply clone the repository on gitorious, develop the feature that you want there
222 and when it's ready, send me a merge request.
223
224
225 --
226 George Kiagiadakis <kiagiadakis.george@gmail.com>
227 14 April 2010