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.tar 和 gstreamer- 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 应用程序时添加此库。
此步骤解决了问题:
- 我将 GSTREAMER_EXTRA_DEPS 添加到我的 Android.mk。
- 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);
}
我只是想将一些字节数组从我的 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.tar 和 gstreamer- 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 应用程序时添加此库。
此步骤解决了问题:
- 我将 GSTREAMER_EXTRA_DEPS 添加到我的 Android.mk。
- 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);
}