Andoird, JNI: gst_element_factory_make returns nullptr when I try create elements of pipeline

156 Views Asked by At

I am writing JNI library that uses GStreamer. I am writing my JNI code separate from Android project, so I am using CMake to build the JNI lib and then I copy .so file to Android project.

The problem is, when I try to create element in JNI code, for example:

auto source = gst_element_factory_make("videotestsrc", "source");

gst_element_factory_make returns nullptr.

I've found an example of how can I use CMake to write JNI stuff with Gstreamer. I also have found question on stackoverflow, which resembles to my problem, but unfortunately, solution for that question doesn't work for me for some reason.

in gstreamer_android.cpp (which builds to gstreamer_android.so):

...
GST_PLUGIN_STATIC_DECLARE_C(coreelements);
GST_PLUGIN_STATIC_DECLARE_C(videotestsrc);

void gst_android_register_static_plugins() {
    GST_PLUGIN_STATIC_REGISTER(coreelements);
    GST_PLUGIN_STATIC_REGISTER(videotestsrc);
    __android_log_print (ANDROID_LOG_INFO, TAG, "plugins registered");
}
...

in my_gstreamer_lib.cpp (which builds to my-gstreamer-lib.so) I have "addTrack" native function, where I build a pipeline, for example this part:

...
auto source = gst_element_factory_make("videotestsrc", "source");
if (
    !source
) {
    __android_log_print (ANDROID_LOG_ERROR, TAG, "videotestsrc couldn't be created");
    return;
}
...

So, I always get "videotestsrc couldn't be created" error. Same happens with all the elements that I want to create, not only with "videotestsrc".

I tried to put this code snippet into "gstreamer_android.cpp" right after "GST_PLUGIN_STATIC_REGISTER(videotestsrc);" and there it works. But for some reason doesnt work in my "my_gstreamer_lib.cpp".

My android classes are:

NativeTest.kt

package com.my.playground

import android.content.Context
import android.util.Log
import android.widget.Toast
import org.freedesktop.gstreamer.GStreamer

class NativeTest {
    companion object {
        init {
            System.loadLibrary("my-gstreamer-lib")
        }
    }

    external fun addTrack(trackID: Int, filepath: String)
}

GStreamer.kt

package org.freedesktop.gstreamer

import android.content.Context

class GStreamer {

    companion object {
        init {
            System.loadLibrary("gstreamer_android")
        }

        @JvmStatic
        @Throws(Exception::class)
        external fun nativeInit(context: Context)

        @Throws(Exception::class)
        fun init(context: Context) {
            nativeInit(context)
        }
    }

}

MainActivity.kt

package com.my.playground

import ...

class MainActivity : ComponentActivity() {

    private lateinit var nativeInterface: NativeTest

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ...
        }

        startLib()
    }

    private fun startLib() {
        try {
            GStreamer.init(this)
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(this, e.message, Toast.LENGTH_LONG).show()
            finish()
            return
        }

        nativeInterface = NativeTest()

        // add track
        nativeInterface.addTrack(
            0,
            File(filesDir, "sample.mp4").absolutePath
        )
    }


    companion object {
        private const val READ_EXTERNAL_STORAGE_PERMISSION = "READ_EXTERNAL_STORAGE"
    }
}

In CMakeLists.txt I link all the libraries and plugins that mentioned in example, and also "gstcoreelements" and "gstvideotestsrc".

Any help is appreciated.

0

There are 0 best solutions below