Qt bindings of GStreamer on Android (failed experience)
Table of Contents
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:
- first thing is that all the fancy automated tools provided by GStreamer team for Android doesn't work here.
- he second is that the Qt bindings are not available in the official pre-built binaries and we need to create our own custom version of gstreamer library.
1. Build the libgstreamer_android.so
Official tutorials of Gstreamer, are based on Android NDK build system, which
automatically build and deploy the libgstreamer_android.so
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 libgstreamer_android.so
file for us:
GSTREAMER_ROOT_ANDROID = $$_PRO_FILE_PWD_/gstreamer-1.0/armv7 gst.target = $$ANDROID_PACKAGE_SOURCE_DIR/libs/armeabi-v7a/libgstreamer_android.so gst.commands = cd $$ANDROID_PACKAGE_SOURCE_DIR; \ ./build_gstreamer.sh TARGET_ARCH_ABI=armeabi-v7a \ GSTREAMER_ROOT_ANDROID=$$GSTREAMER_ROOT_ANDROID \ NDK_PROJECT_PATH=$$ANDROID_PACKAGE_SOURCE_DIR extraclean.commands = rm -rv $$ANDROID_PACKAGE_SOURCE_DIR/libs $$ANDROID_PACKAGE_SOURCE_DIR/obj clean.depends += extraclean QMAKE_EXTRA_TARGETS += gst clean extraclean PRE_TARGETDEPS += $$ANDROID_PACKAGE_SOURCE_DIR/libs/armeabi-v7a/libgstreamer_android.so
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 libgstreamer_android.so
based on
the make file we added to android/jni/Android.mk
.
2. 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 https://gitlab.freedesktop.org/gstreamer/cerbero $ 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 libgstreamer_android.so
using this bundle,
we receive following linker errors, which I didn't have a chance to fix them
yet.
... ../gstqsgtexture.cc:36: error: undefined reference to 'QSGTexture::QSGTexture()' ../gstqsgtexture.cc:36: error: undefined reference to 'QOpenGLFunctions::QOpenGLFunctions()' ../gstqsgtexture.cc:40: error: undefined reference to 'QOpenGLFunctions::initializeOpenGLFunctions()' ../gstqsgtexture.cc:55: error: undefined reference to 'QSGTexture::~QSGTexture()' ../gstqsgtexture.cc:64: error: undefined reference to 'QOpenGLContext::functions() const' ../gstqsgtexture.cc:67: error: undefined reference to 'QSGTexture::~QSGTexture()' ../gstqsgtexture.cc:67: error: undefined reference to 'QSGTexture::~QSGTexture()' ../gstqsgtexture.cc:172: 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)
3. References
these are the usefull references that I found during my journay of working on this issue: