mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 20:20:38 +00:00
232 lines
6.5 KiB
C
232 lines
6.5 KiB
C
/*
|
|
* Copyright (C) 2018 Collabora Ltd.
|
|
* Author: Xavier Claessens <xavier.claessens@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 "gstamc-surfacetexture-ml.h"
|
|
|
|
#include <gst/gst.h>
|
|
#include <ml_media_surface_texture.h>
|
|
|
|
struct _GstAmcSurfaceTextureML
|
|
{
|
|
GObject parent;
|
|
|
|
MLHandle handle;
|
|
GstAmcSurfaceTextureOnFrameAvailableCallback callback;
|
|
gpointer user_data;
|
|
};
|
|
|
|
G_DEFINE_TYPE (GstAmcSurfaceTextureML, gst_amc_surface_texture_ml,
|
|
GST_TYPE_AMC_SURFACE_TEXTURE);
|
|
|
|
gboolean
|
|
gst_amc_surface_texture_static_init (void)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gst_amc_surface_texture_ml_update_tex_image (GstAmcSurfaceTexture * base,
|
|
GError ** err)
|
|
{
|
|
GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
|
|
MLResult result;
|
|
|
|
result = MLMediaSurfaceTextureUpdateTexImage (self->handle);
|
|
if (result != MLResult_Ok) {
|
|
g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
|
|
"Failed to update tex image: %d", result);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gst_amc_surface_texture_ml_detach_from_gl_context (GstAmcSurfaceTexture * base,
|
|
GError ** err)
|
|
{
|
|
GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
|
|
MLResult result;
|
|
|
|
result = MLMediaSurfaceTextureDetachFromGLContext (self->handle);
|
|
if (result != MLResult_Ok) {
|
|
g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
|
|
"Failed to detach from gl context: %d", result);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gst_amc_surface_texture_ml_attach_to_gl_context (GstAmcSurfaceTexture * base,
|
|
gint texture_id, GError ** err)
|
|
{
|
|
GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
|
|
MLResult result;
|
|
|
|
result = MLMediaSurfaceTextureAttachToGLContext (self->handle, texture_id);
|
|
if (result != MLResult_Ok) {
|
|
g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
|
|
"Failed to attach to gl context: %d", result);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gst_amc_surface_texture_ml_get_transform_matrix (GstAmcSurfaceTexture * base,
|
|
gfloat * matrix, GError ** err)
|
|
{
|
|
GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
|
|
MLResult result;
|
|
|
|
result = MLMediaSurfaceTextureGetTransformationMatrix (self->handle, matrix);
|
|
if (result != MLResult_Ok) {
|
|
g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
|
|
"Failed to get transformation matrix: %d", result);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gst_amc_surface_texture_ml_get_timestamp (GstAmcSurfaceTexture * base,
|
|
gint64 * timestamp, GError ** err)
|
|
{
|
|
GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
|
|
MLResult result;
|
|
|
|
result = MLMediaSurfaceTextureGetTimestamp (self->handle, timestamp);
|
|
if (result != MLResult_Ok) {
|
|
g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
|
|
"Failed to get timestamp: %d", result);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gst_amc_surface_texture_ml_release (GstAmcSurfaceTexture * base, GError ** err)
|
|
{
|
|
/* Nothing to do here, resources will be released when this object gets
|
|
* destroyed. */
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gst_amc_surface_texture_ml_set_on_frame_available_callback
|
|
(GstAmcSurfaceTexture * base,
|
|
GstAmcSurfaceTextureOnFrameAvailableCallback callback, gpointer user_data,
|
|
GError ** err)
|
|
{
|
|
GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
|
|
|
|
self->callback = callback;
|
|
self->user_data = user_data;
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
gst_amc_surface_texture_ml_dispose (GObject * object)
|
|
{
|
|
GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (object);
|
|
|
|
MLMediaSurfaceTextureSetOnFrameAvailableCallback (self->handle, NULL, NULL);
|
|
MLMediaSurfaceTextureDestroy (&self->handle);
|
|
|
|
G_OBJECT_CLASS (gst_amc_surface_texture_ml_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
gst_amc_surface_texture_ml_class_init (GstAmcSurfaceTextureMLClass * 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_ml_dispose;
|
|
|
|
surface_texture_class->update_tex_image =
|
|
gst_amc_surface_texture_ml_update_tex_image;
|
|
surface_texture_class->detach_from_gl_context =
|
|
gst_amc_surface_texture_ml_detach_from_gl_context;
|
|
surface_texture_class->attach_to_gl_context =
|
|
gst_amc_surface_texture_ml_attach_to_gl_context;
|
|
surface_texture_class->get_transform_matrix =
|
|
gst_amc_surface_texture_ml_get_transform_matrix;
|
|
surface_texture_class->get_timestamp =
|
|
gst_amc_surface_texture_ml_get_timestamp;
|
|
surface_texture_class->release = gst_amc_surface_texture_ml_release;
|
|
surface_texture_class->set_on_frame_available_callback =
|
|
gst_amc_surface_texture_ml_set_on_frame_available_callback;
|
|
}
|
|
|
|
static void
|
|
on_frame_available_cb (MLHandle handle, gpointer user_data)
|
|
{
|
|
GstAmcSurfaceTextureML *self = user_data;
|
|
|
|
if (self->callback != NULL)
|
|
self->callback (GST_AMC_SURFACE_TEXTURE (self), self->user_data);
|
|
}
|
|
|
|
static void
|
|
gst_amc_surface_texture_ml_init (GstAmcSurfaceTextureML * self)
|
|
{
|
|
MLResult result;
|
|
|
|
result =
|
|
MLMediaSurfaceTextureCreate (MLMediaSurfaceTextureBackend_OpenGL,
|
|
&self->handle);
|
|
if (result != MLResult_Ok) {
|
|
GST_ERROR ("MLMediaSurfaceTextureCreate returned error: %d", result);
|
|
return;
|
|
}
|
|
|
|
result =
|
|
MLMediaSurfaceTextureSetOnFrameAvailableCallback (self->handle,
|
|
on_frame_available_cb, self);
|
|
if (result != MLResult_Ok) {
|
|
GST_ERROR
|
|
("MLMediaSurfaceTextureSetOnFrameAvailableCallback returned error: %d",
|
|
result);
|
|
return;
|
|
}
|
|
}
|
|
|
|
GstAmcSurfaceTextureML *
|
|
gst_amc_surface_texture_ml_new (GError ** err)
|
|
{
|
|
return g_object_new (GST_TYPE_AMC_SURFACE_TEXTURE_ML, NULL);
|
|
}
|
|
|
|
MLHandle
|
|
gst_amc_surface_texture_ml_get_handle (GstAmcSurfaceTextureML * self)
|
|
{
|
|
return self->handle;
|
|
}
|