[Solved] MovieGl on RaspberryPi 3B+

Hi everyone !

I failed to make linux::MovieGl work on the latest RPi.

It fails at GstPlayer.cpp line 566

if( ! gst_gl_context_create( sGstGLContext, sharedCtx, &err ) && err ) {

Deep inside GStreamer, the error comes from a call to eglBindAPI() with the “OpenGL” parameter, not “OpenGL ES”.
If I’m not mistaken, it happens because the distributed version of gstreamer for Raspbian is built with no support for OpenGL ES.

Does anyone else experienced that issue?

(I tried to build gstreamer from source with OpenGL ES support, but, for now, I failed…)

Happy New Year nonetheless!

Guillaume

Any of the info here helpful?

Most of what this thread is about has been merged in master since then.
The “create the shared context on our own” part, which translates to a call to gst_gl_context_create, is where my program fails.

I don’t think it’s a bug in Cinder, rather a incompatible distrib of gstreamer by default on raspbian.
There may be an alternative distrib?
Or an alternative to raspbian?

@petros Hello, sorry to ping you, you seem to be the reference when it comes to gstreamer (at least)

Hi Guillaume,

what version of GStreamer do you have installed? You can check with gst-inspect-1.0 --gst-version

And just to double check, with what command exactly did you try to build Cinder? It should be:
cmake .. -DCINDER_TARGET_GL=es2-rpi

CMake log output during config and part of the actual error could also be potentially helpful.

Cheers,
Petros

GStreamer Core Library version 1.10.4

No info about build option though.

Yes, I used " cmake .. -DCINDER_TARGET_GL=es2-rpi" to build Cinder. Do I need “-DCINDER_TARGET_GL=es2-rpi” for my project too?

Yes you will need the same for the samples also.

Btw 1.10.4 is quite far behind from 1.14 which is the current version of GStreamer. I have a script that will setup a GStreamer uninstalled envrionment as it is called in gst nomenclature that will allow you to use the latest version on the RPi ( it supports also *ubuntu desktop variants for that matter ). I haven’t tried it on the RPi for quite some time now so I hope it still works there but I have been using it, still, without issues on Ubuntu desktop.

The CMake config output for Cinder

pi@raspberrypi:~/Documents/ProjectionMapper/3rdParty/Cinder/build $ cmake .. -DCINDER_TARGET_GL=es2-rpi
-- The C compiler identification is GNU 6.3.0
-- The CXX compiler identification is GNU 6.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found ZLIB: /usr/lib/arm-linux-gnueabihf/libz.so (found version "1.2.8")
-- Found CURL: /usr/lib/arm-linux-gnueabihf/libcurl.so (found version "7.52.1")
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29")
-- Checking for module 'fontconfig'
--   Found fontconfig, version 2.11.0
-- Found Fontconfig: /usr/lib/arm-linux-gnueabihf/libfontconfig.so
-- Found MPG123: /usr/lib/arm-linux-gnueabihf/libmpg123.so (found version "1.23.8")
--   using MPG123 headers at: /usr/include
-- Found SNDFILE: /usr/lib/arm-linux-gnueabihf/libsndfile.so (found version "1.0.27")
--   using SNDFILE headers at: /usr/include
-- Found GLIB: /usr/include/glib-2.0;/usr/lib/arm-linux-gnueabihf/glib-2.0/include (found version "2.50.3")
-- Checking for module 'gstreamer-1.0'
--   Found gstreamer-1.0, version 1.10.4
-- Checking for module 'gstreamer-base-1.0'
--   Found gstreamer-base-1.0, version 1.10.4
-- Checking for module 'gstreamer-app-1.0'
--   Found gstreamer-app-1.0, version 1.10.4
-- Checking for module 'gstreamer-audio-1.0'
--   Found gstreamer-audio-1.0, version 1.10.4
-- Checking for module 'gstreamer-fft-1.0'
--   Found gstreamer-fft-1.0, version 1.10.4
-- Checking for module 'gstreamer-gl-1.0'
--   Found gstreamer-gl-1.0, version 1.10.4
-- Checking for module 'gstreamer-mpegts-1.0>=1.4.0'
--   Found gstreamer-mpegts-1.0, version 1.10.4
-- Checking for module 'gstreamer-pbutils-1.0'
--   Found gstreamer-pbutils-1.0, version 1.10.4
-- Checking for module 'gstreamer-tag-1.0'
--   Found gstreamer-tag-1.0, version 1.10.4
-- Checking for module 'gstreamer-video-1.0'
--   Found gstreamer-video-1.0, version 1.10.4
-- Found GStreamer: GSTREAMER_INCLUDE_DIRS;GSTREAMER_LIBRARIES;GSTREAMER_VERSION;GSTREAMER_BASE_INCLUDE_DIRS;GSTREAMER_BASE_LIBRARIES
-- Version >= 5.1 -- Disabling _GLIBCXX_USE_CXX11_ABI.
-- Performing Test COMPILER_SUPPORTS_CXX14
-- Performing Test COMPILER_SUPPORTS_CXX14 - Success
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/Documents/ProjectionMapper/3rdParty/Cinder/build

I’ll try again with “-DCINDER_TARGET_GL=es2-rpi" for my project. Then I’ll try your script and let you know!
Thanks!

For the record, the error message (actually, a crash)

|info   | bool gst::video::GstPlayer::initializeGStreamer()[406] Initialized GStreamer version : 1.10.4.0
|error  | bool gst::video::GstPlayer::initialize()[567] Failed to create shared context between Cinder and GStreamer : Failed to bind OpenGL API: EGL_BAD_PARAMETER
*** Error in `Debug/ProjectionMapper/ProjectionMapper': free(): invalid pointer: 0x71500d10 ***
Abandon

It tries to bind the OpenGL API, not the OpenGL ES API…

You can also try to explicitly set the platform and GL API by exporting the relevant env variables before running your app. Smt like:

$ export GST_GL_API=gles2
$ export GST_GL_PLATFORM=egl
$ ./Debug/ProjectionMapper/ProjectionMapper

You should still build the application also with -DCINDER_TARGET_GL=es2-rpi.

See here for more details regarding GStreamer env variables.

I got the same build errors with your script than I had before.

The 1st one is easy to fix:

In file included from gst_private.h:49:0,
                 from gstpad.c:90:
gstpad.c: In function ‘cleanup_hook’:
gstpad.c:1376:7: error: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 8 has type ‘gulong {aka long unsigned int}’ [-Werror=format=]
       "cleaning up hook %" G_GUINT64_FORMAT " with flags %08x", hook->hook_id,

I just have to cast “hook->hook_id” to “unsigned long long” (it’s an “unsigned long”). Still the error is weird… why does it fails on the RPi and not on other platforms?

The second error, when build plugins-base, is trickier…

gsteglimage.c: In function ‘_gst_egl_image_check_dmabuf_direct’:
gsteglimage.c:672:25: error: ‘DRM_FORMAT_MOD_LINEAR’ undeclared (first use in this function)
     if (modifiers[i] == DRM_FORMAT_MOD_LINEAR) {
                         ^~~~~~~~~~~~~~~~~~~~~
gsteglimage.c:672:25: note: each undeclared identifier is reported only once for each function it appears in
gsteglimage.c: In function ‘gst_egl_image_from_dmabuf_direct’:
gsteglimage.c:759:25: error: ‘EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT’ undeclared (first use in this function)
       attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gsteglimage.c:760:25: error: ‘DRM_FORMAT_MOD_LINEAR’ undeclared (first use in this function)
       attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff;
                         ^~~~~~~~~~~~~~~~~~~~~
gsteglimage.c:761:25: error: ‘EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT’ undeclared (first use in this function)
       attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gsteglimage.c:775:25: error: ‘EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT’ undeclared (first use in this function)
       attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gsteglimage.c:777:25: error: ‘EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT’ undeclared (first use in this function)
       attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gsteglimage.c:791:25: error: ‘EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT’ undeclared (first use in this function)
       attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gsteglimage.c:793:25: error: ‘EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT’ undeclared (first use in this function)
       attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Makefile:729 : la recette pour la cible « libgstgl_egl_la-gsteglimage.lo » a échouée

I’m stuck there.

Hey Guillaume,

it is not entirely clear to me what exactly you have tried and in what order so maybe taking a step back would help :slight_smile:

To start with, I would suggest to check that your default GStreamer installation is working as expected first.

You can try this by running the following from a terminal:

gst-launch-1.0 playbin uri=file:///path/to/video.mp4

If this works as expected then this is the order I would try things out to to see where things go wrong:

  • First try building with the default installation of GStreamer that ships with the RPi. Make sure you start with fresh/empty build directories otherwise CMake might have cached values that could potentially be messing up the build process:
    cd YourCinderDir/ && mkdir build && cmake .. -DCINDER_TARGET_GL=es2-rpi && make -j4
    cd ProjectionMapper/proj/cmake && mkdir build && cmake .. -DCINDER_TARGET_GL=es2-rpi && make -j4 

This assumes that your app’s project CMakeLists.txt file is located under ProjectionMapper/proj/cmake as it happens with Cinder’s samples also.

Try then to run your app and see if this fails.

  • If the above fails with the GL API error then try requesting explicitly the required GL API by exporting the relevant environment variables before running your app. On a terminal run the following commands assuming you are on the build directory of your project:
    $ export GST_GL_API=gles2
    $ export GST_GL_PLATFORM=egl
    $ ./Debug/ProjectionMapper/ProjectionMapper
  • If this also fails then the next step would be to try and build GStreamer from source - I have in mind a potential fix for the compilation error that you got but want to be sure that everything else has failed before we go down that road for fixing the specific issue that you are facing.

Also not sure how relevant it is in your case but maybe this issue is also related somehow here.

Cheers,
Petros

1 Like

Hi Petros, thanks for taking some time to help me! :slight_smile:

I tried to build GStreamer from source, using the master branch, because after several gdb sessions, it’s pretty clear that the current version of GStreamer that is distributed via APT (version 1.10.5) is not compiled with GLES2 support.
I tried with several build scripts, including yours, but all have failed. Apparently, one cannot build GStreamer 1.15 with the current state of dependencies distributed by APT.

Yet, I made some progress today!
I found the gst-build repo on Github: https://github.com/GStreamer/gst-build
From it, it’s pretty easy to build the version 1.10 of GStreamer with some support of GLES2 (get the 1.10 branch of gst-build)? (I know 1.10 is old, but as it matches the current version on raspbian, the dependencies all well set up)

Using this custom build, I managed to go further in the shared context creation…

The context creation (in gst_gl_context_create_thread from https://github.com/GStreamer/gst-plugins-bad/blob/1.10/gst-libs/gst/gl/gstglcontext.c) still fails, because for some other reason, glGetString(GL_VERSION) fails in gst_gl_context_fill_info.

I wonder what caused that mess, and if I’m the only one suffering from this. (I started from a fresh Raspbian Stretch install) Older messages about GStreamer and RPi suggest it worked at some point…

Hi Guillaume,

compiling GStreamer from source its not the most straightforward thing ( although switching to Meson and gst-build definitely helps ) and especially combined with the RPi, the situation can get much more complicated because of the idiosyncrasies that are specific to this device. So, hang in there it is not just you :slight_smile:

On the RPi, because of the particulars of the specific platform, it is not enough to just build with some support for GLESv2 but instead you must build targeting the Broadcom implementation that exists on the RPi. What Meson options did you use for gst-build? Did you also compile gst-omx? This is necessary to get hardware accelerated decoding

In any case, maybe my script can still be of help because it should take care all of these details for you without having to set RPI-specific parameters from your side. You can use it to clone and compile a specific branch of GStreamer and plugins with sh create-gst-uninstalled-env.sh --branch 1.10.5 --omx-branch 1.10.5.

You can see all the specific flags that it sets for the RPi here and here. Quite a few things that need to be specified…

Give it a try and see if this takes you any further.

HTH,
Petros

I finally have movies on the RPi 3B+, using your script!!

I simply had to fix the git command to checkout a specific branch.

I also had to increase the GPU memory, because the default 64MB is ridiculous. :slight_smile:

It now works as a charm.
Thanks again Petros!

I had some trouble getting this to work on a RPi 3B+ with Raspbian Buster, so just wanted to share the steps that got it to work in case it helps someone later.

  • The Broadcom EGL and GLES2 libraries were missing from the fresh install. This was fixed with rpi-update.

  • In /opt/vc/lib/pkgconfig do
    ln -s brcmegl.pc egl.pc
    ln -s brcmglesv2.pc glesv2.pc
    This allows gstreamer to find and use the Broadcom EGL and GLES2 code.

  • When installing Cinder requirements, do not install libgles2-mesa-dev

  • Do install these packages:
    libxrandr-dev libxinerama-dev libx11-xcb-dev libxi-dev

  • Use petros’ script to install GStreamer 1.16. I couldn’t get the script to work with version 1.18. The build system has apparently changed for that version, but I didn’t try too hard to get it to work. This was the command I used:
    sh create-gst-uninstalled-env.sh --branch 1.16 --omx-branch 1.16 .

  • Before compiling Cinder (I used 0.9.2) do:
    cd ~/gst
    sh gst-1.16
    This sets some environment variables that you will need for Cinder to compile with the GStreamer you just compiled.

When compiling a Cinder app, you need to include /opt/vc/include in your header path.

Hope that helps,
James

1 Like