mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
gstglupload: make the GLMemoryUpload method output the correct texture-target
Now when used with video/x-raw as input, the GLMemoryUpload method checks for ->tex_target in input GLMemory(es) and sets the output texture-target accordingly. Fixes video corruption with a pipeline like avfvideosrc ! video/x-raw ! glimagesink where on macos avfvideosrc pushes RECTANGLE textures but glupload was configuring texture-target=2D as output.
This commit is contained in:
parent
bcc29643db
commit
cc9f65f191
3 changed files with 79 additions and 37 deletions
|
@ -97,6 +97,8 @@ static void
|
||||||
gst_gl_upload_element_init (GstGLUploadElement * upload)
|
gst_gl_upload_element_init (GstGLUploadElement * upload)
|
||||||
{
|
{
|
||||||
gst_base_transform_set_prefer_passthrough (GST_BASE_TRANSFORM (upload), TRUE);
|
gst_base_transform_set_prefer_passthrough (GST_BASE_TRANSFORM (upload), TRUE);
|
||||||
|
|
||||||
|
upload->upload = gst_gl_upload_new (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -133,9 +135,11 @@ static GstCaps *
|
||||||
_gst_gl_upload_element_transform_caps (GstBaseTransform * bt,
|
_gst_gl_upload_element_transform_caps (GstBaseTransform * bt,
|
||||||
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
|
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
|
||||||
{
|
{
|
||||||
|
GstGLUploadElement *upload = GST_GL_UPLOAD_ELEMENT (bt);
|
||||||
GstGLContext *context = GST_GL_BASE_FILTER (bt)->context;
|
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
|
static gboolean
|
||||||
|
@ -177,10 +181,10 @@ _gst_gl_upload_element_decide_allocation (GstBaseTransform * trans,
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return FALSE;
|
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;
|
context = GST_GL_BASE_FILTER (trans)->context;
|
||||||
|
gst_gl_upload_set_context (upload->upload, context);
|
||||||
if (!upload->upload)
|
|
||||||
upload->upload = gst_gl_upload_new (context);
|
|
||||||
|
|
||||||
return gst_gl_upload_set_caps (upload->upload, upload->in_caps,
|
return gst_gl_upload_set_caps (upload->upload, upload->in_caps,
|
||||||
upload->out_caps);
|
upload->out_caps);
|
||||||
|
@ -220,6 +224,10 @@ gst_gl_upload_element_prepare_output_buffer (GstBaseTransform * bt,
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
|
||||||
ret = gst_gl_upload_perform_with_buffer (upload->upload, buffer, outbuf);
|
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) {
|
if (ret != GST_GL_UPLOAD_DONE || *outbuf == NULL) {
|
||||||
GST_ELEMENT_ERROR (bt, RESOURCE, NOT_FOUND, ("%s",
|
GST_ELEMENT_ERROR (bt, RESOURCE, NOT_FOUND, ("%s",
|
||||||
|
|
|
@ -189,7 +189,7 @@ struct _UploadMethod
|
||||||
GstStaticCaps *input_template_caps;
|
GstStaticCaps *input_template_caps;
|
||||||
|
|
||||||
gpointer (*new) (GstGLUpload * upload);
|
gpointer (*new) (GstGLUpload * upload);
|
||||||
GstCaps *(*transform_caps) (GstGLContext * context,
|
GstCaps *(*transform_caps) (gpointer impl, GstGLContext * context,
|
||||||
GstPadDirection direction, GstCaps * caps);
|
GstPadDirection direction, GstCaps * caps);
|
||||||
gboolean (*accept) (gpointer impl, GstBuffer * buffer, GstCaps * in_caps,
|
gboolean (*accept) (gpointer impl, GstBuffer * buffer, GstCaps * in_caps,
|
||||||
GstCaps * out_caps);
|
GstCaps * out_caps);
|
||||||
|
@ -203,6 +203,7 @@ struct _UploadMethod
|
||||||
struct GLMemoryUpload
|
struct GLMemoryUpload
|
||||||
{
|
{
|
||||||
GstGLUpload *upload;
|
GstGLUpload *upload;
|
||||||
|
GstGLTextureTarget input_target;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
|
@ -211,14 +212,16 @@ _gl_memory_upload_new (GstGLUpload * upload)
|
||||||
struct GLMemoryUpload *mem = g_new0 (struct GLMemoryUpload, 1);
|
struct GLMemoryUpload *mem = g_new0 (struct GLMemoryUpload, 1);
|
||||||
|
|
||||||
mem->upload = upload;
|
mem->upload = upload;
|
||||||
|
mem->input_target = GST_GL_TEXTURE_TARGET_NONE;
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_gl_memory_upload_transform_caps (GstGLContext * context,
|
_gl_memory_upload_transform_caps (gpointer impl, GstGLContext * context,
|
||||||
GstPadDirection direction, GstCaps * caps)
|
GstPadDirection direction, GstCaps * caps)
|
||||||
{
|
{
|
||||||
|
struct GLMemoryUpload *upload = impl;
|
||||||
GstCapsFeatures *passthrough =
|
GstCapsFeatures *passthrough =
|
||||||
gst_caps_features_from_string
|
gst_caps_features_from_string
|
||||||
(GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
|
(GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
|
||||||
|
@ -231,12 +234,17 @@ _gl_memory_upload_transform_caps (GstGLContext * context,
|
||||||
gst_caps_features_free (passthrough);
|
gst_caps_features_free (passthrough);
|
||||||
|
|
||||||
if (direction == GST_PAD_SINK) {
|
if (direction == GST_PAD_SINK) {
|
||||||
GstGLTextureTarget target_mask = 0;
|
|
||||||
GstCaps *tmp;
|
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);
|
tmp = _caps_intersect_texture_target (ret, target_mask);
|
||||||
gst_caps_unref (ret);
|
gst_caps_unref (ret);
|
||||||
ret = tmp;
|
ret = tmp;
|
||||||
|
@ -412,6 +420,12 @@ _gl_memory_upload_perform (gpointer impl, GstBuffer * buffer,
|
||||||
gl_mem->mem.context))
|
gl_mem->mem.context))
|
||||||
return GST_GL_UPLOAD_UNSHARED_GL_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))
|
if (gst_is_gl_memory_pbo (mem))
|
||||||
gst_gl_memory_pbo_upload_transfer ((GstGLMemoryPBO *) mem);
|
gst_gl_memory_pbo_upload_transfer ((GstGLMemoryPBO *) mem);
|
||||||
}
|
}
|
||||||
|
@ -466,7 +480,7 @@ _dma_buf_upload_new (GstGLUpload * upload)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_dma_buf_upload_transform_caps (GstGLContext * context,
|
_dma_buf_upload_transform_caps (gpointer impl, GstGLContext * context,
|
||||||
GstPadDirection direction, GstCaps * caps)
|
GstPadDirection direction, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstCapsFeatures *passthrough =
|
GstCapsFeatures *passthrough =
|
||||||
|
@ -714,13 +728,13 @@ _upload_meta_upload_new (GstGLUpload * upload)
|
||||||
struct GLUploadMeta *meta = g_new0 (struct GLUploadMeta, 1);
|
struct GLUploadMeta *meta = g_new0 (struct GLUploadMeta, 1);
|
||||||
|
|
||||||
meta->upload = upload;
|
meta->upload = upload;
|
||||||
meta->pool = gst_gl_buffer_pool_new (upload->context);
|
meta->pool = NULL;
|
||||||
|
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_upload_meta_upload_transform_caps (GstGLContext * context,
|
_upload_meta_upload_transform_caps (gpointer impl, GstGLContext * context,
|
||||||
GstPadDirection direction, GstCaps * caps)
|
GstPadDirection direction, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstCapsFeatures *passthrough =
|
GstCapsFeatures *passthrough =
|
||||||
|
@ -783,6 +797,9 @@ _upload_meta_upload_accept (gpointer impl, GstBuffer * buffer,
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 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)) {
|
if (!gst_buffer_pool_is_active (upload->pool)) {
|
||||||
config = gst_buffer_pool_get_config (upload->pool);
|
config = gst_buffer_pool_get_config (upload->pool);
|
||||||
|
|
||||||
|
@ -1012,7 +1029,7 @@ _raw_data_upload_new (GstGLUpload * upload)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_raw_data_upload_transform_caps (GstGLContext * context,
|
_raw_data_upload_transform_caps (gpointer impl, GstGLContext * context,
|
||||||
GstPadDirection direction, GstCaps * caps)
|
GstPadDirection direction, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstCapsFeatures *passthrough =
|
GstCapsFeatures *passthrough =
|
||||||
|
@ -1216,7 +1233,10 @@ gst_gl_upload_new (GstGLContext * context)
|
||||||
GstGLUpload *upload = g_object_new (GST_TYPE_GL_UPLOAD, NULL);
|
GstGLUpload *upload = g_object_new (GST_TYPE_GL_UPLOAD, NULL);
|
||||||
gint i, n;
|
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);
|
n = G_N_ELEMENTS (upload_methods);
|
||||||
upload->priv->upload_impl = g_malloc (sizeof (gpointer) * n);
|
upload->priv->upload_impl = g_malloc (sizeof (gpointer) * n);
|
||||||
|
@ -1230,6 +1250,14 @@ gst_gl_upload_new (GstGLContext * context)
|
||||||
return upload;
|
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
|
static void
|
||||||
gst_gl_upload_finalize (GObject * object)
|
gst_gl_upload_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
|
@ -1238,8 +1266,6 @@ gst_gl_upload_finalize (GObject * object)
|
||||||
|
|
||||||
upload = GST_GL_UPLOAD (object);
|
upload = GST_GL_UPLOAD (object);
|
||||||
|
|
||||||
if (upload->priv->method_impl)
|
|
||||||
upload->priv->method->free (upload->priv->method_impl);
|
|
||||||
upload->priv->method_i = 0;
|
upload->priv->method_i = 0;
|
||||||
|
|
||||||
if (upload->context) {
|
if (upload->context) {
|
||||||
|
@ -1268,8 +1294,8 @@ gst_gl_upload_finalize (GObject * object)
|
||||||
}
|
}
|
||||||
|
|
||||||
GstCaps *
|
GstCaps *
|
||||||
gst_gl_upload_transform_caps (GstGLContext * context, GstPadDirection direction,
|
gst_gl_upload_transform_caps (GstGLUpload * upload, GstGLContext * context,
|
||||||
GstCaps * caps, GstCaps * filter)
|
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
|
||||||
{
|
{
|
||||||
GstCaps *result, *tmp;
|
GstCaps *result, *tmp;
|
||||||
gint i;
|
gint i;
|
||||||
|
@ -1279,7 +1305,9 @@ gst_gl_upload_transform_caps (GstGLContext * context, GstPadDirection direction,
|
||||||
for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
|
for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
|
||||||
GstCaps *tmp2;
|
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)
|
if (tmp2)
|
||||||
tmp = gst_caps_merge (tmp, tmp2);
|
tmp = gst_caps_merge (tmp, tmp2);
|
||||||
|
@ -1332,8 +1360,6 @@ _gst_gl_upload_set_caps_unlocked (GstGLUpload * upload, GstCaps * in_caps,
|
||||||
gst_video_info_from_caps (&upload->priv->in_info, in_caps);
|
gst_video_info_from_caps (&upload->priv->in_info, in_caps);
|
||||||
gst_video_info_from_caps (&upload->priv->out_info, out_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_impl = NULL;
|
||||||
upload->priv->method_i = 0;
|
upload->priv->method_i = 0;
|
||||||
|
|
||||||
|
@ -1388,16 +1414,14 @@ gst_gl_upload_get_caps (GstGLUpload * upload, GstCaps ** in_caps,
|
||||||
static gboolean
|
static gboolean
|
||||||
_upload_find_method (GstGLUpload * upload)
|
_upload_find_method (GstGLUpload * upload)
|
||||||
{
|
{
|
||||||
|
gint method_i;
|
||||||
|
|
||||||
if (upload->priv->method_i >= G_N_ELEMENTS (upload_methods))
|
if (upload->priv->method_i >= G_N_ELEMENTS (upload_methods))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (upload->priv->method_impl) {
|
method_i = upload->priv->method_i;
|
||||||
upload->priv->method->free (upload->priv->method_impl);
|
upload->priv->method = upload_methods[method_i];
|
||||||
upload->priv->method_impl = NULL;
|
upload->priv->method_impl = upload->priv->upload_impl[method_i];
|
||||||
}
|
|
||||||
|
|
||||||
upload->priv->method = upload_methods[upload->priv->method_i];
|
|
||||||
upload->priv->method_impl = upload->priv->method->new (upload);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (upload, "attempting upload with uploader %s",
|
GST_DEBUG_OBJECT (upload, "attempting upload with uploader %s",
|
||||||
upload->priv->method->name);
|
upload->priv->method->name);
|
||||||
|
@ -1452,19 +1476,24 @@ restart:
|
||||||
upload->priv->method->perform (upload->priv->method_impl, buffer,
|
upload->priv->method->perform (upload->priv->method_impl, buffer,
|
||||||
&outbuf);
|
&outbuf);
|
||||||
if (ret == GST_GL_UPLOAD_UNSHARED_GL_CONTEXT) {
|
if (ret == GST_GL_UPLOAD_UNSHARED_GL_CONTEXT) {
|
||||||
upload->priv->method->free (upload->priv->method_impl);
|
for (int i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
|
||||||
upload->priv->method = &_raw_data_upload;
|
if (upload_methods[i] == &_raw_data_upload) {
|
||||||
upload->priv->method_impl = upload->priv->method->new (upload);
|
upload->priv->method = &_raw_data_upload;
|
||||||
|
upload->priv->method_impl = upload->priv->upload_impl[i];
|
||||||
|
upload->priv->method_i = i;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
goto restart;
|
goto restart;
|
||||||
} else if (ret == GST_GL_UPLOAD_DONE) {
|
} else if (ret == GST_GL_UPLOAD_DONE || ret == GST_GL_UPLOAD_RECONFIGURE) {
|
||||||
/* we are done */
|
/* we are done */
|
||||||
} else {
|
} else {
|
||||||
upload->priv->method->free (upload->priv->method_impl);
|
|
||||||
upload->priv->method_impl = NULL;
|
upload->priv->method_impl = NULL;
|
||||||
NEXT_METHOD;
|
NEXT_METHOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer != outbuf)
|
if (outbuf && buffer != outbuf)
|
||||||
gst_buffer_copy_into (outbuf, buffer,
|
gst_buffer_copy_into (outbuf, buffer,
|
||||||
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
|
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
|
||||||
*outbuf_ptr = outbuf;
|
*outbuf_ptr = outbuf;
|
||||||
|
|
|
@ -47,8 +47,9 @@ typedef enum
|
||||||
|
|
||||||
GST_GL_UPLOAD_ERROR = -1,
|
GST_GL_UPLOAD_ERROR = -1,
|
||||||
GST_GL_UPLOAD_UNSUPPORTED = -2,
|
GST_GL_UPLOAD_UNSUPPORTED = -2,
|
||||||
|
GST_GL_UPLOAD_RECONFIGURE = -3,
|
||||||
/* <private> */
|
/* <private> */
|
||||||
GST_GL_UPLOAD_UNSHARED_GL_CONTEXT = -3,
|
GST_GL_UPLOAD_UNSHARED_GL_CONTEXT = -100,
|
||||||
} GstGLUploadReturn;
|
} GstGLUploadReturn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,7 +83,11 @@ GstCaps * gst_gl_upload_get_input_template_caps (void);
|
||||||
|
|
||||||
GstGLUpload * gst_gl_upload_new (GstGLContext * context);
|
GstGLUpload * gst_gl_upload_new (GstGLContext * context);
|
||||||
|
|
||||||
GstCaps * gst_gl_upload_transform_caps (GstGLContext * context,
|
void gst_gl_upload_set_context (GstGLUpload * upload,
|
||||||
|
GstGLContext * context);
|
||||||
|
|
||||||
|
GstCaps * gst_gl_upload_transform_caps (GstGLUpload * upload,
|
||||||
|
GstGLContext * context,
|
||||||
GstPadDirection direction,
|
GstPadDirection direction,
|
||||||
GstCaps * caps,
|
GstCaps * caps,
|
||||||
GstCaps * filter);
|
GstCaps * filter);
|
||||||
|
|
Loading…
Reference in a new issue