GStreamer on Qt for iOS

Hello,

I'm trying to develop an iOS application (iPad should be the main target) for controlling a device (Linux embedded) connected to the same network.

Basically it is a remote desktop application.

The application must be multi-platform, so it has be built within a multi-platform framework. This requirement is fulfilled by developing the app with Qt and Qt Creator.

The application should play a stream video stream transmitted over the network from the Linux device. I use GStreamer for that. I already downloaded and succesfully installed the iOS package from the official site.

Now, I have some trouble linking the GStreamer framework in the .pro file.

In desktop environments (Windows, Linux and macOS) all I need to do is to use pkg-config

Code Block
mac {
QT_CONFIG -= no-pkg-config
PKG_CONFIG = /usr/local/bin/pkg-config
}
CONFIG += link_pkgconfig
PKGCONFIG += gstreamer-1.0
PKGCONFIG += gstreamer-pbutils-1.0

and it works just fine. In iOS I don't have pkg-config (afik), so I manually added the framework:

Code Block
LIBS += -F$$PWD/../../Library/Developer/GStreamer/iPhone.sdk/ -framework GStreamer
INCLUDEPATH += $$PWD/../../Library/Developer/GStreamer/iPhone.sdk/GStreamer.framework/Versions/1.0/Headers
DEPENDPATH += $$PWD/../../Library/Developer/GStreamer/iPhone.sdk/GStreamer.framework/Versions/1.0/Headers

When I try to build, it gives me this error:

Code Block
GStreamer(libglib-2_0_a-gconvert.c.o):-1: error: Undefined symbols for architecture x86_64:
"___darwin_check_fd_set_overflow", referenced from:
_gst_poll_wait in GStreamer(libgstreamer-1_0_a-gstpoll.c.o)
"_iconv_close", referenced from:
_g_convert in GStreamer(libglib-2_0_a-gconvert.c.o)
_g_convert_with_fallback in GStreamer(libglib-2_0_a-gconvert.c.o)
(maybe you meant: _g_iconv_close)
"_iconv", referenced from:
_g_convert_with_iconv in GStreamer(libglib-2_0_a-gconvert.c.o)
_g_convert_with_fallback in GStreamer(libglib-2_0_a-gconvert.c.o)
(maybe you meant: _g_iconv_close, _g_iconv , _g_iconv_open , _g_convert_with_iconv )
"_iconv_open", referenced from:
_try_conversion in GStreamer(libglib-2_0_a-gconvert.c.o)
(maybe you meant: _g_iconv_open)

Tried to link the apparently missing liconv, but no luck.

Code Block
macx: LIBS += -L$$PWD/../../../../Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/ -liconv
INCLUDEPATH += $$PWD/../../../../Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr
DEPENDPATH += $$PWD/../../../../Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr


I'm aware of the existence of a similar question on nabble.com but I still couldn't figure out the problem.

Any thoughts?
Thanks


Additional info
  • The application must be multi-platform, so it must be built in Qt Creator. It already works on Windows, Linux and macOS.

  • developing machine macOS 11.3.1

  • Xcode version 11.2.1

  • Qt version 5.15.2


Some progress:


So far I've managed to correctly link the library and successfully run the project in the Simulator, but when I try to create *GStreamer* elements it fails at runtime.

Here it is my .pro

Code Block
#iOS
INCLUDEPATH += /Users/user/Library/Developer/GStreamer/iPhone.sdk/GStreamer.framework/Headers
LIBS += -F /Users/user/Library/Developer/GStreamer/iPhone.sdk -framework GStreamer
LIBS += -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib -liconv
QMAKE_IOS_DEPLOYMENT_TARGET = 12.0
# Universal target (iPhone and iPad)
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 1,2
QMAKE_APPLE_DEVICE_ARCHS = arm64
QMAKE_APPLE_SIMULATOR_ARCHS = x86_64


And here it is where it fails:

Code Block
data.pipeline = gst_pipeline_new ("pipeline");
qDebug() << "pipeline" << data.pipeline;
data.udpsrc = gst_element_factory_make("udpsrc", NULL);
data.rtph264depay = gst_element_factory_make("rtph264depay", NULL);
data.avdec_h264 = gst_element_factory_make("avdec_h264", NULL);
data.videoconvert = gst_element_factory_make("videoconvert", NULL);
data.videoflip = gst_element_factory_make ("videoflip", NULL);
qDebug() << "udpsrc" << data.udpsrc;
qDebug() << "rtph264depay" << data.rtph264depay;
qDebug() << "avdec_h264" << data.avdec_h264;
qDebug() << "videoconvert" << data.videoconvert;
qDebug() << "videoflip" << data.videoflip;


All the calls to *gst_element_factory_make* return null.

Additional Info
  • Qt 5.15.2

  • Xcode 12.5

  • Develop on Big Sur

Any ideas?

Thanks
Some progress #2

The error shown is:

Code Block
0:00:12.281788000 5678 0x7fbc5cd1c200 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "udpsrc"!
0:00:12.281795000 5678 0x7fbc5cd1c200 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "rtph264depay"!
0:00:12.281801000 5678 0x7fbc5cd1c200 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "avdec_h264"!
0:00:12.281805000 5678 0x7fbc5cd1c200 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "videoconvert"!
0:00:12.281811000 5678 0x7fbc5cd1c200 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "videoflip"!


so clearly it doesn't find the plugins.

I believe that the correct approach to solve the problem is to register such plugins, by writing something like this in main.cpp:

Code Block
// Declar plugins
G_BEGIN_DECLS
GST_PLUGIN_STATIC_DECLARE(coreelements);
GST_PLUGIN_STATIC_DECLARE(videotestsrc);
GST_PLUGIN_STATIC_DECLARE(videoconvert);
GST_PLUGIN_STATIC_DECLARE(playback);
GST_PLUGIN_STATIC_DECLARE(x264);
GST_PLUGIN_STATIC_DECLARE(libav);
GST_PLUGIN_STATIC_DECLARE(encoding);
//...
G_END_DECLS
int main(int argc, char *argv[]) {
// Initialize the GStreamer library
if (gst_init_check(&argc, &argv, NULL)) {
qDebug() << "This program is linked against" << gst_version_string();
}
// Register plugins
GST_PLUGIN_STATIC_REGISTER(coreelements);
GST_PLUGIN_STATIC_REGISTER(videotestsrc);
GST_PLUGIN_STATIC_REGISTER(videoconvert);
GST_PLUGIN_STATIC_REGISTER(playback);
GST_PLUGIN_STATIC_REGISTER(x264);
GST_PLUGIN_STATIC_REGISTER(libav);
GST_PLUGIN_STATIC_REGISTER(encoding);
//...
}


This does in fact give me some positive results, because now some elements are successfully created:

Code Block
0:01:48.471557000 5973 0x7fa450c1ec00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:361:gst_element_factory_create: creating element "pipeline" named "pipeline"
pipeline 0x7fa452204160
0:01:48.472489000 5973 0x7fa450c1ec00 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "udpsrc"!
0:01:48.472503000 5973 0x7fa450c1ec00 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "rtph264depay"!
0:01:48.472513000 5973 0x7fa450c1ec00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:363:gst_element_factory_create: creating element "avdec_h264"
0:01:48.474720000 5973 0x7fa450c1ec00 INFO GST_ELEMENT_FACTORY gstelementfactory.c:363:gst_element_factory_create: creating element "videoconvert"
0:01:48.474936000 5973 0x7fa450c1ec00 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "videoflip"!
0:01:48.475071000 5973 0x7fa450c1ec00 WARN GST_ELEMENT_FACTORY gstelementfactory.c:467:gst_element_factory_make: no such element factory "glimagesink"!


But if I try to register the others plugins, for example by adding

Code Block
GST_PLUGIN_STATIC_DECLARE(udp);

and

Code Block
GST_PLUGIN_STATIC_REGISTER(udp);

it gives me this error:

Code Block
GStreamer(libgio-2_0_a-gresolver.c.o):-1: error: Undefined symbols for architecture x86_64:
"_res_9_dn_expand", referenced from:
_do_lookup_records in GStreamer(libgio-2_0_a-gthreadedresolver.c.o)
"_res_9_ninit", referenced from:
_do_lookup_records in GStreamer(libgio-2_0_a-gthreadedresolver.c.o)
"_res_9_nquery", referenced from:
_do_lookup_records in GStreamer(libgio-2_0_a-gthreadedresolver.c.o)
"_res_9_ndestroy", referenced from:
_do_lookup_records in GStreamer(libgio-2_0_a-gthreadedresolver.c.o)
"_res_9_init", referenced from:
_g_resolver_maybe_reload in GStreamer(libgio-2_0_a-gresolver.c.o)


I encountered a similar error before and I solved by adding the missing library (where the symbols were) in the .pro file:

Code Block
LIBS += -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib -liconv



It seems that is missing the gio (or something like that) library, but I don't know where to find it.

[EDIT]

After a quick search

Code Block
locate libgio
/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/gio/modules/libgioopenssl.a
/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/gio/modules/libgioopenssl.so
/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libgio-2.0.0.dylib
/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libgio-2.0.a
/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libgio-2.0.dylib
/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libgio-2.0.la


I can locate the library for macOS, but not for iOS. In fact if I try to add it

Code Block
LIBS += -L/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/ -lgio-2.0


it (rightfully) complains about it:

Code Block
:-1: error: building for iOS Simulator, but linking in dylib built for macOS, file '/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libgio-2.0.dylib' for architecture x86_64



I also tried to include the get_ios_init.h and get_ios_init.m configuration files of the GStreamer tutorials by copying them into the project by adding

Code Block
CONFIG += c++11
CONFIG += objective_c
OBJECTIVE_HEADERS = gst_ios_init.h
OBJECTIVE_SOURCES = gst_ios_init.m


but it didn't help.

Any ideas?
Thanks
GStreamer on Qt for iOS
 
 
Q