diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2013-04-16 10:51:35 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2013-04-22 08:35:29 +0200 |
commit | 5586da3302015e50372cd2e444bf247f988661d7 (patch) | |
tree | 5ab65cb8ad921cb7482b34a1f53ef14c8326fc36 | |
parent | 7a0b20f74adb69693f9f2812516061d1a3a7dff3 (diff) |
gstreamer-1.0: Add Android specific 1.0 changes
19 files changed, 1213 insertions, 6 deletions
diff --git a/data/ndk-build-1.0/GStreamer.java b/data/ndk-build-1.0/GStreamer.java new file mode 100644 index 0000000..6c58abe --- /dev/null +++ b/data/ndk-build-1.0/GStreamer.java @@ -0,0 +1,60 @@ +package com.gstreamer; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import android.content.Context; +import android.content.res.AssetManager; + +public class GStreamer { + private static native void nativeInit(Context context) throws Exception; + + public static void init(Context context) throws Exception { + nativeInit(context); + copyFonts(context); + } + + private static void copyFonts(Context context) { + AssetManager assetManager = context.getAssets(); + File filesDir = context.getFilesDir(); + File fontsFCDir = new File (filesDir, "fontconfig"); + File fontsDir = new File (fontsFCDir, "fonts"); + File fontsCfg = new File (fontsFCDir, "fonts.conf"); + + fontsDir.mkdirs(); + + try { + /* Copy the config file */ + copyFile (assetManager, "fontconfig/fonts.conf", fontsCfg); + /* Copy the fonts */ + for(String filename : assetManager.list("fontconfig/fonts/truetype")) { + File font = new File(fontsDir, filename); + copyFile (assetManager, "fontconfig/fonts/truetype/" + filename, font); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void copyFile(AssetManager assetManager, String assetPath, File outFile) throws IOException { + InputStream in; + OutputStream out; + byte[] buffer = new byte[1024]; + int read; + + if (outFile.exists()) + return; + + in = assetManager.open(assetPath); + out = new FileOutputStream (outFile); + while((read = in.read(buffer)) != -1){ + out.write(buffer, 0, read); + } + in.close(); + out.flush(); + out.close(); + } +} diff --git a/data/ndk-build-1.0/fontconfig/fonts.conf b/data/ndk-build-1.0/fontconfig/fonts.conf new file mode 100644 index 0000000..445d8ce --- /dev/null +++ b/data/ndk-build-1.0/fontconfig/fonts.conf @@ -0,0 +1,126 @@ +<?xml version="1.0"?> +<!DOCTYPE fontconfig SYSTEM "fonts.dtd"> +<!-- /etc/fonts/fonts.conf file to configure system font access --> +<fontconfig> + +<!-- Font directory list --> + + <dir prefix="xdg">fontconfig/fonts</dir> + +<!-- Font cache directory list --> + + <cachedir prefix="xdg">fontconfig</cachedir> + +<!-- + Accept deprecated 'mono' alias, replacing it with 'monospace' +--> + <match target="pattern"> + <test qual="any" name="family"> + <string>mono</string> + </test> + <edit name="family" mode="assign" binding="same"> + <string>monospace</string> + </edit> + </match> + +<!-- + Accept alternate 'sans serif' spelling, replacing it with 'sans-serif' +--> + <match target="pattern"> + <test qual="any" name="family"> + <string>sans serif</string> + </test> + <edit name="family" mode="assign" binding="same"> + <string>sans-serif</string> + </edit> + </match> + +<!-- + Accept deprecated 'sans' alias, replacing it with 'sans-serif' +--> + <match target="pattern"> + <test qual="any" name="family"> + <string>sans</string> + </test> + <edit name="family" mode="assign" binding="same"> + <string>sans-serif</string> + </edit> + </match> + + <config> +<!-- + These are the default Unicode chars that are expected to be blank + in fonts. All other blank chars are assumed to be broken and + won't appear in the resulting charsets + --> + <blank> + <int>0x0020</int> <!-- SPACE --> + <int>0x00A0</int> <!-- NO-BREAK SPACE --> + <int>0x00AD</int> <!-- SOFT HYPHEN --> + <int>0x034F</int> <!-- COMBINING GRAPHEME JOINER --> + <int>0x0600</int> <!-- ARABIC NUMBER SIGN --> + <int>0x0601</int> <!-- ARABIC SIGN SANAH --> + <int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER --> + <int>0x0603</int> <!-- ARABIC SIGN SAFHA --> + <int>0x06DD</int> <!-- ARABIC END OF AYAH --> + <int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK --> + <int>0x115F</int> <!-- HANGUL CHOSEONG FILLER --> + <int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER --> + <int>0x1680</int> <!-- OGHAM SPACE MARK --> + <int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ --> + <int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA --> + <int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR --> + <int>0x2000</int> <!-- EN QUAD --> + <int>0x2001</int> <!-- EM QUAD --> + <int>0x2002</int> <!-- EN SPACE --> + <int>0x2003</int> <!-- EM SPACE --> + <int>0x2004</int> <!-- THREE-PER-EM SPACE --> + <int>0x2005</int> <!-- FOUR-PER-EM SPACE --> + <int>0x2006</int> <!-- SIX-PER-EM SPACE --> + <int>0x2007</int> <!-- FIGURE SPACE --> + <int>0x2008</int> <!-- PUNCTUATION SPACE --> + <int>0x2009</int> <!-- THIN SPACE --> + <int>0x200A</int> <!-- HAIR SPACE --> + <int>0x200B</int> <!-- ZERO WIDTH SPACE --> + <int>0x200C</int> <!-- ZERO WIDTH NON-JOINER --> + <int>0x200D</int> <!-- ZERO WIDTH JOINER --> + <int>0x200E</int> <!-- LEFT-TO-RIGHT MARK --> + <int>0x200F</int> <!-- RIGHT-TO-LEFT MARK --> + <int>0x2028</int> <!-- LINE SEPARATOR --> + <int>0x2029</int> <!-- PARAGRAPH SEPARATOR --> + <int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING --> + <int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING --> + <int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING --> + <int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE --> + <int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE --> + <int>0x202F</int> <!-- NARROW NO-BREAK SPACE --> + <int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE --> + <int>0x2060</int> <!-- WORD JOINER --> + <int>0x2061</int> <!-- FUNCTION APPLICATION --> + <int>0x2062</int> <!-- INVISIBLE TIMES --> + <int>0x2063</int> <!-- INVISIBLE SEPARATOR --> + <int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING --> + <int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING --> + <int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING --> + <int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING --> + <int>0x206E</int> <!-- NATIONAL DIGIT SHAPES --> + <int>0x206F</int> <!-- NOMINAL DIGIT SHAPES --> + <int>0x2800</int> <!-- BRAILLE PATTERN BLANK --> + <int>0x3000</int> <!-- IDEOGRAPHIC SPACE --> + <int>0x3164</int> <!-- HANGUL FILLER --> + <int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE --> + <int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER --> + <int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR --> + <int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR --> + <int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR --> + </blank> +<!-- + Rescan configuration every 30 seconds when FcFontSetList is called + --> + <rescan> + <int>30</int> + </rescan> + </config> + +</fontconfig> + diff --git a/data/ndk-build-1.0/fontconfig/fonts/Ubuntu-R.ttf b/data/ndk-build-1.0/fontconfig/fonts/Ubuntu-R.ttf Binary files differnew file mode 100644 index 0000000..45a038b --- /dev/null +++ b/data/ndk-build-1.0/fontconfig/fonts/Ubuntu-R.ttf diff --git a/data/ndk-build-1.0/gstreamer.mk b/data/ndk-build-1.0/gstreamer.mk new file mode 100755 index 0000000..621a66f --- /dev/null +++ b/data/ndk-build-1.0/gstreamer.mk @@ -0,0 +1,187 @@ +# cerbero - a multi-platform build system for Open Source software +# Copyright (C) 2012 Andoni Morales Alastruey <ylatuya@gmail.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +$(call assert-defined, GSTREAMER_SDK_ROOT) +$(if $(wildcard $(GSTREAMER_SDK_ROOT)),,\ + $(error "The directory GSTREAMER_SDK_ROOT=$(GSTREAMER_SDK_ROOT) does not exists")\ +) + + +##################### +# Setup variables # +##################### + +ifndef GSTREAMER_PLUGINS + $(info "The list of GSTREAMER_PLUGINS is empty") +endif + +# Path for GStreamer static plugins +ifndef GSTREAMER_STATIC_PLUGINS_PATH +GSTREAMER_STATIC_PLUGINS_PATH := lib/gstreamer-1.0 +endif +GSTREAMER_STATIC_PLUGINS_PATH := $(GSTREAMER_SDK_ROOT)/lib/gstreamer-1.0/static + +# Path for the NDK integration makefiles +ifndef GSTREAMER_NDK_BUILD_PATH +GSTREAMER_NDK_BUILD_PATH := $(GSTREAMER_SDK_ROOT)/share/gst-android/ndk-build +endif + +# Include tools +include $(GSTREAMER_NDK_BUILD_PATH)/tools.mk + +# Path for the static GIO modules +G_IO_MODULES_PATH := $(GSTREAMER_SDK_ROOT)/lib/gio/modules/static + +# Host tools +ifeq ($(HOST_OS),windows) + HOST_SED := $(GSTREAMER_NDK_BUILD_PATH)/tools/windows/sed + GSTREAMER_LD := +else +endif + +GSTREAMER_ANDROID_MODULE_NAME := gstreamer_android +GSTREAMER_BUILD_DIR := gst-build +GSTREAMER_ANDROID_O := $(GSTREAMER_BUILD_DIR)/$(GSTREAMER_ANDROID_MODULE_NAME).o +GSTREAMER_ANDROID_SO := $(GSTREAMER_BUILD_DIR)/lib$(GSTREAMER_ANDROID_MODULE_NAME).so +GSTREAMER_ANDROID_C := $(GSTREAMER_BUILD_DIR)/$(GSTREAMER_ANDROID_MODULE_NAME).c +GSTREAMER_ANDROID_C_IN := $(GSTREAMER_NDK_BUILD_PATH)/gstreamer_android.c.in +GSTREAMER_DEPS := $(GSTREAMER_EXTRA_DEPS) gstreamer-1.0 +GSTREAMER_LD := -fuse-ld=gold + +################################ +# NDK Build Prebuilt library # +################################ + +# Declare a prebuilt library module, a shared library including +# gstreamer, its dependencies and all its plugins. +# Since the shared library is not really prebuilt, but will be built +# using the defined rules in this file, we can't use the +# PREBUILT_SHARED_LIBRARY makefiles like explained in the docs, +# as it checks for the existance of the shared library. We therefore +# use a custom gstreamer_prebuilt.mk, which skips this step + +include $(CLEAR_VARS) +LOCAL_MODULE := $(GSTREAMER_ANDROID_MODULE_NAME) +LOCAL_SRC_FILES := $(GSTREAMER_ANDROID_SO) +LOCAL_BUILD_SCRIPT := PREBUILT_SHARED_LIBRARY +LOCAL_MODULE_CLASS := PREBUILT_SHARED_LIBRARY +LOCAL_MAKEFILE := $(local-makefile) +LOCAL_PREBUILT_PREFIX := lib +LOCAL_PREBUILT_SUFFIX := .so +LOCAL_EXPORT_C_INCLUDES := $(subst -I$1, $1, $(call pkg-config-get-includes,$(GSTREAMER_DEPS))) +LOCAL_EXPORT_C_INCLUDES += $(GSTREAMER_SDK_ROOT)/include + + +################################################################## +# Our custom rules to create a shared libray with gstreamer # +# and the requested plugins in GSTREAMER_PLUGINS starts here # +################################################################## + +include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer_prebuilt.mk +# This triggers the build of our library using our custom rules +$(GSTREAMER_ANDROID_SO): buildsharedlibrary copyjavasource copyfontsres + + +# Some plugins use a different name for the module name, like the playback +# plugin, which uses playbin for the module name: libgstplaybin.so +fix-plugin-name = \ + $(subst gst$1 ,gst$2 ,$(GSTREAMER_PLUGINS_LIBS)) + +fix-deps = \ + $(subst $1,$1 $2,$(GSTREAMER_ANDROID_LIBS)) + + +# Generate list of plugin links (eg: -lcoreelements -lvideoscale) +GSTREAMER_PLUGINS_LIBS := $(foreach plugin, $(GSTREAMER_PLUGINS), -lgst$(plugin) ) +GSTREAMER_PLUGINS_LIBS := $(call fix-plugin-name,camerabin,camerabin2) +GSTREAMER_PLUGINS_LIBS := $(call fix-plugin-name,encoding,encodebin) +GSTREAMER_PLUGINS_LIBS := $(call fix-plugin-name,soup,souphttpsrc) +GSTREAMER_PLUGINS_LIBS := $(call fix-plugin-name,gstsiren,siren) +GSTREAMER_PLUGINS_LIBS := $(call fix-plugin-name,sdp,sdpelem) +GSTREAMER_PLUGINS_LIBS := $(call fix-plugin-name,scaletempo,scaletempoplugin) +GSTREAMER_PLUGINS_LIBS := $(call fix-plugin-name,realmedia,rmdemux) +GSTREAMER_PLUGINS_LIBS := $(subst gstgnonlin,gnl,$(GSTREAMER_PLUGINS_LIBS)) + +# Generate the plugins' declaration strings +GSTREAMER_PLUGINS_DECLARE := $(foreach plugin, $(GSTREAMER_PLUGINS), \ + GST_PLUGIN_STATIC_DECLARE($(plugin));\n) +# Generate the plugins' registration strings +GSTREAMER_PLUGINS_REGISTER := $(foreach plugin, $(GSTREAMER_PLUGINS), \ + GST_PLUGIN_STATIC_REGISTER($(plugin));\n) + +# Generate list of gio modules +G_IO_MODULES_PATH := $(foreach path, $(G_IO_MODULES_PATH), -L$(path)) +G_IO_MODULES_LIBS := $(foreach module, $(G_IO_MODULES), -lgio$(module)) +G_IO_MODULES_DECLARE := $(foreach module, $(G_IO_MODULES), \ + G_IO_MODULE_DECLARE(gnutls);\n) +G_IO_MODULES_LOAD := $(foreach module, $(G_IO_MODULES), \ + G_IO_MODULE_LOAD(gnutls);\n) + +# Get the full list of libraries +# link at least to gstreamer-1.0 in case the plugins list is empty +GSTREAMER_ANDROID_LIBS := $(call pkg-config-get-libs,$(GSTREAMER_DEPS)) +GSTREAMER_ANDROID_LIBS += $(GSTREAMER_PLUGINS_LIBS) $(G_IO_MODULES_LIBS) -llog -lz +GSTREAMER_ANDROID_WHOLE_AR := $(call pkg-config-get-libs-no-deps,$(GSTREAMER_DEPS)) +# Fix deps for giognutls +GSTREAMER_ANDROID_LIBS := $(call fix-deps,-lgiognutls, -lhogweed) +GSTREAMER_ANDROID_CFLAGS := $(call pkg-config-get-includes,$(GSTREAMER_DEPS)) -I$(GSTREAMER_SDK_ROOT)/include + +# In newer NDK, SYSROOT is replaced by SYSROOT_INC and SYSROOT_LINK, which +# now points to the root directory. But this will probably change in the future from: +# https://android.googlesource.com/platform/ndk/+/fa8c1b4338c1bef2813ecee0ee298e9498a1aaa7 +ifndef SYSROOT + SYSROOT := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-$(TARGET_ARCH) +endif + +# Create the link command +GSTREAMER_ANDROID_CMD := $(call libtool-link,$(TARGET_CC) $(TARGET_LDFLAGS) -shared --sysroot=$(SYSROOT) \ + -o $(GSTREAMER_ANDROID_SO) $(GSTREAMER_ANDROID_O) \ + -L$(GSTREAMER_SDK_ROOT)/lib -L$(GSTREAMER_STATIC_PLUGINS_PATH) $(G_IO_MODULES_PATH) \ + $(GSTREAMER_ANDROID_LIBS), $(GSTREAMER_LD)) -Wl,-no-undefined $(GSTREAMER_LD) +GSTREAMER_ANDROID_CMD := $(call libtool-whole-archive,$(GSTREAMER_ANDROID_CMD),$(GSTREAMER_ANDROID_WHOLE_AR)) + + +# Generates a source file that declares and registers all the required plugins +genstatic: + @$(HOST_ECHO) "GStreamer : [GEN] => $(GSTREAMER_ANDROID_C)" + @$(call host-mkdir,$(GSTREAMER_BUILD_DIR)) + @$(call host-cp,$(GSTREAMER_ANDROID_C_IN),$(GSTREAMER_ANDROID_C)) + @$(HOST_SED) -i "s/@PLUGINS_DECLARATION@/$(GSTREAMER_PLUGINS_DECLARE)/g" $(GSTREAMER_ANDROID_C) + @$(HOST_SED) -i "s/@PLUGINS_REGISTRATION@/$(GSTREAMER_PLUGINS_REGISTER)/g" $(GSTREAMER_ANDROID_C) + @$(HOST_SED) -i "s/@G_IO_MODULES_LOAD@/$(G_IO_MODULES_LOAD)/g" $(GSTREAMER_ANDROID_C) + @$(HOST_SED) -i "s/@G_IO_MODULES_DECLARE@/$(G_IO_MODULES_DECLARE)/g" $(GSTREAMER_ANDROID_C) + +# Compile the source file +$(GSTREAMER_ANDROID_O): genstatic + @$(HOST_ECHO) "GStreamer : [COMPILE] => $(GSTREAMER_ANDROID_C)" + @$(TARGET_CC) --sysroot=$(SYSROOT) $(TARGET_CFLAGS) -c $(GSTREAMER_ANDROID_C) -Wall -Werror -o $(GSTREAMER_ANDROID_O) $(GSTREAMER_ANDROID_CFLAGS) + +# Creates a shared library including gstreamer, its plugins and all the dependencies +buildsharedlibrary: $(GSTREAMER_ANDROID_O) + @$(HOST_ECHO) "GStreamer : [LINK] => $(GSTREAMER_ANDROID_SO)" + @$(GSTREAMER_ANDROID_CMD) + +copyjavasource: + @$(call host-mkdir,src/com/gstreamer) + @$(call host-cp,$(GSTREAMER_NDK_BUILD_PATH)/GStreamer.java,src/com/gstreamer) + +copyfontsres: + @$(call host-mkdir,assets/fontconfig) + @$(call host-mkdir,assets/fontconfig/fonts/truetype/) + @$(call host-cp,$(GSTREAMER_NDK_BUILD_PATH)/fontconfig/fonts.conf,assets/fontconfig) + @$(call host-cp,$(GSTREAMER_NDK_BUILD_PATH)/fontconfig/fonts/Ubuntu-R.ttf,assets/fontconfig/fonts/truetype) diff --git a/data/ndk-build-1.0/gstreamer_android.c.in b/data/ndk-build-1.0/gstreamer_android.c.in new file mode 100644 index 0000000..2d1304b --- /dev/null +++ b/data/ndk-build-1.0/gstreamer_android.c.in @@ -0,0 +1,422 @@ +#include <jni.h> +#include <gst/gst.h> +#include <gio/gio.h> +#include <android/log.h> + +static GstClockTime _priv_gst_info_start_time; + +/* Declaration of static plugins */ + @PLUGINS_DECLARATION@ + +/* Declaration of static gio modules */ + @G_IO_MODULES_DECLARE@ + +/* Call this function to register static plugins */ +void +gst_android_register_static_plugins (void) +{ + @PLUGINS_REGISTRATION@ +} + +/* Call this function to load GIO modules */ +void +gst_android_load_gio_modules (void) +{ + @G_IO_MODULES_LOAD@ +} + +void +glib_print_handler (const gchar * string) +{ + __android_log_print (ANDROID_LOG_INFO, "GLib+stdout", "%s", string); +} + +void +glib_printerr_handler (const gchar * string) +{ + __android_log_print (ANDROID_LOG_ERROR, "GLib+stderr", "%s", string); +} + + +/* Based on GLib's default handler */ +#define CHAR_IS_SAFE(wc) (!((wc < 0x20 && wc != '\t' && wc != '\n' && wc != '\r') || \ + (wc == 0x7f) || \ + (wc >= 0x80 && wc < 0xa0))) +#define FORMAT_UNSIGNED_BUFSIZE ((GLIB_SIZEOF_LONG * 3) + 3) +#define STRING_BUFFER_SIZE (FORMAT_UNSIGNED_BUFSIZE + 32) +#define ALERT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING) +#define DEFAULT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE) +#define INFO_LEVELS (G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG) + +static void +escape_string (GString * string) +{ + const char *p = string->str; + gunichar wc; + + while (p < string->str + string->len) { + gboolean safe; + + wc = g_utf8_get_char_validated (p, -1); + if (wc == (gunichar) - 1 || wc == (gunichar) - 2) { + gchar *tmp; + guint pos; + + pos = p - string->str; + + /* Emit invalid UTF-8 as hex escapes + */ + tmp = g_strdup_printf ("\\x%02x", (guint) (guchar) * p); + g_string_erase (string, pos, 1); + g_string_insert (string, pos, tmp); + + p = string->str + (pos + 4); /* Skip over escape sequence */ + + g_free (tmp); + continue; + } + if (wc == '\r') { + safe = *(p + 1) == '\n'; + } else { + safe = CHAR_IS_SAFE (wc); + } + + if (!safe) { + gchar *tmp; + guint pos; + + pos = p - string->str; + + /* Largest char we escape is 0x0a, so we don't have to worry + * about 8-digit \Uxxxxyyyy + */ + tmp = g_strdup_printf ("\\u%04x", wc); + g_string_erase (string, pos, g_utf8_next_char (p) - p); + g_string_insert (string, pos, tmp); + g_free (tmp); + + p = string->str + (pos + 6); /* Skip over escape sequence */ + } else + p = g_utf8_next_char (p); + } +} + +void +glib_log_handler (const gchar * log_domain, GLogLevelFlags log_level, + const gchar * message, gpointer user_data) +{ + gchar *string; + GString *gstring; + const gchar *domains; + gint android_log_level; + gchar *tag; + + if ((log_level & DEFAULT_LEVELS) || (log_level >> G_LOG_LEVEL_USER_SHIFT)) + goto emit; + + domains = g_getenv ("G_MESSAGES_DEBUG"); + if (((log_level & INFO_LEVELS) == 0) || + domains == NULL || + (strcmp (domains, "all") != 0 && (!log_domain + || !strstr (domains, log_domain)))) + return; + +emit: + + if (log_domain) + tag = g_strdup_printf ("GLib+%s", log_domain); + else + tag = g_strdup ("GLib"); + + switch (log_level & G_LOG_LEVEL_MASK) { + case G_LOG_LEVEL_ERROR: + android_log_level = ANDROID_LOG_ERROR; + break; + case G_LOG_LEVEL_CRITICAL: + android_log_level = ANDROID_LOG_ERROR; + break; + case G_LOG_LEVEL_WARNING: + android_log_level = ANDROID_LOG_WARN; + break; + case G_LOG_LEVEL_MESSAGE: + android_log_level = ANDROID_LOG_INFO; + break; + case G_LOG_LEVEL_INFO: + android_log_level = ANDROID_LOG_INFO; + break; + case G_LOG_LEVEL_DEBUG: + android_log_level = ANDROID_LOG_DEBUG; + break; + default: + android_log_level = ANDROID_LOG_INFO; + break; + } + + gstring = g_string_new (NULL); + if (!message) { + g_string_append (gstring, "(NULL) message"); + } else { + GString * msg = g_string_new (message); + escape_string (msg); + g_string_append (gstring, msg->str); + g_string_free (msg, TRUE); + } + string = g_string_free (gstring, FALSE); + + __android_log_print (android_log_level, tag, "%s", string); + + g_free (string); + g_free (tag); +} + +void +gst_debug_logcat (GstDebugCategory * category, GstDebugLevel level, + const gchar * file, const gchar * function, gint line, + GObject * object, GstDebugMessage * message, gpointer unused) +{ + GstClockTime elapsed; + gint android_log_level; + gchar *tag; + + if (level > gst_debug_category_get_threshold (category)) + return; + + elapsed = GST_CLOCK_DIFF (_priv_gst_info_start_time, + gst_util_get_timestamp ()); + + switch (level) { + case GST_LEVEL_ERROR: + android_log_level = ANDROID_LOG_ERROR; + break; + case GST_LEVEL_WARNING: + android_log_level = ANDROID_LOG_WARN; + break; + case GST_LEVEL_INFO: + android_log_level = ANDROID_LOG_INFO; + break; + case GST_LEVEL_DEBUG: + android_log_level = ANDROID_LOG_DEBUG; + break; + default: + android_log_level = ANDROID_LOG_VERBOSE; + break; + } + + tag = g_strdup_printf ("GStreamer+%s", + gst_debug_category_get_name (category)); + + if (object) { + gchar *obj; + + if (GST_IS_PAD (object) && GST_OBJECT_NAME (object)) { + obj = g_strdup_printf ("<%s:%s>", GST_DEBUG_PAD_NAME (object)); + } else if (GST_IS_OBJECT (object) && GST_OBJECT_NAME (object)) { + obj = g_strdup_printf ("<%s>", GST_OBJECT_NAME (object)); + } else if (G_IS_OBJECT (object)) { + obj = g_strdup_printf ("<%s@%p>", G_OBJECT_TYPE_NAME (object), object); + } else { + obj = g_strdup_printf ("<%p>", object); + } + + __android_log_print (android_log_level, tag, + "%" GST_TIME_FORMAT " %p %s:%d:%s:%s %s\n", + GST_TIME_ARGS (elapsed), g_thread_self (), + file, line, function, obj, gst_debug_message_get (message)); + + g_free (obj); + } else { + __android_log_print (android_log_level, tag, + "%" GST_TIME_FORMAT " %p %s:%d:%s %s\n", + GST_TIME_ARGS (elapsed), g_thread_self (), + file, line, function, gst_debug_message_get (message)); + } + g_free (tag); +} + +static gboolean +get_application_dirs (JNIEnv * env, jobject context, gchar ** cache_dir, + gchar ** files_dir) +{ + jclass context_class; + jmethodID get_cache_dir_id, get_files_dir_id; + jclass file_class; + jmethodID get_absolute_path_id; + jobject dir; + jstring abs_path; + const gchar *abs_path_str; + + *cache_dir = *files_dir = NULL; + + context_class = (*env)->GetObjectClass (env, context); + if (!context_class) { + return FALSE; + } + get_cache_dir_id = + (*env)->GetMethodID (env, context_class, "getCacheDir", + "()Ljava/io/File;"); + get_files_dir_id = + (*env)->GetMethodID (env, context_class, "getFilesDir", + "()Ljava/io/File;"); + if (!get_cache_dir_id || !get_files_dir_id) { + return FALSE; + } + + file_class = (*env)->FindClass (env, "java/io/File"); + get_absolute_path_id = + (*env)->GetMethodID (env, file_class, "getAbsolutePath", + "()Ljava/lang/String;"); + if (!get_absolute_path_id) { + return FALSE; + } + + dir = (*env)->CallObjectMethod (env, context, get_cache_dir_id); + if ((*env)->ExceptionCheck (env)) { + return FALSE; + } + + if (dir) { + abs_path = (*env)->CallObjectMethod (env, dir, get_absolute_path_id); + if ((*env)->ExceptionCheck (env)) { + return FALSE; + } + abs_path_str = (*env)->GetStringUTFChars (env, abs_path, NULL); + if ((*env)->ExceptionCheck (env)) { + return FALSE; + } + *cache_dir = abs_path ? g_strdup (abs_path_str) : NULL; + + (*env)->ReleaseStringUTFChars (env, abs_path, abs_path_str); + (*env)->DeleteLocalRef (env, abs_path); + (*env)->DeleteLocalRef (env, dir); + } + + dir = (*env)->CallObjectMethod (env, context, get_files_dir_id); + if ((*env)->ExceptionCheck (env)) { + return FALSE; + } + if (dir) { + abs_path = (*env)->CallObjectMethod (env, dir, get_absolute_path_id); + if ((*env)->ExceptionCheck (env)) { + return FALSE; + } + abs_path_str = (*env)->GetStringUTFChars (env, abs_path, NULL); + if ((*env)->ExceptionCheck (env)) { + return FALSE; + } + *files_dir = files_dir ? g_strdup (abs_path_str) : NULL; + + (*env)->ReleaseStringUTFChars (env, abs_path, abs_path_str); + (*env)->DeleteLocalRef (env, abs_path); + (*env)->DeleteLocalRef (env, dir); + } + + (*env)->DeleteLocalRef (env, file_class); + (*env)->DeleteLocalRef (env, context_class); + + return TRUE; +} + +static void +gst_android_init (JNIEnv * env, jclass klass, jobject context) +{ + gchar *cache_dir; + gchar *files_dir; + gchar *registry; + GError *error = NULL; + + if (gst_is_initialized ()) { + __android_log_print (ANDROID_LOG_INFO, "GStreamer", + "GStreamer already initialized"); + return; + } + + if (!get_application_dirs (env, context, &cache_dir, &files_dir)) + return; + + if (cache_dir) { + g_setenv ("TMP", cache_dir, TRUE); + g_setenv ("TEMP", cache_dir, TRUE); + g_setenv ("TMPDIR", cache_dir, TRUE); + g_setenv ("XDG_RUNTIME_DIR", cache_dir, TRUE); + g_setenv ("XDG_CACHE_DIR", cache_dir, TRUE); + registry = g_build_filename (cache_dir, "registry.bin", NULL); + g_setenv ("GST_REGISTRY", registry, TRUE); + g_free (registry); + g_setenv ("GST_REUSE_PLUGIN_SCANNER", "no", TRUE); + /* TODO: Should probably also set GST_PLUGIN_SCANNER and GST_PLUGIN_SYSTEM_PATH */ + } + if (files_dir) { + gchar *fontconfig; + + g_setenv ("HOME", files_dir, TRUE); + g_setenv ("XDG_DATA_DIRS", files_dir, TRUE); + g_setenv ("XDG_CONFIG_DIRS", files_dir, TRUE); + g_setenv ("XDG_CONFIG_HOME", files_dir, TRUE); + g_setenv ("XDG_DATA_HOME", files_dir, TRUE); + + fontconfig = g_build_filename (files_dir, "fontconfig", NULL); + g_setenv ("FONTCONFIG_PATH", fontconfig, TRUE); + g_free (fontconfig); + } + g_free (cache_dir); + g_free (files_dir); + + /* Set GLib print handlers */ + g_set_print_handler (glib_print_handler); + g_set_printerr_handler (glib_printerr_handler); + g_log_set_default_handler (glib_log_handler, NULL); + + /* Disable this for releases if performance is important + * or increase the threshold to get more information */ + gst_debug_set_active (TRUE); + gst_debug_set_default_threshold (GST_LEVEL_WARNING); + gst_debug_remove_log_function (gst_debug_log_default); + gst_debug_add_log_function ((GstLogFunction) gst_debug_logcat, NULL, NULL); + + /* get time we started for debugging messages */ + _priv_gst_info_start_time = gst_util_get_timestamp (); + + if (!gst_init_check (NULL, NULL, &error)) { + gchar *message = g_strdup_printf ("GStreamer initialization failed: %s", + error && error->message ? error->message : "(no message)"); + jclass exception_class = (*env)->FindClass (env, "java/lang/Exception"); + __android_log_print (ANDROID_LOG_ERROR, "GStreamer", message); + (*env)->ThrowNew (env, exception_class, message); + g_free (message); + return; + } + gst_android_register_static_plugins (); + gst_android_load_gio_modules (); + __android_log_print (ANDROID_LOG_INFO, "GStreamer", + "GStreamer initialization complete"); +} + +static JNINativeMethod native_methods[] = { + {"nativeInit", "(Landroid/content/Context;)V", (void *) gst_android_init} +}; + +jint +JNI_OnLoad (JavaVM * vm, void *reserved) +{ + JNIEnv *env = NULL; + + if ((*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) { + __android_log_print (ANDROID_LOG_ERROR, "GStreamer", + "Could not retrieve JNIEnv"); + return 0; + } + jclass klass = (*env)->FindClass (env, "com/gstreamer/GStreamer"); + if (!klass) { + __android_log_print (ANDROID_LOG_ERROR, "GStreamer", + "Could not retrieve class com.gstreamer.GStreamer"); + return 0; + } + if ((*env)->RegisterNatives (env, klass, native_methods, + G_N_ELEMENTS (native_methods))) { + __android_log_print (ANDROID_LOG_ERROR, "GStreamer", + "Could not register native methods for com.gstreamer.GStreamer"); + return 0; + } + + return JNI_VERSION_1_4; +} diff --git a/data/ndk-build-1.0/gstreamer_prebuilt.mk b/data/ndk-build-1.0/gstreamer_prebuilt.mk new file mode 100644 index 0000000..1440e3e --- /dev/null +++ b/data/ndk-build-1.0/gstreamer_prebuilt.mk @@ -0,0 +1,70 @@ +# Copyright (C) 2010 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# this file is included from prebuilt-shared-library.mk or +# prebuilt-static-library.mk to declare prebuilt library binaries. +# + +$(call assert-defined, LOCAL_BUILD_SCRIPT LOCAL_MAKEFILE LOCAL_PREBUILT_PREFIX LOCAL_PREBUILT_SUFFIX) + +$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT)) +$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE)) +$(call check-LOCAL_MODULE_FILENAME) + +# Check that LOCAL_SRC_FILES contains only paths to shared libraries +ifneq ($(words $(LOCAL_SRC_FILES)),1) +$(call __ndk_info,ERROR:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): The LOCAL_SRC_FILES for a prebuilt static library should only contain one item)) +$(call __ndk_error,Aborting) +endif + +bad_prebuilts := $(filter-out %$(LOCAL_PREBUILT_SUFFIX),$(LOCAL_SRC_FILES)) +ifdef bad_prebuilts +$(call __ndk_info,ERROR:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_SRC_FILES should point to a file ending with "$(LOCAL_PREBUILT_SUFFIX)") +$(call __ndk_info,The following file is unsupported: $(bad_prebuilts)) +$(call __ndk_error,Aborting) +endif + + +# HACK: This part was modified from the original file as +# the shared library will be built with the gstreamer.mk rules +prebuilt := $(GSTREAMER_ANDROID_SO) + +# If LOCAL_MODULE_FILENAME is defined, it will be used to name the file +# in the TARGET_OUT directory, and then the installation one. Note that +# if shouldn't have an .a or .so extension nor contain directory separators. +# +# If the variable is not defined, we determine its value from LOCAL_SRC_FILES +# +LOCAL_MODULE_FILENAME := $(strip $(LOCAL_MODULE_FILENAME)) +ifndef LOCAL_MODULE_FILENAME + LOCAL_MODULE_FILENAME := $(notdir $(LOCAL_SRC_FILES)) + LOCAL_MODULE_FILENAME := $(LOCAL_MODULE_FILENAME:%$(LOCAL_PREBUILT_SUFFIX)=%) +endif +$(eval $(call ev-check-module-filename)) + +LOCAL_BUILT_MODULE := $(TARGET_OUT)/$(LOCAL_MODULE_FILENAME)$(LOCAL_PREBUILT_SUFFIX) +LOCAL_OBJS_DIR := $(TARGET_OBJS)/$(LOCAL_MODULE) +LOCAL_OBJECTS := $(prebuilt) +LOCAL_SRC_FILES := + +$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS) + +delsharedlib: + @$(call host-rm,$(prebuilt)) + @$(foreach path,$(wildcard $(GSTREAMER_BUILD_DIR)/sed*), $(call host-rm,$(path))) + +include $(BUILD_SYSTEM)/build-module.mk + +$(LOCAL_INSTALLED): delsharedlib diff --git a/data/ndk-build-1.0/tools.mk b/data/ndk-build-1.0/tools.mk new file mode 100644 index 0000000..65ac13d --- /dev/null +++ b/data/ndk-build-1.0/tools.mk @@ -0,0 +1,272 @@ +# cerbero - a multi-platform build system for Open Source software +# Copyright (C) 2012 Andoni Morales Alastruey <ylatuya@gmail.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +################ +# pkg-config # +################ +# Host tools +# Make pkg-config relocatable +# set PKG_CONFIG_LIBDIR and override the prefix and libdir variables +ifeq ($(HOST_OS),windows) + HOST_PKG_CONFIG := $(GSTREAMER_NDK_BUILD_PATH)/tools/windows/pkg-config + # No space before the &&, or it will be added to PKG_CONFIG_LIBDIR + PKG_CONFIG_ORIG := set PKG_CONFIG_LIBDIR=$(GSTREAMER_SDK_ROOT)/lib/pkgconfig&& $(HOST_PKG_CONFIG) + GSTREAMER_SDK_ROOT := $(subst \,/,$(GSTREAMER_SDK_ROOT)) +else + HOST_PKG_CONFIG := pkg-config + PKG_CONFIG_ORIG := PKG_CONFIG_LIBDIR=$(GSTREAMER_SDK_ROOT)/lib/pkgconfig $(HOST_PKG_CONFIG) +endif + +PKG_CONFIG := $(PKG_CONFIG_ORIG) --define-variable=prefix=$(GSTREAMER_SDK_ROOT) --define-variable=libdir=$(GSTREAMER_SDK_ROOT)/lib + +# ----------------------------------------------------------------------------- +# Function : pkg-config-get-includes +# Arguments: 1: package or list of packages +# Returns : list of includes +# Usage : $(call pkg-config-get-includes,<package>) +# ----------------------------------------------------------------------------- +pkg-config-get-includes = \ + $(shell $(PKG_CONFIG) --cflags-only-I $1) + +# ----------------------------------------------------------------------------- +# Function : pkg-config-get-libs +# Arguments: 1: package or list of packages +# Returns : list of libraries to link this package +# Usage : $(call pkg-config-get-libs,<package>) +# ----------------------------------------------------------------------------- +pkg-config-get-libs = \ + $(shell $(PKG_CONFIG) --libs-only-l $1) + +# ----------------------------------------------------------------------------- +# Function : pkg-config-get-libs-no-deps +# Arguments: 1: package or list of packages +# Returns : list of -lfoo libraries for this packages without the deps +# Usage : $(call pkg-config-get-libs,<package>) +# ----------------------------------------------------------------------------- +pkg-config-get-libs-no-deps = \ + $(eval __tmpvar.libs := ) \ + $(foreach package,$1,\ + $(eval __tmpvar.libs += $(shell $(HOST_SED) -n 's/^Libs: \(.*\)/\1/p' $(GSTREAMER_SDK_ROOT)/lib/pkgconfig/$(package).pc)))\ + $(filter -l%, $(__tmpvar.libs)) + +# ----------------------------------------------------------------------------- +# Function : pkg-config-get-prefix +# Arguments: 1: package +# Returns : a string with the prefix variable +# Usage : $(call pkg-config-get-prefix,<package>) +# ----------------------------------------------------------------------------- +pkg-config-get-prefix = \ + $(shell $(HOST_SED) -n 's/^prefix=\(.*\)/\1/p' $(GSTREAMER_SDK_ROOT)/lib/pkgconfig/$1.pc) + +# ----------------------------------------------------------------------------- +# Function : libtool-whole-archive +# Arguments: 1: link command +# 2: list of libraries for which we want to include the whole archive +# Returns : the fixed link command +# Usage : $(call libtool-link,<cmd>,<libs>) +# ----------------------------------------------------------------------------- +WHOLE_ARCHIVE = -Wl,--whole-archive +NO_WHOLE_ARCHIVE = -Wl,--no-whole-archive +libtool-whole-archive = \ + $(eval __tmpvar.archives_paths := ) \ + $(foreach lib,$2, \ + $(eval __tmpvar.archives_paths += $(patsubst %.la,%.a,$(call libtool-find-lib,$(patsubst -l%,%,$(lib)))))) \ + $(eval __tmpvar.cmd := $1) \ + $(foreach ar,$(__tmpvar.archives_paths), \ + $(eval __tmpvar.cmd := $(patsubst %$(ar),$(WHOLE_ARCHIVE) %$(ar) $(NO_WHOLE_ARCHIVE),$(__tmpvar.cmd)))\ + )\ + $(call __libtool_log, "Link Command with whole archives:" $(__tmpvar.cmd))\ + $(__tmpvar.cmd) + +# ----------------------------------------------------------------------------- +# Function : libtool-link +# Arguments: 1: link command +# Returns : a link command with all the dependencies resolved as done by libtool +# Usage : $(call libtool-link,<lib>) +# ----------------------------------------------------------------------------- +libtool-link = \ + $(call libtool-clear-vars)\ + $(eval __libtool.link.command := $1)\ + $(call __libtool_log, original link command = $(__libtool.link.command))\ + $(eval __libtool.link.Lpath := $(call libtool-get-search-paths,$1))\ + $(call __libtool_log, Library Search Paths = $(__libtool.link.Lpath))\ + $(eval __libtool.link.libs := $(call libtool-get-libs,$1))\ + $(call __libtool_log, Libraries = $(__libtool.link.libs))\ + $(foreach library,$(__libtool.link.libs),$(call libtool-parse-lib,$(library)))\ + $(call libtool-gen-link-command) + + +############################################################################### +# # +# This functions are private, don't use them directly # +# # +############################################################################### + +# ----------------------------------------------------------------------------- +# Function : libtool-parse-library +# Arguments: 1: library name +# Returns : "" +# Usage : $(call libtool-parse-library,<libname>) +# Note : Tries to find a libtool library for this name in the libraries search +# path and parses it as well as its dependencies +# ----------------------------------------------------------------------------- +libtool-parse-lib = \ + $(eval __tmpvar := $(strip $(call libtool-find-lib,$(patsubst -l%,%,$1))))\ + $(if $(__tmpvar), \ + $(call libtool-parse-file,$(__tmpvar),$(call libtool-name-from-filepath,$(__tmpvar))),\ + $(eval __libtool.link.shared_libs += $1)\ + $(call __libtool_log, libtool file not found for "$1" and will be added to the shared libs)\ + ) + +# ----------------------------------------------------------------------------- +# Function : libtool-parse-file +# Arguments: 1: libtool file +# 2: library name +# Returns : "" +# Usage : $(call libtool-parse-file,<file>,<libname>) +# Note : +# Parses a libtool library and its dependencies recursively +# +# For each library it sets the following variables: +# __libtool_libs.libname.LIBS -> non-libtool libraries linked with -lfoo +# __libtool_libs.libname.STATIC_LIB -> link statically this library +# __libtool_libs.libname.DYN_LIB -> link dynamically this library +# __libtool_libs.libname.LIBS_SEARCH_PATH -> libraries search path +# +# Processed libraries are stored in __libtool_libs.processed, and +# the list of libraries ordered by dependencies are stored in +# __libtool_lbs.ordered +# ----------------------------------------------------------------------------- +libtool-parse-file = \ + $(call __libtool_log, parsing file $1)\ + $(if $(call libtool-lib-processed,$2),\ + $(call __libtool_log, library $2 already parsed),\ + $(eval __libtool_libs.$2.STATIC_LIB := $(patsubst %.la,%.a,$1))\ + $(eval __libtool_libs.$2.DYN_LIB := -l$2)\ + $(eval __tmpvar.$2.dep_libs := $(call libtool-get-dependency-libs,$1))\ + $(eval __tmpvar.$2.dep_libs := $(call libtool-replace-prefixes,$(__tmpvar.$2.dep_libs)))\ + $(eval __libtool_libs.$2.LIBS := $(call libtool-get-libs,$(__tmpvar.$2.dep_libs)))\ + $(eval __libtool_libs.$2.LIBS_SEARCH_PATH := $(call libtool-get-search-paths,$(__tmpvar.$2.dep_libs)))\ + $(call __libtool_log, $2.libs = $(__libtool_libs.$2.LIBS))\ + $(eval __tmpvar.$2.file_deps := $(call libtool-get-libtool-deps,$(__tmpvar.$2.dep_libs)))\ + $(eval __libtool_libs.$2.DEPS := $(foreach path,$(__tmpvar.$2.file_deps), $(call libtool-name-from-filepath,$(path))))\ + $(call __libtool_log, $2.deps = $(__libtool_libs.$2.DEPS)) \ + $(eval __libtool_libs.processed += $2) \ + $(call __libtool_log, parsed libraries: $(__libtool_libs.processed))\ + $(foreach library,$(__libtool_libs.$2.DEPS), $(call libtool-parse-lib,$(library)))\ + $(eval __libtool_libs.ordered += $2)\ + $(call __libtool_log, ordered list of libraries: $(__libtool_libs.ordered))\ + ) + +__libtool_log = \ + $(if $(strip $(LIBTOOL_DEBUG)),\ + $(call __libtool_info,$1),\ + ) + +__libtool_info = $(info LIBTOOL: $1) + +libtool-clear-vars = \ + $(foreach lib,$(__libtool_libs.processed),\ + $(eval __libtool_libs.$(lib).LIBS := $(empty))\ + $(eval __libtool_libs.$(lib).STATIC_LIB := $(empty))\ + $(eval __libtool_libs.$(lib).DYN_LIB := $(empty))\ + $(eval __libtool_libs.$(lib).LIBS_SEARCH_PATH := $(empty))\ + )\ + $(eval __libtool_libs.ordered := $(empty))\ + $(eval __libtool_libs.processed := $(empty))\ + $(eval __libtool.link.Lpath := $(empty))\ + $(eval __libtool.link.command := $(empty))\ + $(eval __libtool.link.libs := $(empty))\ + $(eval __libtool.link.shared_libs := $(empty)) + +libtool-lib-processed = \ + $(findstring ___$1___, $(foreach lib,$(__libtool_libs.processed), ___$(lib)___)) + +libtool-gen-link-command = \ + $(eval __tmpvar.cmd := $(filter-out -L%,$(__libtool.link.command)))\ + $(eval __tmpvar.cmd := $(filter-out -l%,$(__tmpvar.cmd)))\ + $(eval __tmpvar.cmd += $(__libtool.link.Lpath))\ + $(eval __tmpvar.cmd += $(call libtool-get-libs-search-paths))\ + $(eval __tmpvar.cmd += $(call libtool-get-all-libs))\ + $(eval __tmpvar.cmd += $(__libtool.link.shared_libs))\ + $(call __libtool_log, "Link Command:" $(__tmpvar.cmd))\ + $(__tmpvar.cmd) + +libtool-get-libs-search-paths = \ + $(eval __tmpvar.paths := $(empty))\ + $(foreach library,$(__libtool_libs.ordered),\ + $(foreach path,$(__libtool_libs.$(library).LIBS_SEARCH_PATH),\ + $(if $(findstring $(path), $(__tmpvar.paths)), ,\ + $(eval __tmpvar.paths += $(path))\ + )\ + )\ + )\ + $(call __libtool_log, search paths $(__tmpvar.paths))\ + $(strip $(__tmpvar.paths)) + +libtool-get-all-libs = \ + $(eval __tmpvar.static_libs_reverse := $(empty))\ + $(eval __tmpvar.static_libs := $(empty))\ + $(eval __tmpvar.libs := $(empty))\ + $(foreach library,$(__libtool_libs.ordered),\ + $(eval __tmpvar.static_libs_reverse += $(__libtool_libs.$(library).STATIC_LIB))\ + $(foreach dylib,$(__libtool_libs.$(library).LIBS),\ + $(if $(findstring $(dylib), $(__tmpvar.libs)), ,\ + $(eval __tmpvar.libs += $(dylib))\ + )\ + )\ + )\ + $(foreach path,$(__tmpvar.static_libs_reverse),\ + $(eval __tmpvar.static_libs := $(path) $(__tmpvar.static_libs))\ + )\ + $(strip $(__tmpvar.static_libs) $(__tmpvar.libs) ) + +libtool-find-lib = \ + $(eval __tmpvar := $(empty))\ + $(foreach path,$(__libtool.link.Lpath),\ + $(eval __tmpvar += $(wildcard $(patsubst -L%,%,$(path))/lib$1.la))\ + ) \ + $(firstword $(__tmpvar)) + +libtool-clear-vars = \ + $(eval __libtool.link.command := $(empty)) + $(eval __libtool.link.Lpath := $(empty)) + +libtool-name-from-filepath = \ + $(patsubst lib%.la,%,$(notdir $1)) + +libtool-get-libtool-deps = \ + $(filter %.la,$1) + +libtool-get-deps = \ + $(filter %.la,$1) + +libtool-get-libs = \ + $(filter -l%,$1) + +libtool-get-search-paths = \ + $(filter -L%,$1) + +libtool-get-dependency-libs = \ + $(shell $(HOST_SED) -n "s/^dependency_libs='\(.*\)'/\1/p" $1) + +libtool-replace-prefixes = \ + $(subst $(BUILD_PREFIX),$(GSTREAMER_SDK_ROOT),$1 ) + +libtool-get-static-library = \ + $(shell $(HOST_SED) -n "s/^old_library='\(.*\)'/\1/p" $1) diff --git a/data/ndk-build-1.0/tools/windows/libiconv2.dll b/data/ndk-build-1.0/tools/windows/libiconv2.dll Binary files differnew file mode 100755 index 0000000..544dd92 --- /dev/null +++ b/data/ndk-build-1.0/tools/windows/libiconv2.dll diff --git a/data/ndk-build-1.0/tools/windows/libintl3.dll b/data/ndk-build-1.0/tools/windows/libintl3.dll Binary files differnew file mode 100755 index 0000000..ec11e6b --- /dev/null +++ b/data/ndk-build-1.0/tools/windows/libintl3.dll diff --git a/data/ndk-build-1.0/tools/windows/pkg-config.exe b/data/ndk-build-1.0/tools/windows/pkg-config.exe Binary files differnew file mode 100755 index 0000000..3821dc4 --- /dev/null +++ b/data/ndk-build-1.0/tools/windows/pkg-config.exe diff --git a/data/ndk-build-1.0/tools/windows/regex2.dll b/data/ndk-build-1.0/tools/windows/regex2.dll Binary files differnew file mode 100755 index 0000000..f84a847 --- /dev/null +++ b/data/ndk-build-1.0/tools/windows/regex2.dll diff --git a/data/ndk-build-1.0/tools/windows/sed.exe b/data/ndk-build-1.0/tools/windows/sed.exe Binary files differnew file mode 100755 index 0000000..3190377 --- /dev/null +++ b/data/ndk-build-1.0/tools/windows/sed.exe diff --git a/packages/gstreamer-1.0-core.package b/packages/gstreamer-1.0-core.package index a203521..e65dfc6 100644 --- a/packages/gstreamer-1.0-core.package +++ b/packages/gstreamer-1.0-core.package @@ -27,5 +27,5 @@ class Package(package.Package): platform_files = { Platform.DARWIN: ['gstreamer-1.0-osx-framework'], Platform.IOS: ['gstreamer-1.0-ios-templates'], - Platform.ANDROID: ['gst-1.0-android'], + Platform.ANDROID: ['gst-android-1.0'], } diff --git a/packages/gstreamer-1.0-sdk/gstreamer-1.0-sdk.package b/packages/gstreamer-1.0-sdk/gstreamer-1.0-sdk.package index 06069fc..f0d98b7 100644 --- a/packages/gstreamer-1.0-sdk/gstreamer-1.0-sdk.package +++ b/packages/gstreamer-1.0-sdk/gstreamer-1.0-sdk.package @@ -61,7 +61,7 @@ class SDKPackage(package.SDKPackage): def prepare(self): if self.config.target_platform in [Platform.ANDROID, Platform.IOS]: - p = ['gstreamer-dvd'] + p = ['gstreamer-1.0-dvd'] self.packages = [ x for x in self.packages if x[0] not in p] if self.config.target_platform == Platform.IOS: self.resources_postinstall = 'post_install_ios' diff --git a/recipes/custom.py b/recipes/custom.py index 514c876..1d056ff 100644 --- a/recipes/custom.py +++ b/recipes/custom.py @@ -79,7 +79,7 @@ class GStreamerStatic(recipe.Recipe): os.path.join(self.config.prefix, f)) -def list_gstreamer_plugins_by_category(config): +def list_gstreamer_plugins_by_category(config): cookbook = CookBook(config) # For plugins named differently replacements = {'decodebin2': 'uridecodebin', 'playbin': 'playback', @@ -106,3 +106,31 @@ def list_gstreamer_plugins_by_category(config): continue plugins[cat_name].append(e[25:-8]) return plugins, replacements + +def list_gstreamer_1_0_plugins_by_category(config): + cookbook = CookBook(config) + # For plugins named differently + replacements = {'decodebin': 'playback', 'playbin': 'playback', + 'uridecodebin': 'playback', 'sdpelem': 'sdp', + 'encodebin': 'encoding', 'souphttpsrc': 'soup', + 'siren': 'gstsiren', 'scaletempoplugin' : 'scaletempo', + 'rmdemux': 'realmedia', 'camerabin2': 'camerabin'} + plugins = defaultdict(list) + for r in ['gstreamer-1.0', 'gst-plugins-base-1.0', 'gst-plugins-good-1.0', + 'gst-plugins-bad-1.0', 'gst-plugins-ugly-1.0', 'gst-libav-1.0']: + r = cookbook.get_recipe(r) + for attr_name in dir(r): + if attr_name.startswith('files_plugins_'): + cat_name = attr_name[len('files_plugins_'):] + plugins_list = getattr(r, attr_name) + elif attr_name.startswith('platform_files_plugins_'): + cat_name = attr_name[len('platform_files_plugins_'):] + plugins_dict = getattr(r, attr_name) + plugins_list = plugins_dict.get(config.target_platform, []) + else: + continue + for e in plugins_list: + if not e.startswith('lib/gstreamer-'): + continue + plugins[cat_name].append(e[24:-8]) + return plugins, replacements diff --git a/recipes/gst-android-1.0.recipe b/recipes/gst-android-1.0.recipe new file mode 100644 index 0000000..779849a --- /dev/null +++ b/recipes/gst-android-1.0.recipe @@ -0,0 +1,37 @@ +# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python +from cerbero.utils import shell +from custom import list_gstreamer_1_0_plugins_by_category + +class Recipe(recipe.Recipe): + name = 'gst-android-1.0' + version = '0.1' + licenses = [License.LGPLv2_1] + stype = SourceType.CUSTOM + btype = BuildType.CUSTOM + + files_devel = [ + 'share/gst-android/ndk-build-1.0/gstreamer_android.c.in', + 'share/gst-android/ndk-build-1.0/gstreamer.mk', + 'share/gst-android/ndk-build-1.0/gstreamer_prebuilt.mk', + 'share/gst-android/ndk-build-1.0/tools.mk', + 'share/gst-android/ndk-build-1.0/plugins.mk', + 'share/gst-android/ndk-build-1.0/GStreamer.java', + 'share/gst-android/ndk-build-1.0/tools/windows', + 'share/gst-android/ndk-build-1.0/fontconfig', + ] + + def install(self): + ndk_build_dir = os.path.join(self.config.prefix, 'share', 'gst-android', 'ndk-build-1.0') + shell.copy_dir(os.path.join(self.config.data_dir, 'ndk-build-1.0'), + ndk_build_dir) + + plugins, replacements = list_gstreamer_1_0_plugins_by_category(self.config) + f = open(os.path.join(ndk_build_dir, 'plugins.mk'), 'w') + for c, p in plugins.iteritems(): + p = ' '.join(p) + for k,v in replacements.iteritems(): + p = p.replace(k, v) + f.write('GSTREAMER_PLUGINS_%s := %s\n' % (c.upper(), p)) + f.close() + + diff --git a/recipes/gst-libav-1.0-static.recipe b/recipes/gst-libav-1.0-static.recipe index f5dd22e..011828d 100644 --- a/recipes/gst-libav-1.0-static.recipe +++ b/recipes/gst-libav-1.0-static.recipe @@ -31,7 +31,7 @@ class Recipe(custom.GStreamerStatic): self.configure_options += ' ASFLAGS="%s"' % asflags super(Recipe, self).prepare() - for f in ['libavcodec', 'libavformat', 'libavutil']: + for f in ['libavcodec', 'libavformat', 'libavutil', 'libswscale']: for ext in ['.a', '.la']: path = os.path.join('lib', f + ext) self.files_plugins_codecs_restricted_devel.append(path) @@ -56,7 +56,7 @@ class Recipe(custom.GStreamerStatic): shell.replace(os.path.join(libav_path, 'config.h'), replacements) def post_install(self): - for n in ['avutil', 'avcodec', 'avformat']: + for n in ['avutil', 'avcodec', 'avformat', 'swscale']: name = 'lib%s' % n lib = '%s.a' % name path = os.path.join(self.build_dir, 'gst-libs', 'ext', 'libav', @@ -67,6 +67,8 @@ class Recipe(custom.GStreamerStatic): deps += ['avutil'] if n == 'avformat': deps += ['avutil', 'avcodec'] + if n == 'swscale': + deps += ['avutil'] libtool_la = LibtoolLibrary(n, None, None, None, self.config.libdir, self.config.target_platform, deps) libtool_la.change_value ('dlname', '') @@ -78,5 +80,6 @@ class Recipe(custom.GStreamerStatic): shell.replace (gstlibavlib, {'-lavformat': os.path.join(self.config.libdir, 'libavformat.la'), '-lavcodec': os.path.join(self.config.libdir, 'libavcodec.la'), - '-lavutil': os.path.join(self.config.libdir, 'libavutil.la')}) + '-lavutil': os.path.join(self.config.libdir, 'libavutil.la'), + '-lswscale': os.path.join(self.config.libdir, 'libswscale.la')}) diff --git a/recipes/gst-plugins-bad-1.0-static.recipe b/recipes/gst-plugins-bad-1.0-static.recipe index c0e885a..f63c64d 100644 --- a/recipes/gst-plugins-bad-1.0-static.recipe +++ b/recipes/gst-plugins-bad-1.0-static.recipe @@ -136,6 +136,7 @@ class Recipe(custom.GStreamerStatic): if self.config.target_platform == Platform.ANDROID: for d in ['libdvdnav']: self.deps.remove(d) + self.files_plugins_dvd_devel.remove('libgstresindvd') if self.config.variants.nodebug: self.configure_options += ' --disable-gst-debug' diff --git a/recipes/gst-plugins-bad-1.0.recipe b/recipes/gst-plugins-bad-1.0.recipe index 8651a96..0e3cc83 100644 --- a/recipes/gst-plugins-bad-1.0.recipe +++ b/recipes/gst-plugins-bad-1.0.recipe @@ -142,6 +142,7 @@ class Recipe(recipe.Recipe): if self.config.target_platform == Platform.ANDROID: for d in ['libdvdnav']: self.deps.remove(d) + self.files_plugins_dvd.remove('lib/gstreamer-1.0/libgstresindvd%(mext)s') if self.config.variants.nodebug: self.configure_options += ' --disable-gst-debug' |