mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +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,
|
static void gst_gl_mixer_pad_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec);
|
const GValue * value, GParamSpec * pspec);
|
||||||
static void gst_gl_mixer_pad_finalize (GObject * object);
|
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,
|
static void gst_gl_mixer_set_context (GstElement * element,
|
||||||
GstContext * context);
|
GstContext * context);
|
||||||
|
@ -98,6 +100,8 @@ gst_gl_mixer_pad_class_init (GstGLMixerPadClass * klass)
|
||||||
vaggpad_class->set_info = NULL;
|
vaggpad_class->set_info = NULL;
|
||||||
vaggpad_class->prepare_frame = NULL;
|
vaggpad_class->prepare_frame = NULL;
|
||||||
vaggpad_class->clean_frame = NULL;
|
vaggpad_class->clean_frame = NULL;
|
||||||
|
|
||||||
|
klass->upload_buffer = _default_pad_upload_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
gboolean
|
||||||
gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
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);
|
mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData);
|
||||||
while (walk) {
|
while (walk) {
|
||||||
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
||||||
|
GstGLMixerPadClass *pad_class = GST_GL_MIXER_PAD_GET_CLASS (pad);
|
||||||
GstVideoAggregatorPad *vaggpad = walk->data;
|
GstVideoAggregatorPad *vaggpad = walk->data;
|
||||||
GstGLMixerFrameData *frame;
|
GstGLMixerFrameData *frame;
|
||||||
|
|
||||||
|
@ -1104,84 +1184,17 @@ 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 *uploaded_buf;
|
g_assert (pad_class->upload_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) {
|
|
||||||
++array_index;
|
|
||||||
pad->mapped = FALSE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pad->gl_buffer)
|
if (pad->gl_buffer)
|
||||||
gst_buffer_unref (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_DEBUG_OBJECT (pad,
|
||||||
gst_gl_color_convert_perform (pad->convert, uploaded_buf))) {
|
"uploaded buffer %" GST_PTR_FORMAT " from buffer %" GST_PTR_FORMAT,
|
||||||
++array_index;
|
pad->gl_buffer, vaggpad->buffer);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++array_index;
|
++array_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1217,10 +1230,9 @@ out:
|
||||||
while (walk) {
|
while (walk) {
|
||||||
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
||||||
|
|
||||||
if (pad->mapped)
|
if (pad->upload)
|
||||||
gst_gl_upload_release_buffer (pad->upload);
|
gst_gl_upload_release_buffer (pad->upload);
|
||||||
|
|
||||||
pad->mapped = FALSE;
|
|
||||||
walk = g_list_next (walk);
|
walk = g_list_next (walk);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,15 +29,20 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
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_TYPE_GL_MIXER_PAD (gst_gl_mixer_pad_get_type())
|
||||||
#define GST_GL_MIXER_PAD(obj) \
|
#define GST_GL_MIXER_PAD(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_MIXER_PAD, GstGLMixerPad))
|
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_MIXER_PAD, GstGLMixerPad))
|
||||||
#define GST_GL_MIXER_PAD_CLASS(klass) \
|
#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) \
|
#define GST_IS_GL_MIXER_PAD(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_MIXER_PAD))
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_MIXER_PAD))
|
||||||
#define GST_IS_GL_MIXER_PAD_CLASS(klass) \
|
#define GST_IS_GL_MIXER_PAD_CLASS(klass) \
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_MIXER_PAD))
|
(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 _GstGLMixerPad GstGLMixerPad;
|
||||||
typedef struct _GstGLMixerPadClass GstGLMixerPadClass;
|
typedef struct _GstGLMixerPadClass GstGLMixerPadClass;
|
||||||
|
@ -51,12 +56,13 @@ struct _GstGLMixerPad
|
||||||
GstGLUpload *upload;
|
GstGLUpload *upload;
|
||||||
GstGLColorConvert *convert;
|
GstGLColorConvert *convert;
|
||||||
GstBuffer *gl_buffer;
|
GstBuffer *gl_buffer;
|
||||||
gboolean mapped;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLMixerPadClass
|
struct _GstGLMixerPadClass
|
||||||
{
|
{
|
||||||
GstVideoAggregatorPadClass parent_class;
|
GstVideoAggregatorPadClass parent_class;
|
||||||
|
|
||||||
|
GstBuffer * (*upload_buffer) (GstGLMixer * mix, GstGLMixerFrameData * frame, GstBuffer * buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_gl_mixer_pad_get_type (void);
|
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);
|
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||||
static void gst_gl_video_mixer_pad_get_property (GObject * object,
|
static void gst_gl_video_mixer_pad_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
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_XPOS 0
|
||||||
#define DEFAULT_PAD_YPOS 0
|
#define DEFAULT_PAD_YPOS 0
|
||||||
|
@ -204,6 +206,7 @@ static void
|
||||||
gst_gl_video_mixer_pad_class_init (GstGLVideoMixerPadClass * klass)
|
gst_gl_video_mixer_pad_class_init (GstGLVideoMixerPadClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = (GObjectClass *) 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->set_property = gst_gl_video_mixer_pad_set_property;
|
||||||
gobject_class->get_property = gst_gl_video_mixer_pad_get_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,
|
g_param_spec_double ("alpha", "Alpha", "Alpha of the picture", 0.0, 1.0,
|
||||||
DEFAULT_PAD_ALPHA,
|
DEFAULT_PAD_ALPHA,
|
||||||
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
mix_pad_class->upload_buffer = gst_gl_video_mixer_pad_upload_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -293,6 +298,22 @@ gst_gl_video_mixer_pad_set_property (GObject * object, guint prop_id,
|
||||||
gst_object_unref (mix);
|
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())
|
#define GST_GL_TYPE_VIDEO_MIXER_BACKGROUND (gst_gl_video_mixer_background_get_type())
|
||||||
static GType
|
static GType
|
||||||
gst_gl_video_mixer_background_get_type (void)
|
gst_gl_video_mixer_background_get_type (void)
|
||||||
|
|
Loading…
Reference in a new issue