Android gst_app_src_push_buffer 未定义引用错误上的 Gstreamer

Gstreamer on Android gst_app_src_push_buffer undefined reference error

我只是想将一些字节数组从我的 Java Class 推送到本机 Gstreamer 方法。我已经阅读了 android 的所有 gstreamer 文档,发现我应该使用 gst_app_src_push_buffer 将数据推送到 GstAppSrc 但是当我尝试构建项目时,显示此错误: 错误:对 'gst_app_src_push_buffer' 的未定义引用。 这是我在 mgstreamer.c 文件中的 C 代码:


#define TAG "GSTREAMER_NATIVE"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)

#include <string.h>
#include <jni.h>
#include <gst/gst.h>
#include <android/log.h>
#include <gst/app/gstappsrc.h>

#include <glib.h>
#include <glibconfig.h>
#define GST_VALUE_HOLDS_FOURCC(x)       (G_VALUE_HOLDS(x, gst_type_fourcc))
#define GST_TYPE_FOURCC                  gst_type_fourcc
GST_EXPORT GType gst_type_fourcc;



static void initPipeline(JNIEnv *end,jobject clazz) {

    gst_init(NULL, NULL);

    mData = (MData *) g_malloc0(sizeof(MData));

    gchar *uuid = g_uuid_string_random();
    mData->pipeline = gst_pipeline_new(uuid);


    gst_element_set_state(mData->pipeline, GST_STATE_PLAYING);

    GstElement *appsrc = gst_element_factory_make("appsrc", NULL);
    g_object_set(G_OBJECT(appsrc), "is-live", TRUE, "format", GST_FORMAT_TIME, "do-timestamp", TRUE,
                 "block", TRUE, NULL);
    mData->appSrc = appsrc;

    GstCaps *caps = gst_caps_new_simple("video/x-raw-yuv",
                                        "format", GST_TYPE_FOURCC,
                                        GST_MAKE_FOURCC ('N', 'V', '2', '1'),
                                        "framerate", GST_TYPE_FRACTION, 15, 1,
                                        "width", G_TYPE_INT, 128,
                                        "height", G_TYPE_INT, 96,
                                        NULL);

    GstElement *capsfilter = gst_element_factory_make("capsfilter", NULL);

    g_object_set(G_OBJECT(capsfilter), "caps", caps, NULL);

    gst_bin_add_many(GST_BIN(mData->pipeline), appsrc, capsfilter, NULL);

    gst_element_link_many(appsrc, capsfilter,NULL);

    gst_element_sync_state_with_parent(appsrc);

    gst_element_sync_state_with_parent(capsfilter);


}

static void onReceiveData(JNIEnv *env, jclass clazz, jbyteArray byteArrayData) {

    jbyte *temp = (*env)->GetByteArrayElements(env, byteArrayData, NULL);
    jsize size = (*env)->GetArrayLength(env, byteArrayData);
    GstBuffer *buffer = gst_buffer_new_allocate(NULL, size, NULL);
    gst_buffer_fill(buffer, 0, temp, size);
    GstElement *source = gst_bin_get_by_name(GST_BIN(mData->pipeline), "source");
    gst_app_src_push_buffer((GstAppSrc *) source, buffer);
    gst_object_unref(source);
    (*env)->ReleaseByteArrayElements(env, byteArrayData, temp, JNI_ABORT);


}

这是 Android.mk 文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := test_g_streamer
LOCAL_SRC_FILES := mgstreamer.c
LOCAL_SHARED_LIBRARIES := gstreamer_android
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

ifndef GSTREAMER_ROOT_ANDROID
$(error GSTREAMER_ROOT_ANDROID is not defined!)
endif






ifeq ($(TARGET_ARCH_ABI),armeabi)
GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/arm
else ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/armv7
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/arm64
else ifeq ($(TARGET_ARCH_ABI),x86)
GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/x86
else ifeq ($(TARGET_ARCH_ABI),x86_64)
GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/x86_64
else
$(error Target arch ABI not supported: $(TARGET_ARCH_ABI))
endif


LOCAL_EXPORT_C_INCLUDES +=$(GSTREAMER_ROOT)/include/gstreamer-1.0/
LOCAL_EXPORT_C_INCLUDES +=$(GSTREAMER_ROOT)/include/glib-2.0/gobject
LOCAL_EXPORT_C_INCLUDES +=$(GSTREAMER_ROOT)/include/glib-2.0/
LOCAL_EXPORT_C_INCLUDES +=$(GSTREAMER_ROOT)/lib/

GSTREAMER_NDK_BUILD_PATH  := $(GSTREAMER_ROOT)/share/gst-android/ndk-build/

include $(GSTREAMER_NDK_BUILD_PATH)/plugins.mk

GSTREAMER_PLUGINS         := $(GSTREAMER_PLUGINS_CORE)      \
                             $(GSTREAMER_PLUGINS_PLAYBACK)  \
                             $(GSTREAMER_PLUGINS_CODECS)    \
                             $(GSTREAMER_PLUGINS_NET)       \
                             $(GSTREAMER_PLUGINS_SYS)       \
                             $(GSTREAMER_PLUGINS_CODECS_RESTRICTED) \
                             $(GSTREAMER_CODECS_GPL)        \
                             $(GSTREAMER_PLUGINS_ENCODING)  \
                             $(GSTREAMER_PLUGINS_VIS)       \
                             $(GSTREAMER_PLUGINS_EFFECTS)   \
                             $(GSTREAMER_PLUGINS_NET_RESTRICTED)

GSTREAMER_EXTRA_DEPS      := gstreamer-1.0 glib-2.0 gio-2.0
include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer-1.0.mk

include $(CLEAR_VARS)

LOCAL_MODULE    := fast_image_converter
LOCAL_SRC_FILES := pr_convertor.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)


和Appilcation.mk

APP_ABI = armeabi-v7a arm64-v8a x86 x86_64
APP_STL = c++_shared
APP_PLATFORM := android

build.gradle :

apply plugin: 'com.android.library'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"


        externalNativeBuild {
            ndkBuild {

                def gstRoot = System.env.GSTREAMER_ROOT_ANDROID

                if (gstRoot == null)
                    throw new GradleException('GSTREAMER_ROOT_ANDROID must be set, or "gstAndroidRoot" must be defined in your gradle.properties in the top level directory of the unpacked universal GStreamer Android binaries')

                arguments "NDK_APPLICATION_MK=src/main/jni/Application.mk", "GSTREAMER_JAVA_SRC_DIR=src", "GSTREAMER_ROOT_ANDROID=$gstRoot", "GSTREAMER_ASSETS_DIR=src/assets"

                targets "test_g_streamer", "fast_image_converter"

                // All archs except MIPS and MIPS64 are supported
                abiFilters  'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
            }
        }


        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        ndkBuild {
            path 'src/main/jni/Android.mk'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.2.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}

和项目 build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.1"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

我已经添加了gstreamer的所有插件,但错误仍然存​​在。 我尝试使用的 Gstreamer 版本:gstreamer-1.0-android-universal-1.18.3.targstreamer- 1.0-android-通用-1.18.0.tar NDK 版本:21.3.6528147 PS:我正在开发 windows 10

不确定 android 上的情况,但 app 符号位于单独的库中。例如。 Linux 上有基础 gstreamer-1.0 库,应用程序功能位于 gstreamer-app-1.0 中。因此,您可能必须在链接 android 应用程序时添加此库。

此步骤解决了问题:

  1. 我将 GSTREAMER_EXTRA_DEPS 添加到我的 Android.mk。
  2. GST_PLUGIN_STATIC_DECLARE 和 GST_PLUGIN_STATIC_REGISTER 也需要,因为我试图开发自己的 gstreamer 模块,但我没有使用 gstreamer_android.c 文件。 以下是需要执行相同操作的脚本和源代码:

Android.mk

STREAMER_NDK_BUILD_PATH  := $(GSTREAMER_ROOT)/share/gst-android/ndk-build/
include $(GSTREAMER_NDK_BUILD_PATH)/plugins.mk

GSTREAMER_PLUGINS         := libav videoparsersbad opengl rtp rtpmanager coreelements app vpx videoconvert x264 videofilter opus autodetect audioconvert audioresample audiorate

GSTREAMER_EXTRA_DEPS      := gstreamer-plugins-base-1.0 gstreamer-rtp-1.0 gmodule-2.0 glib-2.0 gstreamer-app-1.0 gstreamer-video-1.0
GSTREAMER_EXTRA_LIBS      := -liconv
include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer-1.0.mk

和静态寄存器:

GST_PLUGIN_STATIC_DECLARE(coreelements);

GST_PLUGIN_STATIC_DECLARE(rtp);

GST_PLUGIN_STATIC_DECLARE(app);

GST_PLUGIN_STATIC_DECLARE(vpx);

GST_PLUGIN_STATIC_DECLARE(videoconvert);

GST_PLUGIN_STATIC_DECLARE(x264);

GST_PLUGIN_STATIC_DECLARE(opengl);

GST_PLUGIN_STATIC_DECLARE(videoparsersbad);

GST_PLUGIN_STATIC_DECLARE(videofilter);
GST_PLUGIN_STATIC_DECLARE(opus);
GST_PLUGIN_STATIC_DECLARE(autodetect);
GST_PLUGIN_STATIC_DECLARE(audioconvert);
GST_PLUGIN_STATIC_DECLARE(rtpmanager);
GST_PLUGIN_STATIC_DECLARE(libav);
/* Call this function to register static plugins */
void
gst_android_register_static_plugins(void) {
    GST_PLUGIN_STATIC_REGISTER(coreelements);
    GST_PLUGIN_STATIC_REGISTER(app);
    GST_PLUGIN_STATIC_REGISTER(rtp);
    GST_PLUGIN_STATIC_REGISTER(vpx);
    GST_PLUGIN_STATIC_REGISTER(videoconvert);
    GST_PLUGIN_STATIC_REGISTER(x264);
    GST_PLUGIN_STATIC_REGISTER(opengl);
    GST_PLUGIN_STATIC_REGISTER(videoparsersbad);
    GST_PLUGIN_STATIC_REGISTER(videofilter);
    GST_PLUGIN_STATIC_REGISTER(opus);
    GST_PLUGIN_STATIC_REGISTER(autodetect);
    GST_PLUGIN_STATIC_REGISTER(audioconvert);
    GST_PLUGIN_STATIC_REGISTER(rtpmanager);
    GST_PLUGIN_STATIC_REGISTER(libav);
}