Personal Notes by ramajd

19 Apr 2022

Qt bindings of GStreamer on Android (failed experience)

for the ones who may read this note, unfortunately I couldn't succeed to provide a working solution. however I decided to write my findings here, hat hopefully help someone else that wants to cdo the same thing in the future. the source code related to my tries is located on this repository.

There are two things that we should consider when we want to start our journay:

Build the

Official tutorials of Gstreamer, are based on Android NDK build system, which automatically build and deploy the library (absolutely without Qt support!) to the target APK based on the plugins has been chosen inside make file.

we need to replace it by custom targets in our qmake project file. to do so we defined two custom targets to build and cleanup the file for us:

GSTREAMER_ROOT_ANDROID = $$_PRO_FILE_PWD_/gstreamer-1.0/armv7 = $$ANDROID_PACKAGE_SOURCE_DIR/libs/armeabi-v7a/
gst.commands = cd $$ANDROID_PACKAGE_SOURCE_DIR; \
               ./ TARGET_ARCH_ABI=armeabi-v7a \

extraclean.commands = rm -rv $$ANDROID_PACKAGE_SOURCE_DIR/libs $$ANDROID_PACKAGE_SOURCE_DIR/obj
clean.depends += extraclean

QMAKE_EXTRA_TARGETS += gst clean extraclean

since we don't have access to the environment variables during our custom target, I wrote a custom bash script to first prepare the environment (the Android relate paths), and then run the ndk-build for me:

source ~/.bashrc
ndk-build $@

finally we have the requirements to build the based on the make file we added to android/jni/

Build the Gstreamer libraries including the Qt bindings

The approach that I followed was to use the cerbero the build system which is provided by GStreamer team to create custom bundles of GStreamer.

to do so, first we need to checkout the cerbero from it's repository and checkout the version we want to build.

$ git clone
$ cd cerbero
$ git checkout 1.20.1

then we need to bootstrap the cerbero to have all of it's requirements. we also need identify our cross compile configuration using one of the configurations provided inside config folder. I used the config/cross-android-universal.cbc config.

Note: in my experience I faced errors about missing python pacakges (distro), my host OS (Manjaro) was also undefined for the bootstrap script, so I add it manually, based on the error messages that I received.

$ ./cerbero-uninstalled -c config/cross-android-universal.cbc bootstrap

after preparing the environment, we go for building our custom GStreamer bundle. to do so we use the package command and add the qt5 variant to list of it's default recipes.

export QMAKE='/path/to/Qt/5.15.2/android/bin/qmake'
$ ./cerbero-uninstalled -c config/cross-android-universal.cbc -v qt5 package gstreamer-1.0

following the above steps, we have a gstreamer-1.0-android-universal-1.20.1.tar.xz` file which including the Qt5 bindings. they will be added as ~GSTREAMER_PLUGINS_QT5 plugin to the list of plugins.

however when I trying to create the using this bundle, we receive following linker errors, which I didn't have a chance to fix them yet.

../ error: undefined reference to 'QSGTexture::QSGTexture()'
../ error: undefined reference to 'QOpenGLFunctions::QOpenGLFunctions()'
../ error: undefined reference to 'QOpenGLFunctions::initializeOpenGLFunctions()'
../ error: undefined reference to 'QSGTexture::~QSGTexture()'
../ error: undefined reference to 'QOpenGLContext::functions() const'
../ error: undefined reference to 'QSGTexture::~QSGTexture()'
../ error: undefined reference to 'QSGTexture::~QSGTexture()'
../ error: undefined reference to 'QOpenGLContext::functions() const'
armeabi-v7a/moc_gstqsgtexture.cpp:88: error: undefined reference to 'QSGTexture::qt_metacast(char const*)'
armeabi-v7a/moc_gstqsgtexture.cpp:93: error: undefined reference to 'QSGTexture::qt_metacall(QMetaObject::Call, int, void**)'
/home/reza/QtProjects/GStreamerTest/gstreamer-1.0/armv7/lib/gstreamer-1.0/libgstqmlgl.a(moc_gstqsgtexture.o):moc_gstqsgtexture.cpp:GstQSGTexture::staticMetaObject: error: undefined reference to 'QSGTexture::staticMetaObject'
/home/reza/QtProjects/GStreamerTest/gstreamer-1.0/armv7/lib/gstreamer-1.0/libgstqmlgl.a(moc_gstqsgtexture.o):moc_gstqsgtexture.cpp:vtable for GstQSGTexture: error: undefined reference to 'QSGTexture::normalizedTextureSubRect() const'
/home/reza/QtProjects/GStreamerTest/gstreamer-1.0/armv7/lib/gstreamer-1.0/libgstqmlgl.a(moc_gstqsgtexture.o):moc_gstqsgtexture.cpp:vtable for GstQSGTexture: error: undefined reference to 'QSGTexture::isAtlasTexture() const'
/home/reza/QtProjects/GStreamerTest/gstreamer-1.0/armv7/lib/gstreamer-1.0/libgstqmlgl.a(moc_gstqsgtexture.o):moc_gstqsgtexture.cpp:vtable for GstQSGTexture: error: undefined reference to 'QSGTexture::removedFromAtlas() const'
/home/reza/QtProjects/GStreamerTest/gstreamer-1.0/armv7/lib/gstreamer-1.0/libgstqmlgl.a(moc_gstqsgtexture.o):moc_gstqsgtexture.cpp:typeinfo for GstQSGTexture: error: undefined reference to 'typeinfo for QSGTexture'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)


these are the usefull references that I found during my journay of working on this issue:

Tags: android gstreamer Qt
13 Dec 2021

Guix: how to set package udev rules

Just read a thread on guix mailing list, about adding udev rules for a package. in order to have an fixed reference about it, I decided to post it here.

adding udev rules for a guix package is as easy as adding it to the <out>/lib/udev/rules.d/ directory. so we can either add it as an INSTALL rule in our CMakefile.txt or add it to manually install the rules as part of our package install phase:

(define-public package-name
      (modify-phases %standard-phases
       (add-after 'unpack 'patch-udev-rules
         (lambda* (#:key outputs #:allow-other-keys)
           (let ((out (assoc-ref outputs "out")))
             (substitute* "CMakefile.txt"
                           (string-append out "/lib/udev/rules.d")))
(define-public package-name
      (modify-phases %standard-phases
       (add-after 'install 'install-udev-rules
         (lambda* (#:key outputs #:allow-other-keys)
           (let ((out (assoc-ref outputs "out")))
             (mkdir-p (string-append out "/lib/udev/rules.d"))
             (copy-file "123-my-custom-udev.rules"
                        (string-append out
Tags: guix
04 Dec 2020

New Start

After a while finally I decided to restore back my personal blog, writting down challenges I'm facing with, during my daily work. this time I decided to write in English, might be more useful for the ones who might face same issues.

One of the challenges that I faced was to choose a proper platform to build my blog on top of. using blog services like Blogger or Wordpress previously they seemd to be kind of over-qualified for my needs. so I decided to switch to static blog generators this time.

It's been a while that I'm using GNU Guix on my work and it was an opportunity for me to use GNU Emacs as my common text editor and IDE. working more with Emacs, I love this editor much more.


Since for each problem you face, Emacs provides you a solution, it also has a solution for my blogging Problem, Org Mode. search for Emacs blogging tools, there are a bunch of packages already available, and since I was looking for a simple tool to allow me setup my blog rapidly, I decided to use org-static-blog.

In order to setup my blog, I just need to add an initial configuration to my init.el file, create new post using org-static-blog-create-new-post and run org-static-blog-publish to generate html files. after that the only thing that I need to do was to publish generated files to github pages.

Tags: personal
Other posts
Creative Commons License
licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.