Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Qt + GStreamer + Android
Qt 6.11 is out! See what's new in the release blog

Qt + GStreamer + Android

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
9 Posts 3 Posters 497 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    felsi
    wrote last edited by
    #1

    Hello, the title says it all.

    What i've done so far:

    1. I installed gstreamer on my linux pc.

    https://gstreamer.freedesktop.org/documentation/installing/on-linux.html?gi-language=c

    2. I read the very informativ tutorials at:

    https://gstreamer.freedesktop.org/documentation/tutorials/?gi-language=c

    3. I tried and played around with the qmlsink module:

    https://gitlab.freedesktop.org/gstreamer/gstreamer/-/tree/main/subprojects/gst-plugins-good/tests/examples/qt/qmlsink?ref_type=heads

    4. I downloaded the precompiled gstreamer libraries for android:

    https://gstreamer.freedesktop.org/data/pkg/android/

    5. I followed the install guide for gstreamer on android:

    https://gstreamer.freedesktop.org/documentation/installing/for-android-development.html?gi-language=c
    I already had NDK, gradle and co, because i already develop cross-platform with Qt.

    6. I built the android tutorials with gradle:

    https://gitlab.freedesktop.org/gstreamer/gstreamer/-/tree/main/subprojects/gst-docs/examples/tutorials/android?ref_type=heads

    7. So, now, the time has come to combine these things.

    I adapted the qmake based project from the qmlsink example.
    My test project contains a simple pipeline ("audiotestsrc ! autoaudiosink"), which works just fine on linux.
    So i naively set in the pro file:
    PKGCONFIG=/PATH/TO/GSTREAMER/arm64/lib/gstreamer-1.0/pkgconfig in the pro file.
    And i got: "Cross compiling without sysroot. Disabling pkg-config."
    So, i tried to add the libraries manually, which seemed to work instantly.
    It compiled, it ran, it crashed...
    It crashed not at the beginning, it crashed at a very boring line in the middle.
    I tried a lot of combinations of:

    • CMake QMake
    • Qt 6.5 6.8 6.11
    • GStreamer 1.26.13 1.28.3 1.29.1
    • Debian 12 (openjdk 17), Debian 13 (openjdk 21)
    • Huawai Android 7 (API 24), Samsung Android 16 (API 36)

    And the result is always the same, it crashes at the same line.
    Whether its my old Huawei with Qt 6.5, or with the new Samsung and Qt 6.11.
    So, this issue can't be new...
    I searched the forum and the web. The conclusion: other people added the libraries manually and it worked (a few year ago).
    Most of the information is not up-to-date, library names and the need to register modules for example.
    This seemed to be a dead end, so...

    8. I looked closer into the code of the working Android+GStreamer tutorial programs.

    https://gitlab.freedesktop.org/gstreamer/gstreamer/-/tree/main/subprojects/gst-docs/examples/tutorials/android/android-tutorial-1?ref_type=heads
    Starting with the build.gradle file of tutorial-1.
    This pointed me to the file 'jni/CMakeLists.txt' within the project.
    I tried to copy paste the relevant parts into the cmake file of my test project.

    cmake_minimum_required(VERSION 3.16)
    
    project(TestProject_GStreamer_CMake VERSION 0.1 LANGUAGES CXX)
    
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    find_package(Qt6 REQUIRED COMPONENTS Quick)
    
    qt_standard_project_setup(REQUIRES 6.8)
    
    qt_add_executable(appTestProject_GStreamer_CMake
        main.cpp
        gst_handler.h
        gst_handler.cpp
    )
    
    qt_add_qml_module(appTestProject_GStreamer_CMake
        URI TestProject_GStreamer_CMake
        QML_FILES
            Main.qml
    )
    
    # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
    # If you are developing for iOS or macOS you should consider setting an
    # explicit, fixed bundle identifier manually though.
    set_target_properties(appTestProject_GStreamer_CMake PROPERTIES
    #    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appTestProject_GStreamer_CMake
        MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
        MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
        MACOSX_BUNDLE TRUE
        WIN32_EXECUTABLE TRUE
    )
    
    
    #
    #
    #
    #   LINUX - working fine
    #
    #
    #
    if(LINUX)
    
        find_package(PkgConfig REQUIRED)
        pkg_search_module(gstreamer REQUIRED IMPORTED_TARGET gstreamer-1.0)
    
        target_link_libraries(appTestProject_GStreamer_CMake
            PRIVATE
                Qt6::Quick
                PkgConfig::gstreamer
        )
    
    endif()
    
    
    
    #
    #
    #
    #   ANDROID - not working
    #
    #
    #
    if(ANDROID)
    
        set(GSTREAMER_ROOT_ANDROID "/home/felsi/Dokumente/TestProjects/gstreamer-1.0-android-universal-1.26.11")
    
        if(NOT DEFINED GSTREAMER_ROOT_ANDROID)
            message(FATAL_ERROR "GSTREAMER_ROOT_ANDROID is not defined!")
        endif()
    
        if(ANDROID_ABI STREQUAL "armeabi")
            set(GSTREAMER_ROOT "${GSTREAMER_ROOT_ANDROID}/arm")
        elseif(ANDROID_ABI STREQUAL "armeabi-v7a")
            set(GSTREAMER_ROOT "${GSTREAMER_ROOT_ANDROID}/armv7")
        elseif(ANDROID_ABI STREQUAL "arm64-v8a")
            set(GSTREAMER_ROOT "${GSTREAMER_ROOT_ANDROID}/arm64")
        elseif(ANDROID_ABI STREQUAL "x86")
            set(GSTREAMER_ROOT "${GSTREAMER_ROOT_ANDROID}/x86")
        elseif(ANDROID_ABI STREQUAL "x86_64")
            set(GSTREAMER_ROOT "${GSTREAMER_ROOT_ANDROID}/x86_64")
        else()
            message(FATAL_ERROR "Target arch ABI not supported: ${ANDROID_ABI}")
        endif()
    
        list(APPEND CMAKE_MODULE_PATH "${GSTREAMER_ROOT}/share/cmake")
    
        set(GSTREAMER_NDK_BUILD_PATH "${GSTREAMER_ROOT}/share/gst-android/ndk-build/")
        set(GSTREAMER_PLUGINS coreelements)
    
        find_library(LOG_LIB log REQUIRED)
        find_package(GStreamerMobile COMPONENTS ${GSTREAMER_PLUGINS} fonts REQUIRED)
    
        target_link_libraries(appTestProject_GStreamer_CMake
            PRIVATE Qt6::Quick
            PUBLIC
                GStreamer::mobile
                ${ANDROID_LIB}
                ${LOG_LIB}
        )
    
    endif()
    
    
    
    install(TARGETS appTestProject_GStreamer_CMake
        BUNDLE DESTINATION .
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )
    
    
    
    

    And i got "Could NOT find GLIB2", triggered at find_package(). The glib library is one of the precompiled libraries, included in the downloaded folder. It turned out, that find_package() calls a cmake file, which was added with list(APPEND CMAKE_MODULE_PATH ...).
    So i followed the rabbit to ".../share/cmake/FindGSTreamer.cmake" within the downloaded folder of the precompiled gstreamer libraries. This cmake file uses pkg-config and prepares the package, so that the cmake file in the project can easily find and link the needed modules. But i have no clue, why it's working for the tutorial, but not for my test project. I lack knowledge.

    However, this approach does not seem to be a dead end, it could be even quite elegant compared to the old qmake solutions, spread across the web. Unfortunately, i ran out of ideas how to fix it, because i am not very experienced with cmake and androiddeployqt. But maybe with a little help from some awesome person, who is, this might work...

    Thank you for reading the whole post.

    1 Reply Last reply
    0
    • JoeCFDJ Offline
      JoeCFDJ Offline
      JoeCFD
      wrote last edited by JoeCFD
      #2

      if you are developing commerical software, it is not legal to link precompiled gstreamer libraries(static) to your project without paying license fee. Check project QGroundcontrol out to see how static libs are added to a project.

      Ideally, you build all libs and plugins of gstreamer you need to a single dynamic lib for Android and wrap the dynamic lib with your project just like Qt libs. This is what I did.
      https://discourse.gstreamer.org/t/how-to-build-gstreamer-for-android/815

      To debug the crash, connect your cell phone with you computer and use qtcreator to find out where it crashes. It is likely that the crash is caused by missing plugins or libs. Build and run your code on Linux to find out which libs and plugins are needed and make sure that they are added in your build for Android.

      F 1 Reply Last reply
      2
      • JoeCFDJ JoeCFD

        if you are developing commerical software, it is not legal to link precompiled gstreamer libraries(static) to your project without paying license fee. Check project QGroundcontrol out to see how static libs are added to a project.

        Ideally, you build all libs and plugins of gstreamer you need to a single dynamic lib for Android and wrap the dynamic lib with your project just like Qt libs. This is what I did.
        https://discourse.gstreamer.org/t/how-to-build-gstreamer-for-android/815

        To debug the crash, connect your cell phone with you computer and use qtcreator to find out where it crashes. It is likely that the crash is caused by missing plugins or libs. Build and run your code on Linux to find out which libs and plugins are needed and make sure that they are added in your build for Android.

        F Offline
        F Offline
        felsi
        wrote last edited by
        #3

        @JoeCFD
        Oh, because of LGPL, i see. Thank you for the hint!
        And thank you for sharing, how you accomplished it.
        The qml plugins are not part of the precompiled libraries, so at some point, i will have to compile it anyway...
        https://gstreamer.freedesktop.org/documentation/installing/building-from-source-using-cerbero.html?gi-language=c

        About the crash:

        Yes, i did this, it crashes at a very boring line, which works on linux just fine.
        The code is similar to the tutorials, which work on android just fine.

        Calling gst_something() methods do not crash, but they just do nothing and they return nothing, not even GstMessages* for errors. Hence, the debug says:
        F/libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x40 in tid 24125 (qtMainLoopThrea), pid 24085 (GStreamer_CMake)
        F/DEBUG : Cause: null pointer dereference

        As a test, i linked just everything within lib and lib/gstreamer-1.0. (ls -1 *.a)
        So, missing libs should not be the problem...

        About QGroundControl:

        To be honest, i just don't understand it.
        I see, they use the similar FindGStreamer.cmake, but the whole setup is way more complex than the tutorials.
        If i would be able to understand it, i would probably know anyway, what went wrong in the simple code, i posted.
        Without cmake experience, it's just mysterious to me, why the FindGStreamer.cmake isn't working in my test project.
        Maybe it's trivial for someone familiar with cmake...
        If you want to test it, the precompiled libs and my posted cmake is all you need.
        A simple cmake based example project, using the precompiled libs might be useful for future readers too.

        Otherwise i'll try the single dynamic lib approach of yours.

        Thank you very much!

        JoeCFDJ 1 Reply Last reply
        0
        • F felsi

          @JoeCFD
          Oh, because of LGPL, i see. Thank you for the hint!
          And thank you for sharing, how you accomplished it.
          The qml plugins are not part of the precompiled libraries, so at some point, i will have to compile it anyway...
          https://gstreamer.freedesktop.org/documentation/installing/building-from-source-using-cerbero.html?gi-language=c

          About the crash:

          Yes, i did this, it crashes at a very boring line, which works on linux just fine.
          The code is similar to the tutorials, which work on android just fine.

          Calling gst_something() methods do not crash, but they just do nothing and they return nothing, not even GstMessages* for errors. Hence, the debug says:
          F/libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x40 in tid 24125 (qtMainLoopThrea), pid 24085 (GStreamer_CMake)
          F/DEBUG : Cause: null pointer dereference

          As a test, i linked just everything within lib and lib/gstreamer-1.0. (ls -1 *.a)
          So, missing libs should not be the problem...

          About QGroundControl:

          To be honest, i just don't understand it.
          I see, they use the similar FindGStreamer.cmake, but the whole setup is way more complex than the tutorials.
          If i would be able to understand it, i would probably know anyway, what went wrong in the simple code, i posted.
          Without cmake experience, it's just mysterious to me, why the FindGStreamer.cmake isn't working in my test project.
          Maybe it's trivial for someone familiar with cmake...
          If you want to test it, the precompiled libs and my posted cmake is all you need.
          A simple cmake based example project, using the precompiled libs might be useful for future readers too.

          Otherwise i'll try the single dynamic lib approach of yours.

          Thank you very much!

          JoeCFDJ Offline
          JoeCFDJ Offline
          JoeCFD
          wrote last edited by
          #4

          @felsi gstreamer plugins and libs are two different things. Make sure that all gstreamer plugins are added in your build.

          1 Reply Last reply
          1
          • F Offline
            F Offline
            felsi
            wrote last edited by
            #5

            What do you mean? I linked just everything within the folders. About 366 files ending with .a.
            And even basic methods like gst_parse_launch() or gst_bus_timed_pop_filtered() don't work.

            1 Reply Last reply
            0
            • JoeCFDJ Offline
              JoeCFDJ Offline
              JoeCFD
              wrote last edited by
              #6

              All plugins are stored in gstreamer/lib/gstreamer-1.0. You add only libs and plugins you need.

              F 1 Reply Last reply
              2
              • JoeCFDJ JoeCFD

                All plugins are stored in gstreamer/lib/gstreamer-1.0. You add only libs and plugins you need.

                F Offline
                F Offline
                felsi
                wrote last edited by
                #7

                I compiled gstreamer with cerbero and tried to use the shared libraries.
                The libraries are loading successfully, but i got the same result as with the static libs.

                I don't know why i haven't noticed it earlier, but there is also this in the debug:

                E/oject_GStreamer: [perfctl] 20023 20023 FPSGO ver:-1
                E/oject_GStreamer: [perfctl] 0 0 0 0
                F/libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x40 in tid 20059 (qtMainLoopThrea), pid 20023 (oject_GStreamer)
                D/oject_GStreamer: Can't load libmbrainSDK
                D/oject_GStreamer: initMbrain failed

                After searching for perfctl, i have the bad feeling, that i have a completely different problem...

                1 Reply Last reply
                0
                • mrdebugM Offline
                  mrdebugM Offline
                  mrdebug
                  wrote last edited by
                  #8

                  Hi, do you need an Android player? If yes try ffmpeg, it is very esasy to use in Qt + Android.
                  https://github.com/denisgottardello/QtFFmpegPlayer

                  Need programmers to hire?
                  www.labcsp.com
                  www.denisgottardello.it
                  GMT+1
                  Skype: mrdebug

                  F 1 Reply Last reply
                  0
                  • mrdebugM mrdebug

                    Hi, do you need an Android player? If yes try ffmpeg, it is very esasy to use in Qt + Android.
                    https://github.com/denisgottardello/QtFFmpegPlayer

                    F Offline
                    F Offline
                    felsi
                    wrote last edited by
                    #9

                    @mrdebug
                    At the moment, i use QtMultimedia, which works fine on android too.
                    However, i have some features on my wish list, like mixing and fading between tracks, multiple output devices, etc.
                    Gstreamer has a comprehensive documentation and it seems to be more suitable than ffmpeg, because of its modularity.

                    But thank you very much for the link.
                    Wow, your project looks pretty clean and well arranged.

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved