diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-12-13 12:13:27 +0000 |
---|---|---|
committer | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2016-01-21 13:49:15 -0500 |
commit | ade85907780a317d856d6fd71e5c530bbd78403e (patch) | |
tree | 90d3ad60b51682b6027611a85e8fc1e6e96e604a /sys | |
parent | ff435e2a7d7572402ba8f78a51085e76bbe0dd14 (diff) | |
download | gstreamer-plugins-bad-ade85907780a317d856d6fd71e5c530bbd78403e.tar.gz |
androidmedia: Add remaining bits of the Java wrappers using libgstdvm
Diffstat (limited to 'sys')
-rw-r--r-- | sys/androidmedia/gst-android-media-mediacodec.c | 84 | ||||
-rw-r--r-- | sys/androidmedia/gst-android-media-mediacodec.h | 10 | ||||
-rw-r--r-- | sys/androidmedia/gst-android-media-mediacodecinfo.c | 491 | ||||
-rw-r--r-- | sys/androidmedia/gst-android-media-mediacodecinfo.h | 91 | ||||
-rw-r--r-- | sys/androidmedia/gst-android-media-mediacodeclist.c | 116 | ||||
-rw-r--r-- | sys/androidmedia/gst-android-media-mediacodeclist.h | 40 | ||||
-rw-r--r-- | sys/androidmedia/gst-android-media-mediaformat.c | 1 | ||||
-rw-r--r-- | sys/androidmedia/gst-android-media-mediaformat.h | 4 |
8 files changed, 800 insertions, 37 deletions
diff --git a/sys/androidmedia/gst-android-media-mediacodec.c b/sys/androidmedia/gst-android-media-mediacodec.c index 6a214f799..306dfc51b 100644 --- a/sys/androidmedia/gst-android-media-mediacodec.c +++ b/sys/androidmedia/gst-android-media-mediacodec.c @@ -56,10 +56,14 @@ static struct jmethodID releaseOutputBuffer; jmethodID start; jmethodID stop; -} android_media_mediacodec = { -0}; - - + jint BUFFER_FLAG_SYNC_FRAME; + jint BUFFER_FLAG_CODEC_CONFIG; + jint BUFFER_FLAG_END_OF_STREAM; + jint CONFIGURE_FLAG_ENCODE; + jint INFO_TRY_AGAIN_LATER; + jint INFO_OUTPUT_FORMAT_CHANGED; + jint INFO_OUTPUT_BUFFERS_CHANGED; +} android_media_mediacodec; static gboolean _init_classes (void) @@ -93,6 +97,38 @@ _init_classes (void) GST_DVM_GET_METHOD (android_media_mediacodec, start, "()V"); GST_DVM_GET_METHOD (android_media_mediacodec, stop, "()V"); + + GST_DVM_GET_CONSTANT (android_media_mediacodec, BUFFER_FLAG_SYNC_FRAME, Int, + "I"); + MediaCodec_BUFFER_FLAG_SYNC_FRAME = + android_media_mediacodec.BUFFER_FLAG_SYNC_FRAME; + GST_DVM_GET_CONSTANT (android_media_mediacodec, BUFFER_FLAG_CODEC_CONFIG, Int, + "I"); + MediaCodec_BUFFER_FLAG_CODEC_CONFIG = + android_media_mediacodec.BUFFER_FLAG_CODEC_CONFIG; + GST_DVM_GET_CONSTANT (android_media_mediacodec, BUFFER_FLAG_END_OF_STREAM, + Int, "I"); + MediaCodec_BUFFER_FLAG_END_OF_STREAM = + android_media_mediacodec.BUFFER_FLAG_END_OF_STREAM; + + GST_DVM_GET_CONSTANT (android_media_mediacodec, CONFIGURE_FLAG_ENCODE, Int, + "I"); + MediaCodec_CONFIGURE_FLAG_ENCODE = + android_media_mediacodec.CONFIGURE_FLAG_ENCODE; + + GST_DVM_GET_CONSTANT (android_media_mediacodec, INFO_TRY_AGAIN_LATER, Int, + "I"); + MediaCodec_INFO_TRY_AGAIN_LATER = + android_media_mediacodec.INFO_TRY_AGAIN_LATER; + GST_DVM_GET_CONSTANT (android_media_mediacodec, INFO_OUTPUT_FORMAT_CHANGED, + Int, "I"); + MediaCodec_INFO_OUTPUT_FORMAT_CHANGED = + android_media_mediacodec.INFO_OUTPUT_FORMAT_CHANGED; + GST_DVM_GET_CONSTANT (android_media_mediacodec, INFO_OUTPUT_BUFFERS_CHANGED, + Int, "I"); + MediaCodec_INFO_OUTPUT_BUFFERS_CHANGED = + android_media_mediacodec.INFO_OUTPUT_BUFFERS_CHANGED; + /* android.media.MediaCodec.BufferInfo */ GST_DVM_GET_CLASS (android_media_mediacodec_bufferinfo, "android/media/MediaCodec$BufferInfo"); @@ -405,40 +441,18 @@ gst_am_mediacodec_dequeue_input_buffer (GstAmMediaCodec * self, return ret; } +#define AMMCBI_FIELD(error_statement, type, field) \ + GST_DVM_FIELD (error_statement, buffer_info, type, \ + android_media_mediacodec_bufferinfo, field); + static gboolean _fill_buffer_info (JNIEnv * env, jobject buffer_info, GstAmmcBufferInfo * info) { - info->flags = (*env)->GetIntField (env, buffer_info, - android_media_mediacodec_bufferinfo.flags); - if ((*env)->ExceptionCheck (env)) { - (*env)->ExceptionClear (env); - GST_ERROR ("Failed to get buffer info field"); - return FALSE; - } - - info->offset = (*env)->GetIntField (env, buffer_info, - android_media_mediacodec_bufferinfo.offset); - if ((*env)->ExceptionCheck (env)) { - (*env)->ExceptionClear (env); - GST_ERROR ("Failed to get buffer info field"); - return FALSE; - } - - info->presentation_time_us = (*env)->GetLongField (env, buffer_info, - android_media_mediacodec_bufferinfo.presentationTimeUs); - if ((*env)->ExceptionCheck (env)) { - (*env)->ExceptionClear (env); - GST_ERROR ("Failed to get buffer info field"); - return FALSE; - } - - info->size = (*env)->GetIntField (env, buffer_info, - android_media_mediacodec_bufferinfo.size); - if ((*env)->ExceptionCheck (env)) { - (*env)->ExceptionClear (env); - GST_ERROR ("Failed to get buffer info field"); - return FALSE; - } + info->flags = AMMCBI_FIELD (return FALSE, Int, flags); + info->offset = AMMCBI_FIELD (return FALSE, Int, offset); + info->presentation_time_us = + AMMCBI_FIELD (return FALSE, Long, presentationTimeUs); + info->size = AMMCBI_FIELD (return FALSE, Int, size); return TRUE; } diff --git a/sys/androidmedia/gst-android-media-mediacodec.h b/sys/androidmedia/gst-android-media-mediacodec.h index 4e242615d..4089ae52f 100644 --- a/sys/androidmedia/gst-android-media-mediacodec.h +++ b/sys/androidmedia/gst-android-media-mediacodec.h @@ -52,6 +52,16 @@ struct _GstAmMediaCodec { jobject object; /* global reference */ }; +extern gint MediaCodec_BUFFER_FLAG_SYNC_FRAME; +extern gint MediaCodec_BUFFER_FLAG_CODEC_CONFIG; +extern gint MediaCodec_BUFFER_FLAG_END_OF_STREAM; + +extern gint MediaCodec_CONFIGURE_FLAG_ENCODE; + +extern gint MediaCodec_INFO_TRY_AGAIN_LATER; +extern gint MediaCodec_INFO_OUTPUT_FORMAT_CHANGED; +extern gint MediaCodec_INFO_OUTPUT_BUFFERS_CHANGED; + gboolean gst_android_media_mediacodec_init (void); void gst_android_media_mediacodec_deinit (void); diff --git a/sys/androidmedia/gst-android-media-mediacodecinfo.c b/sys/androidmedia/gst-android-media-mediacodecinfo.c new file mode 100644 index 000000000..bd897a737 --- /dev/null +++ b/sys/androidmedia/gst-android-media-mediacodecinfo.c @@ -0,0 +1,491 @@ +/* + * Copyright (C) 2012, Collabora Ltd. + * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Author: Youness Alaoui <youness.alaoui@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/dvm/gst-dvm.h> + +#include "gst-android-media-mediacodecinfo.h" + +static struct +{ + jclass klass; + jmethodID getCapabilitiesForType; + jmethodID getName; + jmethodID getSupportedTypes; + jmethodID isEncoder; +} android_media_mediacodecinfo; + +static struct +{ + jclass klass; + jfieldID colorFormats; + jfieldID profileLevels; +} android_media_mediacodeccapabilities; + +static struct +{ + jclass klass; + jfieldID level; + jfieldID profile; +} android_media_mediacodecprofilelevel; + +static struct +{ + jclass klass; + + jint CHANNEL_OUT_FRONT_LEFT; + jint CHANNEL_OUT_FRONT_RIGHT; + jint CHANNEL_OUT_FRONT_CENTER; + jint CHANNEL_OUT_LOW_FREQUENCY; + jint CHANNEL_OUT_BACK_LEFT; + jint CHANNEL_OUT_BACK_RIGHT; + jint CHANNEL_OUT_FRONT_LEFT_OF_CENTER; + jint CHANNEL_OUT_FRONT_RIGHT_OF_CENTER; + jint CHANNEL_OUT_BACK_CENTER; + jint CHANNEL_OUT_SIDE_LEFT; + jint CHANNEL_OUT_SIDE_RIGHT; + jint CHANNEL_OUT_TOP_CENTER; + jint CHANNEL_OUT_TOP_FRONT_LEFT; + jint CHANNEL_OUT_TOP_FRONT_CENTER; + jint CHANNEL_OUT_TOP_FRONT_RIGHT; + jint CHANNEL_OUT_TOP_BACK_LEFT; + jint CHANNEL_OUT_TOP_BACK_CENTER; + jint CHANNEL_OUT_TOP_BACK_RIGHT; +} android_media_audioformat; + +static gboolean +_init_classes (void) +{ + JNIEnv *env = gst_dvm_get_env (); + + /* android.media.MediaCodecInfo */ + GST_DVM_GET_CLASS (android_media_mediacodecinfo, + "android/media/MediaCodecInfo"); + GST_DVM_GET_METHOD (android_media_mediacodecinfo, getCapabilitiesForType, + "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;"); + GST_DVM_GET_METHOD (android_media_mediacodecinfo, getName, + "()Ljava/lang/String;"); + GST_DVM_GET_METHOD (android_media_mediacodecinfo, getSupportedTypes, + "()[java/lang/String;"); + GST_DVM_GET_METHOD (android_media_mediacodecinfo, isEncoder, "()Z"); + + GST_DVM_GET_CLASS (android_media_mediacodeccapabilities, + "android/media/MediaCodecInfo$CodecCapabilities"); + GST_DVM_GET_FIELD (android_media_mediacodeccapabilities, colorFormats, "[I"); + GST_DVM_GET_FIELD (android_media_mediacodeccapabilities, profileLevels, + "[Landroid/media/MediaCodecInfo$CodecProfileLevel;"); + + GST_DVM_GET_CLASS (android_media_mediacodecprofilelevel, + "android/media/MediaCodecInfo$ProfileLevel"); + GST_DVM_GET_FIELD (android_media_mediacodecprofilelevel, level, "I"); + GST_DVM_GET_FIELD (android_media_mediacodecprofilelevel, profile, "I"); + + GST_DVM_GET_CLASS (android_media_audioformat, "android/media/AudioFormat"); + + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_FRONT_LEFT, Int, + "I"); + AudioFormat_CHANNEL_OUT_FRONT_LEFT = + android_media_audioformat.CHANNEL_OUT_FRONT_LEFT; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_FRONT_RIGHT, Int, + "I"); + AudioFormat_CHANNEL_OUT_FRONT_RIGHT = + android_media_audioformat.CHANNEL_OUT_FRONT_RIGHT; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_FRONT_CENTER, + Int, "I"); + AudioFormat_CHANNEL_OUT_FRONT_CENTER = + android_media_audioformat.CHANNEL_OUT_FRONT_CENTER; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_LOW_FREQUENCY, + Int, "I"); + AudioFormat_CHANNEL_OUT_LOW_FREQUENCY = + android_media_audioformat.CHANNEL_OUT_LOW_FREQUENCY; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_BACK_LEFT, Int, + "I"); + AudioFormat_CHANNEL_OUT_BACK_LEFT = + android_media_audioformat.CHANNEL_OUT_BACK_LEFT; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_BACK_RIGHT, Int, + "I"); + AudioFormat_CHANNEL_OUT_BACK_RIGHT = + android_media_audioformat.CHANNEL_OUT_BACK_RIGHT; + GST_DVM_GET_CONSTANT (android_media_audioformat, + CHANNEL_OUT_FRONT_LEFT_OF_CENTER, Int, "I"); + AudioFormat_CHANNEL_OUT_FRONT_LEFT_OF_CENTER = + android_media_audioformat.CHANNEL_OUT_FRONT_LEFT_OF_CENTER; + GST_DVM_GET_CONSTANT (android_media_audioformat, + CHANNEL_OUT_FRONT_RIGHT_OF_CENTER, Int, "I"); + AudioFormat_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = + android_media_audioformat.CHANNEL_OUT_FRONT_RIGHT_OF_CENTER; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_BACK_CENTER, Int, + "I"); + AudioFormat_CHANNEL_OUT_BACK_CENTER = + android_media_audioformat.CHANNEL_OUT_BACK_CENTER; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_SIDE_LEFT, Int, + "I"); + AudioFormat_CHANNEL_OUT_SIDE_LEFT = + android_media_audioformat.CHANNEL_OUT_SIDE_LEFT; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_SIDE_RIGHT, Int, + "I"); + AudioFormat_CHANNEL_OUT_SIDE_RIGHT = + android_media_audioformat.CHANNEL_OUT_SIDE_RIGHT; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_TOP_CENTER, Int, + "I"); + AudioFormat_CHANNEL_OUT_TOP_CENTER = + android_media_audioformat.CHANNEL_OUT_TOP_CENTER; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_TOP_FRONT_LEFT, + Int, "I"); + AudioFormat_CHANNEL_OUT_TOP_FRONT_LEFT = + android_media_audioformat.CHANNEL_OUT_TOP_FRONT_LEFT; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_TOP_FRONT_CENTER, + Int, "I"); + AudioFormat_CHANNEL_OUT_TOP_FRONT_CENTER = + android_media_audioformat.CHANNEL_OUT_TOP_FRONT_CENTER; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_TOP_FRONT_RIGHT, + Int, "I"); + AudioFormat_CHANNEL_OUT_TOP_FRONT_RIGHT = + android_media_audioformat.CHANNEL_OUT_TOP_FRONT_RIGHT; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_TOP_BACK_LEFT, + Int, "I"); + AudioFormat_CHANNEL_OUT_TOP_BACK_LEFT = + android_media_audioformat.CHANNEL_OUT_TOP_BACK_LEFT; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_TOP_BACK_CENTER, + Int, "I"); + AudioFormat_CHANNEL_OUT_TOP_BACK_CENTER = + android_media_audioformat.CHANNEL_OUT_TOP_BACK_CENTER; + GST_DVM_GET_CONSTANT (android_media_audioformat, CHANNEL_OUT_TOP_BACK_RIGHT, + Int, "I"); + AudioFormat_CHANNEL_OUT_TOP_BACK_RIGHT = + android_media_audioformat.CHANNEL_OUT_TOP_BACK_RIGHT; + + return TRUE; +} + +gboolean +gst_android_media_mediacodecinfo_init (void) +{ + if (!_init_classes ()) { + gst_android_media_mediacodecinfo_deinit (); + return FALSE; + } + + return TRUE; +} + +void +gst_android_media_mediacodecinfo_deinit (void) +{ + JNIEnv *env = gst_dvm_get_env (); + + if (android_media_mediacodecinfo.klass) + (*env)->DeleteGlobalRef (env, android_media_mediacodecinfo.klass); + android_media_mediacodecinfo.klass = NULL; + + if (android_media_mediacodeccapabilities.klass) + (*env)->DeleteGlobalRef (env, android_media_mediacodeccapabilities.klass); + android_media_mediacodeccapabilities.klass = NULL; + + if (android_media_mediacodecprofilelevel.klass) + (*env)->DeleteGlobalRef (env, android_media_mediacodecprofilelevel.klass); + android_media_mediacodecprofilelevel.klass = NULL; + + if (android_media_audioformat.klass) + (*env)->DeleteGlobalRef (env, android_media_audioformat.klass); + android_media_audioformat.klass = NULL; +} + +/* android.media.MediaCodecInfo */ +#define AMMCI_CALL(error_statement, type, method, ...) \ + GST_DVM_CALL (error_statement, self->object, type, \ + android_media_mediacodecinfo, method, ## __VA_ARGS__); + +void +gst_am_mediacodecinfo_free (GstAmMediaCodecInfo * self) +{ + JNIEnv *env = gst_dvm_get_env (); + + (*env)->DeleteGlobalRef (env, self->object); + g_slice_free (GstAmMediaCodecInfo, self); +} + +void +gst_am_mediacodeccapabilities_free (GstAmMediaCodecCapabilities * self) +{ + JNIEnv *env = gst_dvm_get_env (); + + (*env)->DeleteGlobalRef (env, self->object); + g_slice_free (GstAmMediaCodecCapabilities, self); +} + +void +gst_am_mediacodecprofilelevel_free (GstAmMediaCodecProfileLevel * self) +{ + JNIEnv *env = gst_dvm_get_env (); + + (*env)->DeleteGlobalRef (env, self->object); + g_slice_free (GstAmMediaCodecProfileLevel, self); +} + + +GstAmMediaCodecCapabilities * +gst_am_mediacodecinfo_get_capabilities_for_type (GstAmMediaCodecInfo * self, + const gchar * type) +{ + JNIEnv *env = gst_dvm_get_env (); + jobject object = NULL; + jstring type_str = NULL; + GstAmMediaCodecCapabilities *caps = NULL; + + type_str = (*env)->NewStringUTF (env, type); + if (!type_str) + goto done; + + object = AMMCI_CALL (goto done, Object, getCapabilitiesForType, type_str); + + if (object) { + caps = g_slice_new0 (GstAmMediaCodecCapabilities); + caps->object = (*env)->NewGlobalRef (env, object); + (*env)->DeleteLocalRef (env, object); + if (!caps->object) { + GST_ERROR ("Failed to create global reference"); + (*env)->ExceptionClear (env); + g_slice_free (GstAmMediaCodecCapabilities, caps); + caps = NULL; + } + } + +done: + if (type_str) + (*env)->DeleteLocalRef (env, type_str); + + return caps; +} + +gchar * +gst_am_mediacodecinfo_get_name (GstAmMediaCodecInfo * self) +{ + JNIEnv *env = gst_dvm_get_env (); + jstring v_str = NULL; + const gchar *v = NULL; + gchar *ret = NULL; + + v_str = AMMCI_CALL (return NULL, Object, getName); + if (v_str) { + v = (*env)->GetStringUTFChars (env, v_str, NULL); + if (!v) { + GST_ERROR ("Failed to convert string to UTF8"); + (*env)->ExceptionClear (env); + goto done; + } + ret = g_strdup (v); + } + +done: + if (v) + (*env)->ReleaseStringUTFChars (env, v_str, v); + if (v_str) + (*env)->DeleteLocalRef (env, v_str); + + return ret; +} + +GList * +gst_am_mediacodecinfo_get_supported_types (GstAmMediaCodecInfo * self) +{ + JNIEnv *env = gst_dvm_get_env (); + jarray arr = NULL; + jint arr_len = 0; + GList *ret = NULL; + gint i; + + arr = AMMCI_CALL (goto done, Object, getSupportedTypes); + if (!arr) + goto done; + arr_len = (*env)->GetArrayLength (env, arr); + if ((*env)->ExceptionCheck (env)) { + (*env)->ExceptionClear (env); + GST_ERROR ("Failed to get array length"); + goto done; + } + + for (i = 0; i < arr_len; i++) { + jstring str = NULL; + const gchar *str_v = NULL; + + str = (*env)->GetObjectArrayElement (env, arr, i); + if ((*env)->ExceptionCheck (env)) { + (*env)->ExceptionClear (env); + GST_ERROR ("Failed to get array element %d", i); + continue; + } + if (!str) + continue; + + str_v = (*env)->GetStringUTFChars (env, str, NULL); + if ((*env)->ExceptionCheck (env)) { + (*env)->ExceptionClear (env); + GST_ERROR ("Failed to get string characters"); + (*env)->DeleteLocalRef (env, str); + str = NULL; + continue; + } + ret = g_list_append (ret, g_strdup (str_v)); + (*env)->ReleaseStringUTFChars (env, str, str_v); + str_v = NULL; + (*env)->DeleteLocalRef (env, str); + str = NULL; + } + +done: + if (arr) + (*env)->DeleteLocalRef (env, arr); + + return ret; +} + +gboolean +gst_am_mediacodecinfo_is_encoder (GstAmMediaCodecInfo * self) +{ + JNIEnv *env = gst_dvm_get_env (); + gboolean ret = FALSE; + + ret = AMMCI_CALL (return FALSE, Boolean, isEncoder); + + return ret; +} + +#define AMMCC_FIELD(error_statement, type, field) \ + GST_DVM_FIELD (error_statement, self->object, type, \ + android_media_mediacodeccapabilities, field); + +GList * +gst_am_mediacodeccapabilities_get_color_formats (GstAmMediaCodecCapabilities * + self) +{ + JNIEnv *env = gst_dvm_get_env (); + GList *ret = NULL; + jarray arr = NULL; + jint arr_len = 0; + jint *arr_n = NULL; + gint i; + + arr = AMMCC_FIELD (goto done, Object, colorFormats); + arr_len = (*env)->GetArrayLength (env, arr); + if ((*env)->ExceptionCheck (env)) { + (*env)->ExceptionClear (env); + GST_ERROR ("Failed to get array length"); + goto done; + } + + arr_n = (*env)->GetIntArrayElements (env, arr, NULL); + if ((*env)->ExceptionCheck (env)) { + (*env)->ExceptionClear (env); + GST_ERROR ("Failed to get array elements"); + goto done; + } + + for (i = 0; i < arr_len; i++) + ret = g_list_append (ret, GINT_TO_POINTER (arr_n[i])); + +done: + if (arr_n) + (*env)->ReleaseIntArrayElements (env, arr, arr_n, JNI_ABORT); + if (arr) + (*env)->DeleteLocalRef (env, arr); + + return ret; +} + +GList * +gst_am_mediacodeccapabilities_get_profile_levels (GstAmMediaCodecCapabilities * + self) +{ + JNIEnv *env = gst_dvm_get_env (); + jarray arr = NULL; + jint arr_len = 0; + GList *ret = NULL; + gint i; + + arr = AMMCC_FIELD (goto done, Object, profileLevels); + if (!arr) + goto done; + arr_len = (*env)->GetArrayLength (env, arr); + if ((*env)->ExceptionCheck (env)) { + (*env)->ExceptionClear (env); + GST_ERROR ("Failed to get array length"); + goto done; + } + + for (i = 0; i < arr_len; i++) { + jobject object = NULL; + + object = (*env)->GetObjectArrayElement (env, arr, i); + if ((*env)->ExceptionCheck (env)) { + (*env)->ExceptionClear (env); + GST_ERROR ("Failed to get array element %d", i); + continue; + } + if (!object) + continue; + + if (object) { + GstAmMediaCodecProfileLevel *profile_level = + g_slice_new0 (GstAmMediaCodecProfileLevel); + + profile_level->object = (*env)->NewGlobalRef (env, object); + (*env)->DeleteLocalRef (env, object); + object = NULL; + if (!profile_level->object) { + GST_ERROR ("Failed to create global reference"); + (*env)->ExceptionClear (env); + g_slice_free (GstAmMediaCodecProfileLevel, profile_level); + } else { + ret = g_list_append (ret, profile_level); + } + } + } + +done: + if (arr) + (*env)->DeleteLocalRef (env, arr); + + return ret; +} + +#define AMMCPL_FIELD(error_statement, type, field) \ + GST_DVM_FIELD (error_statement, self->object, type, \ + android_media_mediacodecprofilelevel, field); + +gint +gst_am_mediacodecprofilelevel_get_level (GstAmMediaCodecProfileLevel * self) +{ + JNIEnv *env = gst_dvm_get_env (); + + return AMMCPL_FIELD (return -1, Int, level); +} + +gint +gst_am_mediacodecprofilelevel_get_profile (GstAmMediaCodecProfileLevel * self) +{ + JNIEnv *env = gst_dvm_get_env (); + + return AMMCPL_FIELD (return -1, Int, profile); +} diff --git a/sys/androidmedia/gst-android-media-mediacodecinfo.h b/sys/androidmedia/gst-android-media-mediacodecinfo.h new file mode 100644 index 000000000..bcdb91f77 --- /dev/null +++ b/sys/androidmedia/gst-android-media-mediacodecinfo.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012, Collabora Ltd. + * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Author: Youness Alaoui <youness.alaoui@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_ANDROID_MEDIA_MEDIACODECINFO_H__ +#define __GST_ANDROID_MEDIA_MEDIACODECINFO_H__ + +#include <gst/gst.h> +#include <jni.h> + +G_BEGIN_DECLS + +typedef struct _GstAmMediaCodecInfo GstAmMediaCodecInfo; +typedef struct _GstAmMediaCodecCapabilities GstAmMediaCodecCapabilities; +typedef struct _GstAmMediaCodecProfileLevel GstAmMediaCodecProfileLevel; + +struct _GstAmMediaCodecInfo { + /*< private >*/ + jobject object; /* global reference */ +}; + +struct _GstAmMediaCodecCapabilities { + /*< private >*/ + jobject object; /* global reference */ +}; + +struct _GstAmMediaCodecProfileLevel { + /*< private >*/ + jobject object; /* global reference */ +}; + +gboolean gst_android_media_mediacodecinfo_init (void); +void gst_android_media_mediacodecinfo_deinit (void); + +void gst_am_mediacodecinfo_free (GstAmMediaCodecInfo * self); +void gst_am_mediacodeccapabilities_free (GstAmMediaCodecCapabilities * self); +void gst_am_mediacodecprofilelevel_free (GstAmMediaCodecProfileLevel * self); + +GstAmMediaCodecCapabilities * gst_am_mediacodecinfo_get_capabilities_for_type (GstAmMediaCodecInfo * self, const gchar *type); +gchar * gst_am_mediacodecinfo_get_name (GstAmMediaCodecInfo * self); +/* GList <gchar *> */ +GList * gst_am_mediacodecinfo_get_supported_types (GstAmMediaCodecInfo * self); +gboolean gst_am_mediacodecinfo_is_encoder (GstAmMediaCodecInfo * self); + +/* GList <int> */ +GList * gst_am_mediacodeccapabilities_get_color_formats (GstAmMediaCodecCapabilities *self); +/* GList <GstAmMediaCodecProfileLevel *> */ +GList * gst_am_mediacodeccapabilities_get_profile_levels (GstAmMediaCodecCapabilities *self); + +gint gst_am_mediacodecprofilelevel_get_level (GstAmMediaCodecProfileLevel *self); +gint gst_am_mediacodecprofilelevel_get_profile (GstAmMediaCodecProfileLevel *self); + +extern gint AudioFormat_CHANNEL_OUT_FRONT_LEFT; +extern gint AudioFormat_CHANNEL_OUT_FRONT_RIGHT; +extern gint AudioFormat_CHANNEL_OUT_FRONT_CENTER; +extern gint AudioFormat_CHANNEL_OUT_LOW_FREQUENCY; +extern gint AudioFormat_CHANNEL_OUT_BACK_LEFT; +extern gint AudioFormat_CHANNEL_OUT_BACK_RIGHT; +extern gint AudioFormat_CHANNEL_OUT_FRONT_LEFT_OF_CENTER; +extern gint AudioFormat_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER; +extern gint AudioFormat_CHANNEL_OUT_BACK_CENTER; +extern gint AudioFormat_CHANNEL_OUT_SIDE_LEFT; +extern gint AudioFormat_CHANNEL_OUT_SIDE_RIGHT; +extern gint AudioFormat_CHANNEL_OUT_TOP_CENTER; +extern gint AudioFormat_CHANNEL_OUT_TOP_FRONT_LEFT; +extern gint AudioFormat_CHANNEL_OUT_TOP_FRONT_CENTER; +extern gint AudioFormat_CHANNEL_OUT_TOP_FRONT_RIGHT; +extern gint AudioFormat_CHANNEL_OUT_TOP_BACK_LEFT; +extern gint AudioFormat_CHANNEL_OUT_TOP_BACK_CENTER; +extern gint AudioFormat_CHANNEL_OUT_TOP_BACK_RIGHT; + +G_END_DECLS + +#endif /* __GST_ANDROID_MEDIA_MEDIACODECINFO_H__ */ diff --git a/sys/androidmedia/gst-android-media-mediacodeclist.c b/sys/androidmedia/gst-android-media-mediacodeclist.c new file mode 100644 index 000000000..faa5a8f89 --- /dev/null +++ b/sys/androidmedia/gst-android-media-mediacodeclist.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2012, Collabora Ltd. + * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Author: Youness Alaoui <youness.alaoui@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/dvm/gst-dvm.h> + +#include "gst-android-media-mediacodeclist.h" + +static struct +{ + jclass klass; + jmethodID getCodecCount; + jmethodID getCodecInfoAt; +} android_media_mediacodeclist; + + +static gboolean +_init_classes (void) +{ + JNIEnv *env = gst_dvm_get_env (); + + /* android.media.MediaCodecList */ + GST_DVM_GET_CLASS (android_media_mediacodeclist, + "android/media/MediaCodecList"); + GST_DVM_GET_STATIC_METHOD (android_media_mediacodeclist, getCodecCount, + "()I;"); + GST_DVM_GET_STATIC_METHOD (android_media_mediacodeclist, getCodecInfoAt, + "(I)Landroid/media/MediaCodecInfo;"); + + return TRUE; +} + +gboolean +gst_android_media_mediacodeclist_init (void) +{ + if (!_init_classes ()) { + gst_android_media_mediacodeclist_deinit (); + return FALSE; + } + + return TRUE; +} + +void +gst_android_media_mediacodeclist_deinit (void) +{ + JNIEnv *env = gst_dvm_get_env (); + + if (android_media_mediacodeclist.klass) + (*env)->DeleteGlobalRef (env, android_media_mediacodeclist.klass); + android_media_mediacodeclist.klass = NULL; +} + +/* android.media.MediaFormat */ +#define AMMCL_STATIC_CALL(error_statement, type, method, ...) \ + GST_DVM_STATIC_CALL (error_statement, type, \ + android_media_mediacodeclist, method, ## __VA_ARGS__); + +gint +gst_am_mediacodeclist_get_codec_count (void) +{ + JNIEnv *env = gst_dvm_get_env (); + gint count = 0; + + count = AMMCL_STATIC_CALL (goto done, Int, getCodecCount); + +done: + + return count; +} + +GstAmMediaCodecInfo * +gst_am_mediacodeclist_get_codec_info_at (gint index) +{ + JNIEnv *env = gst_dvm_get_env (); + GstAmMediaCodecInfo *info = NULL; + jobject object = NULL; + + object = AMMCL_STATIC_CALL (goto done, Object, getCodecInfoAt, index); + if (object) { + info = g_slice_new0 (GstAmMediaCodecInfo); + info->object = (*env)->NewGlobalRef (env, object); + (*env)->DeleteLocalRef (env, object); + if (!info->object) { + GST_ERROR ("Failed to create global reference"); + (*env)->ExceptionClear (env); + g_slice_free (GstAmMediaCodecInfo, info); + info = NULL; + } + } + +done: + + return info; +} diff --git a/sys/androidmedia/gst-android-media-mediacodeclist.h b/sys/androidmedia/gst-android-media-mediacodeclist.h new file mode 100644 index 000000000..e0241022e --- /dev/null +++ b/sys/androidmedia/gst-android-media-mediacodeclist.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012, Collabora Ltd. + * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Author: Youness Alaoui <youness.alaoui@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_ANDROID_MEDIA_MEDIACODECLIST_H__ +#define __GST_ANDROID_MEDIA_MEDIACODECLIST_H__ + +#include <gst/gst.h> +#include <jni.h> + +#include "gst-android-media-mediacodecinfo.h" + +G_BEGIN_DECLS + +gboolean gst_android_media_mediacodeclist_init (void); +void gst_android_media_mediacodeclist_deinit (void); + +gint gst_am_mediacodeclist_get_codec_count (void); +GstAmMediaCodecInfo * gst_am_mediacodeclist_get_codec_info_at (int index); + +G_END_DECLS + +#endif /* __GST_ANDROID_MEDIA_MEDIACODECLIST_H__ */ diff --git a/sys/androidmedia/gst-android-media-mediaformat.c b/sys/androidmedia/gst-android-media-mediaformat.c index ee7baede7..e0ed33839 100644 --- a/sys/androidmedia/gst-android-media-mediaformat.c +++ b/sys/androidmedia/gst-android-media-mediaformat.c @@ -24,6 +24,7 @@ #endif #include <gst/dvm/gst-dvm.h> +#include <string.h> #include "gst-android-media-mediaformat.h" diff --git a/sys/androidmedia/gst-android-media-mediaformat.h b/sys/androidmedia/gst-android-media-mediaformat.h index 28158fccb..a909d1273 100644 --- a/sys/androidmedia/gst-android-media-mediaformat.h +++ b/sys/androidmedia/gst-android-media-mediaformat.h @@ -25,6 +25,8 @@ #include <gst/gst.h> #include <jni.h> +G_BEGIN_DECLS + typedef struct _GstAmMediaFormat GstAmMediaFormat; struct _GstAmMediaFormat { @@ -32,8 +34,6 @@ struct _GstAmMediaFormat { jobject object; /* global reference */ }; -G_BEGIN_DECLS - gboolean gst_android_media_mediaformat_init (void); void gst_android_media_mediaformat_deinit (void); |