mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-31 11:32:38 +00:00
androidmedia: Use gst-dvm and refactor java wrappers (WIP)
Moved the java wrapper API into its own files and made use of the gst-dvm macros. Also renamed the API to have the proper naming convention and coding style in order to match the one in androidcamera. This is a work in progress! "android/media/MediaCodecList" is still missing and the actual elements have not been ported to use the new function names.
This commit is contained in:
parent
eb949625b9
commit
3ac90867ac
4 changed files with 1299 additions and 0 deletions
533
sys/androidmedia/gst-android-media-mediacodec.c
Normal file
533
sys/androidmedia/gst-android-media-mediacodec.c
Normal file
|
@ -0,0 +1,533 @@
|
|||
/*
|
||||
* 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-mediacodec.h"
|
||||
|
||||
|
||||
static struct
|
||||
{
|
||||
jclass klass;
|
||||
jmethodID constructor;
|
||||
jfieldID flags;
|
||||
jfieldID offset;
|
||||
jfieldID presentationTimeUs;
|
||||
jfieldID size;
|
||||
} android_media_mediacodec_bufferinfo;
|
||||
|
||||
static struct
|
||||
{
|
||||
jclass klass;
|
||||
jmethodID configure;
|
||||
jmethodID createByCodecName;
|
||||
jmethodID createDecoderByType;
|
||||
jmethodID createEncoderByType;
|
||||
jmethodID dequeueInputBuffer;
|
||||
jmethodID dequeueOutputBuffer;
|
||||
jmethodID flush;
|
||||
jmethodID getInputBuffers;
|
||||
jmethodID getOutputBuffers;
|
||||
jmethodID getOutputFormat;
|
||||
jmethodID queueInputBuffer;
|
||||
jmethodID release;
|
||||
jmethodID releaseOutputBuffer;
|
||||
jmethodID start;
|
||||
jmethodID stop;
|
||||
} android_media_mediacodec = {
|
||||
0};
|
||||
|
||||
|
||||
|
||||
static gboolean
|
||||
_init_classes (void)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
/* android.media.MediaCodec */
|
||||
GST_DVM_GET_CLASS (android_media_mediacodec, "android/media/MediaCodec");
|
||||
GST_DVM_GET_STATIC_METHOD (android_media_mediacodec, createByCodecName,
|
||||
"(Ljava/lang/String;)Landroid/media/MediaCodec;");
|
||||
GST_DVM_GET_STATIC_METHOD (android_media_mediacodec, createDecoderByType,
|
||||
"(Ljava/lang/String;)Landroid/media/MediaCodec;");
|
||||
GST_DVM_GET_STATIC_METHOD (android_media_mediacodec, createEncoderByType,
|
||||
"(Ljava/lang/String;)Landroid/media/MediaCodec;");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, configure,
|
||||
"(Landroid/media/MediaFormat;Landroid/view/Surface;"
|
||||
"Landroid/media/MediaCrypto;I)V");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, dequeueInputBuffer, "(J)I");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, dequeueOutputBuffer,
|
||||
"(Landroid/media/MediaCodec$BufferInfo;J)I");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, flush, "()V");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, getInputBuffers,
|
||||
"()[Ljava/nio/ByteBuffer;");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, getOutputBuffers,
|
||||
"()[Ljava/nio/ByteBuffer;");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, getOutputFormat,
|
||||
"()Landroid/media/MediaFormat;");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, queueInputBuffer, "(IIIJI)V");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, release, "()V");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, releaseOutputBuffer, "(IZ)V");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, start, "()V");
|
||||
GST_DVM_GET_METHOD (android_media_mediacodec, stop, "()V");
|
||||
|
||||
/* android.media.MediaCodec.BufferInfo */
|
||||
GST_DVM_GET_CLASS (android_media_mediacodec_bufferinfo,
|
||||
"android/media/MediaCodec$BufferInfo");
|
||||
GST_DVM_GET_CONSTRUCTOR (android_media_mediacodec_bufferinfo, constructor,
|
||||
"()V");
|
||||
GST_DVM_GET_FIELD (android_media_mediacodec_bufferinfo, flags, "I");
|
||||
GST_DVM_GET_FIELD (android_media_mediacodec_bufferinfo, offset, "I");
|
||||
GST_DVM_GET_FIELD (android_media_mediacodec_bufferinfo, presentationTimeUs,
|
||||
"J");
|
||||
GST_DVM_GET_FIELD (android_media_mediacodec_bufferinfo, size, "I");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_android_media_mediacodec_init (void)
|
||||
{
|
||||
if (!_init_classes ()) {
|
||||
gst_android_media_mediacodec_deinit ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_android_media_mediacodec_deinit (void)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
if (android_media_mediacodec.klass)
|
||||
(*env)->DeleteGlobalRef (env, android_media_mediacodec.klass);
|
||||
android_media_mediacodec.klass = NULL;
|
||||
|
||||
if (android_media_mediacodec_bufferinfo.klass)
|
||||
(*env)->DeleteGlobalRef (env, android_media_mediacodec_bufferinfo.klass);
|
||||
android_media_mediacodec_bufferinfo.klass = NULL;
|
||||
}
|
||||
|
||||
/* android.media.MediaCodec */
|
||||
|
||||
#define AMMC_CALL(error_statement, type, method, ...) \
|
||||
GST_DVM_CALL (error_statement, self->object, type, \
|
||||
android_media_mediacodec, method, ## __VA_ARGS__);
|
||||
#define AMMC_STATIC_CALL(error_statement, type, method, ...) \
|
||||
GST_DVM_STATIC_CALL (error_statement, type, \
|
||||
android_media_mediacodec, method, ## __VA_ARGS__);
|
||||
|
||||
gboolean
|
||||
gst_am_mediacodec_configure (GstAmMediaCodec * self, GstAmMediaFormat * format,
|
||||
gint flags)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (format != NULL, FALSE);
|
||||
|
||||
AMMC_CALL (return FALSE, Void, configure, format->object, NULL, NULL, flags);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstAmMediaCodec *
|
||||
gst_am_mediacodec_create_by_codec_name (const gchar * name)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
GstAmMediaCodec *codec = NULL;
|
||||
jobject object = NULL;
|
||||
jstring name_str;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
name_str = (*env)->NewStringUTF (env, name);
|
||||
if (name_str == NULL)
|
||||
goto done;
|
||||
|
||||
object = AMMC_STATIC_CALL (goto done, Object, createByCodecName, name_str);
|
||||
if (object) {
|
||||
codec = g_slice_new0 (GstAmMediaCodec);
|
||||
codec->object = (*env)->NewGlobalRef (env, object);
|
||||
(*env)->DeleteLocalRef (env, object);
|
||||
if (!codec->object) {
|
||||
GST_ERROR ("Failed to create global reference");
|
||||
(*env)->ExceptionClear (env);
|
||||
g_slice_free (GstAmMediaCodec, codec);
|
||||
codec = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (name_str)
|
||||
(*env)->DeleteLocalRef (env, name_str);
|
||||
|
||||
return codec;
|
||||
}
|
||||
|
||||
|
||||
GstAmMediaFormat *
|
||||
gst_am_mediacodec_get_output_format (GstAmMediaCodec * self)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
GstAmMediaFormat *format = NULL;
|
||||
jobject object = NULL;
|
||||
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
|
||||
object = AMMC_CALL (return NULL, Object, getOutputFormat);
|
||||
if (object) {
|
||||
format = g_slice_new0 (GstAmMediaFormat);
|
||||
format->object = (*env)->NewGlobalRef (env, object);
|
||||
(*env)->DeleteLocalRef (env, object);
|
||||
if (!format->object) {
|
||||
GST_ERROR ("Failed to create global reference");
|
||||
(*env)->ExceptionClear (env);
|
||||
g_slice_free (GstAmMediaFormat, format);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediacodec_start (GstAmMediaCodec * self)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
AMMC_CALL (return FALSE, Void, start);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediacodec_stop (GstAmMediaCodec * self)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
AMMC_CALL (return FALSE, Void, stop);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediacodec_flush (GstAmMediaCodec * self)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
AMMC_CALL (return FALSE, Void, flush);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_am_mediacodec_release (GstAmMediaCodec * self)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
AMMC_CALL (, Void, release);
|
||||
|
||||
(*env)->DeleteGlobalRef (env, self->object);
|
||||
g_slice_free (GstAmMediaCodec, self);
|
||||
}
|
||||
|
||||
void
|
||||
gst_am_mediacodec_free_buffers (GstAmcBuffer * buffers, gsize n_buffers)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jsize i;
|
||||
|
||||
g_return_if_fail (buffers != NULL);
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
if (buffers[i].object)
|
||||
(*env)->DeleteGlobalRef (env, buffers[i].object);
|
||||
}
|
||||
g_free (buffers);
|
||||
}
|
||||
|
||||
GstAmcBuffer *
|
||||
gst_am_mediacodec_get_output_buffers (GstAmMediaCodec * self, gsize * n_buffers)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jobject output_buffers = NULL;
|
||||
jsize n_output_buffers;
|
||||
GstAmcBuffer *ret = NULL;
|
||||
jsize i;
|
||||
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
g_return_val_if_fail (n_buffers != NULL, NULL);
|
||||
|
||||
*n_buffers = 0;
|
||||
output_buffers = AMMC_CALL (goto done, Object, getOutputBuffers);
|
||||
if (!output_buffers)
|
||||
goto done;
|
||||
|
||||
n_output_buffers = (*env)->GetArrayLength (env, output_buffers);
|
||||
if ((*env)->ExceptionCheck (env)) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to get output buffers array length");
|
||||
goto done;
|
||||
}
|
||||
|
||||
*n_buffers = n_output_buffers;
|
||||
ret = g_new0 (GstAmcBuffer, n_output_buffers);
|
||||
|
||||
for (i = 0; i < n_output_buffers; i++) {
|
||||
jobject buffer = NULL;
|
||||
|
||||
buffer = (*env)->GetObjectArrayElement (env, output_buffers, i);
|
||||
if ((*env)->ExceptionCheck (env) || !buffer) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to get output buffer %d", i);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret[i].object = (*env)->NewGlobalRef (env, buffer);
|
||||
(*env)->DeleteLocalRef (env, buffer);
|
||||
if (!ret[i].object) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to create global reference %d", i);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret[i].data = (*env)->GetDirectBufferAddress (env, ret[i].object);
|
||||
if (!ret[i].data) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to get buffer address %d", i);
|
||||
goto error;
|
||||
}
|
||||
ret[i].size = (*env)->GetDirectBufferCapacity (env, ret[i].object);
|
||||
}
|
||||
|
||||
done:
|
||||
if (output_buffers)
|
||||
(*env)->DeleteLocalRef (env, output_buffers);
|
||||
output_buffers = NULL;
|
||||
|
||||
return ret;
|
||||
error:
|
||||
if (ret)
|
||||
gst_am_mediacodec_free_buffers (ret, n_output_buffers);
|
||||
ret = NULL;
|
||||
*n_buffers = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
GstAmcBuffer *
|
||||
gst_am_mediacodec_get_input_buffers (GstAmMediaCodec * self, gsize * n_buffers)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jobject input_buffers = NULL;
|
||||
jsize n_input_buffers;
|
||||
GstAmcBuffer *ret = NULL;
|
||||
jsize i;
|
||||
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
g_return_val_if_fail (n_buffers != NULL, NULL);
|
||||
|
||||
*n_buffers = 0;
|
||||
|
||||
input_buffers = AMMC_CALL (goto done, Object, getOutputBuffers);
|
||||
if (!input_buffers)
|
||||
goto done;
|
||||
|
||||
n_input_buffers = (*env)->GetArrayLength (env, input_buffers);
|
||||
if ((*env)->ExceptionCheck (env)) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to get input buffers array length");
|
||||
goto done;
|
||||
}
|
||||
|
||||
*n_buffers = n_input_buffers;
|
||||
ret = g_new0 (GstAmcBuffer, n_input_buffers);
|
||||
|
||||
for (i = 0; i < n_input_buffers; i++) {
|
||||
jobject buffer = NULL;
|
||||
|
||||
buffer = (*env)->GetObjectArrayElement (env, input_buffers, i);
|
||||
if ((*env)->ExceptionCheck (env) || !buffer) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to get input buffer %d", i);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret[i].object = (*env)->NewGlobalRef (env, buffer);
|
||||
(*env)->DeleteLocalRef (env, buffer);
|
||||
if (!ret[i].object) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to create global reference %d", i);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret[i].data = (*env)->GetDirectBufferAddress (env, ret[i].object);
|
||||
if (!ret[i].data) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to get buffer address %d", i);
|
||||
goto error;
|
||||
}
|
||||
ret[i].size = (*env)->GetDirectBufferCapacity (env, ret[i].object);
|
||||
}
|
||||
|
||||
done:
|
||||
if (input_buffers)
|
||||
(*env)->DeleteLocalRef (env, input_buffers);
|
||||
input_buffers = NULL;
|
||||
|
||||
return ret;
|
||||
error:
|
||||
if (ret)
|
||||
gst_am_mediacodec_free_buffers (ret, n_input_buffers);
|
||||
ret = NULL;
|
||||
*n_buffers = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
gint
|
||||
gst_am_mediacodec_dequeue_input_buffer (GstAmMediaCodec * self,
|
||||
gint64 timeoutUs)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
gint ret = G_MININT;
|
||||
|
||||
g_return_val_if_fail (self != NULL, G_MININT);
|
||||
|
||||
ret = AMMC_CALL (return G_MININT, Int, dequeueInputBuffer, timeoutUs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_fill_buffer_info (JNIEnv * env, jobject buffer_info, GstAmmcBufferInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (buffer_info != NULL, FALSE);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint
|
||||
gst_am_mediacodec_dequeue_output_buffer (GstAmMediaCodec * self,
|
||||
GstAmmcBufferInfo * info, gint64 timeoutUs)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
gint ret = G_MININT;
|
||||
jobject info_o = NULL;
|
||||
|
||||
g_return_val_if_fail (self != NULL, G_MININT);
|
||||
|
||||
info_o = (*env)->NewObject (env, android_media_mediacodec_bufferinfo.klass,
|
||||
android_media_mediacodec_bufferinfo.constructor);
|
||||
if (!info_o) {
|
||||
GST_ERROR ("Failed to call Java method");
|
||||
(*env)->ExceptionClear (env);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = AMMC_CALL (goto error, Int, dequeueOutputBuffer, info_o, timeoutUs);
|
||||
|
||||
if (!_fill_buffer_info (env, info_o, info))
|
||||
goto error;
|
||||
|
||||
done:
|
||||
if (info_o)
|
||||
(*env)->DeleteLocalRef (env, info_o);
|
||||
info_o = NULL;
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
ret = G_MININT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediacodec_queue_input_buffer (GstAmMediaCodec * self, gint index,
|
||||
const GstAmmcBufferInfo * info)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
|
||||
AMMC_CALL (return FALSE, Void, queueInputBuffer, index, info->offset,
|
||||
info->size, info->presentation_time_us, info->flags);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediacodec_release_output_buffer (GstAmMediaCodec * self, gint index)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
AMMC_CALL (return FALSE, Void, releaseOutputBuffer, index, JNI_FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
89
sys/androidmedia/gst-android-media-mediacodec.h
Normal file
89
sys/androidmedia/gst-android-media-mediacodec.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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_MEDIACODEC_H__
|
||||
#define __GST_ANDROID_MEDIA_MEDIACODEC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include "gst-android-media-mediaformat.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstAmcBuffer GstAmcBuffer;
|
||||
typedef struct _GstAmmcBufferInfo GstAmmcBufferInfo;
|
||||
typedef struct _GstAmMediaCodec GstAmMediaCodec;
|
||||
|
||||
struct _GstAmcBuffer {
|
||||
guint8 *data;
|
||||
gsize size;
|
||||
/*< private >*/
|
||||
jobject object; /* global reference */
|
||||
};
|
||||
|
||||
struct _GstAmmcBufferInfo {
|
||||
gint flags;
|
||||
gint offset;
|
||||
gint64 presentation_time_us;
|
||||
gint size;
|
||||
};
|
||||
|
||||
struct _GstAmMediaCodec {
|
||||
/*< private >*/
|
||||
jobject object; /* global reference */
|
||||
};
|
||||
|
||||
gboolean gst_android_media_mediacodec_init (void);
|
||||
void gst_android_media_mediacodec_deinit (void);
|
||||
|
||||
gboolean gst_am_mediacodec_configure (GstAmMediaCodec * self,
|
||||
GstAmMediaFormat * format, gint flags);
|
||||
|
||||
GstAmMediaCodec * gst_am_mediacodec_create_by_codec_name (const gchar *name);
|
||||
GstAmMediaCodec * gst_am_mediacodec_create_decoder_by_type (const gchar *type);
|
||||
GstAmMediaCodec * gst_am_mediacodec_create_encoder_by_type (const gchar *type);
|
||||
|
||||
gint gst_am_mediacodec_dequeue_input_buffer (GstAmMediaCodec * self,
|
||||
gint64 timeoutUs);
|
||||
gint gst_am_mediacodec_dequeue_output_buffer (GstAmMediaCodec * self,
|
||||
GstAmmcBufferInfo *info, gint64 timeoutUs);
|
||||
gboolean gst_am_mediacodec_flush (GstAmMediaCodec * self);
|
||||
|
||||
GstAmcBuffer * gst_am_mediacodec_get_input_buffers (GstAmMediaCodec * self,
|
||||
gsize * n_buffers);
|
||||
GstAmcBuffer * gst_am_mediacodec_get_output_buffers (GstAmMediaCodec * self,
|
||||
gsize * n_buffers);
|
||||
void gst_am_mediacodec_free_buffers (GstAmcBuffer * buffers, gsize n_buffers);
|
||||
GstAmMediaFormat * gst_am_mediacodec_get_output_format (GstAmMediaCodec * self);
|
||||
|
||||
gboolean gst_am_mediacodec_queue_input_buffer (GstAmMediaCodec * self,
|
||||
gint index, const GstAmmcBufferInfo *info);
|
||||
void gst_am_mediacodec_release (GstAmMediaCodec * self);
|
||||
gboolean gst_am_mediacodec_release_output_buffer (GstAmMediaCodec * self,
|
||||
gint index);
|
||||
|
||||
gboolean gst_am_mediacodec_start (GstAmMediaCodec * self);
|
||||
gboolean gst_am_mediacodec_stop (GstAmMediaCodec * self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ANDROID_MEDIA_MEDIACODEC_H__ */
|
602
sys/androidmedia/gst-android-media-mediaformat.c
Normal file
602
sys/androidmedia/gst-android-media-mediaformat.c
Normal file
|
@ -0,0 +1,602 @@
|
|||
/*
|
||||
* 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-mediaformat.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
jclass klass;
|
||||
jmethodID constructor;
|
||||
jmethodID containsKey;
|
||||
jmethodID createAudioFormat;
|
||||
jmethodID createVideoFormat;
|
||||
jmethodID getByteBuffer;
|
||||
jmethodID getFloat;
|
||||
jmethodID getInteger;
|
||||
jmethodID getLong;
|
||||
jmethodID getString;
|
||||
jmethodID setByteBuffer;
|
||||
jmethodID setFloat;
|
||||
jmethodID setInteger;
|
||||
jmethodID setLong;
|
||||
jmethodID setString;
|
||||
jmethodID toString;
|
||||
} android_media_mediaformat;
|
||||
|
||||
|
||||
static gboolean
|
||||
_init_classes (void)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
/* android.media.MediaFormat */
|
||||
GST_DVM_GET_CLASS (android_media_mediaformat, "android/media/MediaFormat");
|
||||
GST_DVM_GET_CONSTRUCTOR (android_media_mediaformat, constructor, "()V");
|
||||
GST_DVM_GET_STATIC_METHOD (android_media_mediaformat, createAudioFormat,
|
||||
"(Ljava/lang/String;II)Landroid/media/MediaFormat;");
|
||||
GST_DVM_GET_STATIC_METHOD (android_media_mediaformat, createVideoFormat,
|
||||
"(Ljava/lang/String;II)Landroid/media/MediaFormat;");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, toString,
|
||||
"()Ljava/lang/String;");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, containsKey,
|
||||
"(Ljava/lang/String;)Z");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, getFloat,
|
||||
"(Ljava/lang/String;)F");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, setFloat,
|
||||
"(Ljava/lang/String;F)V");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, getInteger,
|
||||
"(Ljava/lang/String;)I");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, setInteger,
|
||||
"(Ljava/lang/String;I)V");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, getLong,
|
||||
"(Ljava/lang/String;)J");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, setLong,
|
||||
"(Ljava/lang/String;J)V");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, getString,
|
||||
"(Ljava/lang/String;)Ljava/lang/String;");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, setString,
|
||||
"(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, getByteBuffer,
|
||||
"(Ljava/lang/String;)Ljava/nio/ByteBuffer;");
|
||||
GST_DVM_GET_METHOD (android_media_mediaformat, setByteBuffer,
|
||||
"(Ljava/lang/String;Ljava/nio/ByteBuffer;)V");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_android_media_mediaformat_init (void)
|
||||
{
|
||||
if (!_init_classes ()) {
|
||||
gst_android_media_mediaformat_deinit ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_android_media_mediaformat_deinit (void)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
if (android_media_mediaformat.klass)
|
||||
(*env)->DeleteGlobalRef (env, android_media_mediaformat.klass);
|
||||
android_media_mediaformat.klass = NULL;
|
||||
}
|
||||
|
||||
/* android.media.MediaFormat */
|
||||
#define AMMF_CALL(error_statement, type, method, ...) \
|
||||
GST_DVM_CALL (error_statement, self->object, type, \
|
||||
android_media_mediaformat, method, ## __VA_ARGS__);
|
||||
#define AMMF_STATIC_CALL(error_statement, type, method, ...) \
|
||||
GST_DVM_STATIC_CALL (error_statement, type, \
|
||||
android_media_mediaformat, method, ## __VA_ARGS__);
|
||||
|
||||
GstAmMediaFormat *
|
||||
gst_am_mediaformat_new (void)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
GstAmMediaFormat *format = NULL;
|
||||
jobject object = NULL;
|
||||
|
||||
object = (*env)->NewObject (env, android_media_mediaformat.klass,
|
||||
android_media_mediaformat.constructor);
|
||||
if ((*env)->ExceptionCheck (env) || !object) {
|
||||
GST_ERROR ("Failed to create callback object");
|
||||
(*env)->ExceptionClear (env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
format = g_slice_new0 (GstAmMediaFormat);
|
||||
format->object = (*env)->NewGlobalRef (env, object);
|
||||
(*env)->DeleteLocalRef (env, object);
|
||||
if (!format->object) {
|
||||
GST_ERROR ("Failed to create global reference");
|
||||
(*env)->ExceptionClear (env);
|
||||
g_slice_free (GstAmMediaFormat, format);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
GstAmMediaFormat *
|
||||
gst_am_mediaformat_create_audio_format (const gchar * mime,
|
||||
gint sample_rate, gint channels)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
GstAmMediaFormat *format = NULL;
|
||||
jstring mime_str;
|
||||
jobject object = NULL;
|
||||
|
||||
g_return_val_if_fail (mime != NULL, NULL);
|
||||
|
||||
mime_str = (*env)->NewStringUTF (env, mime);
|
||||
if (mime_str == NULL)
|
||||
goto done;
|
||||
|
||||
object = AMMF_STATIC_CALL (goto done, Object, createAudioFormat, mime_str,
|
||||
sample_rate, channels);
|
||||
if (object) {
|
||||
format = g_slice_new0 (GstAmMediaFormat);
|
||||
format->object = (*env)->NewGlobalRef (env, object);
|
||||
(*env)->DeleteLocalRef (env, object);
|
||||
if (!format->object) {
|
||||
GST_ERROR ("Failed to create global reference");
|
||||
(*env)->ExceptionClear (env);
|
||||
g_slice_free (GstAmMediaFormat, format);
|
||||
format = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (mime_str)
|
||||
(*env)->DeleteLocalRef (env, mime_str);
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
GstAmMediaFormat *
|
||||
gst_am_mediaformat_create_video_format (const gchar * mime,
|
||||
gint width, gint height)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
GstAmMediaFormat *format = NULL;
|
||||
jstring mime_str;
|
||||
jobject object = NULL;
|
||||
|
||||
g_return_val_if_fail (mime != NULL, NULL);
|
||||
|
||||
mime_str = (*env)->NewStringUTF (env, mime);
|
||||
if (mime_str == NULL)
|
||||
goto done;
|
||||
|
||||
object = AMMF_STATIC_CALL (goto done, Object, createVideoFormat, mime_str,
|
||||
width, height);
|
||||
if (object) {
|
||||
format = g_slice_new0 (GstAmMediaFormat);
|
||||
format->object = (*env)->NewGlobalRef (env, object);
|
||||
(*env)->DeleteLocalRef (env, object);
|
||||
if (!format->object) {
|
||||
GST_ERROR ("Failed to create global reference");
|
||||
(*env)->ExceptionClear (env);
|
||||
g_slice_free (GstAmMediaFormat, format);
|
||||
format = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (mime_str)
|
||||
(*env)->DeleteLocalRef (env, mime_str);
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
void
|
||||
gst_am_mediaformat_free (GstAmMediaFormat * self)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
(*env)->DeleteGlobalRef (env, self->object);
|
||||
g_slice_free (GstAmMediaFormat, self);
|
||||
}
|
||||
|
||||
gchar *
|
||||
gst_am_mediaformat_to_string (GstAmMediaFormat * self)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring v_str = NULL;
|
||||
const gchar *v = NULL;
|
||||
gchar *ret = NULL;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
v_str = AMMF_CALL (return NULL, Object, toString);
|
||||
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;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_contains_key (GstAmMediaFormat * self, const gchar * key)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
gboolean ret = FALSE;
|
||||
jstring key_str = NULL;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
ret = AMMF_CALL (ret = FALSE; goto done, Boolean, containsKey, key_str);
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_get_float (GstAmMediaFormat * self, const gchar * key,
|
||||
gfloat * value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring key_str = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
*value = 0;
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
*value = AMMF_CALL (goto done, Float, getFloat, key_str);
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_set_float (GstAmMediaFormat * self, const gchar * key,
|
||||
gfloat value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring key_str = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
AMMF_CALL (goto done, Void, setFloat, key_str, value);
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_get_int (GstAmMediaFormat * self, const gchar * key,
|
||||
gint * value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring key_str = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
*value = 0;
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
*value = AMMF_CALL (goto done, Int, getInteger, key_str);
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_set_int (GstAmMediaFormat * self, const gchar * key,
|
||||
gint value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring key_str = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
AMMF_CALL (goto done, Void, setInteger, key_str, value);
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_get_long (GstAmMediaFormat * self, const gchar * key,
|
||||
glong * value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring key_str = NULL;
|
||||
gboolean ret = FALSE;
|
||||
jlong long_value;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
*value = 0;
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
long_value = AMMF_CALL (goto done, Long, getLong, key_str);
|
||||
*value = long_value;
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_set_long (GstAmMediaFormat * self, const gchar * key,
|
||||
glong value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring key_str = NULL;
|
||||
gboolean ret = FALSE;
|
||||
jlong long_value = value;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
AMMF_CALL (goto done, Void, setLong, key_str, long_value);
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_get_string (GstAmMediaFormat * self, const gchar * key,
|
||||
gchar ** value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
gboolean ret = FALSE;
|
||||
jstring key_str = NULL;
|
||||
jstring v_str = NULL;
|
||||
const gchar *v = NULL;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
*value = 0;
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
v_str = AMMF_CALL (goto done, Object, getString, key_str);
|
||||
|
||||
v = (*env)->GetStringUTFChars (env, v_str, NULL);
|
||||
if (!v) {
|
||||
GST_ERROR ("Failed to convert string to UTF8");
|
||||
(*env)->ExceptionClear (env);
|
||||
goto done;
|
||||
}
|
||||
|
||||
*value = g_strdup (v);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
if (v)
|
||||
(*env)->ReleaseStringUTFChars (env, v_str, v);
|
||||
if (v_str)
|
||||
(*env)->DeleteLocalRef (env, v_str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_set_string (GstAmMediaFormat * self, const gchar * key,
|
||||
const gchar * value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring key_str = NULL;
|
||||
jstring v_str = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
v_str = (*env)->NewStringUTF (env, value);
|
||||
if (!v_str)
|
||||
goto done;
|
||||
|
||||
AMMF_CALL (goto done, Void, setString, key_str, v_str);
|
||||
ret = TRUE;
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
if (v_str)
|
||||
(*env)->DeleteLocalRef (env, v_str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_get_buffer (GstAmMediaFormat * self, const gchar * key,
|
||||
GstBuffer ** value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
gboolean ret = FALSE;
|
||||
jstring key_str = NULL;
|
||||
jobject v = NULL;
|
||||
guint8 *data;
|
||||
gsize size;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
*value = 0;
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
v = AMMF_CALL (goto done, Object, getByteBuffer, key_str);
|
||||
|
||||
data = (*env)->GetDirectBufferAddress (env, v);
|
||||
if (!data) {
|
||||
(*env)->ExceptionClear (env);
|
||||
GST_ERROR ("Failed to get buffer address");
|
||||
goto done;
|
||||
}
|
||||
size = (*env)->GetDirectBufferCapacity (env, v);
|
||||
*value = gst_buffer_new_and_alloc (size);
|
||||
memcpy (GST_BUFFER_DATA (*value), data, size);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
if (v)
|
||||
(*env)->DeleteLocalRef (env, v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_am_mediaformat_set_buffer (GstAmMediaFormat * self, const gchar * key,
|
||||
GstBuffer * value)
|
||||
{
|
||||
JNIEnv *env = gst_dvm_get_env ();
|
||||
jstring key_str = NULL;
|
||||
jobject v = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
|
||||
key_str = (*env)->NewStringUTF (env, key);
|
||||
if (!key_str)
|
||||
goto done;
|
||||
|
||||
/* FIXME: The buffer must remain valid until the codec is stopped */
|
||||
v = (*env)->NewDirectByteBuffer (env, GST_BUFFER_DATA (value),
|
||||
GST_BUFFER_SIZE (value));
|
||||
if (!v)
|
||||
goto done;
|
||||
|
||||
AMMF_CALL (goto done, Void, setByteBuffer, key_str, v);
|
||||
ret = TRUE;
|
||||
|
||||
done:
|
||||
if (key_str)
|
||||
(*env)->DeleteLocalRef (env, key_str);
|
||||
if (v)
|
||||
(*env)->DeleteLocalRef (env, v);
|
||||
|
||||
return ret;
|
||||
}
|
75
sys/androidmedia/gst-android-media-mediaformat.h
Normal file
75
sys/androidmedia/gst-android-media-mediaformat.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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_MEDIAFORMAT_H__
|
||||
#define __GST_ANDROID_MEDIA_MEDIAFORMAT_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <jni.h>
|
||||
|
||||
typedef struct _GstAmMediaFormat GstAmMediaFormat;
|
||||
|
||||
struct _GstAmMediaFormat {
|
||||
/*< private >*/
|
||||
jobject object; /* global reference */
|
||||
};
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean gst_android_media_mediaformat_init (void);
|
||||
void gst_android_media_mediaformat_deinit (void);
|
||||
|
||||
GstAmMediaFormat * gst_am_mediaformat_new (void);
|
||||
GstAmMediaFormat * gst_am_mediaformat_create_audio_format (const gchar *mime,
|
||||
gint sample_rate, gint channels);
|
||||
GstAmMediaFormat * gst_am_mediaformat_create_video_format (const gchar *mime,
|
||||
gint width, gint height);
|
||||
void gst_am_mediaformat_free (GstAmMediaFormat * self);
|
||||
|
||||
gboolean gst_am_mediaformat_get_float (GstAmMediaFormat * self,
|
||||
const gchar *key, gfloat *value);
|
||||
gboolean gst_am_mediaformat_set_float (GstAmMediaFormat * self,
|
||||
const gchar *key, gfloat value);
|
||||
gboolean gst_am_mediaformat_get_int (GstAmMediaFormat * self,
|
||||
const gchar *key, gint *value);
|
||||
gboolean gst_am_mediaformat_set_int (GstAmMediaFormat * self,
|
||||
const gchar *key, gint value);
|
||||
gboolean gst_am_mediaformat_get_long (GstAmMediaFormat * self,
|
||||
const gchar *key, glong *value);
|
||||
gboolean gst_am_mediaformat_set_long (GstAmMediaFormat * self,
|
||||
const gchar *key, glong value);
|
||||
gboolean gst_am_mediaformat_get_string (GstAmMediaFormat * self,
|
||||
const gchar *key, gchar **value);
|
||||
gboolean gst_am_mediaformat_set_string (GstAmMediaFormat * self,
|
||||
const gchar *key, const gchar *value);
|
||||
gboolean gst_am_mediaformat_get_buffer (GstAmMediaFormat * self,
|
||||
const gchar *key, GstBuffer **value);
|
||||
gboolean gst_am_mediaformat_set_buffer (GstAmMediaFormat * self,
|
||||
const gchar *key, GstBuffer *value);
|
||||
|
||||
|
||||
gboolean gst_am_mediaformat_contains_key (GstAmMediaFormat * self,
|
||||
const gchar *key);
|
||||
gchar * gst_am_mediaformat_to_string (GstAmMediaFormat * self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ANDROID_MEDIA_MEDIAFORMAT_H__ */
|
Loading…
Reference in a new issue