• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 Collabora Ltd.
3  *   Author: Xavier Claessens <xavier.claessens@collabora.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation
8  * version 2.1 of the License.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
18  *
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "gstamc-surfacetexture-ml.h"
26 
27 #include <gst/gst.h>
28 #include <ml_media_surface_texture.h>
29 
30 struct _GstAmcSurfaceTextureML
31 {
32   GObject parent;
33 
34   MLHandle handle;
35   GstAmcSurfaceTextureOnFrameAvailableCallback callback;
36   gpointer user_data;
37 };
38 
39 G_DEFINE_TYPE (GstAmcSurfaceTextureML, gst_amc_surface_texture_ml,
40     GST_TYPE_AMC_SURFACE_TEXTURE);
41 
42 gboolean
gst_amc_surface_texture_static_init(void)43 gst_amc_surface_texture_static_init (void)
44 {
45   return TRUE;
46 }
47 
48 static gboolean
gst_amc_surface_texture_ml_update_tex_image(GstAmcSurfaceTexture * base,GError ** err)49 gst_amc_surface_texture_ml_update_tex_image (GstAmcSurfaceTexture * base,
50     GError ** err)
51 {
52   GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
53   MLResult result;
54 
55   result = MLMediaSurfaceTextureUpdateTexImage (self->handle);
56   if (result != MLResult_Ok) {
57     g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
58         "Failed to update tex image: %d", result);
59     return FALSE;
60   }
61 
62   return TRUE;
63 }
64 
65 static gboolean
gst_amc_surface_texture_ml_detach_from_gl_context(GstAmcSurfaceTexture * base,GError ** err)66 gst_amc_surface_texture_ml_detach_from_gl_context (GstAmcSurfaceTexture * base,
67     GError ** err)
68 {
69   GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
70   MLResult result;
71 
72   result = MLMediaSurfaceTextureDetachFromGLContext (self->handle);
73   if (result != MLResult_Ok) {
74     g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
75         "Failed to detach from gl context: %d", result);
76     return FALSE;
77   }
78 
79   return TRUE;
80 }
81 
82 static gboolean
gst_amc_surface_texture_ml_attach_to_gl_context(GstAmcSurfaceTexture * base,gint texture_id,GError ** err)83 gst_amc_surface_texture_ml_attach_to_gl_context (GstAmcSurfaceTexture * base,
84     gint texture_id, GError ** err)
85 {
86   GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
87   MLResult result;
88 
89   result = MLMediaSurfaceTextureAttachToGLContext (self->handle, texture_id);
90   if (result != MLResult_Ok) {
91     g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
92         "Failed to attach to gl context: %d", result);
93     return FALSE;
94   }
95 
96   return TRUE;
97 }
98 
99 static gboolean
gst_amc_surface_texture_ml_get_transform_matrix(GstAmcSurfaceTexture * base,gfloat * matrix,GError ** err)100 gst_amc_surface_texture_ml_get_transform_matrix (GstAmcSurfaceTexture * base,
101     gfloat * matrix, GError ** err)
102 {
103   GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
104   MLResult result;
105 
106   result = MLMediaSurfaceTextureGetTransformationMatrix (self->handle, matrix);
107   if (result != MLResult_Ok) {
108     g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
109         "Failed to get transformation matrix: %d", result);
110     return FALSE;
111   }
112 
113   return TRUE;
114 }
115 
116 static gboolean
gst_amc_surface_texture_ml_get_timestamp(GstAmcSurfaceTexture * base,gint64 * timestamp,GError ** err)117 gst_amc_surface_texture_ml_get_timestamp (GstAmcSurfaceTexture * base,
118     gint64 * timestamp, GError ** err)
119 {
120   GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
121   MLResult result;
122 
123   result = MLMediaSurfaceTextureGetTimestamp (self->handle, timestamp);
124   if (result != MLResult_Ok) {
125     g_set_error (err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
126         "Failed to get timestamp: %d", result);
127     return FALSE;
128   }
129 
130   return TRUE;
131 }
132 
133 static gboolean
gst_amc_surface_texture_ml_release(GstAmcSurfaceTexture * base,GError ** err)134 gst_amc_surface_texture_ml_release (GstAmcSurfaceTexture * base, GError ** err)
135 {
136   /* Nothing to do here, resources will be released when this object gets
137    * destroyed. */
138   return TRUE;
139 }
140 
141 static gboolean
gst_amc_surface_texture_ml_set_on_frame_available_callback(GstAmcSurfaceTexture * base,GstAmcSurfaceTextureOnFrameAvailableCallback callback,gpointer user_data,GError ** err)142     gst_amc_surface_texture_ml_set_on_frame_available_callback
143     (GstAmcSurfaceTexture * base,
144     GstAmcSurfaceTextureOnFrameAvailableCallback callback, gpointer user_data,
145     GError ** err)
146 {
147   GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (base);
148 
149   self->callback = callback;
150   self->user_data = user_data;
151   return TRUE;
152 }
153 
154 static void
gst_amc_surface_texture_ml_dispose(GObject * object)155 gst_amc_surface_texture_ml_dispose (GObject * object)
156 {
157   GstAmcSurfaceTextureML *self = GST_AMC_SURFACE_TEXTURE_ML (object);
158 
159   MLMediaSurfaceTextureSetOnFrameAvailableCallback (self->handle, NULL, NULL);
160   MLMediaSurfaceTextureDestroy (&self->handle);
161 
162   G_OBJECT_CLASS (gst_amc_surface_texture_ml_parent_class)->dispose (object);
163 }
164 
165 static void
gst_amc_surface_texture_ml_class_init(GstAmcSurfaceTextureMLClass * klass)166 gst_amc_surface_texture_ml_class_init (GstAmcSurfaceTextureMLClass * klass)
167 {
168   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
169   GstAmcSurfaceTextureClass *surface_texture_class =
170       GST_AMC_SURFACE_TEXTURE_CLASS (klass);
171 
172   gobject_class->dispose = gst_amc_surface_texture_ml_dispose;
173 
174   surface_texture_class->update_tex_image =
175       gst_amc_surface_texture_ml_update_tex_image;
176   surface_texture_class->detach_from_gl_context =
177       gst_amc_surface_texture_ml_detach_from_gl_context;
178   surface_texture_class->attach_to_gl_context =
179       gst_amc_surface_texture_ml_attach_to_gl_context;
180   surface_texture_class->get_transform_matrix =
181       gst_amc_surface_texture_ml_get_transform_matrix;
182   surface_texture_class->get_timestamp =
183       gst_amc_surface_texture_ml_get_timestamp;
184   surface_texture_class->release = gst_amc_surface_texture_ml_release;
185   surface_texture_class->set_on_frame_available_callback =
186       gst_amc_surface_texture_ml_set_on_frame_available_callback;
187 }
188 
189 static void
on_frame_available_cb(MLHandle handle,gpointer user_data)190 on_frame_available_cb (MLHandle handle, gpointer user_data)
191 {
192   GstAmcSurfaceTextureML *self = user_data;
193 
194   if (self->callback != NULL)
195     self->callback (GST_AMC_SURFACE_TEXTURE (self), self->user_data);
196 }
197 
198 static void
gst_amc_surface_texture_ml_init(GstAmcSurfaceTextureML * self)199 gst_amc_surface_texture_ml_init (GstAmcSurfaceTextureML * self)
200 {
201   MLResult result;
202 
203   result =
204       MLMediaSurfaceTextureCreate (MLMediaSurfaceTextureBackend_OpenGL,
205       &self->handle);
206   if (result != MLResult_Ok) {
207     GST_ERROR ("MLMediaSurfaceTextureCreate returned error: %d", result);
208     return;
209   }
210 
211   result =
212       MLMediaSurfaceTextureSetOnFrameAvailableCallback (self->handle,
213       on_frame_available_cb, self);
214   if (result != MLResult_Ok) {
215     GST_ERROR
216         ("MLMediaSurfaceTextureSetOnFrameAvailableCallback returned error: %d",
217         result);
218     return;
219   }
220 }
221 
222 GstAmcSurfaceTextureML *
gst_amc_surface_texture_ml_new(GError ** err)223 gst_amc_surface_texture_ml_new (GError ** err)
224 {
225   return g_object_new (GST_TYPE_AMC_SURFACE_TEXTURE_ML, NULL);
226 }
227 
228 MLHandle
gst_amc_surface_texture_ml_get_handle(GstAmcSurfaceTextureML * self)229 gst_amc_surface_texture_ml_get_handle (GstAmcSurfaceTextureML * self)
230 {
231   return self->handle;
232 }
233