gst_gl_upload_element_init (GstGLUploadElement * upload)
{
gst_base_transform_set_prefer_passthrough (GST_BASE_TRANSFORM (upload), TRUE);
+
+ upload->upload = gst_gl_upload_new (NULL);
}
static gboolean
_gst_gl_upload_element_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
+ GstGLUploadElement *upload = GST_GL_UPLOAD_ELEMENT (bt);
GstGLContext *context = GST_GL_BASE_FILTER (bt)->context;
- return gst_gl_upload_transform_caps (context, direction, caps, filter);
+ return gst_gl_upload_transform_caps (upload->upload, context, direction, caps,
+ filter);
}
static gboolean
if (!ret)
return FALSE;
+ /* GstGLBaseFilter populates ->context in ::decide_allocation so now it's the
+ * time to set the ->upload context */
context = GST_GL_BASE_FILTER (trans)->context;
-
- if (!upload->upload)
- upload->upload = gst_gl_upload_new (context);
+ gst_gl_upload_set_context (upload->upload, context);
return gst_gl_upload_set_caps (upload->upload, upload->in_caps,
upload->out_caps);
return GST_FLOW_NOT_NEGOTIATED;
ret = gst_gl_upload_perform_with_buffer (upload->upload, buffer, outbuf);
+ if (ret == GST_GL_UPLOAD_RECONFIGURE) {
+ gst_base_transform_reconfigure_src (bt);
+ return GST_FLOW_OK;
+ }
if (ret != GST_GL_UPLOAD_DONE || *outbuf == NULL) {
GST_ELEMENT_ERROR (bt, RESOURCE, NOT_FOUND, ("%s",
GstStaticCaps *input_template_caps;
gpointer (*new) (GstGLUpload * upload);
- GstCaps *(*transform_caps) (GstGLContext * context,
+ GstCaps *(*transform_caps) (gpointer impl, GstGLContext * context,
GstPadDirection direction, GstCaps * caps);
gboolean (*accept) (gpointer impl, GstBuffer * buffer, GstCaps * in_caps,
GstCaps * out_caps);
struct GLMemoryUpload
{
GstGLUpload *upload;
+ GstGLTextureTarget input_target;
};
static gpointer
struct GLMemoryUpload *mem = g_new0 (struct GLMemoryUpload, 1);
mem->upload = upload;
+ mem->input_target = GST_GL_TEXTURE_TARGET_NONE;
return mem;
}
static GstCaps *
-_gl_memory_upload_transform_caps (GstGLContext * context,
+_gl_memory_upload_transform_caps (gpointer impl, GstGLContext * context,
GstPadDirection direction, GstCaps * caps)
{
+ struct GLMemoryUpload *upload = impl;
GstCapsFeatures *passthrough =
gst_caps_features_from_string
(GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
gst_caps_features_free (passthrough);
if (direction == GST_PAD_SINK) {
- GstGLTextureTarget target_mask = 0;
GstCaps *tmp;
+ GstGLTextureTarget target_mask;
+
+ if (upload->input_target != GST_GL_TEXTURE_TARGET_NONE) {
+ target_mask = 1 << upload->input_target;
+ } else {
+ target_mask = 1 << GST_GL_TEXTURE_TARGET_2D |
+ 1 << GST_GL_TEXTURE_TARGET_RECTANGLE |
+ 1 << GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
+ }
- target_mask |= 1 << GST_GL_TEXTURE_TARGET_2D;
- target_mask |= 1 << GST_GL_TEXTURE_TARGET_RECTANGLE;
- target_mask |= 1 << GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
tmp = _caps_intersect_texture_target (ret, target_mask);
gst_caps_unref (ret);
ret = tmp;
gl_mem->mem.context))
return GST_GL_UPLOAD_UNSHARED_GL_CONTEXT;
+ if (upload->input_target != gl_mem->tex_target) {
+ upload->input_target = gl_mem->tex_target;
+ *outbuf = NULL;
+ return GST_GL_UPLOAD_RECONFIGURE;
+ }
+
if (gst_is_gl_memory_pbo (mem))
gst_gl_memory_pbo_upload_transfer ((GstGLMemoryPBO *) mem);
}
}
static GstCaps *
-_dma_buf_upload_transform_caps (GstGLContext * context,
+_dma_buf_upload_transform_caps (gpointer impl, GstGLContext * context,
GstPadDirection direction, GstCaps * caps)
{
GstCapsFeatures *passthrough =
struct GLUploadMeta *meta = g_new0 (struct GLUploadMeta, 1);
meta->upload = upload;
- meta->pool = gst_gl_buffer_pool_new (upload->context);
+ meta->pool = NULL;
return meta;
}
static GstCaps *
-_upload_meta_upload_transform_caps (GstGLContext * context,
+_upload_meta_upload_transform_caps (gpointer impl, GstGLContext * context,
GstPadDirection direction, GstCaps * caps)
{
GstCapsFeatures *passthrough =
if (!ret)
return ret;
+ if (upload->pool == NULL)
+ upload->pool = gst_gl_buffer_pool_new (upload->upload->context);
+
if (!gst_buffer_pool_is_active (upload->pool)) {
config = gst_buffer_pool_get_config (upload->pool);
}
static GstCaps *
-_raw_data_upload_transform_caps (GstGLContext * context,
+_raw_data_upload_transform_caps (gpointer impl, GstGLContext * context,
GstPadDirection direction, GstCaps * caps)
{
GstCapsFeatures *passthrough =
GstGLUpload *upload = g_object_new (GST_TYPE_GL_UPLOAD, NULL);
gint i, n;
- upload->context = gst_object_ref (context);
+ if (context)
+ gst_gl_upload_set_context (upload, context);
+ else
+ upload->context = NULL;
n = G_N_ELEMENTS (upload_methods);
upload->priv->upload_impl = g_malloc (sizeof (gpointer) * n);
return upload;
}
+void
+gst_gl_upload_set_context (GstGLUpload * upload, GstGLContext * context)
+{
+ g_return_if_fail (upload != NULL);
+
+ gst_object_replace ((GstObject **) & upload->context, (GstObject *) context);
+}
+
static void
gst_gl_upload_finalize (GObject * object)
{
upload = GST_GL_UPLOAD (object);
- if (upload->priv->method_impl)
- upload->priv->method->free (upload->priv->method_impl);
upload->priv->method_i = 0;
if (upload->context) {
}
GstCaps *
-gst_gl_upload_transform_caps (GstGLContext * context, GstPadDirection direction,
- GstCaps * caps, GstCaps * filter)
+gst_gl_upload_transform_caps (GstGLUpload * upload, GstGLContext * context,
+ GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
GstCaps *result, *tmp;
gint i;
for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
GstCaps *tmp2;
- tmp2 = upload_methods[i]->transform_caps (context, direction, caps);
+ tmp2 =
+ upload_methods[i]->transform_caps (upload->priv->upload_impl[i],
+ context, direction, caps);
if (tmp2)
tmp = gst_caps_merge (tmp, tmp2);
gst_video_info_from_caps (&upload->priv->in_info, in_caps);
gst_video_info_from_caps (&upload->priv->out_info, out_caps);
- if (upload->priv->method_impl)
- upload->priv->method->free (upload->priv->method_impl);
upload->priv->method_impl = NULL;
upload->priv->method_i = 0;
static gboolean
_upload_find_method (GstGLUpload * upload)
{
+ gint method_i;
+
if (upload->priv->method_i >= G_N_ELEMENTS (upload_methods))
return FALSE;
- if (upload->priv->method_impl) {
- upload->priv->method->free (upload->priv->method_impl);
- upload->priv->method_impl = NULL;
- }
-
- upload->priv->method = upload_methods[upload->priv->method_i];
- upload->priv->method_impl = upload->priv->method->new (upload);
+ method_i = upload->priv->method_i;
+ upload->priv->method = upload_methods[method_i];
+ upload->priv->method_impl = upload->priv->upload_impl[method_i];
GST_DEBUG_OBJECT (upload, "attempting upload with uploader %s",
upload->priv->method->name);
upload->priv->method->perform (upload->priv->method_impl, buffer,
&outbuf);
if (ret == GST_GL_UPLOAD_UNSHARED_GL_CONTEXT) {
- upload->priv->method->free (upload->priv->method_impl);
- upload->priv->method = &_raw_data_upload;
- upload->priv->method_impl = upload->priv->method->new (upload);
+ for (int i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
+ if (upload_methods[i] == &_raw_data_upload) {
+ upload->priv->method = &_raw_data_upload;
+ upload->priv->method_impl = upload->priv->upload_impl[i];
+ upload->priv->method_i = i;
+
+ break;
+ }
+ }
goto restart;
- } else if (ret == GST_GL_UPLOAD_DONE) {
+ } else if (ret == GST_GL_UPLOAD_DONE || ret == GST_GL_UPLOAD_RECONFIGURE) {
/* we are done */
} else {
- upload->priv->method->free (upload->priv->method_impl);
upload->priv->method_impl = NULL;
NEXT_METHOD;
}
- if (buffer != outbuf)
+ if (outbuf && buffer != outbuf)
gst_buffer_copy_into (outbuf, buffer,
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
*outbuf_ptr = outbuf;