mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
glvideomixer: don't upload if alpha <= 0
Implemented using a upload_buffer vfunc within GstGLMixer allowing NULL uploaded buffers.
This commit is contained in:
parent
aedfadd972
commit
02fdc64844
3 changed files with 116 additions and 77 deletions
|
@ -54,6 +54,8 @@ static void gst_gl_mixer_pad_get_property (GObject * object, guint prop_id,
|
|||
static void gst_gl_mixer_pad_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_gl_mixer_pad_finalize (GObject * object);
|
||||
static GstBuffer *_default_pad_upload_buffer (GstGLMixer * mix,
|
||||
GstGLMixerFrameData * frame, GstBuffer * buffer);
|
||||
|
||||
static void gst_gl_mixer_set_context (GstElement * element,
|
||||
GstContext * context);
|
||||
|
@ -98,6 +100,8 @@ gst_gl_mixer_pad_class_init (GstGLMixerPadClass * klass)
|
|||
vaggpad_class->set_info = NULL;
|
||||
vaggpad_class->prepare_frame = NULL;
|
||||
vaggpad_class->clean_frame = NULL;
|
||||
|
||||
klass->upload_buffer = _default_pad_upload_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1043,6 +1047,81 @@ no_decide_allocation:
|
|||
}
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
_default_pad_upload_buffer (GstGLMixer * mix, GstGLMixerFrameData * frame,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstVideoAggregatorPad *vaggpad = GST_VIDEO_AGGREGATOR_PAD (frame->pad);
|
||||
GstGLMixerPad *pad = frame->pad;
|
||||
GstBuffer *uploaded_buf, *gl_buffer;
|
||||
GstCaps *gl_caps;
|
||||
GstCapsFeatures *gl_features;
|
||||
GstVideoInfo gl_info;
|
||||
GstVideoFrame gl_frame;
|
||||
GstGLSyncMeta *sync_meta;
|
||||
|
||||
gst_video_info_set_format (&gl_info,
|
||||
GST_VIDEO_FORMAT_RGBA,
|
||||
GST_VIDEO_INFO_WIDTH (&vaggpad->info),
|
||||
GST_VIDEO_INFO_HEIGHT (&vaggpad->info));
|
||||
gl_features =
|
||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||
|
||||
gl_caps = gst_video_info_to_caps (&gl_info);
|
||||
gst_caps_set_features (gl_caps, 0, gst_caps_features_copy (gl_features));
|
||||
|
||||
if (!pad->upload) {
|
||||
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);
|
||||
|
||||
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_features_free (gl_features);
|
||||
gst_caps_unref (gl_caps);
|
||||
|
||||
sync_meta = gst_buffer_get_gl_sync_meta (vaggpad->buffer);
|
||||
if (sync_meta)
|
||||
gst_gl_sync_meta_wait (sync_meta);
|
||||
|
||||
if (gst_gl_upload_perform_with_buffer (pad->upload,
|
||||
vaggpad->buffer, &uploaded_buf) != GST_GL_UPLOAD_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(gl_buffer = gst_gl_color_convert_perform (pad->convert, uploaded_buf))) {
|
||||
gst_buffer_unref (uploaded_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!gst_video_frame_map (&gl_frame, &gl_info, gl_buffer,
|
||||
GST_MAP_READ | GST_MAP_GL)) {
|
||||
gst_buffer_unref (uploaded_buf);
|
||||
gst_buffer_unref (gl_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
frame->texture = *(guint *) gl_frame.data[0];
|
||||
|
||||
gst_buffer_unref (uploaded_buf);
|
||||
gst_video_frame_unmap (&gl_frame);
|
||||
|
||||
return gl_buffer;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
||||
{
|
||||
|
@ -1094,6 +1173,7 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
|||
mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData);
|
||||
while (walk) {
|
||||
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
||||
GstGLMixerPadClass *pad_class = GST_GL_MIXER_PAD_GET_CLASS (pad);
|
||||
GstVideoAggregatorPad *vaggpad = walk->data;
|
||||
GstGLMixerFrameData *frame;
|
||||
|
||||
|
@ -1104,84 +1184,17 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
|||
walk = g_list_next (walk);
|
||||
|
||||
if (vaggpad->buffer != NULL) {
|
||||
GstBuffer *uploaded_buf;
|
||||
GstCaps *gl_caps;
|
||||
GstCapsFeatures *gl_features;
|
||||
GstVideoInfo gl_info;
|
||||
GstVideoFrame gl_frame;
|
||||
GstGLSyncMeta *sync_meta;
|
||||
|
||||
gst_video_info_set_format (&gl_info,
|
||||
GST_VIDEO_FORMAT_RGBA,
|
||||
GST_VIDEO_INFO_WIDTH (&vaggpad->info),
|
||||
GST_VIDEO_INFO_HEIGHT (&vaggpad->info));
|
||||
gl_features =
|
||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||
|
||||
gl_caps = gst_video_info_to_caps (&gl_info);
|
||||
gst_caps_set_features (gl_caps, 0, gst_caps_features_copy (gl_features));
|
||||
|
||||
if (!pad->upload) {
|
||||
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);
|
||||
|
||||
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_features_free (gl_features);
|
||||
gst_caps_unref (gl_caps);
|
||||
|
||||
sync_meta = gst_buffer_get_gl_sync_meta (vaggpad->buffer);
|
||||
if (sync_meta)
|
||||
gst_gl_sync_meta_wait (sync_meta);
|
||||
|
||||
if (gst_gl_upload_perform_with_buffer (pad->upload,
|
||||
vaggpad->buffer, &uploaded_buf) != GST_GL_UPLOAD_DONE) {
|
||||
++array_index;
|
||||
pad->mapped = FALSE;
|
||||
continue;
|
||||
}
|
||||
g_assert (pad_class->upload_buffer);
|
||||
|
||||
if (pad->gl_buffer)
|
||||
gst_buffer_unref (pad->gl_buffer);
|
||||
pad->gl_buffer = pad_class->upload_buffer (mix, frame, vaggpad->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)) {
|
||||
++array_index;
|
||||
pad->mapped = FALSE;
|
||||
gst_buffer_unref (uploaded_buf);
|
||||
gst_buffer_unref (pad->gl_buffer);
|
||||
pad->gl_buffer = NULL;
|
||||
continue;
|
||||
}
|
||||
pad->mapped = TRUE;
|
||||
|
||||
frame->texture = *(guint *) gl_frame.data[0];
|
||||
|
||||
gst_buffer_unref (uploaded_buf);
|
||||
gst_video_frame_unmap (&gl_frame);
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"uploaded buffer %" GST_PTR_FORMAT " from buffer %" GST_PTR_FORMAT,
|
||||
pad->gl_buffer, vaggpad->buffer);
|
||||
}
|
||||
|
||||
++array_index;
|
||||
}
|
||||
|
||||
|
@ -1217,10 +1230,9 @@ out:
|
|||
while (walk) {
|
||||
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
||||
|
||||
if (pad->mapped)
|
||||
if (pad->upload)
|
||||
gst_gl_upload_release_buffer (pad->upload);
|
||||
|
||||
pad->mapped = FALSE;
|
||||
walk = g_list_next (walk);
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -29,15 +29,20 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstGLMixer GstGLMixer;
|
||||
typedef struct _GstGLMixerFrameData GstGLMixerFrameData;
|
||||
|
||||
#define GST_TYPE_GL_MIXER_PAD (gst_gl_mixer_pad_get_type())
|
||||
#define GST_GL_MIXER_PAD(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_MIXER_PAD, GstGLMixerPad))
|
||||
#define GST_GL_MIXER_PAD_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GL_MIXER_PAD, GstGLMixerPadiClass))
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GL_MIXER_PAD, GstGLMixerPadClass))
|
||||
#define GST_IS_GL_MIXER_PAD(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_MIXER_PAD))
|
||||
#define GST_IS_GL_MIXER_PAD_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_MIXER_PAD))
|
||||
#define GST_GL_MIXER_PAD_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_GL_MIXER_PAD,GstGLMixerPadClass))
|
||||
|
||||
typedef struct _GstGLMixerPad GstGLMixerPad;
|
||||
typedef struct _GstGLMixerPadClass GstGLMixerPadClass;
|
||||
|
@ -51,12 +56,13 @@ struct _GstGLMixerPad
|
|||
GstGLUpload *upload;
|
||||
GstGLColorConvert *convert;
|
||||
GstBuffer *gl_buffer;
|
||||
gboolean mapped;
|
||||
};
|
||||
|
||||
struct _GstGLMixerPadClass
|
||||
{
|
||||
GstVideoAggregatorPadClass parent_class;
|
||||
|
||||
GstBuffer * (*upload_buffer) (GstGLMixer * mix, GstGLMixerFrameData * frame, GstBuffer * buffer);
|
||||
};
|
||||
|
||||
GType gst_gl_mixer_pad_get_type (void);
|
||||
|
|
|
@ -178,6 +178,8 @@ static void gst_gl_video_mixer_pad_set_property (GObject * object,
|
|||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||
static void gst_gl_video_mixer_pad_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
static GstBuffer *gst_gl_video_mixer_pad_upload_buffer (GstGLMixer * mix,
|
||||
GstGLMixerFrameData * frame, GstBuffer * buffer);
|
||||
|
||||
#define DEFAULT_PAD_XPOS 0
|
||||
#define DEFAULT_PAD_YPOS 0
|
||||
|
@ -204,6 +206,7 @@ static void
|
|||
gst_gl_video_mixer_pad_class_init (GstGLVideoMixerPadClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstGLMixerPadClass *mix_pad_class = (GstGLMixerPadClass *) klass;
|
||||
|
||||
gobject_class->set_property = gst_gl_video_mixer_pad_set_property;
|
||||
gobject_class->get_property = gst_gl_video_mixer_pad_get_property;
|
||||
|
@ -228,6 +231,8 @@ gst_gl_video_mixer_pad_class_init (GstGLVideoMixerPadClass * klass)
|
|||
g_param_spec_double ("alpha", "Alpha", "Alpha of the picture", 0.0, 1.0,
|
||||
DEFAULT_PAD_ALPHA,
|
||||
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
mix_pad_class->upload_buffer = gst_gl_video_mixer_pad_upload_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -293,6 +298,22 @@ gst_gl_video_mixer_pad_set_property (GObject * object, guint prop_id,
|
|||
gst_object_unref (mix);
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
gst_gl_video_mixer_pad_upload_buffer (GstGLMixer * mix,
|
||||
GstGLMixerFrameData * frame, GstBuffer * buffer)
|
||||
{
|
||||
GstGLVideoMixerPad *pad = GST_GL_VIDEO_MIXER_PAD (frame->pad);
|
||||
|
||||
if (pad->alpha > 0.0) {
|
||||
return
|
||||
GST_GL_MIXER_PAD_CLASS
|
||||
(gst_gl_video_mixer_pad_parent_class)->upload_buffer (mix, frame,
|
||||
buffer);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define GST_GL_TYPE_VIDEO_MIXER_BACKGROUND (gst_gl_video_mixer_background_get_type())
|
||||
static GType
|
||||
gst_gl_video_mixer_background_get_type (void)
|
||||
|
|
Loading…
Reference in a new issue