mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
gl: split glcolorconvert usage from glupload
the separation allows the transfer operation to occur in a separate thread/time which may increase performance in specific circumstances.
This commit is contained in:
parent
19fbe2afbc
commit
1dfeae2c42
12 changed files with 251 additions and 101 deletions
|
@ -682,6 +682,11 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
glimage_sink->upload = NULL;
|
glimage_sink->upload = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (glimage_sink->convert) {
|
||||||
|
gst_object_unref (glimage_sink->convert);
|
||||||
|
glimage_sink->convert = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
glimage_sink->window_id = 0;
|
glimage_sink->window_id = 0;
|
||||||
//but do not reset glimage_sink->new_window_id
|
//but do not reset glimage_sink->new_window_id
|
||||||
|
|
||||||
|
@ -760,6 +765,7 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
GstBufferPool *newpool, *oldpool;
|
GstBufferPool *newpool, *oldpool;
|
||||||
GstCapsFeatures *gl_features;
|
GstCapsFeatures *gl_features;
|
||||||
|
GstCaps *uploaded_caps;
|
||||||
|
|
||||||
GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
|
GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
@ -846,14 +852,30 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
|
|
||||||
gl_features =
|
gl_features =
|
||||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
|
|
||||||
|
uploaded_caps = gst_caps_copy (caps);
|
||||||
|
gst_caps_set_features (uploaded_caps, 0,
|
||||||
|
gst_caps_features_copy (gl_features));
|
||||||
|
gst_gl_upload_set_caps (glimage_sink->upload, caps, uploaded_caps);
|
||||||
|
|
||||||
if (glimage_sink->gl_caps)
|
if (glimage_sink->gl_caps)
|
||||||
gst_caps_unref (glimage_sink->gl_caps);
|
gst_caps_unref (glimage_sink->gl_caps);
|
||||||
glimage_sink->gl_caps = gst_caps_copy (caps);
|
glimage_sink->gl_caps = gst_caps_copy (caps);
|
||||||
gst_caps_set_simple (glimage_sink->gl_caps, "format", G_TYPE_STRING, "RGBA",
|
gst_caps_set_simple (glimage_sink->gl_caps, "format", G_TYPE_STRING, "RGBA",
|
||||||
NULL);
|
NULL);
|
||||||
gst_caps_set_features (glimage_sink->gl_caps, 0, gl_features);
|
gst_caps_set_features (glimage_sink->gl_caps, 0,
|
||||||
|
gst_caps_features_copy (gl_features));
|
||||||
|
|
||||||
|
if (glimage_sink->convert)
|
||||||
|
gst_object_unref (glimage_sink->convert);
|
||||||
|
glimage_sink->convert = gst_gl_color_convert_new (glimage_sink->context);
|
||||||
|
if (!gst_gl_color_convert_set_caps (glimage_sink->convert, uploaded_caps,
|
||||||
|
glimage_sink->gl_caps)) {
|
||||||
|
gst_caps_features_free (gl_features);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
gst_caps_features_free (gl_features);
|
||||||
|
|
||||||
gst_gl_upload_set_caps (glimage_sink->upload, caps, glimage_sink->gl_caps);
|
|
||||||
glimage_sink->caps_change = TRUE;
|
glimage_sink->caps_change = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -863,7 +885,7 @@ static GstFlowReturn
|
||||||
gst_glimage_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
gst_glimage_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstGLImageSink *glimage_sink;
|
GstGLImageSink *glimage_sink;
|
||||||
GstBuffer *next_buffer = NULL;
|
GstBuffer *uploaded_buffer, *next_buffer = NULL;
|
||||||
GstVideoFrame gl_frame;
|
GstVideoFrame gl_frame;
|
||||||
GstVideoInfo gl_info;
|
GstVideoInfo gl_info;
|
||||||
|
|
||||||
|
@ -879,17 +901,26 @@ gst_glimage_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
if (!_ensure_gl_setup (glimage_sink))
|
if (!_ensure_gl_setup (glimage_sink))
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
|
||||||
if (!gst_gl_upload_perform_with_buffer (glimage_sink->upload, buf,
|
if (gst_gl_upload_perform_with_buffer (glimage_sink->upload, buf,
|
||||||
&next_buffer))
|
&uploaded_buffer) != GST_GL_UPLOAD_DONE)
|
||||||
goto upload_failed;
|
goto upload_failed;
|
||||||
|
|
||||||
|
if (!(next_buffer =
|
||||||
|
gst_gl_color_convert_perform (glimage_sink->convert,
|
||||||
|
uploaded_buffer))) {
|
||||||
|
gst_buffer_unref (uploaded_buffer);
|
||||||
|
goto upload_failed;
|
||||||
|
}
|
||||||
|
|
||||||
gst_video_info_from_caps (&gl_info, glimage_sink->gl_caps);
|
gst_video_info_from_caps (&gl_info, glimage_sink->gl_caps);
|
||||||
|
|
||||||
if (!gst_video_frame_map (&gl_frame, &gl_info, next_buffer,
|
if (!gst_video_frame_map (&gl_frame, &gl_info, next_buffer,
|
||||||
GST_MAP_READ | GST_MAP_GL)) {
|
GST_MAP_READ | GST_MAP_GL)) {
|
||||||
|
gst_buffer_unref (uploaded_buffer);
|
||||||
gst_buffer_unref (next_buffer);
|
gst_buffer_unref (next_buffer);
|
||||||
goto upload_failed;
|
goto upload_failed;
|
||||||
}
|
}
|
||||||
|
gst_buffer_unref (uploaded_buffer);
|
||||||
|
|
||||||
glimage_sink->next_tex = *(guint *) gl_frame.data[0];
|
glimage_sink->next_tex = *(guint *) gl_frame.data[0];
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ struct _GstGLImageSink
|
||||||
gboolean handle_events;
|
gboolean handle_events;
|
||||||
|
|
||||||
GstGLUpload *upload;
|
GstGLUpload *upload;
|
||||||
|
GstGLColorConvert *convert;
|
||||||
guint next_tex;
|
guint next_tex;
|
||||||
GstBuffer *next_buffer;
|
GstBuffer *next_buffer;
|
||||||
|
|
||||||
|
|
|
@ -1104,7 +1104,7 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
walk = g_list_next (walk);
|
walk = g_list_next (walk);
|
||||||
|
|
||||||
if (vaggpad->buffer != NULL) {
|
if (vaggpad->buffer != NULL) {
|
||||||
GstBuffer *gl_buf;
|
GstBuffer *uploaded_buf;
|
||||||
GstCaps *gl_caps;
|
GstCaps *gl_caps;
|
||||||
GstCapsFeatures *gl_features;
|
GstCapsFeatures *gl_features;
|
||||||
GstVideoInfo gl_info;
|
GstVideoInfo gl_info;
|
||||||
|
@ -1119,45 +1119,68 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
|
|
||||||
gl_caps = gst_video_info_to_caps (&gl_info);
|
gl_caps = gst_video_info_to_caps (&gl_info);
|
||||||
gst_caps_set_features (gl_caps, 0, gl_features);
|
gst_caps_set_features (gl_caps, 0, gst_caps_features_copy (gl_features));
|
||||||
|
|
||||||
if (!pad->upload) {
|
if (!pad->upload) {
|
||||||
GstCaps *in_caps = gst_pad_get_current_caps (GST_PAD (pad));
|
GstCaps *in_caps = gst_pad_get_current_caps (GST_PAD (pad));
|
||||||
|
GstCaps *upload_caps = gst_caps_copy (in_caps);
|
||||||
|
|
||||||
pad->upload = gst_gl_upload_new (mix->context);
|
pad->upload = gst_gl_upload_new (mix->context);
|
||||||
|
|
||||||
gst_gl_upload_set_caps (pad->upload, in_caps, gl_caps);
|
gst_caps_set_features (upload_caps, 0,
|
||||||
|
gst_caps_features_copy (gl_features));
|
||||||
|
gst_gl_upload_set_caps (pad->upload, in_caps, upload_caps);
|
||||||
|
|
||||||
|
if (!pad->convert) {
|
||||||
|
pad->convert = gst_gl_color_convert_new (mix->context);
|
||||||
|
|
||||||
|
gst_gl_color_convert_set_caps (pad->convert, upload_caps, gl_caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_caps_unref (upload_caps);
|
||||||
gst_caps_unref (in_caps);
|
gst_caps_unref (in_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_caps_features_free (gl_features);
|
||||||
|
gst_caps_unref (gl_caps);
|
||||||
|
|
||||||
sync_meta = gst_buffer_get_gl_sync_meta (vaggpad->buffer);
|
sync_meta = gst_buffer_get_gl_sync_meta (vaggpad->buffer);
|
||||||
if (sync_meta)
|
if (sync_meta)
|
||||||
gst_gl_sync_meta_wait (sync_meta);
|
gst_gl_sync_meta_wait (sync_meta);
|
||||||
|
|
||||||
if (!gst_gl_upload_perform_with_buffer (pad->upload,
|
if (gst_gl_upload_perform_with_buffer (pad->upload,
|
||||||
vaggpad->buffer, &gl_buf)) {
|
vaggpad->buffer, &uploaded_buf) != GST_GL_UPLOAD_DONE) {
|
||||||
++array_index;
|
++array_index;
|
||||||
pad->mapped = FALSE;
|
pad->mapped = FALSE;
|
||||||
gst_caps_unref (gl_caps);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_video_frame_map (&gl_frame, &gl_info, gl_buf,
|
if (pad->gl_buffer)
|
||||||
|
gst_buffer_unref (pad->gl_buffer);
|
||||||
|
|
||||||
|
if (!(pad->gl_buffer =
|
||||||
|
gst_gl_color_convert_perform (pad->convert, uploaded_buf))) {
|
||||||
|
++array_index;
|
||||||
|
pad->mapped = FALSE;
|
||||||
|
gst_buffer_unref (uploaded_buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_video_frame_map (&gl_frame, &gl_info, pad->gl_buffer,
|
||||||
GST_MAP_READ | GST_MAP_GL)) {
|
GST_MAP_READ | GST_MAP_GL)) {
|
||||||
++array_index;
|
++array_index;
|
||||||
pad->mapped = FALSE;
|
pad->mapped = FALSE;
|
||||||
gst_buffer_unref (gl_buf);
|
gst_buffer_unref (uploaded_buf);
|
||||||
gst_caps_unref (gl_caps);
|
gst_buffer_unref (pad->gl_buffer);
|
||||||
|
pad->gl_buffer = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pad->mapped = TRUE;
|
pad->mapped = TRUE;
|
||||||
|
|
||||||
frame->texture = *(guint *) gl_frame.data[0];
|
frame->texture = *(guint *) gl_frame.data[0];
|
||||||
|
|
||||||
gst_caps_unref (gl_caps);
|
gst_buffer_unref (uploaded_buf);
|
||||||
gst_video_frame_unmap (&gl_frame);
|
gst_video_frame_unmap (&gl_frame);
|
||||||
gst_buffer_unref (gl_buf);
|
|
||||||
}
|
}
|
||||||
++array_index;
|
++array_index;
|
||||||
}
|
}
|
||||||
|
@ -1292,11 +1315,21 @@ _clean_upload (GstAggregator * agg, GstAggregatorPad * aggpad, gpointer udata)
|
||||||
{
|
{
|
||||||
GstGLMixerPad *pad = GST_GL_MIXER_PAD (aggpad);
|
GstGLMixerPad *pad = GST_GL_MIXER_PAD (aggpad);
|
||||||
|
|
||||||
|
if (pad->gl_buffer) {
|
||||||
|
gst_buffer_unref (pad->gl_buffer);
|
||||||
|
pad->gl_buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (pad->upload) {
|
if (pad->upload) {
|
||||||
gst_object_unref (pad->upload);
|
gst_object_unref (pad->upload);
|
||||||
pad->upload = NULL;
|
pad->upload = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pad->convert) {
|
||||||
|
gst_object_unref (pad->convert);
|
||||||
|
pad->convert = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,8 @@ struct _GstGLMixerPad
|
||||||
|
|
||||||
/* <private> */
|
/* <private> */
|
||||||
GstGLUpload *upload;
|
GstGLUpload *upload;
|
||||||
guint in_tex_id;
|
GstGLColorConvert *convert;
|
||||||
|
GstBuffer *gl_buffer;
|
||||||
gboolean mapped;
|
gboolean mapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -545,47 +545,76 @@ gst_gl_color_convert_reset (GstGLColorConvert * convert)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
_gst_gl_color_convert_set_format_unlocked (GstGLColorConvert * convert,
|
_gst_gl_color_convert_set_caps_unlocked (GstGLColorConvert * convert,
|
||||||
GstVideoInfo * in_info, GstVideoInfo * out_info)
|
GstCaps * in_caps, GstCaps * out_caps)
|
||||||
{
|
{
|
||||||
g_return_if_fail (convert != NULL);
|
GstVideoInfo in_info, out_info;
|
||||||
g_return_if_fail (in_info);
|
GstCapsFeatures *in_features, *out_features, *gl_features;
|
||||||
g_return_if_fail (out_info);
|
|
||||||
g_return_if_fail (GST_VIDEO_INFO_FORMAT (in_info) !=
|
|
||||||
GST_VIDEO_FORMAT_UNKNOWN);
|
|
||||||
g_return_if_fail (GST_VIDEO_INFO_FORMAT (in_info) !=
|
|
||||||
GST_VIDEO_FORMAT_ENCODED);
|
|
||||||
g_return_if_fail (GST_VIDEO_INFO_FORMAT (out_info) !=
|
|
||||||
GST_VIDEO_FORMAT_UNKNOWN);
|
|
||||||
g_return_if_fail (GST_VIDEO_INFO_FORMAT (out_info) !=
|
|
||||||
GST_VIDEO_FORMAT_ENCODED);
|
|
||||||
|
|
||||||
if (gst_video_info_is_equal (&convert->in_info, in_info) &&
|
g_return_val_if_fail (convert != NULL, FALSE);
|
||||||
gst_video_info_is_equal (&convert->out_info, out_info))
|
g_return_val_if_fail (in_caps, FALSE);
|
||||||
return;
|
g_return_val_if_fail (out_caps, FALSE);
|
||||||
|
|
||||||
|
if (!gst_video_info_from_caps (&in_info, in_caps))
|
||||||
|
g_assert_not_reached ();
|
||||||
|
|
||||||
|
if (!gst_video_info_from_caps (&out_info, out_caps))
|
||||||
|
g_assert_not_reached ();
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&in_info) !=
|
||||||
|
GST_VIDEO_FORMAT_UNKNOWN, FALSE);
|
||||||
|
g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&in_info) !=
|
||||||
|
GST_VIDEO_FORMAT_ENCODED, FALSE);
|
||||||
|
g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&out_info) !=
|
||||||
|
GST_VIDEO_FORMAT_UNKNOWN, FALSE);
|
||||||
|
g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&out_info) !=
|
||||||
|
GST_VIDEO_FORMAT_ENCODED, FALSE);
|
||||||
|
|
||||||
|
gl_features =
|
||||||
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
|
in_features = gst_caps_get_features (in_caps, 0);
|
||||||
|
out_features = gst_caps_get_features (out_caps, 0);
|
||||||
|
|
||||||
|
if (!gst_caps_features_is_equal (in_features, gl_features)
|
||||||
|
|| !gst_caps_features_is_equal (out_features, gl_features)) {
|
||||||
|
gst_caps_features_free (gl_features);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_caps_features_free (gl_features);
|
||||||
|
|
||||||
|
if (gst_video_info_is_equal (&convert->in_info, &in_info) &&
|
||||||
|
gst_video_info_is_equal (&convert->out_info, &out_info))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
gst_gl_color_convert_reset (convert);
|
gst_gl_color_convert_reset (convert);
|
||||||
convert->in_info = *in_info;
|
convert->in_info = in_info;
|
||||||
convert->out_info = *out_info;
|
convert->out_info = out_info;
|
||||||
convert->initted = FALSE;
|
convert->initted = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_gl_color_convert_set_format:
|
* gst_gl_color_convert_set_caps:
|
||||||
* @convert: a #GstGLColorConvert
|
* @convert: a #GstGLColorConvert
|
||||||
* @in_info: input #GstVideoInfo
|
* @in_info: input #GstVideoInfo
|
||||||
* @out_info: output #GstVideoInfo
|
* @out_info: output #GstVideoInfo
|
||||||
*
|
*
|
||||||
* Initializes @convert with the information required for conversion.
|
* Initializes @convert with the information required for conversion.
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_gl_color_convert_set_format (GstGLColorConvert * convert,
|
gst_gl_color_convert_set_caps (GstGLColorConvert * convert,
|
||||||
GstVideoInfo * in_info, GstVideoInfo * out_info)
|
GstCaps * in_caps, GstCaps * out_caps)
|
||||||
{
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (convert);
|
GST_OBJECT_LOCK (convert);
|
||||||
_gst_gl_color_convert_set_format_unlocked (convert, in_info, out_info);
|
ret = _gst_gl_color_convert_set_caps_unlocked (convert, in_caps, out_caps);
|
||||||
GST_OBJECT_UNLOCK (convert);
|
GST_OBJECT_UNLOCK (convert);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -594,7 +623,7 @@ gst_gl_color_convert_set_format (GstGLColorConvert * convert,
|
||||||
* @inbuf: the texture ids for input formatted according to in_info
|
* @inbuf: the texture ids for input formatted according to in_info
|
||||||
*
|
*
|
||||||
* Converts the data contained by @inbuf using the formats specified by the
|
* Converts the data contained by @inbuf using the formats specified by the
|
||||||
* #GstVideoInfo<!-- -->s passed to gst_gl_color_convert_set_format()
|
* #GstVideoInfo<!-- -->s passed to gst_gl_color_convert_set_caps()
|
||||||
*
|
*
|
||||||
* Returns: a converted #GstBuffer or %NULL%
|
* Returns: a converted #GstBuffer or %NULL%
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -97,9 +97,9 @@ struct _GstGLColorConvertClass
|
||||||
|
|
||||||
GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context);
|
GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context);
|
||||||
|
|
||||||
void gst_gl_color_convert_set_format (GstGLColorConvert * convert,
|
gboolean gst_gl_color_convert_set_caps (GstGLColorConvert * convert,
|
||||||
GstVideoInfo * in_info,
|
GstCaps * in_caps,
|
||||||
GstVideoInfo * out_info);
|
GstCaps * out_caps);
|
||||||
|
|
||||||
GstBuffer * gst_gl_color_convert_perform (GstGLColorConvert * convert, GstBuffer * inbuf);
|
GstBuffer * gst_gl_color_convert_perform (GstGLColorConvert * convert, GstBuffer * inbuf);
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,9 @@ _init_download (GstGLDownload * download)
|
||||||
GstVideoFormat v_format;
|
GstVideoFormat v_format;
|
||||||
guint out_width, out_height;
|
guint out_width, out_height;
|
||||||
GstVideoInfo in_info;
|
GstVideoInfo in_info;
|
||||||
|
GstCaps *in_caps, *out_caps;
|
||||||
|
GstCapsFeatures *in_gl_features, *out_gl_features;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
v_format = GST_VIDEO_INFO_FORMAT (&download->info);
|
v_format = GST_VIDEO_INFO_FORMAT (&download->info);
|
||||||
out_width = GST_VIDEO_INFO_WIDTH (&download->info);
|
out_width = GST_VIDEO_INFO_WIDTH (&download->info);
|
||||||
|
@ -266,13 +269,24 @@ _init_download (GstGLDownload * download)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_gl_features =
|
||||||
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
gst_video_info_set_format (&in_info, GST_VIDEO_FORMAT_RGBA, out_width,
|
gst_video_info_set_format (&in_info, GST_VIDEO_FORMAT_RGBA, out_width,
|
||||||
out_height);
|
out_height);
|
||||||
|
in_caps = gst_video_info_to_caps (&in_info);
|
||||||
|
gst_caps_set_features (in_caps, 0, in_gl_features);
|
||||||
|
|
||||||
gst_gl_color_convert_set_format (download->convert, &in_info,
|
out_gl_features =
|
||||||
&download->info);
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
|
out_caps = gst_video_info_to_caps (&download->info);
|
||||||
|
gst_caps_set_features (out_caps, 0, out_gl_features);
|
||||||
|
|
||||||
return TRUE;
|
res = gst_gl_color_convert_set_caps (download->convert, in_caps, out_caps);
|
||||||
|
|
||||||
|
gst_caps_unref (in_caps);
|
||||||
|
gst_caps_unref (out_caps);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -253,6 +253,11 @@ gst_gl_filter_reset (GstGLFilter * filter)
|
||||||
filter->upload = NULL;
|
filter->upload = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter->in_convert) {
|
||||||
|
gst_object_unref (filter->in_convert);
|
||||||
|
filter->in_convert = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->download) {
|
if (filter->download) {
|
||||||
gst_object_unref (filter->download);
|
gst_object_unref (filter->download);
|
||||||
filter->download = NULL;
|
filter->download = NULL;
|
||||||
|
@ -309,9 +314,9 @@ gst_gl_filter_reset (GstGLFilter * filter)
|
||||||
gst_object_unref (filter->context);
|
gst_object_unref (filter->context);
|
||||||
filter->context = NULL;
|
filter->context = NULL;
|
||||||
|
|
||||||
if (filter->in_gl_caps) {
|
if (filter->in_converted_caps) {
|
||||||
gst_caps_unref (filter->in_gl_caps);
|
gst_caps_unref (filter->in_converted_caps);
|
||||||
filter->in_gl_caps = NULL;
|
filter->in_converted_caps = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1225,26 +1230,34 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf,
|
||||||
gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY,
|
gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY,
|
||||||
gst_caps_get_features (filter->out_caps, 0));
|
gst_caps_get_features (filter->out_caps, 0));
|
||||||
GstMapFlags out_map_flags = GST_MAP_WRITE;
|
GstMapFlags out_map_flags = GST_MAP_WRITE;
|
||||||
|
GstBuffer *upload_buffer;
|
||||||
|
|
||||||
filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||||
|
|
||||||
|
if (gst_gl_upload_perform_with_buffer (filter->upload, inbuf,
|
||||||
|
&upload_buffer) != GST_GL_UPLOAD_DONE) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->uploaded_buffer) {
|
if (filter->uploaded_buffer) {
|
||||||
gst_buffer_unref (filter->uploaded_buffer);
|
gst_buffer_unref (filter->uploaded_buffer);
|
||||||
filter->uploaded_buffer = NULL;
|
filter->uploaded_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_gl_upload_perform_with_buffer (filter->upload, inbuf,
|
filter->uploaded_buffer =
|
||||||
&filter->uploaded_buffer)) {
|
gst_gl_color_convert_perform (filter->in_convert, upload_buffer);
|
||||||
|
|
||||||
|
if (!filter->uploaded_buffer) {
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
goto upload_error;
|
goto inbuf_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_video_info_from_caps (&gl_info, filter->in_gl_caps);
|
gst_video_info_from_caps (&gl_info, filter->in_converted_caps);
|
||||||
|
|
||||||
if (!gst_video_frame_map (&gl_frame, &gl_info, filter->uploaded_buffer,
|
if (!gst_video_frame_map (&gl_frame, &gl_info, filter->uploaded_buffer,
|
||||||
GST_MAP_READ | GST_MAP_GL)) {
|
GST_MAP_READ | GST_MAP_GL)) {
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
goto upload_error;
|
goto inbuf_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_tex = *(guint *) gl_frame.data[0];
|
in_tex = *(guint *) gl_frame.data[0];
|
||||||
|
@ -1257,7 +1270,7 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf,
|
||||||
if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
|
if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
|
||||||
out_map_flags)) {
|
out_map_flags)) {
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
goto inbuf_error;
|
goto unmap_out_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!to_download) {
|
if (!to_download) {
|
||||||
|
@ -1290,10 +1303,11 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_video_frame_unmap (&gl_frame);
|
gst_video_frame_unmap (&gl_frame);
|
||||||
upload_error:
|
unmap_out_error:
|
||||||
gst_video_frame_unmap (&out_frame);
|
gst_video_frame_unmap (&out_frame);
|
||||||
inbuf_error:
|
inbuf_error:
|
||||||
gst_gl_upload_release_buffer (filter->upload);
|
gst_gl_upload_release_buffer (filter->upload);
|
||||||
|
gst_buffer_unref (upload_buffer);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1315,6 +1329,7 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
if (!filter->upload) {
|
if (!filter->upload) {
|
||||||
GstCaps *in_caps =
|
GstCaps *in_caps =
|
||||||
gst_pad_get_current_caps (GST_BASE_TRANSFORM_SINK_PAD (bt));
|
gst_pad_get_current_caps (GST_BASE_TRANSFORM_SINK_PAD (bt));
|
||||||
|
GstCaps *uploaded_caps;
|
||||||
GstCapsFeatures *out_features;
|
GstCapsFeatures *out_features;
|
||||||
GstVideoInfo out_info;
|
GstVideoInfo out_info;
|
||||||
|
|
||||||
|
@ -1325,16 +1340,42 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
out_features =
|
out_features =
|
||||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
|
|
||||||
if (filter->in_gl_caps)
|
uploaded_caps = gst_caps_copy (in_caps);
|
||||||
gst_caps_unref (filter->in_gl_caps);
|
gst_caps_set_features (uploaded_caps, 0, out_features);
|
||||||
filter->in_gl_caps = gst_video_info_to_caps (&out_info);
|
|
||||||
gst_caps_set_features (filter->in_gl_caps, 0, out_features);
|
|
||||||
|
|
||||||
filter->upload = gst_gl_upload_new (filter->context);
|
filter->upload = gst_gl_upload_new (filter->context);
|
||||||
if (!gst_gl_upload_set_caps (filter->upload, in_caps, filter->in_gl_caps))
|
if (!gst_gl_upload_set_caps (filter->upload, in_caps, uploaded_caps)) {
|
||||||
|
gst_caps_unref (in_caps);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
gst_caps_unref (in_caps);
|
gst_caps_unref (in_caps);
|
||||||
|
|
||||||
|
if (!filter->in_convert) {
|
||||||
|
GstCapsFeatures *converted_features;
|
||||||
|
GstVideoInfo converted_info;
|
||||||
|
|
||||||
|
gst_video_info_set_format (&converted_info,
|
||||||
|
GST_VIDEO_FORMAT_RGBA,
|
||||||
|
GST_VIDEO_INFO_WIDTH (&filter->in_info),
|
||||||
|
GST_VIDEO_INFO_HEIGHT (&filter->in_info));
|
||||||
|
converted_features =
|
||||||
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
|
|
||||||
|
if (filter->in_converted_caps)
|
||||||
|
gst_caps_unref (filter->in_converted_caps);
|
||||||
|
filter->in_converted_caps = gst_video_info_to_caps (&converted_info);
|
||||||
|
gst_caps_set_features (filter->in_converted_caps, 0, converted_features);
|
||||||
|
|
||||||
|
filter->in_convert = gst_gl_color_convert_new (filter->context);
|
||||||
|
if (!gst_gl_color_convert_set_caps (filter->in_convert, uploaded_caps,
|
||||||
|
filter->in_converted_caps)) {
|
||||||
|
gst_caps_unref (uploaded_caps);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_caps_unref (uploaded_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert (filter_class->filter || filter_class->filter_texture);
|
g_assert (filter_class->filter || filter_class->filter_texture);
|
||||||
|
|
|
@ -75,6 +75,9 @@ struct _GstGLFilter
|
||||||
GLuint depthbuffer;
|
GLuint depthbuffer;
|
||||||
|
|
||||||
GstGLUpload *upload;
|
GstGLUpload *upload;
|
||||||
|
GstGLColorConvert *in_convert;
|
||||||
|
GstCaps *in_converted_caps;
|
||||||
|
|
||||||
GstGLDownload *download;
|
GstGLDownload *download;
|
||||||
|
|
||||||
GstBuffer *uploaded_buffer;
|
GstBuffer *uploaded_buffer;
|
||||||
|
@ -88,8 +91,6 @@ struct _GstGLFilter
|
||||||
GstGLContext *context;
|
GstGLContext *context;
|
||||||
GstGLContext *other_context;
|
GstGLContext *other_context;
|
||||||
|
|
||||||
GstCaps *in_gl_caps;
|
|
||||||
|
|
||||||
GLuint vao;
|
GLuint vao;
|
||||||
GLuint vertex_buffer;
|
GLuint vertex_buffer;
|
||||||
GLint draw_attr_position_loc;
|
GLint draw_attr_position_loc;
|
||||||
|
|
|
@ -68,16 +68,6 @@ struct _GstGLUploadPrivate
|
||||||
int method_i;
|
int method_i;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
GST_GL_UPLOAD_DONE = 1,
|
|
||||||
GST_GL_UPLOAD_CONVERT_GL_MEMORY = 2,
|
|
||||||
|
|
||||||
GST_GL_UPLOAD_ERROR = -1,
|
|
||||||
GST_GL_UPLOAD_UNSUPPORTED = -2,
|
|
||||||
GST_GL_UPLOAD_UNSHARED_GL_CONTEXT = 3,
|
|
||||||
} GstGLUploadReturn;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
METHOD_FLAG_CAN_SHARE_CONTEXT = 1,
|
METHOD_FLAG_CAN_SHARE_CONTEXT = 1,
|
||||||
|
@ -165,7 +155,7 @@ _gl_memory_upload_perform (gpointer impl, GstBuffer * buffer,
|
||||||
|
|
||||||
*outbuf = gst_buffer_ref (buffer);
|
*outbuf = gst_buffer_ref (buffer);
|
||||||
|
|
||||||
return GST_GL_UPLOAD_CONVERT_GL_MEMORY;
|
return GST_GL_UPLOAD_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -277,7 +267,7 @@ _egl_image_upload_perform (gpointer impl, GstBuffer * buffer,
|
||||||
gst_gl_buffer_pool_replace_last_buffer (GST_GL_BUFFER_POOL (buffer->pool),
|
gst_gl_buffer_pool_replace_last_buffer (GST_GL_BUFFER_POOL (buffer->pool),
|
||||||
buffer);
|
buffer);
|
||||||
|
|
||||||
return GST_GL_UPLOAD_CONVERT_GL_MEMORY;
|
return GST_GL_UPLOAD_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -421,7 +411,7 @@ _upload_meta_upload_perform (gpointer impl, GstBuffer * buffer,
|
||||||
if (!upload->result)
|
if (!upload->result)
|
||||||
return GST_GL_UPLOAD_ERROR;
|
return GST_GL_UPLOAD_ERROR;
|
||||||
|
|
||||||
return GST_GL_UPLOAD_CONVERT_GL_MEMORY;
|
return GST_GL_UPLOAD_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -522,7 +512,7 @@ _raw_data_upload_perform (gpointer impl, GstBuffer * buffer,
|
||||||
gst_memory_ref ((GstMemory *) raw->in_tex[i]));
|
gst_memory_ref ((GstMemory *) raw->in_tex[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_GL_UPLOAD_CONVERT_GL_MEMORY;
|
return GST_GL_UPLOAD_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -768,11 +758,11 @@ _upload_find_method (GstGLUpload * upload)
|
||||||
*
|
*
|
||||||
* Returns: whether the upload was successful
|
* Returns: whether the upload was successful
|
||||||
*/
|
*/
|
||||||
gboolean
|
GstGLUploadReturn
|
||||||
gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer,
|
gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer,
|
||||||
GstBuffer ** outbuf_ptr)
|
GstBuffer ** outbuf_ptr)
|
||||||
{
|
{
|
||||||
GstGLUploadReturn ret;
|
GstGLUploadReturn ret = GST_GL_UPLOAD_ERROR;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_GL_UPLOAD (upload), FALSE);
|
g_return_val_if_fail (GST_IS_GL_UPLOAD (upload), FALSE);
|
||||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
|
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
|
||||||
|
@ -806,22 +796,6 @@ restart:
|
||||||
upload->priv->method = &_raw_data_upload;
|
upload->priv->method = &_raw_data_upload;
|
||||||
upload->priv->method_impl = upload->priv->method->new (upload);
|
upload->priv->method_impl = upload->priv->method->new (upload);
|
||||||
goto restart;
|
goto restart;
|
||||||
} else if (ret == GST_GL_UPLOAD_CONVERT_GL_MEMORY) {
|
|
||||||
GstBuffer *outbuf;
|
|
||||||
|
|
||||||
if (!upload->priv->convert)
|
|
||||||
upload->priv->convert = gst_gl_color_convert_new (upload->context);
|
|
||||||
gst_gl_color_convert_set_format (upload->priv->convert,
|
|
||||||
&upload->priv->in_info, &upload->priv->out_info);
|
|
||||||
|
|
||||||
if (!(outbuf = gst_gl_color_convert_perform (upload->priv->convert,
|
|
||||||
upload->priv->outbuf))) {
|
|
||||||
gst_gl_upload_release_buffer_unlocked (upload);
|
|
||||||
NEXT_METHOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_buffer_unref (upload->priv->outbuf);
|
|
||||||
upload->priv->outbuf = outbuf;
|
|
||||||
} else if (ret == GST_GL_UPLOAD_DONE) {
|
} else if (ret == GST_GL_UPLOAD_DONE) {
|
||||||
/* we are done */
|
/* we are done */
|
||||||
} else {
|
} else {
|
||||||
|
@ -835,7 +809,7 @@ restart:
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (upload);
|
GST_OBJECT_UNLOCK (upload);
|
||||||
|
|
||||||
return upload->priv->outbuf != NULL;
|
return ret;
|
||||||
|
|
||||||
#undef NEXT_METHOD
|
#undef NEXT_METHOD
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,22 @@ GType gst_gl_upload_get_type (void);
|
||||||
#define GST_IS_GL_UPLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_UPLOAD))
|
#define GST_IS_GL_UPLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_UPLOAD))
|
||||||
#define GST_GL_UPLOAD_CAST(obj) ((GstGLUpload*)(obj))
|
#define GST_GL_UPLOAD_CAST(obj) ((GstGLUpload*)(obj))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstGLUploadReturn:
|
||||||
|
* @GST_GL_UPLOAD_DONE: No further processing required
|
||||||
|
* @GST_GL_UPLOAD_ERROR: An unspecified error occured
|
||||||
|
* @GST_GL_UPLOAD_UNSUPPORTED: The configuration is unsupported.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_GL_UPLOAD_DONE = 1,
|
||||||
|
|
||||||
|
GST_GL_UPLOAD_ERROR = -1,
|
||||||
|
GST_GL_UPLOAD_UNSUPPORTED = -2,
|
||||||
|
/* <private> */
|
||||||
|
GST_GL_UPLOAD_UNSHARED_GL_CONTEXT = -3,
|
||||||
|
} GstGLUploadReturn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstGLUpload
|
* GstGLUpload
|
||||||
*
|
*
|
||||||
|
@ -67,8 +83,8 @@ GstGLUpload * gst_gl_upload_new (GstGLContext * context);
|
||||||
gboolean gst_gl_upload_set_caps (GstGLUpload * upload, GstCaps * in_caps, GstCaps * out_caps);
|
gboolean gst_gl_upload_set_caps (GstGLUpload * upload, GstCaps * in_caps, GstCaps * out_caps);
|
||||||
void gst_gl_upload_get_caps (GstGLUpload * upload, GstCaps ** in_caps, GstCaps ** out_caps);
|
void gst_gl_upload_get_caps (GstGLUpload * upload, GstCaps ** in_caps, GstCaps ** out_caps);
|
||||||
|
|
||||||
gboolean gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, GstBuffer ** outbuf);
|
GstGLUploadReturn gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, GstBuffer ** outbuf);
|
||||||
void gst_gl_upload_release_buffer (GstGLUpload * upload);
|
void gst_gl_upload_release_buffer (GstGLUpload * upload);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -120,8 +120,12 @@ check_conversion (TestFrame * frames, guint size)
|
||||||
gchar *in_data[GST_VIDEO_MAX_PLANES] = { 0 };
|
gchar *in_data[GST_VIDEO_MAX_PLANES] = { 0 };
|
||||||
GstGLMemory *in_mem[GST_VIDEO_MAX_PLANES] = { 0 };
|
GstGLMemory *in_mem[GST_VIDEO_MAX_PLANES] = { 0 };
|
||||||
GstVideoFrame in_frame;
|
GstVideoFrame in_frame;
|
||||||
|
GstCaps *in_caps;
|
||||||
|
|
||||||
gst_video_info_set_format (&in_info, in_v_format, in_width, in_height);
|
gst_video_info_set_format (&in_info, in_v_format, in_width, in_height);
|
||||||
|
in_caps = gst_video_info_to_caps (&in_info);
|
||||||
|
gst_caps_set_features (in_caps, 0,
|
||||||
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));
|
||||||
|
|
||||||
for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&in_info); j++) {
|
for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&in_info); j++) {
|
||||||
in_data[j] = frames[i].data[j];
|
in_data[j] = frames[i].data[j];
|
||||||
|
@ -155,15 +159,19 @@ check_conversion (TestFrame * frames, guint size)
|
||||||
GstVideoFormat out_v_format = frames[j].v_format;
|
GstVideoFormat out_v_format = frames[j].v_format;
|
||||||
gchar *out_data[GST_VIDEO_MAX_PLANES] = { 0 };
|
gchar *out_data[GST_VIDEO_MAX_PLANES] = { 0 };
|
||||||
GstVideoFrame out_frame;
|
GstVideoFrame out_frame;
|
||||||
|
GstCaps *out_caps;
|
||||||
|
|
||||||
gst_video_info_set_format (&out_info, out_v_format, out_width,
|
gst_video_info_set_format (&out_info, out_v_format, out_width,
|
||||||
out_height);
|
out_height);
|
||||||
|
out_caps = gst_video_info_to_caps (&out_info);
|
||||||
|
gst_caps_set_features (out_caps, 0,
|
||||||
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));
|
||||||
|
|
||||||
for (k = 0; k < GST_VIDEO_INFO_N_PLANES (&out_info); k++) {
|
for (k = 0; k < GST_VIDEO_INFO_N_PLANES (&out_info); k++) {
|
||||||
out_data[k] = frames[j].data[k];
|
out_data[k] = frames[j].data[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_gl_color_convert_set_format (convert, &in_info, &out_info);
|
gst_gl_color_convert_set_caps (convert, in_caps, out_caps);
|
||||||
|
|
||||||
/* convert the data */
|
/* convert the data */
|
||||||
outbuf = gst_gl_color_convert_perform (convert, inbuf);
|
outbuf = gst_gl_color_convert_perform (convert, inbuf);
|
||||||
|
@ -190,6 +198,7 @@ check_conversion (TestFrame * frames, guint size)
|
||||||
gst_buffer_unref (outbuf);
|
gst_buffer_unref (outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_caps_unref (in_caps);
|
||||||
gst_video_frame_unmap (&in_frame);
|
gst_video_frame_unmap (&in_frame);
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue