summaryrefslogtreecommitdiff
path: root/README
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <kiagiadakis.george@gmail.com>2010-04-14 12:17:46 +0300
committerGeorge Kiagiadakis <kiagiadakis.george@gmail.com>2010-04-14 12:17:46 +0300
commit246328aff0e81a62bb8e1e9e76237ed085508040 (patch)
treebf2d8fb32bba61ce604a6d98686e9401fe06e8cf /README
parent321bc745d792fda87b5ab77d14f69993559a91ec (diff)
Add a README file with various information, mostly targeted to people that want to contribute.
Diffstat (limited to 'README')
-rw-r--r--README227
1 files changed, 227 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..f27a6fa
--- /dev/null
+++ b/README
@@ -0,0 +1,227 @@
+1. About
+--------
+
+- What is QtGstreamer?
+
+QtGstreamer aims to become a library providing C++ bindings for Gstreamer [1]
+with a Qt-style API plus some helper classes for integrating Gstreamer better
+in Qt [2] applications.
+
+[1]. http://gstreamer.freedesktop.org/
+[2]. http://qt.nokia.com/
+
+- What is QtGstreamer’s development state at the moment?
+
+QtGstreamer is still in early development state and is not suitable for use.
+
+- What are the differences between the C++ bindings of QtGstreamer and Gstreamermm?
+
+ * QtGstreamer provides bindings that completely hide the Gstreamer ABI,
+ so your application doesn’t need to link to Gstreamer itself.
+ * QtGstreamer uses QtCore helper classes (QString, QList, etc..) where it can,
+ to ease integration with Qt.
+ * QtGstreamer provides support for connecting arbitrary GObject signals to
+ slots, while in Gstreamermm every signal needs to be defined in the bindings,
+ or else you need to use the C API for connecting it. This is especially useful
+ for connecting signals from element plugins, where their interface is unknown
+ at compile time.
+
+
+2. Building
+-----------
+
+QtGstreamer requires the following software to be installed in order to build:
+ * CMake <http://www.cmake.org/>
+ * Gstreamer <http://gstreamer.freedesktop.org/>
+ With its dependencies:
+ - Glib / GObject <http://www.gtk.org/>
+ - libxml2 <http://xmlsoft.org/>
+ * Qt 4 <http://qt.nokia.com/>
+ * Automoc <svn://anonsvn.kde.org/home/kde/trunk/kdesupport/automoc/>
+ * Boost (static_assert, type_traits, function, bind) <http://www.boost.org/>
+ * Flex <http://flex.sourceforge.net/>
+ * Bison <http://www.gnu.org/software/bison/>
+
+Also, for the moment, the GNU C++ compiler (g++) version 4.4 or later is required
+in order to build the GObject signals wrapper, which is based on C++0x variadic
+templates. In the future I plan to provide a non-variadic template version too,
+with some limitation on the number of signal arguments.
+
+To build, the procedure is simple:
+
+$ mkdir build && cd build
+$ cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/installation/prefix
+$ make
+$ make install
+
+
+3. Coding style
+---------------
+
+QtGstreamer follows the kdelibs coding style:
+http://techbase.kde.org/Policies/Kdelibs_Coding_Style
+
+
+4. Naming policies
+------------------
+
+4.1 The namespaces
+------------------
+
+The "G" namespace (GObject, GValue, etc...) is referred to as "QGlib".
+The "Gst" namespace (GstObject, GstElement, etc...) is referred to as "QGst".
+I didn't like them much when I chose them, better names could be discussed...
+
+4.2 The class names
+-------------------
+
+Class names should be the same as their G* equivalents, with the namespace
+prefix removed. For example, "GstObject" becomes "QGst::Object", "GParamSpec"
+becomes "QGlib::ParamSpec", etc...
+
+4.3 The method names
+--------------------
+
+In general the method names should be the same as the gstreamer ones,
+with the g[st]_<class> prefix removed and converted to camel case.
+
+For example,
+ gboolean gst_caps_is_empty(const GstCaps *caps);
+becomes:
+ bool isEmpty() const;
+(and member of the QGst::Caps class)
+
+There are cases where this may not be followed:
+
+1) Properties. Most property getters have a "get" prefix, for example,
+gst_object_get_name(). In QtGstreamer the "get" prefix is omitted, so this
+becomes just name().
+
+2) Overloaded members. In C there is no possibility to have two methods with
+the same name, so overloaded members usually have some extra suffix, like "_full".
+For example, g_object_set_data and g_object_set_data_full. In C++ we just add
+a method with the same name, or put optional parameters in the existing method.
+
+3) Other cases where the glib/gstreamer method name doesn't make much sense...
+For example, gst_element_is_locked_state(). That doesn't make sense in english,
+as "state" is the subject and should go before the verb "is".
+So, it becomes stateIsLocked().
+
+
+5. Refcounted wrappers policy
+-----------------------------
+
+All reference counted classes must:
+1) Inherit from QGlib::RefCountedObject and implement its virtual ref() and
+ unref() methods.
+2) Include the QGLIB_WRAPPER (or QGST_WRAPPER) macro in their class declaration.
+ This is used like this: QGST_WRAPPER(ClassName).
+3) Be used with QGlib::RefPointer<T> and provide a
+ typedef QGlib::RefPointer<ClassName> ClassNamePtr;
+
+No constructor/destructor/copy constructor/assignment operator is allowed for
+these classes and they are all defined as private in the QGLIB_WRAPPER/QGST_WRAPPER
+macros.
+
+RefPointer always creates a new instance of the wrapper class every time it is
+copied, but it keeps the m_object protected variable of RefCountedObject pointing
+to the same underlying glib/gstreamer object, using ref()/unref() to keep its
+reference count correct.
+
+
+6. About codegen
+----------------
+
+Codegen is a simple code generator that does two basic jobs:
+
+ 1) It generates all the implementations of the QGlib::GetType<T> specializations.
+GetType<T>() is used to get the GType of a type at runtime. Since we don't want
+the target application to include any glib/gstreamer headers and/or link to
+glib/gstreamer directly, this is the only way to be able to find the GType of
+a class in a template class or method, such as RefPointer::dynamicCast(),
+Value::init(), etc...
+
+The header declaration of all these specializations is added on the header of each
+class, with the QGLIB_REGISTER_TYPE() macro. This defines the declaration of the
+specialization and also acts as a keyword for codegen, which then generates the
+implementation.
+
+The usage is simple. For example: QGLIB_REGISTER_TYPE(QGst::Element)
+With this declaration, codegen will generate an implementation that returns
+GST_TYPE_ELEMENT.
+
+If a class name doesn't exactly reflect its GType getter macro, then one can
+tell codegen which is the real GType macro with a special "codegen instruction"
+comment after the QGLIB_REGISTER_TYPE keyword that goes like this:
+
+ //codegen: GType=GST_TYPE_FOO
+
+For example, QGLIB_REGISTER_TYPE(QGlib::ParamSpec) would generate an implementation
+that returns G_TYPE_PARAM_SPEC. However, that macro doesn't really exist, the
+correct one is G_TYPE_PARAM. So, we define it like this:
+
+ QGLIB_REGISTER_TYPE(QGst::ParamSpec) //codegen: GType=G_TYPE_PARAM
+
+
+ 2) It generates static assertions for all the enums to make sure that their
+value is exactly the same as their glib/gstreamer equivalent. This is just used
+as a safety test for developers and doesn't have any impact on the library.
+
+Since, according to the coding style, all enums should be camel case, starting
+with a capital and glib's coding style says all enums should be capitals with
+underscores for separators, codegen does a style conversion to find out the
+glib/gstreamer equivalent of the enum. An enum that is defined as: FooBar
+in the namespace QGst will become GST_FOO_BAR. If an enum is defined in such a way
+that the conversion is not accurate, then one can use a "codegen instruction"
+after the opening brace of the enum definition that goes like this:
+
+ //codegen: EnumToBeConverted=ENUM_HOW_IT_SHOULD_BE_CONVERTED, SecondEnum=SECONDENUM , ...
+
+This will assume that "EnumToBeConverted" is "GST_ENUM_HOW_IT_SHOULD_BE_CONVERTED"
+(assuming that the namespace is QGst), and similar for "SecondEnum" -> GST_SECONDENUM
+
+A real world example:
+
+---- snip ----
+namespace QGst {
+ enum PadLinkReturn {
+ //codegen: PadLinkNoFormat=PAD_LINK_NOFORMAT, PadLinkNoSched=PAD_LINK_NOSCHED
+ PadLinkOk = 0,
+ PadLinkWrongHierarchy = -1,
+ PadLinkWasLinked = -2,
+ PadLinkWrongDirection = -3,
+ PadLinkNoFormat = -4,
+ PadLinkNoSched = -5,
+ PadLinkRefused = -6
+ };
+}
+QGLIB_REGISTER_TYPE(QGst::PadLinkReturn)
+---- endsnip ----
+
+For this snippet, codegen will generate:
+
+---- snip ----
+QGLIB_REGISTER_TYPE_IMPLEMENTATION(QGst::PadLinkReturn,GST_TYPE_PAD_LINK_RETURN)
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkOk) == static_cast<int>(GST_PAD_LINK_OK));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongHierarchy) == static_cast<int>(GST_PAD_LINK_WRONG_HIERARCHY));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWasLinked) == static_cast<int>(GST_PAD_LINK_WAS_LINKED));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongDirection) == static_cast<int>(GST_PAD_LINK_WRONG_DIRECTION));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoFormat) == static_cast<int>(GST_PAD_LINK_NOFORMAT));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoSched) == static_cast<int>(GST_PAD_LINK_NOSCHED));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkRefused) == static_cast<int>(GST_PAD_LINK_REFUSED));
+}
+---- endsnip ----
+
+
+7. How to contribute
+--------------------
+
+Simply clone the repository on gitorious, develop the feature that you want there
+and when it's ready, send me a merge request.
+
+
+--
+George Kiagiadakis <kiagiadakis.george@gmail.com>
+14 April 2010