amc: Turn GstAmcSurfaceTexture into a base class with JNI implementation

This commit is contained in:
Xavier Claessens 2018-11-12 14:02:37 -05:00
parent 29ef89983c
commit 7fcf3ebf07
17 changed files with 647 additions and 410 deletions

View file

@ -2503,13 +2503,14 @@ done:
void
gst_ah_camera_set_preview_texture (GstAHCamera * self,
GstAmcSurfaceTexture * surfaceTexture)
GstAmcSurfaceTextureJNI * surfaceTexture)
{
JNIEnv *env = gst_amc_jni_get_env ();
GError *err = NULL;
gst_amc_jni_call_void_method (env, &err, self->object,
android_hardware_camera.setPreviewTexture, surfaceTexture->jobject);
android_hardware_camera.setPreviewTexture,
gst_amc_surface_texture_jni_get_jobject (surfaceTexture));
if (err) {
GST_ERROR ("Failed to call android.hardware.Camera.setPreviewTexture: %s",
err->message);

View file

@ -29,7 +29,7 @@
#include <jni.h>
#include "gst-android-graphics-imageformat.h"
#include "gstamcsurfacetexture.h"
#include "jni/gstamcsurfacetexture-jni.h"
G_BEGIN_DECLS
@ -150,7 +150,7 @@ gboolean gst_ah_camera_set_error_callback (GstAHCamera * self,
gboolean gst_ah_camera_set_preview_callback_with_buffer (GstAHCamera * self,
GstAHCPreviewCallback cb, gpointer user_data);
void gst_ah_camera_set_preview_texture (GstAHCamera * self,
GstAmcSurfaceTexture * surfaceTexture);
GstAmcSurfaceTextureJNI * surfaceTexture);
gboolean gst_ah_camera_start_preview (GstAHCamera * self);
gboolean gst_ah_camera_start_smooth_zoom (GstAHCamera * self, gint value);
gboolean gst_ah_camera_stop_preview (GstAHCamera * self);

View file

@ -2176,7 +2176,7 @@ gst_ahc_src_open (GstAHCSrc * self)
if (self->camera) {
GST_DEBUG_OBJECT (self, "Opened camera");
self->texture = gst_amc_surface_texture_new (&err);
self->texture = gst_amc_surface_texture_jni_new (&err);
if (self->texture == NULL) {
GST_ERROR_OBJECT (self,
"Failed to create surface texture object: %s", err->message);
@ -2222,9 +2222,11 @@ gst_ahc_src_close (GstAHCSrc * self)
}
self->camera = NULL;
if (self->texture && !gst_amc_surface_texture_release (self->texture, &err)) {
GST_ERROR_OBJECT (self,
"Failed to release surface texture object: %s", err->message);
if (self->texture
&& !gst_amc_surface_texture_release ((GstAmcSurfaceTexture *)
self->texture, &err)) {
GST_ERROR_OBJECT (self, "Failed to release surface texture object: %s",
err->message);
g_clear_error (&err);
}

View file

@ -30,7 +30,7 @@
#include <gst/base/gstdataqueue.h>
#include "gst-android-hardware-camera.h"
#include "gstamcsurfacetexture.h"
#include "jni/gstamcsurfacetexture-jni.h"
G_BEGIN_DECLS
@ -60,7 +60,7 @@ struct _GstAHCSrc
GstPushSrc parent;
GstAHCamera *camera;
GstAmcSurfaceTexture *texture;
GstAmcSurfaceTextureJNI *texture;
GList *data;
GstDataQueue *queue;
gint buffer_size;

View file

@ -24,6 +24,7 @@
#include <gst/gst.h>
#include "gstamc-format.h"
#include "gstamcsurfacetexture.h"
G_BEGIN_DECLS
@ -52,7 +53,7 @@ gboolean gst_amc_buffer_set_position_and_limit (GstAmcBuffer * buffer, GError **
GstAmcCodec * gst_amc_codec_new (const gchar *name, GError **err);
void gst_amc_codec_free (GstAmcCodec * codec);
gboolean gst_amc_codec_configure (GstAmcCodec * codec, GstAmcFormat * format, jobject surface, gint flags, GError **err);
gboolean gst_amc_codec_configure (GstAmcCodec * codec, GstAmcFormat * format, GstAmcSurfaceTexture * surface_texture, gint flags, GError **err);
GstAmcFormat * gst_amc_codec_get_output_format (GstAmcCodec * codec, GError **err);
gboolean gst_amc_codec_start (GstAmcCodec * codec, GError **err);
@ -69,6 +70,8 @@ gint gst_amc_codec_dequeue_output_buffer (GstAmcCodec * codec, GstAmcBufferInfo
gboolean gst_amc_codec_queue_input_buffer (GstAmcCodec * codec, gint index, const GstAmcBufferInfo *info, GError **err);
gboolean gst_amc_codec_release_output_buffer (GstAmcCodec * codec, gint index, gboolean render, GError **err);
GstAmcSurfaceTexture * gst_amc_codec_new_surface_texture (GError ** err);
G_END_DECLS
#endif /* __GST_AMC_CODEC_H__ */

View file

@ -1828,6 +1828,9 @@ amc_init (GstPlugin * plugin)
if (!gst_amc_format_static_init ())
return FALSE;
if (!gst_amc_surface_texture_static_init ())
return FALSE;
/* Set this to TRUE to allow registering decoders that have
* any unknown color formats, or encoders that only have
* unknown color formats

View file

@ -2,7 +2,7 @@
* Copyright (C) 2013, Fluendo S.A.
* Author: Andoni Morales <amorales@fluendo.com>
*
* Copyright (C) 2014, Collabora Ltd.
* Copyright (C) 2014,2018 Collabora Ltd.
* Author: Matthieu Bouron <matthieu.bouron@collabora.com>
*
* This library is free software; you can redistribute it and/or
@ -25,93 +25,10 @@
#include "config.h"
#endif
#include "gstjniutils.h"
#include "gstamcsurfacetexture.h"
G_DEFINE_TYPE (GstAmcSurfaceTexture, gst_amc_surface_texture, G_TYPE_OBJECT);
static gpointer parent_class = NULL;
static void gst_amc_surface_texture_dispose (GObject * object);
static gboolean
_cache_java_class (GstAmcSurfaceTextureClass * klass, GError ** err)
{
JNIEnv *env;
gst_amc_jni_initialize ();
env = gst_amc_jni_get_env ();
klass->jklass =
gst_amc_jni_get_class (env, err, "android/graphics/SurfaceTexture");
if (!klass->jklass) {
return FALSE;
}
klass->constructor =
gst_amc_jni_get_method_id (env, err, klass->jklass, "<init>", "(I)V");
if (!klass->constructor) {
goto error;
}
klass->set_on_frame_available_listener =
gst_amc_jni_get_method_id (env, err, klass->jklass,
"setOnFrameAvailableListener",
"(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V");
klass->set_default_buffer_size =
gst_amc_jni_get_method_id (env, err, klass->jklass,
"setDefaultBufferSize", "(II)V");
if (!klass->set_default_buffer_size) {
goto error;
}
klass->update_tex_image =
gst_amc_jni_get_method_id (env, err, klass->jklass, "updateTexImage",
"()V");
if (!klass->update_tex_image) {
goto error;
}
klass->detach_from_gl_context =
gst_amc_jni_get_method_id (env, err, klass->jklass, "detachFromGLContext",
"()V");
if (!klass->detach_from_gl_context) {
goto error;
}
klass->attach_to_gl_context =
gst_amc_jni_get_method_id (env, err, klass->jklass, "attachToGLContext",
"(I)V");
if (!klass->attach_to_gl_context) {
goto error;
}
klass->get_transform_matrix =
gst_amc_jni_get_method_id (env, err, klass->jklass, "getTransformMatrix",
"([F)V");
if (!klass->get_transform_matrix) {
goto error;
}
klass->get_timestamp =
gst_amc_jni_get_method_id (env, err, klass->jklass, "getTimestamp",
"()J");
if (!klass->get_timestamp) {
goto error;
}
klass->release =
gst_amc_jni_get_method_id (env, err, klass->jklass, "release", "()V");
if (!klass->release) {
goto error;
}
return TRUE;
error:
gst_amc_jni_object_unref (env, klass->constructor);
return FALSE;
}
G_DEFINE_ABSTRACT_TYPE (GstAmcSurfaceTexture, gst_amc_surface_texture,
G_TYPE_OBJECT);
static void
gst_amc_surface_texture_init (GstAmcSurfaceTexture * self)
@ -121,198 +38,77 @@ gst_amc_surface_texture_init (GstAmcSurfaceTexture * self)
static void
gst_amc_surface_texture_class_init (GstAmcSurfaceTextureClass * klass)
{
GError *err = NULL;
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
gobject_class->dispose = gst_amc_surface_texture_dispose;
if (!_cache_java_class (klass, &err)) {
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"Could not cache java class android/graphics/SurfaceTexture: %s",
err->message);
g_clear_error (&err);
}
}
static void
gst_amc_surface_texture_dispose (GObject * object)
{
GstAmcSurfaceTexture *self;
JNIEnv *env;
GError *err = NULL;
self = GST_AMC_SURFACE_TEXTURE (object);
env = gst_amc_jni_get_env ();
if (!gst_amc_surface_texture_release (self, &err)) {
GST_ERROR ("Could not release surface texture: %s", err->message);
g_clear_error (&err);
}
if (self->jobject) {
gst_amc_jni_object_unref (env, self->jobject);
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
GstAmcSurfaceTexture *
gst_amc_surface_texture_new (GError ** err)
{
GstAmcSurfaceTexture *texture = NULL;
GstAmcSurfaceTextureClass *klass;
JNIEnv *env;
texture = g_object_new (GST_TYPE_AMC_SURFACE_TEXTURE, NULL);
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (texture);
env = gst_amc_jni_get_env ();
texture->texture_id = 0;
texture->jobject = gst_amc_jni_new_object (env, err, TRUE, klass->jklass,
klass->constructor, texture->texture_id);
if (texture->jobject == NULL) {
goto error;
}
if (!gst_amc_surface_texture_detach_from_gl_context (texture, err)) {
goto error;
}
return texture;
error:
if (texture)
g_object_unref (texture);
return NULL;
}
gboolean
gst_amc_surface_texture_set_default_buffer_size (GstAmcSurfaceTexture * self,
gint width, gint height, GError ** err)
{
JNIEnv *env;
GstAmcSurfaceTextureClass *klass;
env = gst_amc_jni_get_env ();
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (self);
return gst_amc_jni_call_void_method (env, err, self->jobject,
klass->set_default_buffer_size, width, height);
return klass->set_default_buffer_size (self, width, height, err);
}
gboolean
gst_amc_surface_texture_update_tex_image (GstAmcSurfaceTexture * self,
GError ** err)
{
JNIEnv *env;
GstAmcSurfaceTextureClass *klass;
env = gst_amc_jni_get_env ();
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (self);
return gst_amc_jni_call_void_method (env, err, self->jobject,
klass->update_tex_image);
return klass->update_tex_image (self, err);
}
gboolean
gst_amc_surface_texture_detach_from_gl_context (GstAmcSurfaceTexture * self,
GError ** err)
{
JNIEnv *env;
gboolean ret;
GstAmcSurfaceTextureClass *klass;
env = gst_amc_jni_get_env ();
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (self);
ret =
gst_amc_jni_call_void_method (env, err, self->jobject,
klass->detach_from_gl_context);
self->texture_id = 0;
return ret;
return klass->detach_from_gl_context (self, err);
}
gboolean
gst_amc_surface_texture_attach_to_gl_context (GstAmcSurfaceTexture * self,
gint texture_id, GError ** err)
{
JNIEnv *env;
gboolean ret;
GstAmcSurfaceTextureClass *klass;
env = gst_amc_jni_get_env ();
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (self);
ret =
gst_amc_jni_call_void_method (env, err, self->jobject,
klass->attach_to_gl_context, texture_id);
self->texture_id = texture_id;
return ret;
return klass->attach_to_gl_context (self, texture_id, err);
}
gboolean
gst_amc_surface_texture_get_transform_matrix (GstAmcSurfaceTexture * self,
const gfloat * matrix, GError ** err)
{
JNIEnv *env;
gboolean ret;
GstAmcSurfaceTextureClass *klass;
/* 4x4 Matrix */
jsize size = 16;
jfloatArray floatarray;
env = gst_amc_jni_get_env ();
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (self);
floatarray = (*env)->NewFloatArray (env, size);
ret =
gst_amc_jni_call_void_method (env, err, self->jobject,
klass->get_transform_matrix, floatarray);
if (ret) {
(*env)->GetFloatArrayRegion (env, floatarray, 0, size, (jfloat *) matrix);
(*env)->DeleteLocalRef (env, floatarray);
}
return ret;
return klass->get_transform_matrix (self, matrix, err);
}
gboolean
gst_amc_surface_texture_get_timestamp (GstAmcSurfaceTexture * self,
gint64 * result, GError ** err)
{
JNIEnv *env;
GstAmcSurfaceTextureClass *klass;
env = gst_amc_jni_get_env ();
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (self);
return gst_amc_jni_call_long_method (env, err, self->jobject,
klass->get_timestamp, result);
return klass->get_timestamp (self, result, err);
}
gboolean
gst_amc_surface_texture_release (GstAmcSurfaceTexture * self, GError ** err)
{
JNIEnv *env;
GstAmcSurfaceTextureClass *klass;
env = gst_amc_jni_get_env ();
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (self);
return gst_amc_jni_call_void_method (env, err, self->jobject, klass->release);
return klass->release (self, err);
}
gboolean
gst_amc_surface_texture_set_on_frame_available_listener (GstAmcSurfaceTexture *
self, jobject listener, GError ** err)
gst_amc_surface_texture_set_on_frame_available_callback (GstAmcSurfaceTexture *
self, GstAmcSurfaceTextureOnFrameAvailableCallback callback,
gpointer user_data, GError ** err)
{
JNIEnv *env;
GstAmcSurfaceTextureClass *klass;
env = gst_amc_jni_get_env ();
klass = GST_AMC_SURFACE_TEXTURE_GET_CLASS (self);
return gst_amc_jni_call_void_method (env, err, self->jobject,
klass->set_on_frame_available_listener, listener);
return klass->set_on_frame_available_callback (self, callback, user_data,
err);
}

View file

@ -2,7 +2,7 @@
* Copyright (C) 2013, Fluendo S.A.
* Author: Andoni Morales <amorales@fluendo.com>
*
* Copyright (C) 2014, Collabora Ltd.
* Copyright (C) 2014,2018 Collabora Ltd.
* Author: Matthieu Bouron <matthieu.bouron@collabora.com>
*
* This library is free software; you can redistribute it and/or
@ -26,51 +26,51 @@
#include <glib.h>
#include <glib-object.h>
#include <jni.h>
G_BEGIN_DECLS
#define GST_TYPE_AMC_SURFACE_TEXTURE (gst_amc_surface_texture_get_type ())
#define GST_AMC_SURFACE_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_AMC_SURFACE_TEXTURE, GstAmcSurfaceTexture))
#define GST_IS_AMC_SURFACE_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_AMC_SURFACE_TEXTURE))
#define GST_AMC_SURFACE_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_AMC_SURFACE_TEXTURE, GstAmcSurfaceTextureClass))
#define GST_IS_AMC_SURFACE_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_AMC_SURFACE_TEXTURE))
#define GST_AMC_SURFACE_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_AMC_SURFACE_TEXTURE, GstAmcSurfaceTextureClass))
#define GST_TYPE_AMC_SURFACE_TEXTURE gst_amc_surface_texture_get_type ()
G_DECLARE_DERIVABLE_TYPE (GstAmcSurfaceTexture, gst_amc_surface_texture, GST, AMC_SURFACE_TEXTURE, GObject)
typedef struct _GstAmcSurfaceTexture GstAmcSurfaceTexture;
typedef struct _GstAmcSurfaceTextureClass GstAmcSurfaceTextureClass;
struct _GstAmcSurfaceTexture
{
GObject parent_instance;
/* instance members */
gint texture_id;
jobject jobject;
};
typedef void (* GstAmcSurfaceTextureOnFrameAvailableCallback) (GstAmcSurfaceTexture * self, gpointer user_data);
struct _GstAmcSurfaceTextureClass
{
GObjectClass parent_class;
/* class members */
gint texture_id;
gboolean (* set_default_buffer_size) (GstAmcSurfaceTexture *texture,
gint width,
gint height,
GError ** err);
jclass jklass;
jmethodID constructor;
jmethodID set_on_frame_available_listener;
jmethodID set_default_buffer_size;
jmethodID update_tex_image;
jmethodID detach_from_gl_context;
jmethodID attach_to_gl_context;
jmethodID get_transform_matrix;
jmethodID get_timestamp;
jmethodID release;
gboolean (* update_tex_image) (GstAmcSurfaceTexture *texture,
GError ** err);
gboolean (* detach_from_gl_context) (GstAmcSurfaceTexture *texture,
GError ** err);
gboolean (* attach_to_gl_context) (GstAmcSurfaceTexture *texture,
gint index,
GError ** err);
gboolean (* get_transform_matrix) (GstAmcSurfaceTexture *texture,
const gfloat *matrix,
GError ** err);
gboolean (* get_timestamp) (GstAmcSurfaceTexture *texture,
gint64 * result,
GError ** err);
gboolean (* release) (GstAmcSurfaceTexture *texture,
GError ** err);
gboolean (* set_on_frame_available_callback) (GstAmcSurfaceTexture * self,
GstAmcSurfaceTextureOnFrameAvailableCallback callback,
gpointer user_data,
GError ** err);
};
GType gst_amc_surface_texture_get_type (void);
GstAmcSurfaceTexture * gst_amc_surface_texture_new (GError ** err);
gboolean gst_amc_surface_texture_static_init (void);
gboolean gst_amc_surface_texture_set_default_buffer_size (GstAmcSurfaceTexture *texture,
gint width,
@ -98,9 +98,11 @@ gboolean gst_amc_surface_texture_get_timestamp (GstAmcSurfaceTexture *
gboolean gst_amc_surface_texture_release (GstAmcSurfaceTexture *texture,
GError ** err);
gboolean gst_amc_surface_texture_set_on_frame_available_listener (GstAmcSurfaceTexture * self,
jobject listener,
GError ** err);
gboolean gst_amc_surface_texture_set_on_frame_available_callback (GstAmcSurfaceTexture * self,
GstAmcSurfaceTextureOnFrameAvailableCallback callback,
gpointer user_data,
GError ** err);
G_END_DECLS
#endif

View file

@ -68,14 +68,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_amc_video_dec_debug_category);
g_clear_error (&err); \
} G_STMT_END
#if GLIB_SIZEOF_VOID_P == 8
#define JLONG_TO_GST_AMC_VIDEO_DEC(value) (GstAmcVideoDec *)(value)
#define GST_AMC_VIDEO_DEC_TO_JLONG(value) (jlong)(value)
#else
#define JLONG_TO_GST_AMC_VIDEO_DEC(value) (GstAmcVideoDec *)(jint)(value)
#define GST_AMC_VIDEO_DEC_TO_JLONG(value) (jlong)(jint)(value)
#endif
typedef struct _BufferIdentification BufferIdentification;
struct _BufferIdentification
{
@ -123,7 +115,7 @@ struct gl_sync
gint buffer_idx; /* idx of the AMC buffer we should render */
GstBuffer *buffer; /* back reference to the buffer */
GstGLMemory *oes_mem; /* where amc is rendering into. The same for every gl_sync */
GstAmcSurface *surface; /* java wrapper for where amc is rendering into */
GstAmcSurfaceTexture *surface; /* java wrapper for where amc is rendering into */
guint gl_frame_no; /* effectively the frame id */
gint64 released_ts; /* microseconds from g_get_monotonic_time() */
struct gl_sync_result *result;
@ -181,8 +173,8 @@ static void
_attach_mem_to_context (GstGLContext * context, GstAmcVideoDec * self)
{
GST_TRACE_OBJECT (self, "attaching texture %p id %u to current context",
self->surface->texture, self->oes_mem->tex_id);
if (!gst_amc_surface_texture_attach_to_gl_context (self->surface->texture,
self->surface, self->oes_mem->tex_id);
if (!gst_amc_surface_texture_attach_to_gl_context (self->surface,
self->oes_mem->tex_id, &self->gl_error)) {
GST_ERROR_OBJECT (self, "Failed to attach texture to the GL context");
GST_ELEMENT_ERROR_FROM_ERROR (self, self->gl_error);
@ -198,9 +190,9 @@ _dettach_mem_from_context (GstGLContext * context, GstAmcVideoDec * self)
guint tex_id = self->oes_mem ? self->oes_mem->tex_id : 0;
GST_TRACE_OBJECT (self, "detaching texture %p id %u from current context",
self->surface->texture, tex_id);
self->surface, tex_id);
if (!gst_amc_surface_texture_detach_from_gl_context (self->surface->texture,
if (!gst_amc_surface_texture_detach_from_gl_context (self->surface,
&self->gl_error)) {
GST_ERROR_OBJECT (self, "Failed to attach texture to the GL context");
GST_ELEMENT_ERROR_FROM_ERROR (self, self->gl_error);
@ -252,8 +244,8 @@ static gboolean gst_amc_video_dec_src_query (GstVideoDecoder * bdec,
static GstFlowReturn gst_amc_video_dec_drain (GstAmcVideoDec * self);
static gboolean gst_amc_video_dec_check_codec_config (GstAmcVideoDec * self);
static void
gst_amc_video_dec_on_frame_available (JNIEnv * env, jobject thiz,
long long context, jobject surfaceTexture);
gst_amc_video_dec_on_frame_available (GstAmcSurfaceTexture * texture,
gpointer user_data);
enum
{
@ -484,24 +476,19 @@ gst_amc_video_dec_close (GstVideoDecoder * decoder)
self->gl_last_rendered_frame = 0;
if (self->surface) {
gst_object_unref (self->surface);
self->surface = NULL;
}
if (self->listener) {
JNIEnv *env = gst_amc_jni_get_env ();
GError *err = NULL;
if (!gst_amc_jni_call_void_method (env, &err, self->listener,
self->set_context_id, GST_AMC_VIDEO_DEC_TO_JLONG (NULL))) {
GST_ERROR_OBJECT (self, "Failed to unset back pointer on the listener. "
if (!gst_amc_surface_texture_set_on_frame_available_callback (self->surface,
NULL, NULL, &err)) {
GST_ERROR_OBJECT (self,
"Failed to unset back pointer on the listener. "
"crashes/hangs may ensue: %s", err ? err->message : "Unknown");
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
}
gst_amc_jni_object_unref (env, self->listener);
gst_object_unref (self->surface);
self->surface = NULL;
}
self->listener = NULL;
if (self->codec) {
GError *err = NULL;
@ -1069,8 +1056,7 @@ _gl_sync_render_unlocked (struct gl_sync *sync)
/* FIXME: if this ever starts returning valid values we should attempt
* to use it */
if (!gst_amc_surface_texture_get_timestamp (sync->surface->texture, &ts,
&error)) {
if (!gst_amc_surface_texture_get_timestamp (sync->surface, &ts, &error)) {
GST_ERROR_OBJECT (sync->sink, "Failed to update texture image");
GST_ELEMENT_ERROR_FROM_ERROR (sync->sink, error);
goto out;
@ -1079,8 +1065,7 @@ _gl_sync_render_unlocked (struct gl_sync *sync)
sync, ts);
GST_TRACE ("gl_sync %p update_tex_image", sync);
if (!gst_amc_surface_texture_update_tex_image (sync->surface->texture,
&error)) {
if (!gst_amc_surface_texture_update_tex_image (sync->surface, &error)) {
GST_ERROR_OBJECT (sync->sink, "Failed to update texture image");
GST_ELEMENT_ERROR_FROM_ERROR (sync->sink, error);
goto out;
@ -1089,8 +1074,7 @@ _gl_sync_render_unlocked (struct gl_sync *sync)
sync->result->updated = TRUE;
sync->sink->gl_last_rendered_frame = sync->gl_frame_no;
if (!gst_amc_surface_texture_get_timestamp (sync->surface->texture, &ts,
&error)) {
if (!gst_amc_surface_texture_get_timestamp (sync->surface, &ts, &error)) {
GST_ERROR_OBJECT (sync->sink, "Failed to update texture image");
GST_ELEMENT_ERROR_FROM_ERROR (sync->sink, error);
goto out;
@ -1102,8 +1086,8 @@ _gl_sync_render_unlocked (struct gl_sync *sync)
if (!af_meta) {
GST_WARNING ("Failed to retreive the transformation meta from the "
"gl_sync %p buffer %p", sync, sync->buffer);
} else if (gst_amc_surface_texture_get_transform_matrix (sync->surface->
texture, matrix, &error)) {
} else if (gst_amc_surface_texture_get_transform_matrix (sync->surface,
matrix, &error)) {
gfloat inv_mat[16];
/* The transform from mediacodec applies to the texture coords, but
@ -1123,7 +1107,7 @@ _gl_sync_render_unlocked (struct gl_sync *sync)
}
GST_LOG ("gl_sync %p successfully updated SurfaceTexture %p into "
"OES texture %u", sync, sync->surface->texture, sync->oes_mem->tex_id);
"OES texture %u", sync, sync->surface, sync->oes_mem->tex_id);
out:
if (error) {
@ -1807,64 +1791,6 @@ gst_amc_video_dec_stop (GstVideoDecoder * decoder)
return TRUE;
}
static jobject
gst_amc_video_dec_new_on_frame_available_listener (GstAmcVideoDec * decoder,
JNIEnv * env, GError ** err)
{
jobject listener = NULL;
jclass listener_cls = NULL;
jmethodID constructor_id = 0;
JNINativeMethod amcOnFrameAvailableListener = {
"native_onFrameAvailable",
"(JLandroid/graphics/SurfaceTexture;)V",
(void *) gst_amc_video_dec_on_frame_available,
};
listener_cls =
gst_amc_jni_get_application_class (env,
"org/freedesktop/gstreamer/androidmedia/GstAmcOnFrameAvailableListener",
err);
if (!listener_cls) {
return FALSE;
}
(*env)->RegisterNatives (env, listener_cls, &amcOnFrameAvailableListener, 1);
if ((*env)->ExceptionCheck (env)) {
(*env)->ExceptionClear (env);
goto done;
}
constructor_id =
gst_amc_jni_get_method_id (env, err, listener_cls, "<init>", "()V");
if (!constructor_id) {
goto done;
}
decoder->set_context_id =
gst_amc_jni_get_method_id (env, err, listener_cls, "setContext", "(J)V");
if (!decoder->set_context_id) {
goto done;
}
listener =
gst_amc_jni_new_object (env, err, TRUE, listener_cls, constructor_id);
if (!listener) {
goto done;
}
if (!gst_amc_jni_call_void_method (env, err, listener,
decoder->set_context_id, GST_AMC_VIDEO_DEC_TO_JLONG (decoder))) {
gst_amc_jni_object_unref (env, listener);
listener = NULL;
}
done:
gst_amc_jni_object_unref (env, listener_cls);
return listener;
}
static gboolean
gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
GstVideoCodecState * state)
@ -1879,7 +1805,6 @@ gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
guint8 *codec_data = NULL;
gsize codec_data_size = 0;
GError *err = NULL;
jobject jsurface = NULL;
self = GST_AMC_VIDEO_DEC (decoder);
klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);
@ -2071,50 +1996,31 @@ gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
}
if (self->downstream_supports_gl && self->surface) {
jsurface = self->surface->jobject;
self->codec_config = AMC_CODEC_CONFIG_WITH_SURFACE;
} else if (self->downstream_supports_gl && !self->surface) {
int ret = TRUE;
JNIEnv *env = NULL;
GstAmcSurfaceTexture *surface_texture = NULL;
env = gst_amc_jni_get_env ();
surface_texture = gst_amc_surface_texture_new (&err);
if (!surface_texture) {
self->surface = gst_amc_codec_new_surface_texture (&err);
if (!self->surface) {
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
return FALSE;
}
if (self->listener) {
if (!gst_amc_jni_call_void_method (env, &err, self->listener,
self->set_context_id, GST_AMC_VIDEO_DEC_TO_JLONG (NULL))) {
ret = FALSE;
goto done;
}
gst_amc_jni_object_unref (env, self->listener);
}
self->listener =
gst_amc_video_dec_new_on_frame_available_listener (self, env, &err);
if (!self->listener) {
if (!gst_amc_surface_texture_set_on_frame_available_callback
(self->surface, gst_amc_video_dec_on_frame_available, self, &err)) {
ret = FALSE;
goto done;
}
if (!gst_amc_surface_texture_set_on_frame_available_listener
(surface_texture, self->listener, &err)) {
ret = FALSE;
goto done;
}
self->surface = gst_amc_surface_new (surface_texture, &err);
jsurface = self->surface->jobject;
self->codec_config = AMC_CODEC_CONFIG_WITH_SURFACE;
done:
g_object_unref (surface_texture);
if (!ret) {
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
return FALSE;
}
} else {
self->codec_config = AMC_CODEC_CONFIG_WITHOUT_SURFACE;
}
format_string = gst_amc_format_to_string (format, &err);
@ -2124,16 +2030,11 @@ gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
GST_STR_NULL (format_string));
g_free (format_string);
if (!gst_amc_codec_configure (self->codec, format, jsurface, 0, &err)) {
if (!gst_amc_codec_configure (self->codec, format, self->surface, 0, &err)) {
GST_ERROR_OBJECT (self, "Failed to configure codec");
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
return FALSE;
}
if (jsurface) {
self->codec_config = AMC_CODEC_CONFIG_WITH_SURFACE;
} else {
self->codec_config = AMC_CODEC_CONFIG_WITHOUT_SURFACE;
}
gst_amc_format_free (format);
@ -2606,10 +2507,10 @@ context_error:
}
static void
gst_amc_video_dec_on_frame_available (JNIEnv * env, jobject thiz,
long long context, jobject surfaceTexture)
gst_amc_video_dec_on_frame_available (GstAmcSurfaceTexture * texture,
gpointer user_data)
{
GstAmcVideoDec *self = JLONG_TO_GST_AMC_VIDEO_DEC (context);
GstAmcVideoDec *self = (GstAmcVideoDec *) user_data;
/* apparently we can be called after the decoder has been closed */
if (!self)

View file

@ -27,7 +27,7 @@
#include <gst/video/gstvideodecoder.h>
#include "gstamc.h"
#include "gstamcsurface.h"
#include "gstamcsurfacetexture.h"
G_BEGIN_DECLS
@ -91,7 +91,7 @@ struct _GstAmcVideoDec
/* TRUE if the component is drained currently */
gboolean drained;
GstAmcSurface *surface;
GstAmcSurfaceTexture *surface;
GstGLDisplay *gl_display;
GstGLContext *gl_context;
@ -100,9 +100,6 @@ struct _GstAmcVideoDec
gboolean downstream_supports_gl;
GstFlowReturn downstream_flow_ret;
jobject listener;
jmethodID set_context_id;
gboolean gl_mem_attached;
GstGLMemory *oes_mem;
GError *gl_error;

View file

@ -29,6 +29,14 @@
#include <glib.h>
#include <gst/gst.h>
#if GLIB_SIZEOF_VOID_P == 8
#define JLONG_TO_GPOINTER(value) (gpointer)(value)
#define GPOINTER_TO_JLONG(value) (jlong)(value)
#else
#define JLONG_TO_GPOINTER(value) (gpointer)(jint)(value)
#define GPOINTER_TO_JLONG(value) (jlong)(jint)(value)
#endif
jclass gst_amc_jni_get_class (JNIEnv * env,
GError ** err,
const gchar * name);

View file

@ -27,6 +27,8 @@
#include "../gstamc-codec.h"
#include "../gstamc-constants.h"
#include "gstamc-internal-jni.h"
#include "gstamcsurfacetexture-jni.h"
#include "gstamcsurface.h"
struct _GstAmcCodec
{
@ -34,6 +36,7 @@ struct _GstAmcCodec
RealBuffer *input_buffers, *output_buffers;
gsize n_input_buffers, n_output_buffers;
GstAmcSurface *surface;
};
static struct
@ -503,22 +506,34 @@ gst_amc_codec_free (GstAmcCodec * codec)
codec->output_buffers = NULL;
codec->n_output_buffers = 0;
g_clear_object (&codec->surface);
gst_amc_jni_object_unref (env, codec->object);
g_slice_free (GstAmcCodec, codec);
}
gboolean
gst_amc_codec_configure (GstAmcCodec * codec, GstAmcFormat * format,
jobject surface, gint flags, GError ** err)
GstAmcSurfaceTexture * surface, gint flags, GError ** err)
{
JNIEnv *env;
g_return_val_if_fail (codec != NULL, FALSE);
g_return_val_if_fail (format != NULL, FALSE);
g_return_val_if_fail (GST_IS_AMC_SURFACE_TEXTURE_JNI (surface), FALSE);
env = gst_amc_jni_get_env ();
if (surface) {
g_object_unref (codec->surface);
codec->surface =
gst_amc_surface_new ((GstAmcSurfaceTextureJNI *) surface, err);
if (!codec->surface)
return FALSE;
}
return gst_amc_jni_call_void_method (env, err, codec->object,
media_codec.configure, format->object, surface, NULL, flags);
media_codec.configure, format->object, codec->surface, NULL, flags);
}
GstAmcFormat *
@ -934,3 +949,9 @@ gst_amc_codec_release_output_buffer (GstAmcCodec * codec, gint index,
return gst_amc_jni_call_void_method (env, err, codec->object,
media_codec.release_output_buffer, index, render);
}
GstAmcSurfaceTexture *
gst_amc_codec_new_surface_texture (GError ** err)
{
return (GstAmcSurfaceTexture *) gst_amc_surface_texture_jni_new (err);
}

View file

@ -131,7 +131,7 @@ gst_amc_surface_dispose (GObject * object)
}
GstAmcSurface *
gst_amc_surface_new (GstAmcSurfaceTexture * texture, GError ** err)
gst_amc_surface_new (GstAmcSurfaceTextureJNI * texture, GError ** err)
{
GstAmcSurface *surface;
GstAmcSurfaceClass *klass;
@ -142,7 +142,7 @@ gst_amc_surface_new (GstAmcSurfaceTexture * texture, GError ** err)
klass = GST_AMC_SURFACE_GET_CLASS (surface);
surface->jobject = gst_amc_jni_new_object (env, err, TRUE, klass->jklass,
klass->constructor, texture->jobject);
klass->constructor, gst_amc_surface_texture_jni_get_jobject (texture));
if (surface->jobject == NULL) {
g_object_unref (surface);
return NULL;

View file

@ -26,7 +26,7 @@
#include <glib-object.h>
#include <jni.h>
#include "gstamcsurfacetexture.h"
#include "jni/gstamcsurfacetexture-jni.h"
G_BEGIN_DECLS
@ -46,7 +46,7 @@ struct _GstAmcSurface
/* instance members */
jobject jobject;
GstAmcSurfaceTexture *texture;
GstAmcSurfaceTextureJNI *texture;
};
struct _GstAmcSurfaceClass
@ -63,7 +63,7 @@ struct _GstAmcSurfaceClass
GType gst_amc_surface_get_type (void);
GstAmcSurface * gst_amc_surface_new (GstAmcSurfaceTexture *texture,
GstAmcSurface * gst_amc_surface_new (GstAmcSurfaceTextureJNI *texture,
GError ** err);
gboolean gst_amc_surface_is_valid (GstAmcSurface *surface,

View file

@ -0,0 +1,462 @@
/*
* Copyright (C) 2013, Fluendo S.A.
* Author: Andoni Morales <amorales@fluendo.com>
*
* Copyright (C) 2014,2018 Collabora Ltd.
* Author: Matthieu Bouron <matthieu.bouron@collabora.com>
*
* 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 "gstjniutils.h"
#include "gstamcsurfacetexture-jni.h"
struct _GstAmcSurfaceTextureJNI
{
jobject jobject;
gint texture_id;
jobject listener;
jmethodID set_context_id;
GstAmcSurfaceTextureOnFrameAvailableCallback callback;
gpointer user_data;
};
static struct
{
jclass jklass;
jmethodID constructor;
jmethodID set_on_frame_available_listener;
jmethodID set_default_buffer_size;
jmethodID update_tex_image;
jmethodID detach_from_gl_context;
jmethodID attach_to_gl_context;
jmethodID get_transform_matrix;
jmethodID get_timestamp;
jmethodID release;
} surface_texture;
G_DEFINE_TYPE (GstAmcSurfaceTextureJNI, gst_amc_surface_texture_jni,
GST_TYPE_AMC_SURFACE_TEXTURE);
gboolean
gst_amc_surface_texture_static_init (void)
{
JNIEnv *env;
GError *err = NULL;
env = gst_amc_jni_get_env ();
surface_texture.jklass = gst_amc_jni_get_class (env, &err,
"android/graphics/SurfaceTexture");
if (!surface_texture.jklass) {
GST_ERROR ("Failed to get android.graphics.SurfaceTexture class: %s",
err->message);
g_clear_error (&err);
return FALSE;
}
surface_texture.constructor =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass, "<init>",
"(I)V");
if (!surface_texture.constructor) {
goto error;
}
surface_texture.set_on_frame_available_listener =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass,
"setOnFrameAvailableListener",
"(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V");
if (!surface_texture.set_on_frame_available_listener) {
goto error;
}
surface_texture.set_default_buffer_size =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass,
"setDefaultBufferSize", "(II)V");
if (!surface_texture.set_default_buffer_size) {
goto error;
}
surface_texture.update_tex_image =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass,
"updateTexImage", "()V");
if (!surface_texture.update_tex_image) {
goto error;
}
surface_texture.detach_from_gl_context =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass,
"detachFromGLContext", "()V");
if (!surface_texture.detach_from_gl_context) {
goto error;
}
surface_texture.attach_to_gl_context =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass,
"attachToGLContext", "(I)V");
if (!surface_texture.attach_to_gl_context) {
goto error;
}
surface_texture.get_transform_matrix =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass,
"getTransformMatrix", "([F)V");
if (!surface_texture.get_transform_matrix) {
goto error;
}
surface_texture.get_timestamp =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass,
"getTimestamp", "()J");
if (!surface_texture.get_timestamp) {
goto error;
}
surface_texture.release =
gst_amc_jni_get_method_id (env, &err, surface_texture.jklass, "release",
"()V");
if (!surface_texture.release) {
goto error;
}
return TRUE;
error:
GST_ERROR ("Failed to get android.graphics.SurfaceTexture methods: %s",
err->message);
g_clear_error (&err);
gst_amc_jni_object_unref (env, surface_texture.constructor);
return FALSE;
}
static gboolean
gst_amc_surface_texture_jni_set_default_buffer_size (GstAmcSurfaceTexture *
base, gint width, gint height, GError ** err)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (base);
JNIEnv *env;
env = gst_amc_jni_get_env ();
return gst_amc_jni_call_void_method (env, err, self->jobject,
surface_texture.set_default_buffer_size, width, height);
}
static gboolean
gst_amc_surface_texture_jni_update_tex_image (GstAmcSurfaceTexture * base,
GError ** err)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (base);
JNIEnv *env;
env = gst_amc_jni_get_env ();
return gst_amc_jni_call_void_method (env, err, self->jobject,
surface_texture.update_tex_image);
}
static gboolean
gst_amc_surface_texture_jni_detach_from_gl_context (GstAmcSurfaceTexture * base,
GError ** err)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (base);
JNIEnv *env;
gboolean ret;
env = gst_amc_jni_get_env ();
ret =
gst_amc_jni_call_void_method (env, err, self->jobject,
surface_texture.detach_from_gl_context);
self->texture_id = 0;
return ret;
}
static gboolean
gst_amc_surface_texture_jni_attach_to_gl_context (GstAmcSurfaceTexture * base,
gint texture_id, GError ** err)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (base);
JNIEnv *env;
gboolean ret;
env = gst_amc_jni_get_env ();
ret =
gst_amc_jni_call_void_method (env, err, self->jobject,
surface_texture.attach_to_gl_context, texture_id);
self->texture_id = texture_id;
return ret;
}
static gboolean
gst_amc_surface_texture_jni_get_transform_matrix (GstAmcSurfaceTexture * base,
const gfloat * matrix, GError ** err)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (base);
JNIEnv *env;
gboolean ret;
/* 4x4 Matrix */
jsize size = 16;
jfloatArray floatarray;
env = gst_amc_jni_get_env ();
floatarray = (*env)->NewFloatArray (env, size);
ret =
gst_amc_jni_call_void_method (env, err, self->jobject,
surface_texture.get_transform_matrix, floatarray);
if (ret) {
(*env)->GetFloatArrayRegion (env, floatarray, 0, size, (jfloat *) matrix);
(*env)->DeleteLocalRef (env, floatarray);
}
return ret;
}
static gboolean
gst_amc_surface_texture_jni_get_timestamp (GstAmcSurfaceTexture * base,
gint64 * result, GError ** err)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (base);
JNIEnv *env;
env = gst_amc_jni_get_env ();
return gst_amc_jni_call_long_method (env, err, self->jobject,
surface_texture.get_timestamp, result);
}
static gboolean
gst_amc_surface_texture_jni_release (GstAmcSurfaceTexture * base, GError ** err)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (base);
JNIEnv *env;
env = gst_amc_jni_get_env ();
return gst_amc_jni_call_void_method (env, err, self->jobject,
surface_texture.release);
}
static void
on_frame_available_cb (JNIEnv * env, jobject thiz,
long long context, jobject surfaceTexture)
{
GstAmcSurfaceTextureJNI *self = JLONG_TO_GPOINTER (context);
self->callback (GST_AMC_SURFACE_TEXTURE (self), self->user_data);
}
static gboolean
create_listener (GstAmcSurfaceTextureJNI * self, JNIEnv * env, GError ** err)
{
jclass listener_cls = NULL;
jmethodID constructor_id = 0;
JNINativeMethod amcOnFrameAvailableListener = {
"native_onFrameAvailable",
"(JLandroid/graphics/SurfaceTexture;)V",
(void *) on_frame_available_cb,
};
listener_cls =
gst_amc_jni_get_application_class (env,
"org/freedesktop/gstreamer/androidmedia/GstAmcOnFrameAvailableListener",
err);
if (!listener_cls) {
return FALSE;
}
(*env)->RegisterNatives (env, listener_cls, &amcOnFrameAvailableListener, 1);
if ((*env)->ExceptionCheck (env)) {
(*env)->ExceptionClear (env);
goto done;
}
constructor_id =
gst_amc_jni_get_method_id (env, err, listener_cls, "<init>", "()V");
if (!constructor_id) {
goto done;
}
self->set_context_id =
gst_amc_jni_get_method_id (env, err, listener_cls, "setContext", "(J)V");
if (!self->set_context_id) {
goto done;
}
self->listener =
gst_amc_jni_new_object (env, err, TRUE, listener_cls, constructor_id);
if (!self->listener) {
goto done;
}
if (!gst_amc_jni_call_void_method (env, err, self->listener,
self->set_context_id, GPOINTER_TO_JLONG (self))) {
gst_amc_jni_object_unref (env, self->listener);
self->listener = NULL;
}
done:
gst_amc_jni_object_unref (env, listener_cls);
return self->listener != NULL;
}
static gboolean
remove_listener (GstAmcSurfaceTextureJNI * self, JNIEnv * env, GError ** err)
{
if (self->listener) {
if (!gst_amc_jni_call_void_method (env, err, self->listener,
self->set_context_id, GPOINTER_TO_JLONG (NULL)))
return FALSE;
gst_amc_jni_object_unref (env, self->listener);
self->listener = NULL;
}
return TRUE;
}
static gboolean
gst_amc_surface_texture_jni_set_on_frame_available_callback
(GstAmcSurfaceTexture * base,
GstAmcSurfaceTextureOnFrameAvailableCallback callback, gpointer user_data,
GError ** err)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (base);
JNIEnv *env;
env = gst_amc_jni_get_env ();
if (!remove_listener (self, env, err))
return FALSE;
self->callback = callback;
self->user_data = user_data;
if (callback == NULL)
return TRUE;
if (!create_listener (self, env, err))
return FALSE;
if (!gst_amc_jni_call_void_method (env, err, self->jobject,
surface_texture.set_on_frame_available_listener, self->listener)) {
remove_listener (self, env, NULL);
return FALSE;
}
return TRUE;
}
static void
gst_amc_surface_texture_jni_dispose (GObject * object)
{
GstAmcSurfaceTextureJNI *self = GST_AMC_SURFACE_TEXTURE_JNI (object);
JNIEnv *env;
GError *err = NULL;
env = gst_amc_jni_get_env ();
if (!gst_amc_surface_texture_jni_release (GST_AMC_SURFACE_TEXTURE (self),
&err)) {
GST_ERROR ("Could not release surface texture: %s", err->message);
g_clear_error (&err);
}
remove_listener (self, env, NULL);
if (self->jobject) {
gst_amc_jni_object_unref (env, self->jobject);
}
G_OBJECT_CLASS (gst_amc_surface_texture_jni_parent_class)->dispose (object);
}
static void
gst_amc_surface_texture_jni_class_init (GstAmcSurfaceTextureJNIClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstAmcSurfaceTextureClass *surface_texture_class =
GST_AMC_SURFACE_TEXTURE_CLASS (klass);
gobject_class->dispose = gst_amc_surface_texture_jni_dispose;
surface_texture_class->set_default_buffer_size =
gst_amc_surface_texture_jni_set_default_buffer_size;
surface_texture_class->update_tex_image =
gst_amc_surface_texture_jni_update_tex_image;
surface_texture_class->detach_from_gl_context =
gst_amc_surface_texture_jni_detach_from_gl_context;
surface_texture_class->attach_to_gl_context =
gst_amc_surface_texture_jni_attach_to_gl_context;
surface_texture_class->get_transform_matrix =
gst_amc_surface_texture_jni_get_transform_matrix;
surface_texture_class->get_timestamp =
gst_amc_surface_texture_jni_get_timestamp;
surface_texture_class->release = gst_amc_surface_texture_jni_release;
surface_texture_class->set_on_frame_available_callback =
gst_amc_surface_texture_jni_set_on_frame_available_callback;
}
static void
gst_amc_surface_texture_jni_init (GstAmcSurfaceTextureJNI * self)
{
}
GstAmcSurfaceTextureJNI *
gst_amc_surface_texture_jni_new (GError ** err)
{
GstAmcSurfaceTextureJNI *self = NULL;
JNIEnv *env;
self = g_object_new (GST_TYPE_AMC_SURFACE_TEXTURE_JNI, NULL);
env = gst_amc_jni_get_env ();
self->texture_id = 0;
self->jobject =
gst_amc_jni_new_object (env, err, TRUE, surface_texture.jklass,
surface_texture.constructor, self->texture_id);
if (self->jobject == NULL) {
goto error;
}
if (!gst_amc_surface_texture_jni_detach_from_gl_context ((GstAmcSurfaceTexture
*) self, err)) {
goto error;
}
return self;
error:
if (self)
g_object_unref (self);
return NULL;
}
jobject
gst_amc_surface_texture_jni_get_jobject (GstAmcSurfaceTextureJNI * self)
{
return self->jobject;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2013, Fluendo S.A.
* Author: Andoni Morales <amorales@fluendo.com>
*
* Copyright (C) 2014,2018 Collabora Ltd.
* Author: Matthieu Bouron <matthieu.bouron@collabora.com>
*
* 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_AMC_SURFACE_TEXTURE_JNI_H__
#define __GST_AMC_SURFACE_TEXTURE_JNI_H__
#include "../gstamcsurfacetexture.h"
G_BEGIN_DECLS
#define GST_TYPE_AMC_SURFACE_TEXTURE_JNI gst_amc_surface_texture_jni_get_type ()
G_DECLARE_FINAL_TYPE (GstAmcSurfaceTextureJNI, gst_amc_surface_texture_jni, GST, AMC_SURFACE_TEXTURE_JNI, GstAmcSurfaceTexture)
GstAmcSurfaceTextureJNI * gst_amc_surface_texture_jni_new (GError ** err);
jobject gst_amc_surface_texture_jni_get_jobject (GstAmcSurfaceTextureJNI * self);
G_END_DECLS
#endif

View file

@ -3,7 +3,6 @@ androidmedia_sources = [
'gstahssrc.c',
'gstamcaudiodec.c',
'gstamc.c',
'gstamcsurface.c',
'gstamcsurfacetexture.c',
'gstamcvideodec.c',
'gstamcvideoenc.c',
@ -14,6 +13,8 @@ androidmedia_sources = [
'jni/gstamc-codec-jni.c',
'jni/gstamc-codeclist-jni.c',
'jni/gstamc-format-jni.c',
'jni/gstamcsurface.c',
'jni/gstamcsurfacetexture-jni.c',
]
androidmedia_java_sources = [